xref: /AOO42X/main/libxmlsec/xmlsec1-nssmangleciphers.patch (revision 5c188fd8b0acfebcf1dd47494903a089da5b9bcd)
1cdf0e10cSrcweir--- misc/xmlsec1-1.2.14/src/nss/ciphers.c   2009-09-10 05:16:27.000000000 -0400
2cdf0e10cSrcweir+++ misc/build/xmlsec1-1.2.14/src/nss/ciphers.c 2009-09-10 06:59:39.000000000 -0400
3cdf0e10cSrcweir@@ -11,180 +11,421 @@
4cdf0e10cSrcweir
5cdf0e10cSrcweir #include <string.h>
6cdf0e10cSrcweir
7cdf0e10cSrcweir-#include <nspr.h>
8cdf0e10cSrcweir #include <nss.h>
9cdf0e10cSrcweir-#include <secoid.h>
10cdf0e10cSrcweir #include <pk11func.h>
11cdf0e10cSrcweir
12cdf0e10cSrcweir #include <xmlsec/xmlsec.h>
13cdf0e10cSrcweir+#include <xmlsec/xmltree.h>
14cdf0e10cSrcweir+#include <xmlsec/base64.h>
15cdf0e10cSrcweir #include <xmlsec/keys.h>
16cdf0e10cSrcweir #include <xmlsec/transforms.h>
17cdf0e10cSrcweir #include <xmlsec/errors.h>
18cdf0e10cSrcweir
19cdf0e10cSrcweir #include <xmlsec/nss/crypto.h>
20cdf0e10cSrcweir-
21cdf0e10cSrcweir-#define XMLSEC_NSS_MAX_KEY_SIZE        32
22cdf0e10cSrcweir-#define XMLSEC_NSS_MAX_IV_SIZE     32
23cdf0e10cSrcweir-#define XMLSEC_NSS_MAX_BLOCK_SIZE  32
24cdf0e10cSrcweir+#include <xmlsec/nss/ciphers.h>
25cdf0e10cSrcweir
26cdf0e10cSrcweir /**************************************************************************
27cdf0e10cSrcweir  *
28cdf0e10cSrcweir- * Internal Nss Block cipher CTX
29cdf0e10cSrcweir+ * Internal Nss Block Cipher Context
30cdf0e10cSrcweir+ * This context is designed for repositing a block cipher for transform
31cdf0e10cSrcweir  *
32cdf0e10cSrcweir  *****************************************************************************/
33cdf0e10cSrcweir-typedef struct _xmlSecNssBlockCipherCtx        xmlSecNssBlockCipherCtx,
34cdf0e10cSrcweir-                           *xmlSecNssBlockCipherCtxPtr;
35cdf0e10cSrcweir+typedef struct _xmlSecNssBlockCipherCtx                xmlSecNssBlockCipherCtx ;
36cdf0e10cSrcweir+typedef struct _xmlSecNssBlockCipherCtx*       xmlSecNssBlockCipherCtxPtr ;
37cdf0e10cSrcweir+
38cdf0e10cSrcweir struct _xmlSecNssBlockCipherCtx {
39cdf0e10cSrcweir     CK_MECHANISM_TYPE  cipher;
40cdf0e10cSrcweir+    PK11SymKey*         symkey ;
41cdf0e10cSrcweir     PK11Context*   cipherCtx;
42cdf0e10cSrcweir     xmlSecKeyDataId    keyId;
43cdf0e10cSrcweir-    int            keyInitialized;
44cdf0e10cSrcweir-    int            ctxInitialized;
45cdf0e10cSrcweir-    xmlSecByte     key[XMLSEC_NSS_MAX_KEY_SIZE];
46cdf0e10cSrcweir-    xmlSecSize     keySize;
47cdf0e10cSrcweir-    xmlSecByte     iv[XMLSEC_NSS_MAX_IV_SIZE];
48cdf0e10cSrcweir-    xmlSecSize     ivSize;
49cdf0e10cSrcweir };
50cdf0e10cSrcweir-static int     xmlSecNssBlockCipherCtxInit     (xmlSecNssBlockCipherCtxPtr ctx,
51cdf0e10cSrcweir-                            xmlSecBufferPtr in,
52cdf0e10cSrcweir-                            xmlSecBufferPtr out,
53cdf0e10cSrcweir-                            int encrypt,
54cdf0e10cSrcweir-                            const xmlChar* cipherName,
55cdf0e10cSrcweir-                            xmlSecTransformCtxPtr transformCtx);
56cdf0e10cSrcweir-static int     xmlSecNssBlockCipherCtxUpdate   (xmlSecNssBlockCipherCtxPtr ctx,
57cdf0e10cSrcweir-                            xmlSecBufferPtr in,
58cdf0e10cSrcweir-                            xmlSecBufferPtr out,
59cdf0e10cSrcweir-                            int encrypt,
60cdf0e10cSrcweir-                            const xmlChar* cipherName,
61cdf0e10cSrcweir-                            xmlSecTransformCtxPtr transformCtx);
62cdf0e10cSrcweir-static int     xmlSecNssBlockCipherCtxFinal        (xmlSecNssBlockCipherCtxPtr ctx,
63cdf0e10cSrcweir-                            xmlSecBufferPtr in,
64cdf0e10cSrcweir-                            xmlSecBufferPtr out,
65cdf0e10cSrcweir-                            int encrypt,
66cdf0e10cSrcweir-                            const xmlChar* cipherName,
67cdf0e10cSrcweir-                            xmlSecTransformCtxPtr transformCtx);
68cdf0e10cSrcweir+
69cdf0e10cSrcweir+#define xmlSecNssBlockCipherSize       \
70cdf0e10cSrcweir+       ( sizeof( xmlSecTransform ) + sizeof( xmlSecNssBlockCipherCtx ) )
71cdf0e10cSrcweir+
72cdf0e10cSrcweir+#define xmlSecNssBlockCipherGetCtx( transform ) \
73cdf0e10cSrcweir+       ( ( xmlSecNssBlockCipherCtxPtr )( ( ( xmlSecByte* )( transform ) ) + sizeof( xmlSecTransform ) ) )
74cdf0e10cSrcweir+
75cdf0e10cSrcweir+static int
76cdf0e10cSrcweir+xmlSecNssBlockCipherCheckId(
77cdf0e10cSrcweir+       xmlSecTransformPtr transform
78cdf0e10cSrcweir+) {
79cdf0e10cSrcweir+       #ifndef XMLSEC_NO_DES
80cdf0e10cSrcweir+       if( xmlSecTransformCheckId( transform, xmlSecNssTransformDes3CbcId ) ) {
81cdf0e10cSrcweir+               return 1 ;
82cdf0e10cSrcweir+       }
83cdf0e10cSrcweir+       #endif /* XMLSEC_NO_DES */
84cdf0e10cSrcweir+
85cdf0e10cSrcweir+       #ifndef XMLSEC_NO_AES
86cdf0e10cSrcweir+       if( xmlSecTransformCheckId( transform, xmlSecNssTransformAes128CbcId ) ||
87cdf0e10cSrcweir+               xmlSecTransformCheckId( transform, xmlSecNssTransformAes192CbcId ) ||
88cdf0e10cSrcweir+               xmlSecTransformCheckId( transform, xmlSecNssTransformAes256CbcId ) ) {
89cdf0e10cSrcweir+
90cdf0e10cSrcweir+               return 1 ;
91cdf0e10cSrcweir+    }
92cdf0e10cSrcweir+       #endif /* XMLSEC_NO_AES */
93cdf0e10cSrcweir+
94cdf0e10cSrcweir+    return 0 ;
95cdf0e10cSrcweir+}
96cdf0e10cSrcweir+
97cdf0e10cSrcweir+static int
98cdf0e10cSrcweir+xmlSecNssBlockCipherFetchCtx(
99cdf0e10cSrcweir+       xmlSecNssBlockCipherCtxPtr              context ,
100cdf0e10cSrcweir+       xmlSecTransformId                               id
101cdf0e10cSrcweir+) {
102cdf0e10cSrcweir+       xmlSecAssert2( context != NULL, -1 ) ;
103cdf0e10cSrcweir+
104cdf0e10cSrcweir+       #ifndef XMLSEC_NO_DES
105cdf0e10cSrcweir+       if( id == xmlSecNssTransformDes3CbcId ) {
106cdf0e10cSrcweir+               context->cipher = CKM_DES3_CBC ;
107cdf0e10cSrcweir+               context->keyId = xmlSecNssKeyDataDesId ;
108cdf0e10cSrcweir+       } else
109cdf0e10cSrcweir+       #endif          /* XMLSEC_NO_DES */
110cdf0e10cSrcweir+
111cdf0e10cSrcweir+       #ifndef XMLSEC_NO_AES
112cdf0e10cSrcweir+       if( id == xmlSecNssTransformAes128CbcId ) {
113cdf0e10cSrcweir+               context->cipher = CKM_AES_CBC ;
114cdf0e10cSrcweir+               context->keyId = xmlSecNssKeyDataAesId ;
115cdf0e10cSrcweir+       } else
116cdf0e10cSrcweir+       if( id == xmlSecNssTransformAes192CbcId ) {
117cdf0e10cSrcweir+               context->cipher = CKM_AES_CBC ;
118cdf0e10cSrcweir+               context->keyId = xmlSecNssKeyDataAesId ;
119cdf0e10cSrcweir+       } else
120cdf0e10cSrcweir+       if( id == xmlSecNssTransformAes256CbcId ) {
121cdf0e10cSrcweir+               context->cipher = CKM_AES_CBC ;
122cdf0e10cSrcweir+               context->keyId = xmlSecNssKeyDataAesId ;
123cdf0e10cSrcweir+       } else
124cdf0e10cSrcweir+       #endif          /* XMLSEC_NO_AES */
125cdf0e10cSrcweir+
126cdf0e10cSrcweir+       if( 1 ) {
127cdf0e10cSrcweir+               xmlSecError( XMLSEC_ERRORS_HERE ,
128cdf0e10cSrcweir+                   NULL ,
129cdf0e10cSrcweir+                   NULL ,
130cdf0e10cSrcweir+                   XMLSEC_ERRORS_R_CRYPTO_FAILED ,
131cdf0e10cSrcweir+                   XMLSEC_ERRORS_NO_MESSAGE ) ;
132cdf0e10cSrcweir+               return -1 ;
133cdf0e10cSrcweir+       }
134cdf0e10cSrcweir+
135cdf0e10cSrcweir+       return 0 ;
136cdf0e10cSrcweir+}
137cdf0e10cSrcweir+
138cdf0e10cSrcweir+/**
139cdf0e10cSrcweir+ * xmlSecTransformInitializeMethod:
140cdf0e10cSrcweir+ * @transform:                 the pointer to transform object.
141cdf0e10cSrcweir+ *
142cdf0e10cSrcweir+ * The transform specific initialization method.
143cdf0e10cSrcweir+ *
144cdf0e10cSrcweir+ * Returns 0 on success or a negative value otherwise.
145cdf0e10cSrcweir+ */
146cdf0e10cSrcweir+static int
147cdf0e10cSrcweir+xmlSecNssBlockCipherInitialize(
148cdf0e10cSrcweir+       xmlSecTransformPtr transform
149cdf0e10cSrcweir+) {
150cdf0e10cSrcweir+       xmlSecNssBlockCipherCtxPtr context = NULL ;
151cdf0e10cSrcweir+
152cdf0e10cSrcweir+       xmlSecAssert2( xmlSecNssBlockCipherCheckId( transform ), -1 ) ;
153cdf0e10cSrcweir+       xmlSecAssert2( xmlSecTransformCheckSize( transform, xmlSecNssBlockCipherSize ), -1 ) ;
154cdf0e10cSrcweir+
155cdf0e10cSrcweir+       context = xmlSecNssBlockCipherGetCtx( transform ) ;
156cdf0e10cSrcweir+       if( context == NULL ) {
157cdf0e10cSrcweir+               xmlSecError( XMLSEC_ERRORS_HERE ,
158cdf0e10cSrcweir+                   xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
159cdf0e10cSrcweir+                   "xmlSecNssBlockCipherGetCtx" ,
160cdf0e10cSrcweir+                   XMLSEC_ERRORS_R_CRYPTO_FAILED ,
161cdf0e10cSrcweir+                   XMLSEC_ERRORS_NO_MESSAGE ) ;
162cdf0e10cSrcweir+               return -1 ;
163cdf0e10cSrcweir+       }
164cdf0e10cSrcweir+
165cdf0e10cSrcweir+       if( xmlSecNssBlockCipherFetchCtx( context , transform->id ) < 0 ) {
166cdf0e10cSrcweir+               xmlSecError( XMLSEC_ERRORS_HERE ,
167cdf0e10cSrcweir+                   xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
168cdf0e10cSrcweir+                   "xmlSecNssBlockCipherFetchCtx" ,
169cdf0e10cSrcweir+                   XMLSEC_ERRORS_R_CRYPTO_FAILED ,
170cdf0e10cSrcweir+                   XMLSEC_ERRORS_NO_MESSAGE ) ;
171cdf0e10cSrcweir+               return -1 ;
172cdf0e10cSrcweir+       }
173cdf0e10cSrcweir+
174cdf0e10cSrcweir+       context->symkey = NULL ;
175cdf0e10cSrcweir+       context->cipherCtx = NULL ;
176cdf0e10cSrcweir+
177cdf0e10cSrcweir+       return 0 ;
178cdf0e10cSrcweir+}
179cdf0e10cSrcweir+
180cdf0e10cSrcweir+/**
181cdf0e10cSrcweir+ * xmlSecTransformFinalizeMethod:
182cdf0e10cSrcweir+ * @transform:                 the pointer to transform object.
183cdf0e10cSrcweir+ *
184cdf0e10cSrcweir+ * The transform specific destroy method.
185cdf0e10cSrcweir+ */
186cdf0e10cSrcweir+static void
187cdf0e10cSrcweir+xmlSecNssBlockCipherFinalize(
188cdf0e10cSrcweir+       xmlSecTransformPtr transform
189cdf0e10cSrcweir+) {
190cdf0e10cSrcweir+       xmlSecNssBlockCipherCtxPtr context = NULL ;
191cdf0e10cSrcweir+
192cdf0e10cSrcweir+       xmlSecAssert( xmlSecNssBlockCipherCheckId( transform ) ) ;
193cdf0e10cSrcweir+       xmlSecAssert( xmlSecTransformCheckSize( transform, xmlSecNssBlockCipherSize ) ) ;
194cdf0e10cSrcweir+
195cdf0e10cSrcweir+       context = xmlSecNssBlockCipherGetCtx( transform ) ;
196cdf0e10cSrcweir+       if( context == NULL ) {
197cdf0e10cSrcweir+               xmlSecError( XMLSEC_ERRORS_HERE ,
198cdf0e10cSrcweir+                   xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
199cdf0e10cSrcweir+                   "xmlSecNssBlockCipherGetCtx" ,
200cdf0e10cSrcweir+                   XMLSEC_ERRORS_R_CRYPTO_FAILED ,
201cdf0e10cSrcweir+                   XMLSEC_ERRORS_NO_MESSAGE ) ;
202cdf0e10cSrcweir+               return ;
203cdf0e10cSrcweir+       }
204cdf0e10cSrcweir+
205cdf0e10cSrcweir+       if( context->cipherCtx != NULL ) {
206cdf0e10cSrcweir+               PK11_DestroyContext( context->cipherCtx, PR_TRUE ) ;
207cdf0e10cSrcweir+               context->cipherCtx = NULL ;
208cdf0e10cSrcweir+       }
209cdf0e10cSrcweir+
210cdf0e10cSrcweir+       if( context->symkey != NULL ) {
211cdf0e10cSrcweir+               PK11_FreeSymKey( context->symkey ) ;
212cdf0e10cSrcweir+               context->symkey = NULL ;
213cdf0e10cSrcweir+       }
214cdf0e10cSrcweir+
215cdf0e10cSrcweir+       context->cipher = CKM_INVALID_MECHANISM ;
216cdf0e10cSrcweir+       context->keyId = NULL ;
217cdf0e10cSrcweir+}
218cdf0e10cSrcweir+
219cdf0e10cSrcweir+/**
220cdf0e10cSrcweir+ * xmlSecTransformSetKeyRequirementsMethod:
221cdf0e10cSrcweir+ * @transform:                 the pointer to transform object.
222cdf0e10cSrcweir+ * @keyReq:                            the pointer to key requirements structure.
223cdf0e10cSrcweir+ *
224cdf0e10cSrcweir+ * Transform specific method to set transform's key requirements.
225cdf0e10cSrcweir+ *
226cdf0e10cSrcweir+ * Returns 0 on success or a negative value otherwise.
227cdf0e10cSrcweir+ */
228cdf0e10cSrcweir+static int
229cdf0e10cSrcweir+xmlSecNssBlockCipherSetKeyReq(
230cdf0e10cSrcweir+       xmlSecTransformPtr transform ,
231cdf0e10cSrcweir+       xmlSecKeyReqPtr keyReq
232cdf0e10cSrcweir+) {
233cdf0e10cSrcweir+       xmlSecNssBlockCipherCtxPtr context = NULL ;
234cdf0e10cSrcweir+       xmlSecSize cipherSize = 0 ;
235cdf0e10cSrcweir+
236cdf0e10cSrcweir+       xmlSecAssert2( xmlSecNssBlockCipherCheckId( transform ), -1 ) ;
237cdf0e10cSrcweir+       xmlSecAssert2( xmlSecTransformCheckSize( transform, xmlSecNssBlockCipherSize ), -1 ) ;
238cdf0e10cSrcweir+       xmlSecAssert2( keyReq != NULL , -1 ) ;
239cdf0e10cSrcweir+       xmlSecAssert2( ( transform->operation == xmlSecTransformOperationEncrypt ) || ( transform->operation == xmlSecTransformOperationDecrypt ), -1 ) ;
240cdf0e10cSrcweir+
241cdf0e10cSrcweir+       context = xmlSecNssBlockCipherGetCtx( transform ) ;
242cdf0e10cSrcweir+       if( context == NULL ) {
243cdf0e10cSrcweir+               xmlSecError( XMLSEC_ERRORS_HERE ,
244cdf0e10cSrcweir+                   xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
245cdf0e10cSrcweir+                   "xmlSecNssBlockCipherGetCtx" ,
246cdf0e10cSrcweir+                   XMLSEC_ERRORS_R_CRYPTO_FAILED ,
247cdf0e10cSrcweir+                   XMLSEC_ERRORS_NO_MESSAGE ) ;
248cdf0e10cSrcweir+               return -1 ;
249cdf0e10cSrcweir+       }
250cdf0e10cSrcweir+
251cdf0e10cSrcweir+       keyReq->keyId = context->keyId ;
252cdf0e10cSrcweir+       keyReq->keyType = xmlSecKeyDataTypeSymmetric ;
253cdf0e10cSrcweir+
254cdf0e10cSrcweir+       if( transform->operation == xmlSecTransformOperationEncrypt ) {
255cdf0e10cSrcweir+               keyReq->keyUsage = xmlSecKeyUsageEncrypt ;
256cdf0e10cSrcweir+       } else {
257cdf0e10cSrcweir+               keyReq->keyUsage = xmlSecKeyUsageDecrypt ;
258cdf0e10cSrcweir+       }
259cdf0e10cSrcweir+
260cdf0e10cSrcweir+       /*
261cdf0e10cSrcweir+       if( context->symkey != NULL )
262cdf0e10cSrcweir+               cipherSize = PK11_GetKeyLength( context->symkey ) ;
263cdf0e10cSrcweir+
264cdf0e10cSrcweir+       keyReq->keyBitsSize = cipherSize * 8 ;
265cdf0e10cSrcweir+       */
266cdf0e10cSrcweir+
267cdf0e10cSrcweir+       return 0 ;
268cdf0e10cSrcweir+}
269cdf0e10cSrcweir+
270cdf0e10cSrcweir+/**
271cdf0e10cSrcweir+ * xmlSecTransformSetKeyMethod:
272cdf0e10cSrcweir+ * @transform:                 the pointer to transform object.
273cdf0e10cSrcweir+ * @key:                               the pointer to key.
274cdf0e10cSrcweir+ *
275cdf0e10cSrcweir+ * The transform specific method to set the key for use.
276cdf0e10cSrcweir+ *
277cdf0e10cSrcweir+ * Returns 0 on success or a negative value otherwise.
278cdf0e10cSrcweir+ */
279cdf0e10cSrcweir+static int
280cdf0e10cSrcweir+xmlSecNssBlockCipherSetKey(
281cdf0e10cSrcweir+       xmlSecTransformPtr transform ,
282cdf0e10cSrcweir+       xmlSecKeyPtr key
283cdf0e10cSrcweir+) {
284cdf0e10cSrcweir+       xmlSecNssBlockCipherCtxPtr context = NULL ;
285cdf0e10cSrcweir+       xmlSecKeyDataPtr        keyData = NULL ;
286cdf0e10cSrcweir+       PK11SymKey*                     symkey = NULL ;
287cdf0e10cSrcweir+       CK_ATTRIBUTE_TYPE       operation ;
288cdf0e10cSrcweir+       int                                     ivLen ;
289cdf0e10cSrcweir+
290cdf0e10cSrcweir+       xmlSecAssert2( xmlSecNssBlockCipherCheckId( transform ), -1 ) ;
291cdf0e10cSrcweir+       xmlSecAssert2( xmlSecTransformCheckSize( transform, xmlSecNssBlockCipherSize ), -1 ) ;
292cdf0e10cSrcweir+       xmlSecAssert2( key != NULL , -1 ) ;
293cdf0e10cSrcweir+    xmlSecAssert2( ( transform->operation == xmlSecTransformOperationEncrypt ) || ( transform->operation == xmlSecTransformOperationDecrypt ), -1 ) ;
294cdf0e10cSrcweir+
295cdf0e10cSrcweir+       context = xmlSecNssBlockCipherGetCtx( transform ) ;
296cdf0e10cSrcweir+       if( context == NULL || context->keyId == NULL || context->symkey != NULL ) {
297cdf0e10cSrcweir+               xmlSecError( XMLSEC_ERRORS_HERE ,
298cdf0e10cSrcweir+                   xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
299cdf0e10cSrcweir+                   "xmlSecNssBlockCipherGetCtx" ,
300cdf0e10cSrcweir+                   XMLSEC_ERRORS_R_CRYPTO_FAILED ,
301cdf0e10cSrcweir+                   XMLSEC_ERRORS_NO_MESSAGE ) ;
302cdf0e10cSrcweir+               return -1 ;
303cdf0e10cSrcweir+       }
304cdf0e10cSrcweir+       xmlSecAssert2( xmlSecKeyCheckId( key, context->keyId ), -1 ) ;
305cdf0e10cSrcweir+
306cdf0e10cSrcweir+       keyData = xmlSecKeyGetValue( key ) ;
307cdf0e10cSrcweir+       if( keyData == NULL ) {
308cdf0e10cSrcweir+               xmlSecError( XMLSEC_ERRORS_HERE ,
309cdf0e10cSrcweir+                   xmlSecErrorsSafeString( xmlSecKeyGetName( key ) ) ,
310cdf0e10cSrcweir+                   "xmlSecKeyGetValue" ,
311cdf0e10cSrcweir+                   XMLSEC_ERRORS_R_CRYPTO_FAILED ,
312cdf0e10cSrcweir+                   XMLSEC_ERRORS_NO_MESSAGE ) ;
313cdf0e10cSrcweir+               return -1 ;
314cdf0e10cSrcweir+       }
315cdf0e10cSrcweir+
316cdf0e10cSrcweir+       if( ( symkey = xmlSecNssSymKeyDataGetKey( keyData ) ) == NULL ) {
317cdf0e10cSrcweir+               xmlSecError( XMLSEC_ERRORS_HERE ,
318cdf0e10cSrcweir+                   xmlSecErrorsSafeString( xmlSecKeyDataGetName( keyData ) ) ,
319cdf0e10cSrcweir+                   "xmlSecNssSymKeyDataGetKey" ,
320cdf0e10cSrcweir+                   XMLSEC_ERRORS_R_CRYPTO_FAILED ,
321cdf0e10cSrcweir+                   XMLSEC_ERRORS_NO_MESSAGE ) ;
322cdf0e10cSrcweir+               return -1 ;
323cdf0e10cSrcweir+       }
324cdf0e10cSrcweir+
325cdf0e10cSrcweir+       context->symkey = symkey ;
326cdf0e10cSrcweir+
327cdf0e10cSrcweir+       return 0 ;
328cdf0e10cSrcweir+}
329cdf0e10cSrcweir+
330cdf0e10cSrcweir static int
331cdf0e10cSrcweir xmlSecNssBlockCipherCtxInit(xmlSecNssBlockCipherCtxPtr ctx,
332cdf0e10cSrcweir                xmlSecBufferPtr in, xmlSecBufferPtr out,
333cdf0e10cSrcweir                int encrypt,
334cdf0e10cSrcweir                const xmlChar* cipherName,
335cdf0e10cSrcweir                xmlSecTransformCtxPtr transformCtx) {
336cdf0e10cSrcweir-    SECItem keyItem;
337cdf0e10cSrcweir     SECItem ivItem;
338cdf0e10cSrcweir-    PK11SlotInfo* slot;
339cdf0e10cSrcweir-    PK11SymKey* symKey;
340cdf0e10cSrcweir+    SECItem* secParam = NULL ;
341cdf0e10cSrcweir+    xmlSecBufferPtr ivBuf = NULL ;
342cdf0e10cSrcweir     int ivLen;
343cdf0e10cSrcweir-    SECStatus rv;
344cdf0e10cSrcweir-    int ret;
345cdf0e10cSrcweir
346cdf0e10cSrcweir     xmlSecAssert2(ctx != NULL, -1);
347cdf0e10cSrcweir-    xmlSecAssert2(ctx->cipher != 0, -1);
348cdf0e10cSrcweir+    xmlSecAssert2( ctx->cipher != CKM_INVALID_MECHANISM , -1 ) ;
349cdf0e10cSrcweir+    xmlSecAssert2( ctx->symkey != NULL , -1 ) ;
350cdf0e10cSrcweir     xmlSecAssert2(ctx->cipherCtx == NULL, -1);
351cdf0e10cSrcweir-    xmlSecAssert2(ctx->keyInitialized != 0, -1);
352cdf0e10cSrcweir-    xmlSecAssert2(ctx->ctxInitialized == 0, -1);
353cdf0e10cSrcweir+    xmlSecAssert2( ctx->keyId != NULL , -1 ) ;
354cdf0e10cSrcweir     xmlSecAssert2(in != NULL, -1);
355cdf0e10cSrcweir     xmlSecAssert2(out != NULL, -1);
356cdf0e10cSrcweir     xmlSecAssert2(transformCtx != NULL, -1);
357cdf0e10cSrcweir
358cdf0e10cSrcweir     ivLen = PK11_GetIVLength(ctx->cipher);
359cdf0e10cSrcweir-    xmlSecAssert2(ivLen > 0, -1);
360cdf0e10cSrcweir-    xmlSecAssert2((xmlSecSize)ivLen <= sizeof(ctx->iv), -1);
361cdf0e10cSrcweir+    if( ivLen < 0 ) {
362cdf0e10cSrcweir+            xmlSecError( XMLSEC_ERRORS_HERE ,
363cdf0e10cSrcweir+                    NULL ,
364cdf0e10cSrcweir+                    "PK11_GetIVLength" ,
365cdf0e10cSrcweir+                    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
366cdf0e10cSrcweir+                    XMLSEC_ERRORS_NO_MESSAGE ) ;
367cdf0e10cSrcweir+            return -1 ;
368cdf0e10cSrcweir+    }
369cdf0e10cSrcweir+
370cdf0e10cSrcweir+    if( ( ivBuf = xmlSecBufferCreate( ivLen ) ) == NULL ) {
371cdf0e10cSrcweir+            xmlSecError( XMLSEC_ERRORS_HERE ,
372cdf0e10cSrcweir+                    NULL ,
373cdf0e10cSrcweir+                    "xmlSecBufferCreate" ,
374cdf0e10cSrcweir+                    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
375cdf0e10cSrcweir+                    XMLSEC_ERRORS_NO_MESSAGE ) ;
376cdf0e10cSrcweir+            return -1 ;
377cdf0e10cSrcweir+    }
378cdf0e10cSrcweir
379cdf0e10cSrcweir     if(encrypt) {
380cdf0e10cSrcweir-        /* generate random iv */
381cdf0e10cSrcweir-        rv = PK11_GenerateRandom(ctx->iv, ivLen);
382cdf0e10cSrcweir-   if(rv != SECSuccess) {
383cdf0e10cSrcweir+   if( PK11_GenerateRandom( ivBuf->data , ivLen ) != SECSuccess ) {
384cdf0e10cSrcweir        xmlSecError(XMLSEC_ERRORS_HERE,
385cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
386cdf0e10cSrcweir            "PK11_GenerateRandom",
387cdf0e10cSrcweir            XMLSEC_ERRORS_R_CRYPTO_FAILED,
388cdf0e10cSrcweir-           "size=%d", ivLen);
389cdf0e10cSrcweir+           XMLSEC_ERRORS_NO_MESSAGE);
390cdf0e10cSrcweir+       xmlSecBufferDestroy( ivBuf ) ;
391cdf0e10cSrcweir        return(-1);
392cdf0e10cSrcweir    }
393cdf0e10cSrcweir+        if( xmlSecBufferSetSize( ivBuf , ivLen ) < 0 ) {
394cdf0e10cSrcweir+                xmlSecError( XMLSEC_ERRORS_HERE ,
395cdf0e10cSrcweir+                        NULL ,
396cdf0e10cSrcweir+                        "xmlSecBufferSetSize" ,
397cdf0e10cSrcweir+                        XMLSEC_ERRORS_R_CRYPTO_FAILED ,
398cdf0e10cSrcweir+                        XMLSEC_ERRORS_NO_MESSAGE ) ;
399cdf0e10cSrcweir+                xmlSecBufferDestroy( ivBuf ) ;
400cdf0e10cSrcweir+                return -1 ;
401cdf0e10cSrcweir+        }
402cdf0e10cSrcweir
403cdf0e10cSrcweir-   /* write iv to the output */
404cdf0e10cSrcweir-   ret = xmlSecBufferAppend(out, ctx->iv, ivLen);
405cdf0e10cSrcweir-   if(ret < 0) {
406cdf0e10cSrcweir+   if( xmlSecBufferAppend( out , ivBuf->data , ivLen ) < 0 ) {
407cdf0e10cSrcweir        xmlSecError(XMLSEC_ERRORS_HERE,
408cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
409cdf0e10cSrcweir            "xmlSecBufferAppend",
410cdf0e10cSrcweir-           XMLSEC_ERRORS_R_XMLSEC_FAILED,
411cdf0e10cSrcweir-           "size=%d", ivLen);
412cdf0e10cSrcweir+           XMLSEC_ERRORS_R_CRYPTO_FAILED,
413cdf0e10cSrcweir+           XMLSEC_ERRORS_NO_MESSAGE);
414cdf0e10cSrcweir+       xmlSecBufferDestroy( ivBuf ) ;
415cdf0e10cSrcweir        return(-1);
416cdf0e10cSrcweir    }
417cdf0e10cSrcweir
418cdf0e10cSrcweir     } else {
419cdf0e10cSrcweir-   /* if we don't have enough data, exit and hope that
420cdf0e10cSrcweir-    * we'll have iv next time */
421cdf0e10cSrcweir-   if(xmlSecBufferGetSize(in) < (xmlSecSize)ivLen) {
422cdf0e10cSrcweir-       return(0);
423cdf0e10cSrcweir-   }
424cdf0e10cSrcweir-
425cdf0e10cSrcweir-   /* copy iv to our buffer*/
426cdf0e10cSrcweir-   xmlSecAssert2(xmlSecBufferGetData(in) != NULL, -1);
427cdf0e10cSrcweir-   memcpy(ctx->iv, xmlSecBufferGetData(in), ivLen);
428cdf0e10cSrcweir-
429cdf0e10cSrcweir-   /* and remove from input */
430cdf0e10cSrcweir-   ret = xmlSecBufferRemoveHead(in, ivLen);
431cdf0e10cSrcweir-   if(ret < 0) {
432cdf0e10cSrcweir+   if( xmlSecBufferSetData( ivBuf , in->data , ivLen ) < 0 ) {
433cdf0e10cSrcweir        xmlSecError(XMLSEC_ERRORS_HERE,
434cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
435cdf0e10cSrcweir-           "xmlSecBufferRemoveHead",
436cdf0e10cSrcweir-           XMLSEC_ERRORS_R_XMLSEC_FAILED,
437cdf0e10cSrcweir-           "size=%d", ivLen);
438cdf0e10cSrcweir+           "xmlSecBufferSetData",
439cdf0e10cSrcweir+           XMLSEC_ERRORS_R_CRYPTO_FAILED,
440cdf0e10cSrcweir+           XMLSEC_ERRORS_NO_MESSAGE);
441cdf0e10cSrcweir+       xmlSecBufferDestroy( ivBuf ) ;
442cdf0e10cSrcweir        return(-1);
443cdf0e10cSrcweir    }
444cdf0e10cSrcweir     }
445cdf0e10cSrcweir
446cdf0e10cSrcweir-    memset(&keyItem, 0, sizeof(keyItem));
447cdf0e10cSrcweir-    keyItem.data = ctx->key;
448cdf0e10cSrcweir-    keyItem.len  = ctx->keySize;
449cdf0e10cSrcweir-    memset(&ivItem, 0, sizeof(ivItem));
450cdf0e10cSrcweir-    ivItem.data = ctx->iv;
451cdf0e10cSrcweir-    ivItem.len  = ctx->ivSize;
452cdf0e10cSrcweir-
453cdf0e10cSrcweir-    slot = PK11_GetBestSlot(ctx->cipher, NULL);
454cdf0e10cSrcweir-    if(slot == NULL) {
455cdf0e10cSrcweir+    if( xmlSecBufferRemoveHead( in , ivLen ) < 0 ) {
456cdf0e10cSrcweir    xmlSecError(XMLSEC_ERRORS_HERE,
457cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
458cdf0e10cSrcweir-           "PK11_GetBestSlot",
459cdf0e10cSrcweir+           "xmlSecBufferRemoveHead",
460cdf0e10cSrcweir            XMLSEC_ERRORS_R_CRYPTO_FAILED,
461cdf0e10cSrcweir            XMLSEC_ERRORS_NO_MESSAGE);
462cdf0e10cSrcweir+   xmlSecBufferDestroy( ivBuf ) ;
463cdf0e10cSrcweir    return(-1);
464cdf0e10cSrcweir     }
465cdf0e10cSrcweir
466cdf0e10cSrcweir-    symKey = PK11_ImportSymKey(slot, ctx->cipher, PK11_OriginDerive,
467cdf0e10cSrcweir-                  CKA_SIGN, &keyItem, NULL);
468cdf0e10cSrcweir-    if(symKey == NULL) {
469cdf0e10cSrcweir+    ivItem.data = xmlSecBufferGetData( ivBuf ) ;
470cdf0e10cSrcweir+    ivItem.len = xmlSecBufferGetSize( ivBuf ) ;
471cdf0e10cSrcweir+    if( ( secParam = PK11_ParamFromIV( ctx->cipher , &ivItem ) ) == NULL ) {
472cdf0e10cSrcweir    xmlSecError(XMLSEC_ERRORS_HERE,
473cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
474cdf0e10cSrcweir-           "PK11_ImportSymKey",
475cdf0e10cSrcweir+           "PK11_ParamFromIV",
476cdf0e10cSrcweir            XMLSEC_ERRORS_R_CRYPTO_FAILED,
477cdf0e10cSrcweir            XMLSEC_ERRORS_NO_MESSAGE);
478cdf0e10cSrcweir-        PK11_FreeSlot(slot);
479cdf0e10cSrcweir+        xmlSecBufferDestroy( ivBuf ) ;
480cdf0e10cSrcweir    return(-1);
481cdf0e10cSrcweir     }
482cdf0e10cSrcweir
483cdf0e10cSrcweir     ctx->cipherCtx = PK11_CreateContextBySymKey(ctx->cipher,
484cdf0e10cSrcweir            (encrypt) ? CKA_ENCRYPT : CKA_DECRYPT,
485cdf0e10cSrcweir-           symKey, &ivItem);
486cdf0e10cSrcweir+           ctx->symkey, secParam);
487cdf0e10cSrcweir     if(ctx->cipherCtx == NULL) {
488cdf0e10cSrcweir    xmlSecError(XMLSEC_ERRORS_HERE,
489cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
490cdf0e10cSrcweir-           "PK11_CreateContextBySymKey",
491cdf0e10cSrcweir+           "xmlSecBufferRemoveHead",
492cdf0e10cSrcweir            XMLSEC_ERRORS_R_CRYPTO_FAILED,
493cdf0e10cSrcweir            XMLSEC_ERRORS_NO_MESSAGE);
494cdf0e10cSrcweir-   PK11_FreeSymKey(symKey);
495cdf0e10cSrcweir-        PK11_FreeSlot(slot);
496cdf0e10cSrcweir+   SECITEM_FreeItem( secParam , PR_TRUE ) ;
497cdf0e10cSrcweir+        xmlSecBufferDestroy( ivBuf ) ;
498cdf0e10cSrcweir    return(-1);
499cdf0e10cSrcweir     }
500cdf0e10cSrcweir
501cdf0e10cSrcweir-    ctx->ctxInitialized = 1;
502cdf0e10cSrcweir-    PK11_FreeSymKey(symKey);
503cdf0e10cSrcweir-    PK11_FreeSlot(slot);
504cdf0e10cSrcweir+    SECITEM_FreeItem( secParam , PR_TRUE ) ;
505cdf0e10cSrcweir+    xmlSecBufferDestroy( ivBuf ) ;
506cdf0e10cSrcweir     return(0);
507cdf0e10cSrcweir }
508cdf0e10cSrcweir
509cdf0e10cSrcweir+/**
510cdf0e10cSrcweir+ * Block cipher transform update
511cdf0e10cSrcweir+ */
512cdf0e10cSrcweir static int
513cdf0e10cSrcweir xmlSecNssBlockCipherCtxUpdate(xmlSecNssBlockCipherCtxPtr ctx,
514cdf0e10cSrcweir                  xmlSecBufferPtr in, xmlSecBufferPtr out,
515cdf0e10cSrcweir@@ -192,54 +433,49 @@
516cdf0e10cSrcweir                  const xmlChar* cipherName,
517cdf0e10cSrcweir                  xmlSecTransformCtxPtr transformCtx) {
518cdf0e10cSrcweir     xmlSecSize inSize, inBlocks, outSize;
519cdf0e10cSrcweir-    int blockLen;
520cdf0e10cSrcweir+    int blockSize;
521cdf0e10cSrcweir     int outLen = 0;
522cdf0e10cSrcweir     xmlSecByte* outBuf;
523cdf0e10cSrcweir-    SECStatus rv;
524cdf0e10cSrcweir-    int ret;
525cdf0e10cSrcweir
526cdf0e10cSrcweir     xmlSecAssert2(ctx != NULL, -1);
527cdf0e10cSrcweir-    xmlSecAssert2(ctx->cipher != 0, -1);
528cdf0e10cSrcweir+    xmlSecAssert2( ctx->cipher != CKM_INVALID_MECHANISM , -1 ) ;
529cdf0e10cSrcweir+    xmlSecAssert2( ctx->symkey != NULL , -1 ) ;
530cdf0e10cSrcweir     xmlSecAssert2(ctx->cipherCtx != NULL, -1);
531cdf0e10cSrcweir-    xmlSecAssert2(ctx->ctxInitialized != 0, -1);
532cdf0e10cSrcweir+    xmlSecAssert2( ctx->keyId != NULL , -1 ) ;
533cdf0e10cSrcweir     xmlSecAssert2(in != NULL, -1);
534cdf0e10cSrcweir     xmlSecAssert2(out != NULL, -1);
535cdf0e10cSrcweir     xmlSecAssert2(transformCtx != NULL, -1);
536cdf0e10cSrcweir
537cdf0e10cSrcweir-    blockLen = PK11_GetBlockSize(ctx->cipher, NULL);
538cdf0e10cSrcweir-    xmlSecAssert2(blockLen > 0, -1);
539cdf0e10cSrcweir+    if( ( blockSize = PK11_GetBlockSize( ctx->cipher , NULL ) ) < 0 ) {
540cdf0e10cSrcweir+        xmlSecError( XMLSEC_ERRORS_HERE ,
541cdf0e10cSrcweir+            xmlSecErrorsSafeString( cipherName ) ,
542cdf0e10cSrcweir+            "PK11_GetBlockSize" ,
543cdf0e10cSrcweir+            XMLSEC_ERRORS_R_CRYPTO_FAILED ,
544cdf0e10cSrcweir+            XMLSEC_ERRORS_NO_MESSAGE ) ;
545cdf0e10cSrcweir+        return -1 ;
546cdf0e10cSrcweir+    }
547cdf0e10cSrcweir
548cdf0e10cSrcweir     inSize = xmlSecBufferGetSize(in);
549cdf0e10cSrcweir     outSize = xmlSecBufferGetSize(out);
550cdf0e10cSrcweir-
551cdf0e10cSrcweir-    if(inSize < (xmlSecSize)blockLen) {
552cdf0e10cSrcweir-   return(0);
553cdf0e10cSrcweir+
554cdf0e10cSrcweir+    inBlocks = ( encrypt != 0 ? inSize : ( inSize - 1 ) ) / blockSize ;
555cdf0e10cSrcweir+    inSize = inBlocks * blockSize ;
556cdf0e10cSrcweir+
557cdf0e10cSrcweir+    if( inSize < blockSize ) {
558cdf0e10cSrcweir+        return 0 ;
559cdf0e10cSrcweir     }
560cdf0e10cSrcweir
561cdf0e10cSrcweir-    if(encrypt) {
562cdf0e10cSrcweir-        inBlocks = inSize / ((xmlSecSize)blockLen);
563cdf0e10cSrcweir-    } else {
564cdf0e10cSrcweir-   /* we want to have the last block in the input buffer
565cdf0e10cSrcweir-    * for padding check */
566cdf0e10cSrcweir-        inBlocks = (inSize - 1) / ((xmlSecSize)blockLen);
567cdf0e10cSrcweir-    }
568cdf0e10cSrcweir-    inSize = inBlocks * ((xmlSecSize)blockLen);
569cdf0e10cSrcweir-
570cdf0e10cSrcweir-    /* we write out the input size plus may be one block */
571cdf0e10cSrcweir-    ret = xmlSecBufferSetMaxSize(out, outSize + inSize + blockLen);
572cdf0e10cSrcweir-    if(ret < 0) {
573cdf0e10cSrcweir+    if( xmlSecBufferSetMaxSize( out , outSize + inSize + blockSize ) < 0 ) {
574cdf0e10cSrcweir    xmlSecError(XMLSEC_ERRORS_HERE,
575cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
576cdf0e10cSrcweir            "xmlSecBufferSetMaxSize",
577cdf0e10cSrcweir-           XMLSEC_ERRORS_R_XMLSEC_FAILED,
578cdf0e10cSrcweir-           "size=%d", outSize + inSize + blockLen);
579cdf0e10cSrcweir+           XMLSEC_ERRORS_R_CRYPTO_FAILED,
580cdf0e10cSrcweir+           XMLSEC_ERRORS_NO_MESSAGE);
581cdf0e10cSrcweir    return(-1);
582cdf0e10cSrcweir     }
583cdf0e10cSrcweir     outBuf = xmlSecBufferGetData(out) + outSize;
584cdf0e10cSrcweir
585cdf0e10cSrcweir-    rv = PK11_CipherOp(ctx->cipherCtx, outBuf, &outLen, inSize + blockLen,
586cdf0e10cSrcweir-           xmlSecBufferGetData(in), inSize);
587cdf0e10cSrcweir-    if(rv != SECSuccess) {
588cdf0e10cSrcweir+    if(PK11_CipherOp( ctx->cipherCtx , outBuf , &outLen , inSize + blockSize , xmlSecBufferGetData( in ) , inSize ) != SECSuccess ) {
589cdf0e10cSrcweir    xmlSecError(XMLSEC_ERRORS_HERE,
590cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
591cdf0e10cSrcweir            "PK11_CipherOp",
592cdf0e10cSrcweir@@ -247,27 +483,22 @@
593cdf0e10cSrcweir            XMLSEC_ERRORS_NO_MESSAGE);
594cdf0e10cSrcweir    return(-1);
595cdf0e10cSrcweir     }
596cdf0e10cSrcweir-    xmlSecAssert2((xmlSecSize)outLen == inSize, -1);
597cdf0e10cSrcweir
598cdf0e10cSrcweir-    /* set correct output buffer size */
599cdf0e10cSrcweir-    ret = xmlSecBufferSetSize(out, outSize + outLen);
600cdf0e10cSrcweir-    if(ret < 0) {
601cdf0e10cSrcweir+    if( xmlSecBufferSetSize( out , outSize + outLen ) < 0 ) {
602cdf0e10cSrcweir    xmlSecError(XMLSEC_ERRORS_HERE,
603cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
604cdf0e10cSrcweir            "xmlSecBufferSetSize",
605cdf0e10cSrcweir-           XMLSEC_ERRORS_R_XMLSEC_FAILED,
606cdf0e10cSrcweir-           "size=%d", outSize + outLen);
607cdf0e10cSrcweir+           XMLSEC_ERRORS_R_CRYPTO_FAILED,
608cdf0e10cSrcweir+           XMLSEC_ERRORS_NO_MESSAGE);
609cdf0e10cSrcweir    return(-1);
610cdf0e10cSrcweir     }
611cdf0e10cSrcweir
612cdf0e10cSrcweir-    /* remove the processed block from input */
613cdf0e10cSrcweir-    ret = xmlSecBufferRemoveHead(in, inSize);
614cdf0e10cSrcweir-    if(ret < 0) {
615cdf0e10cSrcweir+    if( xmlSecBufferRemoveHead( in , inSize ) < 0 ) {
616cdf0e10cSrcweir    xmlSecError(XMLSEC_ERRORS_HERE,
617cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
618cdf0e10cSrcweir            "xmlSecBufferRemoveHead",
619cdf0e10cSrcweir-           XMLSEC_ERRORS_R_XMLSEC_FAILED,
620cdf0e10cSrcweir-           "size=%d", inSize);
621cdf0e10cSrcweir+           XMLSEC_ERRORS_R_CRYPTO_FAILED,
622cdf0e10cSrcweir+           XMLSEC_ERRORS_NO_MESSAGE);
623cdf0e10cSrcweir    return(-1);
624cdf0e10cSrcweir     }
625cdf0e10cSrcweir     return(0);
626cdf0e10cSrcweir@@ -281,81 +512,82 @@
627cdf0e10cSrcweir                 const xmlChar* cipherName,
628cdf0e10cSrcweir                 xmlSecTransformCtxPtr transformCtx) {
629cdf0e10cSrcweir     xmlSecSize inSize, outSize;
630cdf0e10cSrcweir-    int blockLen, outLen = 0;
631cdf0e10cSrcweir+    int blockSize, outLen = 0;
632cdf0e10cSrcweir     xmlSecByte* inBuf;
633cdf0e10cSrcweir     xmlSecByte* outBuf;
634cdf0e10cSrcweir-    SECStatus rv;
635cdf0e10cSrcweir-    int ret;
636cdf0e10cSrcweir
637cdf0e10cSrcweir     xmlSecAssert2(ctx != NULL, -1);
638cdf0e10cSrcweir-    xmlSecAssert2(ctx->cipher != 0, -1);
639cdf0e10cSrcweir+    xmlSecAssert2( ctx->cipher != CKM_INVALID_MECHANISM , -1 ) ;
640cdf0e10cSrcweir+    xmlSecAssert2( ctx->symkey != NULL , -1 ) ;
641cdf0e10cSrcweir     xmlSecAssert2(ctx->cipherCtx != NULL, -1);
642cdf0e10cSrcweir-    xmlSecAssert2(ctx->ctxInitialized != 0, -1);
643cdf0e10cSrcweir+    xmlSecAssert2( ctx->keyId != NULL , -1 ) ;
644cdf0e10cSrcweir     xmlSecAssert2(in != NULL, -1);
645cdf0e10cSrcweir     xmlSecAssert2(out != NULL, -1);
646cdf0e10cSrcweir     xmlSecAssert2(transformCtx != NULL, -1);
647cdf0e10cSrcweir
648cdf0e10cSrcweir-    blockLen = PK11_GetBlockSize(ctx->cipher, NULL);
649cdf0e10cSrcweir-    xmlSecAssert2(blockLen > 0, -1);
650cdf0e10cSrcweir+    if( ( blockSize = PK11_GetBlockSize( ctx->cipher , NULL ) ) < 0 ) {
651cdf0e10cSrcweir+        xmlSecError( XMLSEC_ERRORS_HERE ,
652cdf0e10cSrcweir+            xmlSecErrorsSafeString( cipherName ) ,
653cdf0e10cSrcweir+            "PK11_GetBlockSize" ,
654cdf0e10cSrcweir+            XMLSEC_ERRORS_R_CRYPTO_FAILED ,
655cdf0e10cSrcweir+            XMLSEC_ERRORS_NO_MESSAGE ) ;
656cdf0e10cSrcweir+        return -1 ;
657cdf0e10cSrcweir+    }
658cdf0e10cSrcweir
659cdf0e10cSrcweir     inSize = xmlSecBufferGetSize(in);
660cdf0e10cSrcweir     outSize = xmlSecBufferGetSize(out);
661cdf0e10cSrcweir
662cdf0e10cSrcweir+    /******************************************************************/
663cdf0e10cSrcweir     if(encrypt != 0) {
664cdf0e10cSrcweir-        xmlSecAssert2(inSize < (xmlSecSize)blockLen, -1);
665cdf0e10cSrcweir+        xmlSecAssert2( inSize < blockSize, -1 ) ;
666cdf0e10cSrcweir
667cdf0e10cSrcweir    /* create padding */
668cdf0e10cSrcweir-        ret = xmlSecBufferSetMaxSize(in, blockLen);
669cdf0e10cSrcweir-   if(ret < 0) {
670cdf0e10cSrcweir+   if( xmlSecBufferSetMaxSize( in , blockSize ) < 0 ) {
671cdf0e10cSrcweir        xmlSecError(XMLSEC_ERRORS_HERE,
672cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
673cdf0e10cSrcweir            "xmlSecBufferSetMaxSize",
674cdf0e10cSrcweir-           XMLSEC_ERRORS_R_XMLSEC_FAILED,
675cdf0e10cSrcweir-           "size=%d", blockLen);
676cdf0e10cSrcweir+           XMLSEC_ERRORS_R_CRYPTO_FAILED,
677cdf0e10cSrcweir+           XMLSEC_ERRORS_NO_MESSAGE);
678cdf0e10cSrcweir        return(-1);
679cdf0e10cSrcweir    }
680cdf0e10cSrcweir    inBuf = xmlSecBufferGetData(in);
681cdf0e10cSrcweir
682cdf0e10cSrcweir-        /* generate random padding */
683cdf0e10cSrcweir-   if((xmlSecSize)blockLen > (inSize + 1)) {
684cdf0e10cSrcweir-       rv = PK11_GenerateRandom(inBuf + inSize, blockLen - inSize - 1);
685cdf0e10cSrcweir-       if(rv != SECSuccess) {
686cdf0e10cSrcweir+        /* generate random */
687cdf0e10cSrcweir+   if( blockSize > ( inSize + 1 ) ) {
688cdf0e10cSrcweir+       if( PK11_GenerateRandom( inBuf + inSize, blockSize - inSize - 1 ) != SECSuccess ) {
689cdf0e10cSrcweir        xmlSecError(XMLSEC_ERRORS_HERE,
690cdf0e10cSrcweir                xmlSecErrorsSafeString(cipherName),
691cdf0e10cSrcweir                "PK11_GenerateRandom",
692cdf0e10cSrcweir                XMLSEC_ERRORS_R_CRYPTO_FAILED,
693cdf0e10cSrcweir-               "size=%d", blockLen - inSize - 1);
694cdf0e10cSrcweir+               XMLSEC_ERRORS_NO_MESSAGE);
695cdf0e10cSrcweir        return(-1);
696cdf0e10cSrcweir        }
697cdf0e10cSrcweir    }
698cdf0e10cSrcweir-   inBuf[blockLen - 1] = blockLen - inSize;
699cdf0e10cSrcweir-   inSize = blockLen;
700cdf0e10cSrcweir+   inBuf[blockSize-1] = blockSize - inSize ;
701cdf0e10cSrcweir+   inSize = blockSize ;
702cdf0e10cSrcweir     } else {
703cdf0e10cSrcweir-   if(inSize != (xmlSecSize)blockLen) {
704cdf0e10cSrcweir+   if( inSize != blockSize ) {
705cdf0e10cSrcweir        xmlSecError(XMLSEC_ERRORS_HERE,
706cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
707cdf0e10cSrcweir            NULL,
708cdf0e10cSrcweir-           XMLSEC_ERRORS_R_INVALID_DATA,
709cdf0e10cSrcweir-           "data=%d;block=%d", inSize, blockLen);
710cdf0e10cSrcweir+           XMLSEC_ERRORS_R_CRYPTO_FAILED,
711cdf0e10cSrcweir+           XMLSEC_ERRORS_NO_MESSAGE);
712cdf0e10cSrcweir        return(-1);
713cdf0e10cSrcweir    }
714cdf0e10cSrcweir     }
715cdf0e10cSrcweir
716cdf0e10cSrcweir-    /* process last block */
717cdf0e10cSrcweir-    ret = xmlSecBufferSetMaxSize(out, outSize + 2 * blockLen);
718cdf0e10cSrcweir-    if(ret < 0) {
719cdf0e10cSrcweir+    /* process the last block */
720cdf0e10cSrcweir+    if( xmlSecBufferSetMaxSize( out , outSize + inSize + blockSize ) < 0 ) {
721cdf0e10cSrcweir    xmlSecError(XMLSEC_ERRORS_HERE,
722cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
723cdf0e10cSrcweir            "xmlSecBufferSetMaxSize",
724cdf0e10cSrcweir-           XMLSEC_ERRORS_R_XMLSEC_FAILED,
725cdf0e10cSrcweir-           "size=%d", outSize + 2 * blockLen);
726cdf0e10cSrcweir+           XMLSEC_ERRORS_R_CRYPTO_FAILED,
727cdf0e10cSrcweir+           XMLSEC_ERRORS_NO_MESSAGE);
728cdf0e10cSrcweir    return(-1);
729cdf0e10cSrcweir     }
730cdf0e10cSrcweir     outBuf = xmlSecBufferGetData(out) + outSize;
731cdf0e10cSrcweir
732cdf0e10cSrcweir-    rv = PK11_CipherOp(ctx->cipherCtx, outBuf, &outLen, 2 * blockLen,
733cdf0e10cSrcweir-           xmlSecBufferGetData(in), inSize);
734cdf0e10cSrcweir-    if(rv != SECSuccess) {
735cdf0e10cSrcweir+    if( PK11_CipherOp( ctx->cipherCtx , outBuf , &outLen , inSize + blockSize , xmlSecBufferGetData( in ) , inSize ) != SECSuccess ) {
736cdf0e10cSrcweir    xmlSecError(XMLSEC_ERRORS_HERE,
737cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
738cdf0e10cSrcweir            "PK11_CipherOp",
739*5c188fd8SDon Lewis@@ -363,300 +595,170 @@
740cdf0e10cSrcweir            XMLSEC_ERRORS_NO_MESSAGE);
741cdf0e10cSrcweir    return(-1);
742cdf0e10cSrcweir     }
743cdf0e10cSrcweir-    xmlSecAssert2((xmlSecSize)outLen == inSize, -1);
744cdf0e10cSrcweir
745cdf0e10cSrcweir     if(encrypt == 0) {
746cdf0e10cSrcweir    /* check padding */
747cdf0e10cSrcweir-   if(outLen < outBuf[blockLen - 1]) {
748cdf0e10cSrcweir+   if( outLen < outBuf[blockSize-1] ) {
749cdf0e10cSrcweir        xmlSecError(XMLSEC_ERRORS_HERE,
750cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
751cdf0e10cSrcweir            NULL,
752cdf0e10cSrcweir-           XMLSEC_ERRORS_R_INVALID_DATA,
753cdf0e10cSrcweir-           "padding=%d;buffer=%d",
754cdf0e10cSrcweir-           outBuf[blockLen - 1], outLen);
755cdf0e10cSrcweir+           XMLSEC_ERRORS_R_CRYPTO_FAILED,
756cdf0e10cSrcweir+           XMLSEC_ERRORS_NO_MESSAGE);
757cdf0e10cSrcweir        return(-1);
758cdf0e10cSrcweir    }
759cdf0e10cSrcweir-   outLen -= outBuf[blockLen - 1];
760cdf0e10cSrcweir+   outLen -= outBuf[blockSize-1] ;
761cdf0e10cSrcweir     }
762cdf0e10cSrcweir
763cdf0e10cSrcweir-    /* set correct output buffer size */
764cdf0e10cSrcweir-    ret = xmlSecBufferSetSize(out, outSize + outLen);
765cdf0e10cSrcweir-    if(ret < 0) {
766cdf0e10cSrcweir-   xmlSecError(XMLSEC_ERRORS_HERE,
767cdf0e10cSrcweir-           xmlSecErrorsSafeString(cipherName),
768cdf0e10cSrcweir-           "xmlSecBufferSetSize",
769cdf0e10cSrcweir-           XMLSEC_ERRORS_R_XMLSEC_FAILED,
770cdf0e10cSrcweir-           "size=%d", outSize + outLen);
771cdf0e10cSrcweir-   return(-1);
772cdf0e10cSrcweir-    }
773cdf0e10cSrcweir+    /******************************************************************/
774cdf0e10cSrcweir
775cdf0e10cSrcweir-    /* remove the processed block from input */
776cdf0e10cSrcweir-    ret = xmlSecBufferRemoveHead(in, inSize);
777cdf0e10cSrcweir-    if(ret < 0) {
778cdf0e10cSrcweir+    /******************************************************************
779cdf0e10cSrcweir+    if( xmlSecBufferSetMaxSize( out , outSize + blockSize ) < 0 ) {
780cdf0e10cSrcweir    xmlSecError(XMLSEC_ERRORS_HERE,
781cdf0e10cSrcweir            xmlSecErrorsSafeString(cipherName),
782cdf0e10cSrcweir-           "xmlSecBufferRemoveHead",
783cdf0e10cSrcweir-           XMLSEC_ERRORS_R_XMLSEC_FAILED,
784cdf0e10cSrcweir-           "size=%d", inSize);
785cdf0e10cSrcweir-   return(-1);
786cdf0e10cSrcweir-    }
787cdf0e10cSrcweir-
788cdf0e10cSrcweir-    return(0);
789cdf0e10cSrcweir-}
790cdf0e10cSrcweir-
791cdf0e10cSrcweir-
792cdf0e10cSrcweir-/******************************************************************************
793cdf0e10cSrcweir- *
794cdf0e10cSrcweir- * EVP Block Cipher transforms
795cdf0e10cSrcweir- *
796cdf0e10cSrcweir- * xmlSecNssBlockCipherCtx block is located after xmlSecTransform structure
797cdf0e10cSrcweir- *
798cdf0e10cSrcweir- *****************************************************************************/
799cdf0e10cSrcweir-#define xmlSecNssBlockCipherSize   \
800cdf0e10cSrcweir-    (sizeof(xmlSecTransform) + sizeof(xmlSecNssBlockCipherCtx))
801cdf0e10cSrcweir-#define xmlSecNssBlockCipherGetCtx(transform) \
802cdf0e10cSrcweir-    ((xmlSecNssBlockCipherCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)))
803cdf0e10cSrcweir-
804cdf0e10cSrcweir-static int xmlSecNssBlockCipherInitialize  (xmlSecTransformPtr transform);
805cdf0e10cSrcweir-static void    xmlSecNssBlockCipherFinalize        (xmlSecTransformPtr transform);
806cdf0e10cSrcweir-static int     xmlSecNssBlockCipherSetKeyReq   (xmlSecTransformPtr transform,
807cdf0e10cSrcweir-                            xmlSecKeyReqPtr keyReq);
808cdf0e10cSrcweir-static int xmlSecNssBlockCipherSetKey      (xmlSecTransformPtr transform,
809cdf0e10cSrcweir-                            xmlSecKeyPtr key);
810cdf0e10cSrcweir-static int xmlSecNssBlockCipherExecute     (xmlSecTransformPtr transform,
811cdf0e10cSrcweir-                            int last,
812cdf0e10cSrcweir-                            xmlSecTransformCtxPtr transformCtx);
813cdf0e10cSrcweir-static int xmlSecNssBlockCipherCheckId     (xmlSecTransformPtr transform);
814cdf0e10cSrcweir-
815cdf0e10cSrcweir-
816cdf0e10cSrcweir-
817cdf0e10cSrcweir-static int
818cdf0e10cSrcweir-xmlSecNssBlockCipherCheckId(xmlSecTransformPtr transform) {
819cdf0e10cSrcweir-#ifndef XMLSEC_NO_DES
820cdf0e10cSrcweir-    if(xmlSecTransformCheckId(transform, xmlSecNssTransformDes3CbcId)) {
821cdf0e10cSrcweir-   return(1);
822cdf0e10cSrcweir-    }
823cdf0e10cSrcweir-#endif /* XMLSEC_NO_DES */
824cdf0e10cSrcweir-
825cdf0e10cSrcweir-#ifndef XMLSEC_NO_AES
826cdf0e10cSrcweir-    if(xmlSecTransformCheckId(transform, xmlSecNssTransformAes128CbcId) ||
827cdf0e10cSrcweir-       xmlSecTransformCheckId(transform, xmlSecNssTransformAes192CbcId) ||
828cdf0e10cSrcweir-       xmlSecTransformCheckId(transform, xmlSecNssTransformAes256CbcId)) {
829cdf0e10cSrcweir-
830cdf0e10cSrcweir-       return(1);
831cdf0e10cSrcweir-    }
832cdf0e10cSrcweir-#endif /* XMLSEC_NO_AES */
833cdf0e10cSrcweir-
834cdf0e10cSrcweir-    return(0);
835cdf0e10cSrcweir-}
836cdf0e10cSrcweir-
837cdf0e10cSrcweir-static int
838cdf0e10cSrcweir-xmlSecNssBlockCipherInitialize(xmlSecTransformPtr transform) {
839cdf0e10cSrcweir-    xmlSecNssBlockCipherCtxPtr ctx;
840cdf0e10cSrcweir-
841cdf0e10cSrcweir-    xmlSecAssert2(xmlSecNssBlockCipherCheckId(transform), -1);
842cdf0e10cSrcweir-    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize), -1);
843cdf0e10cSrcweir-
844cdf0e10cSrcweir-    ctx = xmlSecNssBlockCipherGetCtx(transform);
845cdf0e10cSrcweir-    xmlSecAssert2(ctx != NULL, -1);
846cdf0e10cSrcweir-
847cdf0e10cSrcweir-    memset(ctx, 0, sizeof(xmlSecNssBlockCipherCtx));
848cdf0e10cSrcweir-
849cdf0e10cSrcweir-#ifndef XMLSEC_NO_DES
850cdf0e10cSrcweir-    if(transform->id == xmlSecNssTransformDes3CbcId) {
851cdf0e10cSrcweir-   ctx->cipher     = CKM_DES3_CBC;
852cdf0e10cSrcweir-   ctx->keyId  = xmlSecNssKeyDataDesId;
853cdf0e10cSrcweir-   ctx->keySize    = 24;
854cdf0e10cSrcweir-    } else
855cdf0e10cSrcweir-#endif /* XMLSEC_NO_DES */
856cdf0e10cSrcweir-
857cdf0e10cSrcweir-#ifndef XMLSEC_NO_AES
858cdf0e10cSrcweir-    if(transform->id == xmlSecNssTransformAes128CbcId) {
859cdf0e10cSrcweir-   ctx->cipher     = CKM_AES_CBC;
860cdf0e10cSrcweir-   ctx->keyId  = xmlSecNssKeyDataAesId;
861cdf0e10cSrcweir-   ctx->keySize    = 16;
862cdf0e10cSrcweir-    } else if(transform->id == xmlSecNssTransformAes192CbcId) {
863cdf0e10cSrcweir-   ctx->cipher     = CKM_AES_CBC;
864cdf0e10cSrcweir-   ctx->keyId  = xmlSecNssKeyDataAesId;
865cdf0e10cSrcweir-   ctx->keySize    = 24;
866cdf0e10cSrcweir-    } else if(transform->id == xmlSecNssTransformAes256CbcId) {
867cdf0e10cSrcweir-   ctx->cipher     = CKM_AES_CBC;
868cdf0e10cSrcweir-   ctx->keyId  = xmlSecNssKeyDataAesId;
869cdf0e10cSrcweir-   ctx->keySize    = 32;
870cdf0e10cSrcweir-    } else
871cdf0e10cSrcweir-#endif /* XMLSEC_NO_AES */
872cdf0e10cSrcweir-
873cdf0e10cSrcweir-    if(1) {
874cdf0e10cSrcweir-   xmlSecError(XMLSEC_ERRORS_HERE,
875cdf0e10cSrcweir-           xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
876cdf0e10cSrcweir-           NULL,
877cdf0e10cSrcweir-           XMLSEC_ERRORS_R_INVALID_TRANSFORM,
878cdf0e10cSrcweir+           "xmlSecBufferSetMaxSize",
879cdf0e10cSrcweir+           XMLSEC_ERRORS_R_CRYPTO_FAILED,
880cdf0e10cSrcweir            XMLSEC_ERRORS_NO_MESSAGE);
881cdf0e10cSrcweir    return(-1);
882cdf0e10cSrcweir-    }
883cdf0e10cSrcweir-
884cdf0e10cSrcweir-    return(0);
885cdf0e10cSrcweir-}
886cdf0e10cSrcweir-
887cdf0e10cSrcweir-static void
888cdf0e10cSrcweir-xmlSecNssBlockCipherFinalize(xmlSecTransformPtr transform) {
889cdf0e10cSrcweir-    xmlSecNssBlockCipherCtxPtr ctx;
890cdf0e10cSrcweir-
891cdf0e10cSrcweir-    xmlSecAssert(xmlSecNssBlockCipherCheckId(transform));
892cdf0e10cSrcweir-    xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize));
893cdf0e10cSrcweir-
894cdf0e10cSrcweir-    ctx = xmlSecNssBlockCipherGetCtx(transform);
895cdf0e10cSrcweir-    xmlSecAssert(ctx != NULL);
896cdf0e10cSrcweir-
897cdf0e10cSrcweir-    if(ctx->cipherCtx != NULL) {
898cdf0e10cSrcweir-        PK11_DestroyContext(ctx->cipherCtx, PR_TRUE);
899cdf0e10cSrcweir     }
900cdf0e10cSrcweir-
901cdf0e10cSrcweir-    memset(ctx, 0, sizeof(xmlSecNssBlockCipherCtx));
902cdf0e10cSrcweir-}
903cdf0e10cSrcweir
904cdf0e10cSrcweir-static int
905cdf0e10cSrcweir-xmlSecNssBlockCipherSetKeyReq(xmlSecTransformPtr transform,  xmlSecKeyReqPtr keyReq) {
906cdf0e10cSrcweir-    xmlSecNssBlockCipherCtxPtr ctx;
907cdf0e10cSrcweir-
908cdf0e10cSrcweir-    xmlSecAssert2(xmlSecNssBlockCipherCheckId(transform), -1);
909cdf0e10cSrcweir-    xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
910cdf0e10cSrcweir-    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize), -1);
911cdf0e10cSrcweir-    xmlSecAssert2(keyReq != NULL, -1);
912cdf0e10cSrcweir-
913cdf0e10cSrcweir-    ctx = xmlSecNssBlockCipherGetCtx(transform);
914cdf0e10cSrcweir-    xmlSecAssert2(ctx != NULL, -1);
915cdf0e10cSrcweir-    xmlSecAssert2(ctx->keyId != NULL, -1);
916cdf0e10cSrcweir+    outBuf = xmlSecBufferGetData( out ) + outSize ;
917cdf0e10cSrcweir+    if( PK11_DigestFinal( ctx->cipherCtx , outBuf , &outLen , blockSize ) != SECSuccess ) {
918cdf0e10cSrcweir+            xmlSecError( XMLSEC_ERRORS_HERE ,
919cdf0e10cSrcweir+                    xmlSecErrorsSafeString( cipherName ) ,
920cdf0e10cSrcweir+                    "PK11_DigestFinal" ,
921cdf0e10cSrcweir+                    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
922cdf0e10cSrcweir+                    XMLSEC_ERRORS_NO_MESSAGE ) ;
923cdf0e10cSrcweir+            return -1 ;
924cdf0e10cSrcweir+    }
925cdf0e10cSrcweir+    ******************************************************************/
926cdf0e10cSrcweir+
927cdf0e10cSrcweir+    if( xmlSecBufferSetSize( out , outSize + outLen ) < 0 ) {
928cdf0e10cSrcweir+            xmlSecError( XMLSEC_ERRORS_HERE ,
929cdf0e10cSrcweir+                    xmlSecErrorsSafeString( cipherName ) ,
930cdf0e10cSrcweir+                    "xmlSecBufferSetSize" ,
931cdf0e10cSrcweir+                    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
932cdf0e10cSrcweir+                    XMLSEC_ERRORS_NO_MESSAGE ) ;
933cdf0e10cSrcweir+            return -1 ;
934cdf0e10cSrcweir+    }
935cdf0e10cSrcweir+
936cdf0e10cSrcweir+    if( xmlSecBufferRemoveHead( in , inSize ) < 0 ) {
937cdf0e10cSrcweir+            xmlSecError( XMLSEC_ERRORS_HERE ,
938cdf0e10cSrcweir+                    xmlSecErrorsSafeString( cipherName ) ,
939cdf0e10cSrcweir+                    "xmlSecBufferRemoveHead" ,
940cdf0e10cSrcweir+                    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
941cdf0e10cSrcweir+                    XMLSEC_ERRORS_NO_MESSAGE ) ;
942cdf0e10cSrcweir+            return -1 ;
943cdf0e10cSrcweir+    }
944cdf0e10cSrcweir+
945cdf0e10cSrcweir+/*    PK11_Finalize( ctx->cipherCtx ) ;*/
946cdf0e10cSrcweir+    PK11_DestroyContext(ctx->cipherCtx, PR_TRUE);
947cdf0e10cSrcweir+    ctx->cipherCtx = NULL ;
948cdf0e10cSrcweir
949cdf0e10cSrcweir-    keyReq->keyId  = ctx->keyId;
950cdf0e10cSrcweir-    keyReq->keyType    = xmlSecKeyDataTypeSymmetric;
951cdf0e10cSrcweir-    if(transform->operation == xmlSecTransformOperationEncrypt) {
952cdf0e10cSrcweir-   keyReq->keyUsage = xmlSecKeyUsageEncrypt;
953cdf0e10cSrcweir-    } else {
954cdf0e10cSrcweir-   keyReq->keyUsage = xmlSecKeyUsageDecrypt;
955cdf0e10cSrcweir-    }
956cdf0e10cSrcweir-    keyReq->keyBitsSize = 8 * ctx->keySize;
957cdf0e10cSrcweir     return(0);
958cdf0e10cSrcweir }
959cdf0e10cSrcweir
960cdf0e10cSrcweir-static int
961cdf0e10cSrcweir-xmlSecNssBlockCipherSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
962cdf0e10cSrcweir-    xmlSecNssBlockCipherCtxPtr ctx;
963cdf0e10cSrcweir-    xmlSecBufferPtr buffer;
964cdf0e10cSrcweir+/**
965cdf0e10cSrcweir+ * xmlSecTransformExecuteMethod:
966cdf0e10cSrcweir+ * @transform:                 the pointer to transform object.
967cdf0e10cSrcweir+ * @last:                      the flag: if set to 1 then it's the last data chunk.
968cdf0e10cSrcweir+ * @transformCtx:              the pointer to transform context object.
969cdf0e10cSrcweir+ *
970cdf0e10cSrcweir+ * Transform specific method to process a chunk of data.
971cdf0e10cSrcweir+ *
972cdf0e10cSrcweir+ * Returns 0 on success or a negative value otherwise.
973cdf0e10cSrcweir+ */
974*5c188fd8SDon Lewis+static int
975cdf0e10cSrcweir+xmlSecNssBlockCipherExecute(
976cdf0e10cSrcweir+    xmlSecTransformPtr transform ,
977cdf0e10cSrcweir+    int last ,
978cdf0e10cSrcweir+    xmlSecTransformCtxPtr transformCtx
979cdf0e10cSrcweir+) {
980cdf0e10cSrcweir+    xmlSecNssBlockCipherCtxPtr context = NULL ;
981cdf0e10cSrcweir+    xmlSecBufferPtr inBuf = NULL ;
982cdf0e10cSrcweir+    xmlSecBufferPtr outBuf = NULL ;
983cdf0e10cSrcweir+    const xmlChar* cipherName ;
984cdf0e10cSrcweir+    int operation ;
985cdf0e10cSrcweir+    int rtv ;
986cdf0e10cSrcweir
987cdf0e10cSrcweir     xmlSecAssert2(xmlSecNssBlockCipherCheckId(transform), -1);
988cdf0e10cSrcweir-    xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
989cdf0e10cSrcweir     xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize), -1);
990cdf0e10cSrcweir-    xmlSecAssert2(key != NULL, -1);
991cdf0e10cSrcweir-
992cdf0e10cSrcweir-    ctx = xmlSecNssBlockCipherGetCtx(transform);
993cdf0e10cSrcweir-    xmlSecAssert2(ctx != NULL, -1);
994cdf0e10cSrcweir-    xmlSecAssert2(ctx->cipher != 0, -1);
995cdf0e10cSrcweir-    xmlSecAssert2(ctx->keyInitialized == 0, -1);
996cdf0e10cSrcweir-    xmlSecAssert2(ctx->keyId != NULL, -1);
997cdf0e10cSrcweir-    xmlSecAssert2(xmlSecKeyCheckId(key, ctx->keyId), -1);
998cdf0e10cSrcweir-
999cdf0e10cSrcweir-    xmlSecAssert2(ctx->keySize > 0, -1);
1000cdf0e10cSrcweir-    xmlSecAssert2(ctx->keySize <= sizeof(ctx->key), -1);
1001cdf0e10cSrcweir
1002cdf0e10cSrcweir-    buffer = xmlSecKeyDataBinaryValueGetBuffer(xmlSecKeyGetValue(key));
1003cdf0e10cSrcweir-    xmlSecAssert2(buffer != NULL, -1);
1004cdf0e10cSrcweir+    xmlSecAssert2( ( transform->operation == xmlSecTransformOperationEncrypt ) || ( transform->operation == xmlSecTransformOperationDecrypt ), -1 ) ;
1005cdf0e10cSrcweir+    xmlSecAssert2( transformCtx != NULL , -1 ) ;
1006cdf0e10cSrcweir
1007cdf0e10cSrcweir-    if(xmlSecBufferGetSize(buffer) < ctx->keySize) {
1008cdf0e10cSrcweir+    context = xmlSecNssBlockCipherGetCtx( transform ) ;
1009cdf0e10cSrcweir+    if( context == NULL ) {
1010cdf0e10cSrcweir    xmlSecError(XMLSEC_ERRORS_HERE,
1011cdf0e10cSrcweir            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
1012cdf0e10cSrcweir-           NULL,
1013cdf0e10cSrcweir-           XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,
1014cdf0e10cSrcweir-           "keySize=%d;expected=%d",
1015cdf0e10cSrcweir-           xmlSecBufferGetSize(buffer), ctx->keySize);
1016cdf0e10cSrcweir-   return(-1);
1017cdf0e10cSrcweir+                    "xmlSecNssBlockCipherGetCtx" ,
1018cdf0e10cSrcweir+                    XMLSEC_ERRORS_R_CRYPTO_FAILED ,
1019cdf0e10cSrcweir+                    XMLSEC_ERRORS_NO_MESSAGE ) ;
1020cdf0e10cSrcweir     }
1021cdf0e10cSrcweir-
1022cdf0e10cSrcweir-    xmlSecAssert2(xmlSecBufferGetData(buffer) != NULL, -1);
1023cdf0e10cSrcweir-    memcpy(ctx->key, xmlSecBufferGetData(buffer), ctx->keySize);
1024cdf0e10cSrcweir-
1025cdf0e10cSrcweir-    ctx->keyInitialized = 1;
1026cdf0e10cSrcweir-    return(0);
1027cdf0e10cSrcweir-}
1028cdf0e10cSrcweir-
1029cdf0e10cSrcweir-static int
1030cdf0e10cSrcweir-xmlSecNssBlockCipherExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
1031cdf0e10cSrcweir-    xmlSecNssBlockCipherCtxPtr ctx;
1032cdf0e10cSrcweir-    xmlSecBufferPtr in, out;
1033cdf0e10cSrcweir-    int ret;
1034cdf0e10cSrcweir-
1035cdf0e10cSrcweir-    xmlSecAssert2(xmlSecNssBlockCipherCheckId(transform), -1);
1036cdf0e10cSrcweir-    xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
1037cdf0e10cSrcweir-    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssBlockCipherSize), -1);
1038cdf0e10cSrcweir-    xmlSecAssert2(transformCtx != NULL, -1);
1039cdf0e10cSrcweir
1040cdf0e10cSrcweir-    in = &(transform->inBuf);
1041cdf0e10cSrcweir-    out = &(transform->outBuf);
1042cdf0e10cSrcweir-
1043cdf0e10cSrcweir-    ctx = xmlSecNssBlockCipherGetCtx(transform);
1044cdf0e10cSrcweir-    xmlSecAssert2(ctx != NULL, -1);
1045cdf0e10cSrcweir+    inBuf = &( transform->inBuf ) ;
1046cdf0e10cSrcweir+    outBuf = &( transform->outBuf ) ;
1047cdf0e10cSrcweir
1048cdf0e10cSrcweir     if(transform->status == xmlSecTransformStatusNone) {
1049cdf0e10cSrcweir    transform->status = xmlSecTransformStatusWorking;
1050cdf0e10cSrcweir     }
1051cdf0e10cSrcweir
1052cdf0e10cSrcweir+    operation = ( transform->operation == xmlSecTransformOperationEncrypt ) ? 1 : 0 ;
1053cdf0e10cSrcweir+    cipherName = xmlSecTransformGetName( transform ) ;
1054cdf0e10cSrcweir+
1055cdf0e10cSrcweir     if(transform->status == xmlSecTransformStatusWorking) {
1056cdf0e10cSrcweir-   if(ctx->ctxInitialized == 0) {
1057cdf0e10cSrcweir-       ret = xmlSecNssBlockCipherCtxInit(ctx, in, out,
1058cdf0e10cSrcweir-           (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
1059cdf0e10cSrcweir-           xmlSecTransformGetName(transform), transformCtx);
1060cdf0e10cSrcweir-       if(ret < 0) {
1061cdf0e10cSrcweir+   if( context->cipherCtx == NULL ) {
1062cdf0e10cSrcweir+       rtv = xmlSecNssBlockCipherCtxInit( context, inBuf , outBuf , operation , cipherName , transformCtx ) ;
1063cdf0e10cSrcweir+       if( rtv < 0 ) {
1064cdf0e10cSrcweir        xmlSecError(XMLSEC_ERRORS_HERE,
1065cdf0e10cSrcweir                xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
1066cdf0e10cSrcweir                "xmlSecNssBlockCipherCtxInit",
1067cdf0e10cSrcweir-               XMLSEC_ERRORS_R_XMLSEC_FAILED,
1068cdf0e10cSrcweir+               XMLSEC_ERRORS_R_INVALID_STATUS,
1069cdf0e10cSrcweir                XMLSEC_ERRORS_NO_MESSAGE);
1070cdf0e10cSrcweir        return(-1);
1071cdf0e10cSrcweir        }
1072cdf0e10cSrcweir    }
1073cdf0e10cSrcweir-   if((ctx->ctxInitialized == 0) && (last != 0)) {
1074cdf0e10cSrcweir+   if( context->cipherCtx == NULL && last != 0 ) {
1075cdf0e10cSrcweir        xmlSecError(XMLSEC_ERRORS_HERE,
1076cdf0e10cSrcweir            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
1077cdf0e10cSrcweir            NULL,
1078cdf0e10cSrcweir-           XMLSEC_ERRORS_R_INVALID_DATA,
1079cdf0e10cSrcweir+           XMLSEC_ERRORS_R_INVALID_STATUS,
1080cdf0e10cSrcweir            "not enough data to initialize transform");
1081cdf0e10cSrcweir        return(-1);
1082cdf0e10cSrcweir    }
1083cdf0e10cSrcweir
1084cdf0e10cSrcweir-   if(ctx->ctxInitialized != 0) {
1085cdf0e10cSrcweir-       ret = xmlSecNssBlockCipherCtxUpdate(ctx, in, out,
1086cdf0e10cSrcweir-           (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
1087cdf0e10cSrcweir-           xmlSecTransformGetName(transform), transformCtx);
1088cdf0e10cSrcweir-       if(ret < 0) {
1089cdf0e10cSrcweir+   if( context->cipherCtx != NULL ) {
1090cdf0e10cSrcweir+       rtv = xmlSecNssBlockCipherCtxUpdate( context, inBuf , outBuf , operation , cipherName , transformCtx ) ;
1091cdf0e10cSrcweir+       if( rtv < 0 ) {
1092cdf0e10cSrcweir        xmlSecError(XMLSEC_ERRORS_HERE,
1093cdf0e10cSrcweir                xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
1094cdf0e10cSrcweir                "xmlSecNssBlockCipherCtxUpdate",
1095cdf0e10cSrcweir-               XMLSEC_ERRORS_R_XMLSEC_FAILED,
1096cdf0e10cSrcweir+               XMLSEC_ERRORS_R_INVALID_STATUS,
1097cdf0e10cSrcweir                XMLSEC_ERRORS_NO_MESSAGE);
1098cdf0e10cSrcweir        return(-1);
1099cdf0e10cSrcweir        }
1100cdf0e10cSrcweir    }
1101cdf0e10cSrcweir
1102cdf0e10cSrcweir    if(last) {
1103cdf0e10cSrcweir-       ret = xmlSecNssBlockCipherCtxFinal(ctx, in, out,
1104cdf0e10cSrcweir-           (transform->operation == xmlSecTransformOperationEncrypt) ? 1 : 0,
1105cdf0e10cSrcweir-           xmlSecTransformGetName(transform), transformCtx);
1106cdf0e10cSrcweir-       if(ret < 0) {
1107cdf0e10cSrcweir+       rtv = xmlSecNssBlockCipherCtxFinal( context, inBuf , outBuf , operation , cipherName , transformCtx ) ;
1108cdf0e10cSrcweir+       if( rtv < 0 ) {
1109cdf0e10cSrcweir        xmlSecError(XMLSEC_ERRORS_HERE,
1110cdf0e10cSrcweir                xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
1111cdf0e10cSrcweir                "xmlSecNssBlockCipherCtxFinal",
1112cdf0e10cSrcweir-               XMLSEC_ERRORS_R_XMLSEC_FAILED,
1113cdf0e10cSrcweir+               XMLSEC_ERRORS_R_INVALID_STATUS,
1114cdf0e10cSrcweir                XMLSEC_ERRORS_NO_MESSAGE);
1115cdf0e10cSrcweir        return(-1);
1116cdf0e10cSrcweir        }
1117cdf0e10cSrcweir        transform->status = xmlSecTransformStatusFinished;
1118cdf0e10cSrcweir    }
1119cdf0e10cSrcweir     } else if(transform->status == xmlSecTransformStatusFinished) {
1120cdf0e10cSrcweir-   /* the only way we can get here is if there is no input */
1121cdf0e10cSrcweir-   xmlSecAssert2(xmlSecBufferGetSize(in) == 0, -1);
1122cdf0e10cSrcweir-    } else if(transform->status == xmlSecTransformStatusNone) {
1123cdf0e10cSrcweir-   /* the only way we can get here is if there is no enough data in the input */
1124cdf0e10cSrcweir-   xmlSecAssert2(last == 0, -1);
1125cdf0e10cSrcweir+        if( xmlSecBufferGetSize( inBuf ) != 0 ) {
1126cdf0e10cSrcweir+            xmlSecError( XMLSEC_ERRORS_HERE ,
1127cdf0e10cSrcweir+                    xmlSecErrorsSafeString( xmlSecTransformGetName( transform ) ) ,
1128cdf0e10cSrcweir+                    NULL ,
1129cdf0e10cSrcweir+                    XMLSEC_ERRORS_R_INVALID_STATUS ,
1130cdf0e10cSrcweir+                    "status=%d", transform->status ) ;
1131cdf0e10cSrcweir+            return -1 ;
1132cdf0e10cSrcweir+        }
1133cdf0e10cSrcweir     } else {
1134cdf0e10cSrcweir    xmlSecError(XMLSEC_ERRORS_HERE,
1135cdf0e10cSrcweir            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
1136