5 * AES Algorithm support
7 * This is free software; see Copyright file in the source
8 * distribution for preciese wording.
10 * Copyright .................................
22 #include <xmlsec/xmlsec.h>
23 #include <xmlsec/xmltree.h>
24 #include <xmlsec/keys.h>
25 #include <xmlsec/transforms.h>
26 #include <xmlsec/errors.h>
28 #include <xmlsec/nss/crypto.h>
29 #include <xmlsec/nss/ciphers.h>
31 #define XMLSEC_NSS_AES128_KEY_SIZE 16
32 #define XMLSEC_NSS_AES192_KEY_SIZE 24
33 #define XMLSEC_NSS_AES256_KEY_SIZE 32
34 #define XMLSEC_NSS_DES3_KEY_SIZE 24
35 #define XMLSEC_NSS_DES3_KEY_LENGTH 24
36 #define XMLSEC_NSS_DES3_IV_LENGTH 8
37 #define XMLSEC_NSS_DES3_BLOCK_LENGTH 8
39 static xmlSecByte xmlSecNssKWDes3Iv
[XMLSEC_NSS_DES3_IV_LENGTH
] = {
40 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05
43 /*********************************************************************
47 ********************************************************************/
48 typedef struct _xmlSecNssKeyWrapCtx xmlSecNssKeyWrapCtx
;
49 typedef struct _xmlSecNssKeyWrapCtx
* xmlSecNssKeyWrapCtxPtr
;
51 #define xmlSecNssKeyWrapSize \
52 ( sizeof( xmlSecTransform ) + sizeof( xmlSecNssKeyWrapCtx ) )
54 #define xmlSecNssKeyWrapGetCtx( transform ) \
55 ( ( xmlSecNssKeyWrapCtxPtr )( ( ( xmlSecByte* )( transform ) ) + sizeof( xmlSecTransform ) ) )
57 struct _xmlSecNssKeyWrapCtx
{
58 CK_MECHANISM_TYPE cipher
;
60 xmlSecKeyDataId keyId
;
61 xmlSecBufferPtr material
; /* to be encrypted/decrypted key material */
64 static int xmlSecNssKeyWrapInitialize(xmlSecTransformPtr transform
);
65 static void xmlSecNssKeyWrapFinalize(xmlSecTransformPtr transform
);
66 static int xmlSecNssKeyWrapSetKeyReq(xmlSecTransformPtr transform
,
67 xmlSecKeyReqPtr keyReq
);
68 static int xmlSecNssKeyWrapSetKey(xmlSecTransformPtr transform
,
70 static int xmlSecNssKeyWrapExecute(xmlSecTransformPtr transform
,
72 xmlSecTransformCtxPtr transformCtx
);
73 static xmlSecSize
xmlSecNssKeyWrapGetKeySize(xmlSecTransformPtr transform
);
76 xmlSecNssKeyWrapCheckId(
77 xmlSecTransformPtr transform
80 if( xmlSecTransformCheckId( transform
, xmlSecNssTransformKWDes3Id
) ) {
83 #endif /* XMLSEC_NO_DES */
86 if( xmlSecTransformCheckId( transform
, xmlSecNssTransformKWAes128Id
) ||
87 xmlSecTransformCheckId( transform
, xmlSecNssTransformKWAes192Id
) ||
88 xmlSecTransformCheckId( transform
, xmlSecNssTransformKWAes256Id
) ) {
92 #endif /* XMLSEC_NO_AES */
98 xmlSecNssKeyWrapGetKeySize(xmlSecTransformPtr transform
) {
100 if( xmlSecTransformCheckId( transform
, xmlSecNssTransformKWDes3Id
) ) {
101 return(XMLSEC_NSS_DES3_KEY_SIZE
);
103 #endif /* XMLSEC_NO_DES */
105 #ifndef XMLSEC_NO_AES
106 if(xmlSecTransformCheckId(transform
, xmlSecNssTransformKWAes128Id
)) {
107 return(XMLSEC_NSS_AES128_KEY_SIZE
);
108 } else if(xmlSecTransformCheckId(transform
, xmlSecNssTransformKWAes192Id
)) {
109 return(XMLSEC_NSS_AES192_KEY_SIZE
);
110 } else if(xmlSecTransformCheckId(transform
, xmlSecNssTransformKWAes256Id
)) {
111 return(XMLSEC_NSS_AES256_KEY_SIZE
);
112 } else if(xmlSecTransformCheckId(transform
, xmlSecNssTransformKWAes256Id
)) {
113 return(XMLSEC_NSS_AES256_KEY_SIZE
);
115 #endif /* XMLSEC_NO_AES */
123 xmlSecNssKeyWrapInitialize(xmlSecTransformPtr transform
) {
124 xmlSecNssKeyWrapCtxPtr context
;
127 xmlSecAssert2(xmlSecNssKeyWrapCheckId(transform
), -1);
128 xmlSecAssert2(xmlSecTransformCheckSize(transform
, xmlSecNssKeyWrapSize
), -1);
130 context
= xmlSecNssKeyWrapGetCtx( transform
) ;
131 xmlSecAssert2( context
!= NULL
, -1 ) ;
133 #ifndef XMLSEC_NO_DES
134 if( transform
->id
== xmlSecNssTransformKWDes3Id
) {
135 context
->cipher
= CKM_DES3_CBC
;
136 context
->keyId
= xmlSecNssKeyDataDesId
;
138 #endif /* XMLSEC_NO_DES */
140 #ifndef XMLSEC_NO_AES
141 if( transform
->id
== xmlSecNssTransformKWAes128Id
) {
142 /* context->cipher = CKM_NETSCAPE_AES_KEY_WRAP ;*/
143 context
->cipher
= CKM_AES_CBC
;
144 context
->keyId
= xmlSecNssKeyDataAesId
;
146 if( transform
->id
== xmlSecNssTransformKWAes192Id
) {
147 /* context->cipher = CKM_NETSCAPE_AES_KEY_WRAP ;*/
148 context
->cipher
= CKM_AES_CBC
;
149 context
->keyId
= xmlSecNssKeyDataAesId
;
151 if( transform
->id
== xmlSecNssTransformKWAes256Id
) {
152 /* context->cipher = CKM_NETSCAPE_AES_KEY_WRAP ;*/
153 context
->cipher
= CKM_AES_CBC
;
154 context
->keyId
= xmlSecNssKeyDataAesId
;
156 #endif /* XMLSEC_NO_AES */
160 xmlSecError( XMLSEC_ERRORS_HERE
,
161 xmlSecErrorsSafeString(xmlSecTransformGetName(transform
)),
163 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
164 XMLSEC_ERRORS_NO_MESSAGE
) ;
168 context
->symkey
= NULL
;
169 context
->material
= NULL
;
175 xmlSecNssKeyWrapFinalize(xmlSecTransformPtr transform
) {
176 xmlSecNssKeyWrapCtxPtr context
;
178 xmlSecAssert(xmlSecNssKeyWrapCheckId(transform
));
179 xmlSecAssert(xmlSecTransformCheckSize(transform
, xmlSecNssKeyWrapSize
));
181 context
= xmlSecNssKeyWrapGetCtx( transform
) ;
182 xmlSecAssert( context
!= NULL
) ;
184 if( context
->symkey
!= NULL
) {
185 PK11_FreeSymKey( context
->symkey
) ;
186 context
->symkey
= NULL
;
189 if( context
->material
!= NULL
) {
190 xmlSecBufferDestroy(context
->material
);
191 context
->material
= NULL
;
196 xmlSecNssKeyWrapSetKeyReq(xmlSecTransformPtr transform
, xmlSecKeyReqPtr keyReq
) {
197 xmlSecNssKeyWrapCtxPtr context
;
198 xmlSecSize cipherSize
= 0 ;
201 xmlSecAssert2(xmlSecNssKeyWrapCheckId(transform
), -1);
202 xmlSecAssert2(xmlSecTransformCheckSize(transform
, xmlSecNssKeyWrapSize
), -1);
203 xmlSecAssert2((transform
->operation
== xmlSecTransformOperationEncrypt
) || (transform
->operation
== xmlSecTransformOperationDecrypt
), -1);
204 xmlSecAssert2(keyReq
!= NULL
, -1);
206 context
= xmlSecNssKeyWrapGetCtx( transform
) ;
207 xmlSecAssert2( context
!= NULL
, -1 ) ;
209 keyReq
->keyId
= context
->keyId
;
210 keyReq
->keyType
= xmlSecKeyDataTypeSymmetric
;
211 if(transform
->operation
== xmlSecTransformOperationEncrypt
) {
212 keyReq
->keyUsage
= xmlSecKeyUsageEncrypt
;
214 keyReq
->keyUsage
= xmlSecKeyUsageDecrypt
;
217 keyReq
->keyBitsSize
= xmlSecNssKeyWrapGetKeySize( transform
) ;
223 xmlSecNssKeyWrapSetKey(xmlSecTransformPtr transform
, xmlSecKeyPtr key
) {
224 xmlSecNssKeyWrapCtxPtr context
= NULL
;
225 xmlSecKeyDataPtr keyData
= NULL
;
226 PK11SymKey
* symkey
= NULL
;
228 xmlSecAssert2(xmlSecNssKeyWrapCheckId(transform
), -1);
229 xmlSecAssert2(xmlSecTransformCheckSize(transform
, xmlSecNssKeyWrapSize
), -1);
230 xmlSecAssert2((transform
->operation
== xmlSecTransformOperationEncrypt
) || (transform
->operation
== xmlSecTransformOperationDecrypt
), -1);
231 xmlSecAssert2(key
!= NULL
, -1);
233 context
= xmlSecNssKeyWrapGetCtx( transform
) ;
234 if( context
== NULL
|| context
->keyId
== NULL
|| context
->symkey
!= NULL
) {
235 xmlSecError( XMLSEC_ERRORS_HERE
,
236 xmlSecErrorsSafeString( xmlSecTransformGetName( transform
) ) ,
237 "xmlSecNssKeyWrapGetCtx" ,
238 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
239 XMLSEC_ERRORS_NO_MESSAGE
) ;
242 xmlSecAssert2( xmlSecKeyCheckId( key
, context
->keyId
), -1 ) ;
244 keyData
= xmlSecKeyGetValue( key
) ;
245 if( keyData
== NULL
) {
246 xmlSecError( XMLSEC_ERRORS_HERE
,
247 xmlSecErrorsSafeString( xmlSecKeyGetName( key
) ) ,
248 "xmlSecKeyGetValue" ,
249 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
250 XMLSEC_ERRORS_NO_MESSAGE
) ;
254 if( ( symkey
= xmlSecNssSymKeyDataGetKey( keyData
) ) == NULL
) {
255 xmlSecError( XMLSEC_ERRORS_HERE
,
256 xmlSecErrorsSafeString( xmlSecKeyDataGetName( keyData
) ) ,
257 "xmlSecNssSymKeyDataGetKey" ,
258 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
259 XMLSEC_ERRORS_NO_MESSAGE
) ;
263 context
->symkey
= symkey
;
272 xmlSecNssKeyWrapCtxInit(
273 xmlSecNssKeyWrapCtxPtr ctx
,
275 xmlSecBufferPtr out
,
277 xmlSecTransformCtxPtr transformCtx
279 xmlSecSize blockSize
;
281 xmlSecAssert2( ctx
!= NULL
, -1 ) ;
282 xmlSecAssert2( ctx
->cipher
!= CKM_INVALID_MECHANISM
, -1 ) ;
283 xmlSecAssert2( ctx
->symkey
!= NULL
, -1 ) ;
284 xmlSecAssert2( ctx
->keyId
!= NULL
, -1 ) ;
285 xmlSecAssert2( in
!= NULL
, -1 ) ;
286 xmlSecAssert2( out
!= NULL
, -1 ) ;
287 xmlSecAssert2( transformCtx
!= NULL
, -1 ) ;
289 if( ctx
->material
!= NULL
) {
290 xmlSecBufferDestroy( ctx
->material
) ;
291 ctx
->material
= NULL
;
294 if( ( blockSize
= PK11_GetBlockSize( ctx
->cipher
, NULL
) ) < 0 ) {
295 xmlSecError( XMLSEC_ERRORS_HERE
,
297 "PK11_GetBlockSize" ,
298 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
299 XMLSEC_ERRORS_NO_MESSAGE
) ;
303 ctx
->material
= xmlSecBufferCreate( blockSize
) ;
304 if( ctx
->material
== NULL
) {
305 xmlSecError( XMLSEC_ERRORS_HERE
,
307 "xmlSecBufferCreate" ,
308 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
309 XMLSEC_ERRORS_NO_MESSAGE
) ;
313 /* read raw key material into context */
314 if( xmlSecBufferSetData( ctx
->material
, xmlSecBufferGetData(in
), xmlSecBufferGetSize(in
) ) < 0 ) {
315 xmlSecError( XMLSEC_ERRORS_HERE
,
317 "xmlSecBufferSetData" ,
318 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
319 XMLSEC_ERRORS_NO_MESSAGE
) ;
323 if( xmlSecBufferRemoveHead( in
, xmlSecBufferGetSize(in
) ) < 0 ) {
324 xmlSecError( XMLSEC_ERRORS_HERE
,
326 "xmlSecBufferRemoveHead" ,
327 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
328 XMLSEC_ERRORS_NO_MESSAGE
) ;
336 * key wrap transform update
339 xmlSecNssKeyWrapCtxUpdate(
340 xmlSecNssKeyWrapCtxPtr ctx
,
342 xmlSecBufferPtr out
,
344 xmlSecTransformCtxPtr transformCtx
346 xmlSecAssert2( ctx
!= NULL
, -1 ) ;
347 xmlSecAssert2( ctx
->cipher
!= CKM_INVALID_MECHANISM
, -1 ) ;
348 xmlSecAssert2( ctx
->symkey
!= NULL
, -1 ) ;
349 xmlSecAssert2( ctx
->keyId
!= NULL
, -1 ) ;
350 xmlSecAssert2( ctx
->material
!= NULL
, -1 ) ;
351 xmlSecAssert2( in
!= NULL
, -1 ) ;
352 xmlSecAssert2( out
!= NULL
, -1 ) ;
353 xmlSecAssert2( transformCtx
!= NULL
, -1 ) ;
355 /* read raw key material and append into context */
356 if( xmlSecBufferAppend( ctx
->material
, xmlSecBufferGetData(in
), xmlSecBufferGetSize(in
) ) < 0 ) {
357 xmlSecError( XMLSEC_ERRORS_HERE
,
359 "xmlSecBufferAppend" ,
360 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
361 XMLSEC_ERRORS_NO_MESSAGE
) ;
365 if( xmlSecBufferRemoveHead( in
, xmlSecBufferGetSize(in
) ) < 0 ) {
366 xmlSecError( XMLSEC_ERRORS_HERE
,
368 "xmlSecBufferRemoveHead" ,
369 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
370 XMLSEC_ERRORS_NO_MESSAGE
) ;
378 xmlSecNssKWDes3BufferReverse(xmlSecByte
*buf
, xmlSecSize size
) {
383 xmlSecAssert2(buf
!= NULL
, -1);
387 for(i
= 0; i
< s
; ++i
) {
389 buf
[i
] = buf
[size
- i
];
396 xmlSecNssComputeSHA1(const xmlSecByte
*in
, xmlSecSize inSize
,
397 xmlSecByte
*out
, xmlSecSize outSize
)
399 PK11Context
*context
= NULL
;
401 xmlSecByte
*digest
= NULL
;
404 xmlSecAssert2(in
!= NULL
, NULL
);
405 xmlSecAssert2(out
!= NULL
, NULL
);
406 xmlSecAssert2(outSize
>= SHA1_LENGTH
, NULL
);
408 /* Create a context for hashing (digesting) */
409 context
= PK11_CreateDigestContext(SEC_OID_SHA1
);
410 if (context
== NULL
) {
411 xmlSecError(XMLSEC_ERRORS_HERE
,
413 "PK11_CreateDigestContext",
414 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
415 "error code = %d", PORT_GetError());
419 s
= PK11_DigestBegin(context
);
420 if (s
!= SECSuccess
) {
421 xmlSecError(XMLSEC_ERRORS_HERE
,
424 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
425 "error code = %d", PORT_GetError());
429 s
= PK11_DigestOp(context
, in
, inSize
);
430 if (s
!= SECSuccess
) {
431 xmlSecError(XMLSEC_ERRORS_HERE
,
434 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
435 "error code = %d", PORT_GetError());
439 s
= PK11_DigestFinal(context
, out
, &len
, outSize
);
440 if (s
!= SECSuccess
) {
441 xmlSecError(XMLSEC_ERRORS_HERE
,
444 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
445 "error code = %d", PORT_GetError());
448 xmlSecAssert2(len
== SHA1_LENGTH
, NULL
);
453 if (context
!= NULL
) {
454 PK11_DestroyContext(context
, PR_TRUE
);
460 xmlSecNssKWDes3Encrypt(
462 CK_MECHANISM_TYPE cipherMech
,
463 const xmlSecByte
* iv
,
465 const xmlSecByte
* in
,
471 PK11Context
* EncContext
= NULL
;
473 SECItem
* secParam
= NULL
;
475 unsigned int tmp2_outlen
;
479 xmlSecAssert2( cipherMech
!= CKM_INVALID_MECHANISM
, -1 ) ;
480 xmlSecAssert2( symKey
!= NULL
, -1 ) ;
481 xmlSecAssert2(iv
!= NULL
, -1);
482 xmlSecAssert2(ivSize
== XMLSEC_NSS_DES3_IV_LENGTH
, -1);
483 xmlSecAssert2(in
!= NULL
, -1);
484 xmlSecAssert2(inSize
> 0, -1);
485 xmlSecAssert2(out
!= NULL
, -1);
486 xmlSecAssert2(outSize
>= inSize
, -1);
489 ivItem
.data
= ( unsigned char* )iv
;
490 ivItem
.len
= ivSize
;
492 secParam
= PK11_ParamFromIV(cipherMech
, &ivItem
);
493 if (secParam
== NULL
) {
494 xmlSecError(XMLSEC_ERRORS_HERE
,
497 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
498 "Error code = %d", PORT_GetError());
502 EncContext
= PK11_CreateContextBySymKey(cipherMech
,
503 enc
? CKA_ENCRYPT
: CKA_DECRYPT
,
505 if (EncContext
== NULL
) {
506 xmlSecError(XMLSEC_ERRORS_HERE
,
508 "PK11_CreateContextBySymKey",
509 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
510 "Error code = %d", PORT_GetError());
514 tmp1_outlen
= tmp2_outlen
= 0;
515 rv
= PK11_CipherOp(EncContext
, out
, &tmp1_outlen
, outSize
,
516 (unsigned char *)in
, inSize
);
517 if (rv
!= SECSuccess
) {
518 xmlSecError(XMLSEC_ERRORS_HERE
,
521 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
522 "Error code = %d", PORT_GetError());
526 rv
= PK11_DigestFinal(EncContext
, out
+tmp1_outlen
,
527 &tmp2_outlen
, outSize
-tmp1_outlen
);
528 if (rv
!= SECSuccess
) {
529 xmlSecError(XMLSEC_ERRORS_HERE
,
532 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
533 "Error code = %d", PORT_GetError());
537 result_len
= tmp1_outlen
+ tmp2_outlen
;
541 SECITEM_FreeItem(secParam
, PR_TRUE
);
544 PK11_DestroyContext(EncContext
, PR_TRUE
);
551 xmlSecNssKeyWrapDesOp(
552 xmlSecNssKeyWrapCtxPtr ctx
,
554 xmlSecBufferPtr result
556 xmlSecByte sha1
[SHA1_LENGTH
];
557 xmlSecByte iv
[XMLSEC_NSS_DES3_IV_LENGTH
];
566 xmlSecAssert2( ctx
!= NULL
, -1 ) ;
567 xmlSecAssert2( ctx
->cipher
!= CKM_INVALID_MECHANISM
, -1 ) ;
568 xmlSecAssert2( ctx
->symkey
!= NULL
, -1 ) ;
569 xmlSecAssert2( ctx
->keyId
!= NULL
, -1 ) ;
570 xmlSecAssert2( ctx
->material
!= NULL
, -1 ) ;
571 xmlSecAssert2( result
!= NULL
, -1 ) ;
573 in
= xmlSecBufferGetData(ctx
->material
);
574 inSize
= xmlSecBufferGetSize(ctx
->material
) ;
575 out
= xmlSecBufferGetData(result
);
576 outSize
= xmlSecBufferGetMaxSize(result
) ;
578 /* step 2: calculate sha1 and CMS */
579 if(xmlSecNssComputeSHA1(in
, inSize
, sha1
, SHA1_LENGTH
) == NULL
) {
580 xmlSecError(XMLSEC_ERRORS_HERE
,
582 "xmlSecNssComputeSHA1",
583 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
584 XMLSEC_ERRORS_NO_MESSAGE
);
588 /* step 3: construct WKCKS */
589 memcpy(out
, in
, inSize
);
590 memcpy(out
+ inSize
, sha1
, XMLSEC_NSS_DES3_BLOCK_LENGTH
);
592 /* step 4: generate random iv */
593 status
= PK11_GenerateRandom(iv
, XMLSEC_NSS_DES3_IV_LENGTH
);
594 if(status
!= SECSuccess
) {
595 xmlSecError(XMLSEC_ERRORS_HERE
,
597 "PK11_GenerateRandom",
598 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
599 "error code = %d", PORT_GetError());
603 /* step 5: first encryption, result is TEMP1 */
604 ret
= xmlSecNssKWDes3Encrypt( ctx
->symkey
, ctx
->cipher
,
605 iv
, XMLSEC_NSS_DES3_IV_LENGTH
,
606 out
, inSize
+ XMLSEC_NSS_DES3_IV_LENGTH
,
609 xmlSecError(XMLSEC_ERRORS_HERE
,
611 "xmlSecNssKWDes3Encrypt",
612 XMLSEC_ERRORS_R_XMLSEC_FAILED
,
613 XMLSEC_ERRORS_NO_MESSAGE
);
617 /* step 6: construct TEMP2=IV || TEMP1 */
618 memmove(out
+ XMLSEC_NSS_DES3_IV_LENGTH
, out
,
619 inSize
+ XMLSEC_NSS_DES3_IV_LENGTH
);
620 memcpy(out
, iv
, XMLSEC_NSS_DES3_IV_LENGTH
);
621 s
= ret
+ XMLSEC_NSS_DES3_IV_LENGTH
;
623 /* step 7: reverse octets order, result is TEMP3 */
624 ret
= xmlSecNssKWDes3BufferReverse(out
, s
);
626 xmlSecError(XMLSEC_ERRORS_HERE
,
628 "xmlSecNssKWDes3BufferReverse",
629 XMLSEC_ERRORS_R_XMLSEC_FAILED
,
630 XMLSEC_ERRORS_NO_MESSAGE
);
634 /* step 8: second encryption with static IV */
635 ret
= xmlSecNssKWDes3Encrypt( ctx
->symkey
, ctx
->cipher
,
636 xmlSecNssKWDes3Iv
, XMLSEC_NSS_DES3_IV_LENGTH
,
640 xmlSecError(XMLSEC_ERRORS_HERE
,
642 "xmlSecNssKWDes3Encrypt",
643 XMLSEC_ERRORS_R_XMLSEC_FAILED
,
644 XMLSEC_ERRORS_NO_MESSAGE
);
649 if( xmlSecBufferSetSize( result
, s
) < 0 ) {
650 xmlSecError(XMLSEC_ERRORS_HERE
,
652 "xmlSecBufferSetSize",
653 XMLSEC_ERRORS_R_XMLSEC_FAILED
,
654 XMLSEC_ERRORS_NO_MESSAGE
);
658 /* step 2: first decryption with static IV, result is TEMP3 */
659 ret
= xmlSecNssKWDes3Encrypt( ctx
->symkey
, ctx
->cipher
,
660 xmlSecNssKWDes3Iv
, XMLSEC_NSS_DES3_IV_LENGTH
,
663 if((ret
< 0) || (ret
< XMLSEC_NSS_DES3_IV_LENGTH
)) {
664 xmlSecError(XMLSEC_ERRORS_HERE
,
666 "xmlSecNssKWDes3Encrypt",
667 XMLSEC_ERRORS_R_XMLSEC_FAILED
,
668 XMLSEC_ERRORS_NO_MESSAGE
);
673 /* step 3: reverse octets order in TEMP3, result is TEMP2 */
674 ret
= xmlSecNssKWDes3BufferReverse(out
, s
);
676 xmlSecError(XMLSEC_ERRORS_HERE
,
678 "xmlSecNssKWDes3BufferReverse",
679 XMLSEC_ERRORS_R_XMLSEC_FAILED
,
680 XMLSEC_ERRORS_NO_MESSAGE
);
684 /* steps 4 and 5: get IV and decrypt second time, result is WKCKS */
685 ret
= xmlSecNssKWDes3Encrypt( ctx
->symkey
, ctx
->cipher
,
686 out
, XMLSEC_NSS_DES3_IV_LENGTH
,
687 out
+XMLSEC_NSS_DES3_IV_LENGTH
, s
-XMLSEC_NSS_DES3_IV_LENGTH
,
689 if((ret
< 0) || (ret
< XMLSEC_NSS_DES3_BLOCK_LENGTH
)) {
690 xmlSecError(XMLSEC_ERRORS_HERE
,
692 "xmlSecNssKWDes3Encrypt",
693 XMLSEC_ERRORS_R_XMLSEC_FAILED
,
694 XMLSEC_ERRORS_NO_MESSAGE
);
697 s
= ret
- XMLSEC_NSS_DES3_IV_LENGTH
;
699 /* steps 6 and 7: calculate SHA1 and validate it */
700 if(xmlSecNssComputeSHA1(out
, s
, sha1
, SHA1_LENGTH
) == NULL
) {
701 xmlSecError(XMLSEC_ERRORS_HERE
,
703 "xmlSecNssComputeSHA1",
704 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
705 XMLSEC_ERRORS_NO_MESSAGE
);
709 if(memcmp(sha1
, out
+ s
, XMLSEC_NSS_DES3_BLOCK_LENGTH
) != 0) {
710 xmlSecError(XMLSEC_ERRORS_HERE
,
713 XMLSEC_ERRORS_R_INVALID_DATA
,
714 "SHA1 does not match");
718 if( xmlSecBufferSetSize( result
, s
) < 0 ) {
719 xmlSecError(XMLSEC_ERRORS_HERE
,
721 "xmlSecBufferSetSize",
722 XMLSEC_ERRORS_R_XMLSEC_FAILED
,
723 XMLSEC_ERRORS_NO_MESSAGE
);
732 xmlSecNssKeyWrapAesOp(
733 xmlSecNssKeyWrapCtxPtr ctx
,
735 xmlSecBufferPtr result
737 PK11Context
* cipherCtx
= NULL
;
739 SECItem
* secParam
= NULL
;
741 xmlSecSize inBlocks
;
748 xmlSecAssert2( ctx
!= NULL
, -1 ) ;
749 xmlSecAssert2( ctx
->cipher
!= CKM_INVALID_MECHANISM
, -1 ) ;
750 xmlSecAssert2( ctx
->symkey
!= NULL
, -1 ) ;
751 xmlSecAssert2( ctx
->keyId
!= NULL
, -1 ) ;
752 xmlSecAssert2( ctx
->material
!= NULL
, -1 ) ;
753 xmlSecAssert2( result
!= NULL
, -1 ) ;
755 /* Do not set any IV */
756 memset(&ivItem
, 0, sizeof(ivItem
));
759 if( ( blockSize
= PK11_GetBlockSize( ctx
->cipher
, NULL
) ) < 0 ) {
760 xmlSecError( XMLSEC_ERRORS_HERE
,
762 "PK11_GetBlockSize" ,
763 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
764 XMLSEC_ERRORS_NO_MESSAGE
) ;
768 inSize
= xmlSecBufferGetSize( ctx
->material
) ;
769 if( xmlSecBufferSetMaxSize( result
, inSize
+ blockSize
) < 0 ) {
770 xmlSecError( XMLSEC_ERRORS_HERE
,
772 "xmlSecBufferSetMaxSize" ,
773 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
774 XMLSEC_ERRORS_NO_MESSAGE
) ;
778 /* Get Param for context initialization */
779 if( ( secParam
= PK11_ParamFromIV( ctx
->cipher
, &ivItem
) ) == NULL
) {
780 xmlSecError( XMLSEC_ERRORS_HERE
,
783 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
784 XMLSEC_ERRORS_NO_MESSAGE
) ;
788 cipherCtx
= PK11_CreateContextBySymKey( ctx
->cipher
, encrypt
? CKA_ENCRYPT
: CKA_DECRYPT
, ctx
->symkey
, secParam
) ;
789 if( cipherCtx
== NULL
) {
790 xmlSecError( XMLSEC_ERRORS_HERE
,
792 "PK11_CreateContextBySymKey" ,
793 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
794 XMLSEC_ERRORS_NO_MESSAGE
) ;
795 SECITEM_FreeItem( secParam
, PR_TRUE
) ;
799 out
= xmlSecBufferGetData(result
) ;
800 outSize
= xmlSecBufferGetMaxSize(result
) ;
801 if( PK11_CipherOp( cipherCtx
, out
, &midSize
, outSize
, xmlSecBufferGetData( ctx
->material
) , inSize
) != SECSuccess
) {
802 xmlSecError( XMLSEC_ERRORS_HERE
,
805 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
806 XMLSEC_ERRORS_NO_MESSAGE
) ;
810 if( PK11_DigestFinal( cipherCtx
, out
+ midSize
, &finSize
, outSize
- midSize
) != SECSuccess
) {
811 xmlSecError( XMLSEC_ERRORS_HERE
,
814 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
815 XMLSEC_ERRORS_NO_MESSAGE
) ;
819 if( xmlSecBufferSetSize( result
, midSize
+ finSize
) < 0 ) {
820 xmlSecError( XMLSEC_ERRORS_HERE
,
822 "xmlSecBufferSetSize" ,
823 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
824 XMLSEC_ERRORS_NO_MESSAGE
) ;
832 * Block cipher transform final
835 xmlSecNssKeyWrapCtxFinal(
836 xmlSecNssKeyWrapCtxPtr ctx
,
838 xmlSecBufferPtr out
,
840 xmlSecTransformCtxPtr transformCtx
842 PK11SymKey
* targetKey
;
843 xmlSecSize blockSize
;
844 xmlSecBufferPtr result
;
846 xmlSecAssert2( ctx
!= NULL
, -1 ) ;
847 xmlSecAssert2( ctx
->cipher
!= CKM_INVALID_MECHANISM
, -1 ) ;
848 xmlSecAssert2( ctx
->symkey
!= NULL
, -1 ) ;
849 xmlSecAssert2( ctx
->keyId
!= NULL
, -1 ) ;
850 xmlSecAssert2( ctx
->material
!= NULL
, -1 ) ;
851 xmlSecAssert2( in
!= NULL
, -1 ) ;
852 xmlSecAssert2( out
!= NULL
, -1 ) ;
853 xmlSecAssert2( transformCtx
!= NULL
, -1 ) ;
855 /* read raw key material and append into context */
856 if( xmlSecBufferAppend( ctx
->material
, xmlSecBufferGetData(in
), xmlSecBufferGetSize(in
) ) < 0 ) {
857 xmlSecError( XMLSEC_ERRORS_HERE
,
859 "xmlSecBufferAppend" ,
860 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
861 XMLSEC_ERRORS_NO_MESSAGE
) ;
865 if( xmlSecBufferRemoveHead( in
, xmlSecBufferGetSize(in
) ) < 0 ) {
866 xmlSecError( XMLSEC_ERRORS_HERE
,
868 "xmlSecBufferRemoveHead" ,
869 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
870 XMLSEC_ERRORS_NO_MESSAGE
) ;
874 /* Now we get all of the key materail */
875 /* from now on we will wrap or unwrap the key */
876 if( ( blockSize
= PK11_GetBlockSize( ctx
->cipher
, NULL
) ) < 0 ) {
877 xmlSecError( XMLSEC_ERRORS_HERE
,
879 "PK11_GetBlockSize" ,
880 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
881 XMLSEC_ERRORS_NO_MESSAGE
) ;
885 result
= xmlSecBufferCreate( blockSize
) ;
886 if( result
== NULL
) {
887 xmlSecError( XMLSEC_ERRORS_HERE
,
889 "xmlSecBufferCreate" ,
890 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
891 XMLSEC_ERRORS_NO_MESSAGE
) ;
895 switch( ctx
->cipher
) {
897 if( xmlSecNssKeyWrapDesOp(ctx
, encrypt
, result
) < 0 ) {
898 xmlSecError( XMLSEC_ERRORS_HERE
,
900 "xmlSecNssKeyWrapDesOp" ,
901 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
902 XMLSEC_ERRORS_NO_MESSAGE
) ;
903 xmlSecBufferDestroy(result
);
907 /* case CKM_NETSCAPE_AES_KEY_WRAP :*/
909 if( xmlSecNssKeyWrapAesOp(ctx
, encrypt
, result
) < 0 ) {
910 xmlSecError( XMLSEC_ERRORS_HERE
,
912 "xmlSecNssKeyWrapAesOp" ,
913 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
914 XMLSEC_ERRORS_NO_MESSAGE
) ;
915 xmlSecBufferDestroy(result
);
922 if( xmlSecBufferAppend( out
, xmlSecBufferGetData(result
), xmlSecBufferGetSize(result
) ) < 0 ) {
923 xmlSecError( XMLSEC_ERRORS_HERE
,
925 "xmlSecBufferAppend" ,
926 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
927 XMLSEC_ERRORS_NO_MESSAGE
) ;
928 xmlSecBufferDestroy(result
);
931 xmlSecBufferDestroy(result
);
937 xmlSecNssKeyWrapExecute(xmlSecTransformPtr transform
, int last
, xmlSecTransformCtxPtr transformCtx
) {
938 xmlSecNssKeyWrapCtxPtr context
= NULL
;
939 xmlSecBufferPtr inBuf
, outBuf
;
943 xmlSecAssert2( xmlSecNssKeyWrapCheckId( transform
), -1 ) ;
944 xmlSecAssert2( xmlSecTransformCheckSize( transform
, xmlSecNssKeyWrapSize
), -1 ) ;
945 xmlSecAssert2( ( transform
->operation
== xmlSecTransformOperationEncrypt
) || ( transform
->operation
== xmlSecTransformOperationDecrypt
), -1 ) ;
946 xmlSecAssert2( transformCtx
!= NULL
, -1 ) ;
948 context
= xmlSecNssKeyWrapGetCtx( transform
) ;
949 if( context
== NULL
) {
950 xmlSecError( XMLSEC_ERRORS_HERE
,
951 xmlSecErrorsSafeString( xmlSecTransformGetName( transform
) ) ,
952 "xmlSecNssKeyWrapGetCtx" ,
953 XMLSEC_ERRORS_R_CRYPTO_FAILED
,
954 XMLSEC_ERRORS_NO_MESSAGE
) ;
958 inBuf
= &( transform
->inBuf
) ;
959 outBuf
= &( transform
->outBuf
) ;
961 if( transform
->status
== xmlSecTransformStatusNone
) {
962 transform
->status
= xmlSecTransformStatusWorking
;
965 operation
= ( transform
->operation
== xmlSecTransformOperationEncrypt
) ? 1 : 0 ;
966 if( transform
->status
== xmlSecTransformStatusWorking
) {
967 if( context
->material
== NULL
) {
968 rtv
= xmlSecNssKeyWrapCtxInit( context
, inBuf
, outBuf
, operation
, transformCtx
) ;
970 xmlSecError( XMLSEC_ERRORS_HERE
,
971 xmlSecErrorsSafeString( xmlSecTransformGetName( transform
) ) ,
972 "xmlSecNssKeyWrapCtxInit" ,
973 XMLSEC_ERRORS_R_INVALID_STATUS
,
974 XMLSEC_ERRORS_NO_MESSAGE
) ;
979 if( context
->material
== NULL
&& last
!= 0 ) {
980 xmlSecError( XMLSEC_ERRORS_HERE
,
981 xmlSecErrorsSafeString( xmlSecTransformGetName( transform
) ) ,
983 XMLSEC_ERRORS_R_INVALID_STATUS
,
984 "No enough data to intialize transform" ) ;
988 if( context
->material
!= NULL
) {
989 rtv
= xmlSecNssKeyWrapCtxUpdate( context
, inBuf
, outBuf
, operation
, transformCtx
) ;
991 xmlSecError( XMLSEC_ERRORS_HERE
,
992 xmlSecErrorsSafeString( xmlSecTransformGetName( transform
) ) ,
993 "xmlSecNssKeyWrapCtxUpdate" ,
994 XMLSEC_ERRORS_R_INVALID_STATUS
,
995 XMLSEC_ERRORS_NO_MESSAGE
) ;
1001 rtv
= xmlSecNssKeyWrapCtxFinal( context
, inBuf
, outBuf
, operation
, transformCtx
) ;
1003 xmlSecError( XMLSEC_ERRORS_HERE
,
1004 xmlSecErrorsSafeString( xmlSecTransformGetName( transform
) ) ,
1005 "xmlSecNssKeyWrapCtxFinal" ,
1006 XMLSEC_ERRORS_R_INVALID_STATUS
,
1007 XMLSEC_ERRORS_NO_MESSAGE
) ;
1010 transform
->status
= xmlSecTransformStatusFinished
;
1012 } else if( transform
->status
== xmlSecTransformStatusFinished
) {
1013 if( xmlSecBufferGetSize( inBuf
) != 0 ) {
1014 xmlSecError( XMLSEC_ERRORS_HERE
,
1015 xmlSecErrorsSafeString( xmlSecTransformGetName( transform
) ) ,
1017 XMLSEC_ERRORS_R_INVALID_STATUS
,
1018 "status=%d", transform
->status
) ;
1022 xmlSecError( XMLSEC_ERRORS_HERE
,
1023 xmlSecErrorsSafeString( xmlSecTransformGetName( transform
) ) ,
1025 XMLSEC_ERRORS_R_INVALID_STATUS
,
1026 "status=%d", transform
->status
) ;
1033 #ifndef XMLSEC_NO_AES
1036 #ifdef __MINGW32__ // for runtime-pseudo-reloc
1037 static struct _xmlSecTransformKlass xmlSecNssKWAes128Klass
= {
1039 static xmlSecTransformKlass xmlSecNssKWAes128Klass
= {
1041 /* klass/object sizes */
1042 sizeof(xmlSecTransformKlass
), /* xmlSecSize klassSize */
1043 xmlSecNssKeyWrapSize
, /* xmlSecSize objSize */
1045 xmlSecNameKWAes128
, /* const xmlChar* name; */
1046 xmlSecHrefKWAes128
, /* const xmlChar* href; */
1047 xmlSecTransformUsageEncryptionMethod
, /* xmlSecAlgorithmUsage usage; */
1049 xmlSecNssKeyWrapInitialize
, /* xmlSecTransformInitializeMethod initialize; */
1050 xmlSecNssKeyWrapFinalize
, /* xmlSecTransformFinalizeMethod finalize; */
1051 NULL
, /* xmlSecTransformNodeReadMethod readNode; */
1052 NULL
, /* xmlSecTransformNodeWriteMethod writeNode; */
1053 xmlSecNssKeyWrapSetKeyReq
, /* xmlSecTransformSetKeyMethod setKeyReq; */
1054 xmlSecNssKeyWrapSetKey
, /* xmlSecTransformSetKeyMethod setKey; */
1055 NULL
, /* xmlSecTransformValidateMethod validate; */
1056 xmlSecTransformDefaultGetDataType
, /* xmlSecTransformGetDataTypeMethod getDataType; */
1057 xmlSecTransformDefaultPushBin
, /* xmlSecTransformPushBinMethod pushBin; */
1058 xmlSecTransformDefaultPopBin
, /* xmlSecTransformPopBinMethod popBin; */
1059 NULL
, /* xmlSecTransformPushXmlMethod pushXml; */
1060 NULL
, /* xmlSecTransformPopXmlMethod popXml; */
1061 xmlSecNssKeyWrapExecute
, /* xmlSecTransformExecuteMethod execute; */
1063 NULL
, /* void* reserved0; */
1064 NULL
, /* void* reserved1; */
1067 #ifdef __MINGW32__ // for runtime-pseudo-reloc
1068 static struct _xmlSecTransformKlass xmlSecNssKWAes192Klass
= {
1070 static xmlSecTransformKlass xmlSecNssKWAes192Klass
= {
1072 /* klass/object sizes */
1073 sizeof(xmlSecTransformKlass
), /* xmlSecSize klassSize */
1074 xmlSecNssKeyWrapSize
, /* xmlSecSize objSize */
1076 xmlSecNameKWAes192
, /* const xmlChar* name; */
1077 xmlSecHrefKWAes192
, /* const xmlChar* href; */
1078 xmlSecTransformUsageEncryptionMethod
, /* xmlSecAlgorithmUsage usage; */
1080 xmlSecNssKeyWrapInitialize
, /* xmlSecTransformInitializeMethod initialize; */
1081 xmlSecNssKeyWrapFinalize
, /* xmlSecTransformFinalizeMethod finalize; */
1082 NULL
, /* xmlSecTransformNodeReadMethod readNode; */
1083 NULL
, /* xmlSecTransformNodeWriteMethod writeNode; */
1084 xmlSecNssKeyWrapSetKeyReq
, /* xmlSecTransformSetKeyMethod setKeyReq; */
1085 xmlSecNssKeyWrapSetKey
, /* xmlSecTransformSetKeyMethod setKey; */
1086 NULL
, /* xmlSecTransformValidateMethod validate; */
1087 xmlSecTransformDefaultGetDataType
, /* xmlSecTransformGetDataTypeMethod getDataType; */
1088 xmlSecTransformDefaultPushBin
, /* xmlSecTransformPushBinMethod pushBin; */
1089 xmlSecTransformDefaultPopBin
, /* xmlSecTransformPopBinMethod popBin; */
1090 NULL
, /* xmlSecTransformPushXmlMethod pushXml; */
1091 NULL
, /* xmlSecTransformPopXmlMethod popXml; */
1092 xmlSecNssKeyWrapExecute
, /* xmlSecTransformExecuteMethod execute; */
1094 NULL
, /* void* reserved0; */
1095 NULL
, /* void* reserved1; */
1098 #ifdef __MINGW32__ // for runtime-pseudo-reloc
1099 static struct _xmlSecTransformKlass xmlSecNssKWAes256Klass
= {
1101 static xmlSecTransformKlass xmlSecNssKWAes256Klass
= {
1103 /* klass/object sizes */
1104 sizeof(xmlSecTransformKlass
), /* xmlSecSize klassSize */
1105 xmlSecNssKeyWrapSize
, /* xmlSecSize objSize */
1107 xmlSecNameKWAes256
, /* const xmlChar* name; */
1108 xmlSecHrefKWAes256
, /* const xmlChar* href; */
1109 xmlSecTransformUsageEncryptionMethod
, /* xmlSecAlgorithmUsage usage; */
1111 xmlSecNssKeyWrapInitialize
, /* xmlSecTransformInitializeMethod initialize; */
1112 xmlSecNssKeyWrapFinalize
, /* xmlSecTransformFinalizeMethod finalize; */
1113 NULL
, /* xmlSecTransformNodeReadMethod readNode; */
1114 NULL
, /* xmlSecTransformNodeWriteMethod writeNode; */
1115 xmlSecNssKeyWrapSetKeyReq
, /* xmlSecTransformSetKeyMethod setKeyReq; */
1116 xmlSecNssKeyWrapSetKey
, /* xmlSecTransformSetKeyMethod setKey; */
1117 NULL
, /* xmlSecTransformValidateMethod validate; */
1118 xmlSecTransformDefaultGetDataType
, /* xmlSecTransformGetDataTypeMethod getDataType; */
1119 xmlSecTransformDefaultPushBin
, /* xmlSecTransformPushBinMethod pushBin; */
1120 xmlSecTransformDefaultPopBin
, /* xmlSecTransformPopBinMethod popBin; */
1121 NULL
, /* xmlSecTransformPushXmlMethod pushXml; */
1122 NULL
, /* xmlSecTransformPopXmlMethod popXml; */
1123 xmlSecNssKeyWrapExecute
, /* xmlSecTransformExecuteMethod execute; */
1125 NULL
, /* void* reserved0; */
1126 NULL
, /* void* reserved1; */
1130 * xmlSecNssTransformKWAes128GetKlass:
1132 * The AES-128 key wrapper transform klass.
1134 * Returns AES-128 key wrapper transform klass.
1137 xmlSecNssTransformKWAes128GetKlass(void) {
1138 return(&xmlSecNssKWAes128Klass
);
1142 * xmlSecNssTransformKWAes192GetKlass:
1144 * The AES-192 key wrapper transform klass.
1146 * Returns AES-192 key wrapper transform klass.
1149 xmlSecNssTransformKWAes192GetKlass(void) {
1150 return(&xmlSecNssKWAes192Klass
);
1155 * The AES-256 key wrapper transform klass.
1157 * Returns AES-256 key wrapper transform klass.
1160 xmlSecNssTransformKWAes256GetKlass(void) {
1161 return(&xmlSecNssKWAes256Klass
);
1164 #endif /* XMLSEC_NO_AES */
1167 #ifndef XMLSEC_NO_DES
1169 #ifdef __MINGW32__ // for runtime-pseudo-reloc
1170 static struct _xmlSecTransformKlass xmlSecNssKWDes3Klass
= {
1172 static xmlSecTransformKlass xmlSecNssKWDes3Klass
= {
1174 /* klass/object sizes */
1175 sizeof(xmlSecTransformKlass
), /* xmlSecSize klassSize */
1176 xmlSecNssKeyWrapSize
, /* xmlSecSize objSize */
1178 xmlSecNameKWDes3
, /* const xmlChar* name; */
1179 xmlSecHrefKWDes3
, /* const xmlChar* href; */
1180 xmlSecTransformUsageEncryptionMethod
, /* xmlSecAlgorithmUsage usage; */
1182 xmlSecNssKeyWrapInitialize
, /* xmlSecTransformInitializeMethod initialize; */
1183 xmlSecNssKeyWrapFinalize
, /* xmlSecTransformFinalizeMethod finalize; */
1184 NULL
, /* xmlSecTransformNodeReadMethod readNode; */
1185 NULL
, /* xmlSecTransformNodeWriteMethod writeNode; */
1186 xmlSecNssKeyWrapSetKeyReq
, /* xmlSecTransformSetKeyMethod setKeyReq; */
1187 xmlSecNssKeyWrapSetKey
, /* xmlSecTransformSetKeyMethod setKey; */
1188 NULL
, /* xmlSecTransformValidateMethod validate; */
1189 xmlSecTransformDefaultGetDataType
, /* xmlSecTransformGetDataTypeMethod getDataType; */
1190 xmlSecTransformDefaultPushBin
, /* xmlSecTransformPushBinMethod pushBin; */
1191 xmlSecTransformDefaultPopBin
, /* xmlSecTransformPopBinMethod popBin; */
1192 NULL
, /* xmlSecTransformPushXmlMethod pushXml; */
1193 NULL
, /* xmlSecTransformPopXmlMethod popXml; */
1194 xmlSecNssKeyWrapExecute
, /* xmlSecTransformExecuteMethod execute; */
1196 NULL
, /* void* reserved0; */
1197 NULL
, /* void* reserved1; */
1201 * xmlSecNssTransformKWDes3GetKlass:
1203 * The Triple DES key wrapper transform klass.
1205 * Returns Triple DES key wrapper transform klass.
1208 xmlSecNssTransformKWDes3GetKlass(void) {
1209 return(&xmlSecNssKWDes3Klass
);
1212 #endif /* XMLSEC_NO_DES */