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