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