5 * DES Algorithm support
7 * This is free software; see Copyright file in the source
8 * distribution for preciese wording.
10 * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
19 #include <openssl/des.h>
20 #include <openssl/rand.h>
21 #include <openssl/sha.h>
23 #include <xmlsec/xmlsec.h>
24 #include <xmlsec/xmltree.h>
25 #include <xmlsec/keys.h>
26 #include <xmlsec/transforms.h>
27 #include <xmlsec/errors.h>
29 #include <xmlsec/openssl/crypto.h>
31 #define XMLSEC_OPENSSL_DES3_KEY_LENGTH 24
32 #define XMLSEC_OPENSSL_DES3_IV_LENGTH 8
33 #define XMLSEC_OPENSSL_DES3_BLOCK_LENGTH 8
35 /*********************************************************************
37 * Triple DES Key Wrap transform
39 * key (xmlSecBuffer) is located after xmlSecTransform structure
41 ********************************************************************/
42 #define xmlSecOpenSSLKWDes3GetKey(transform) \
43 ((xmlSecBufferPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)))
44 #define xmlSecOpenSSLKWDes3Size \
45 (sizeof(xmlSecTransform) + sizeof(xmlSecBuffer))
47 static int xmlSecOpenSSLKWDes3Initialize (xmlSecTransformPtr transform);
48 static void xmlSecOpenSSLKWDes3Finalize (xmlSecTransformPtr transform);
49 static int xmlSecOpenSSLKWDes3SetKeyReq (xmlSecTransformPtr transform,
50 xmlSecKeyReqPtr keyReq);
51 static int xmlSecOpenSSLKWDes3SetKey (xmlSecTransformPtr transform,
53 static int xmlSecOpenSSLKWDes3Execute (xmlSecTransformPtr transform,
55 xmlSecTransformCtxPtr transformCtx);
56 static int xmlSecOpenSSLKWDes3Encode (const xmlSecByte *key,
62 static int xmlSecOpenSSLKWDes3Decode (const xmlSecByte *key,
68 static int xmlSecOpenSSLKWDes3Encrypt (const xmlSecByte *key,
77 static int xmlSecOpenSSLKWDes3BufferReverse (xmlSecByte *buf,
80 static xmlSecTransformKlass xmlSecOpenSSLKWDes3Klass = {
81 /* klass/object sizes */
82 sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
83 xmlSecOpenSSLKWDes3Size, /* xmlSecSize objSize */
85 xmlSecNameKWDes3, /* const xmlChar* name; */
86 xmlSecHrefKWDes3, /* const xmlChar* href; */
87 xmlSecTransformUsageEncryptionMethod, /* xmlSecAlgorithmUsage usage; */
89 xmlSecOpenSSLKWDes3Initialize, /* xmlSecTransformInitializeMethod initialize; */
90 xmlSecOpenSSLKWDes3Finalize, /* xmlSecTransformFinalizeMethod finalize; */
91 NULL, /* xmlSecTransformNodeReadMethod readNode; */
92 NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
93 xmlSecOpenSSLKWDes3SetKeyReq, /* xmlSecTransformSetKeyMethod setKeyReq; */
94 xmlSecOpenSSLKWDes3SetKey, /* xmlSecTransformSetKeyMethod setKey; */
95 NULL, /* xmlSecTransformValidateMethod validate; */
96 xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
97 xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
98 xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
99 NULL, /* xmlSecTransformPushXmlMethod pushXml; */
100 NULL, /* xmlSecTransformPopXmlMethod popXml; */
101 xmlSecOpenSSLKWDes3Execute, /* xmlSecTransformExecuteMethod execute; */
103 NULL, /* void* reserved0; */
104 NULL, /* void* reserved1; */
108 * xmlSecOpenSSLTransformKWDes3GetKlass:
110 * The Triple DES key wrapper transform klass.
112 * Returns: Triple DES key wrapper transform klass.
115 xmlSecOpenSSLTransformKWDes3GetKlass(void) {
116 return(&xmlSecOpenSSLKWDes3Klass);
120 xmlSecOpenSSLKWDes3Initialize(xmlSecTransformPtr transform) {
123 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformKWDes3Id), -1);
124 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLKWDes3Size), -1);
126 ret = xmlSecBufferInitialize(xmlSecOpenSSLKWDes3GetKey(transform), 0);
128 xmlSecError(XMLSEC_ERRORS_HERE,
129 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
130 "xmlSecBufferInitialize",
131 XMLSEC_ERRORS_R_XMLSEC_FAILED,
132 XMLSEC_ERRORS_NO_MESSAGE);
140 xmlSecOpenSSLKWDes3Finalize(xmlSecTransformPtr transform) {
141 xmlSecAssert(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformKWDes3Id));
142 xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecOpenSSLKWDes3Size));
144 if(xmlSecOpenSSLKWDes3GetKey(transform) != NULL) {
145 xmlSecBufferFinalize(xmlSecOpenSSLKWDes3GetKey(transform));
150 xmlSecOpenSSLKWDes3SetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq) {
151 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformKWDes3Id), -1);
152 xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
153 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLKWDes3Size), -1);
154 xmlSecAssert2(keyReq != NULL, -1);
156 keyReq->keyId = xmlSecOpenSSLKeyDataDesId;
157 keyReq->keyType = xmlSecKeyDataTypeSymmetric;
158 if(transform->operation == xmlSecTransformOperationEncrypt) {
159 keyReq->keyUsage= xmlSecKeyUsageEncrypt;
161 keyReq->keyUsage= xmlSecKeyUsageDecrypt;
163 keyReq->keyBitsSize = 8 * XMLSEC_OPENSSL_DES3_KEY_LENGTH;
168 xmlSecOpenSSLKWDes3SetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
169 xmlSecBufferPtr buffer;
173 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformKWDes3Id), -1);
174 xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
175 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLKWDes3Size), -1);
176 xmlSecAssert2(xmlSecOpenSSLKWDes3GetKey(transform) != NULL, -1);
177 xmlSecAssert2(key != NULL, -1);
178 xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecOpenSSLKeyDataDesId), -1);
180 buffer = xmlSecKeyDataBinaryValueGetBuffer(xmlSecKeyGetValue(key));
181 xmlSecAssert2(buffer != NULL, -1);
183 keySize = xmlSecBufferGetSize(buffer);
184 if(keySize < XMLSEC_OPENSSL_DES3_KEY_LENGTH) {
185 xmlSecError(XMLSEC_ERRORS_HERE,
186 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
188 XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,
189 "key length %d is not enough (%d expected)",
190 keySize, XMLSEC_OPENSSL_DES3_KEY_LENGTH);
194 ret = xmlSecBufferSetData(xmlSecOpenSSLKWDes3GetKey(transform),
195 xmlSecBufferGetData(buffer),
196 XMLSEC_OPENSSL_DES3_KEY_LENGTH);
198 xmlSecError(XMLSEC_ERRORS_HERE,
199 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
200 "xmlSecBufferSetData",
201 XMLSEC_ERRORS_R_XMLSEC_FAILED,
202 "size=%d", XMLSEC_OPENSSL_DES3_KEY_LENGTH);
210 xmlSecOpenSSLKWDes3Execute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
211 xmlSecBufferPtr in, out, key;
212 xmlSecSize inSize, outSize, keySize;
215 xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformKWDes3Id), -1);
216 xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
217 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLKWDes3Size), -1);
218 xmlSecAssert2(transformCtx != NULL, -1);
220 key = xmlSecOpenSSLKWDes3GetKey(transform);
221 xmlSecAssert2(key != NULL, -1);
223 keySize = xmlSecBufferGetSize(key);
224 xmlSecAssert2(keySize == XMLSEC_OPENSSL_DES3_KEY_LENGTH, -1);
226 in = &(transform->inBuf);
227 out = &(transform->outBuf);
228 inSize = xmlSecBufferGetSize(in);
229 outSize = xmlSecBufferGetSize(out);
230 xmlSecAssert2(outSize == 0, -1);
232 if(transform->status == xmlSecTransformStatusNone) {
233 transform->status = xmlSecTransformStatusWorking;
236 if((transform->status == xmlSecTransformStatusWorking) && (last == 0)) {
237 /* just do nothing */
238 } else if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) {
239 if((inSize % XMLSEC_OPENSSL_DES3_BLOCK_LENGTH) != 0) {
240 xmlSecError(XMLSEC_ERRORS_HERE,
241 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
243 XMLSEC_ERRORS_R_INVALID_SIZE,
244 "%d bytes - not %d bytes aligned",
245 inSize, XMLSEC_OPENSSL_DES3_BLOCK_LENGTH);
249 if(transform->operation == xmlSecTransformOperationEncrypt) {
250 /* the encoded key might be 16 bytes longer plus one block just in case */
251 outSize = inSize + XMLSEC_OPENSSL_DES3_IV_LENGTH +
252 XMLSEC_OPENSSL_DES3_BLOCK_LENGTH +
253 XMLSEC_OPENSSL_DES3_BLOCK_LENGTH;
255 outSize = inSize + XMLSEC_OPENSSL_DES3_BLOCK_LENGTH;
258 ret = xmlSecBufferSetMaxSize(out, outSize);
260 xmlSecError(XMLSEC_ERRORS_HERE,
261 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
262 "xmlSecBufferSetMaxSize",
263 XMLSEC_ERRORS_R_XMLSEC_FAILED,
268 if(transform->operation == xmlSecTransformOperationEncrypt) {
269 ret = xmlSecOpenSSLKWDes3Encode(xmlSecBufferGetData(key), keySize,
270 xmlSecBufferGetData(in), inSize,
271 xmlSecBufferGetData(out), outSize);
273 xmlSecError(XMLSEC_ERRORS_HERE,
274 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
275 "xmlSecOpenSSLKWDes3Encode",
276 XMLSEC_ERRORS_R_XMLSEC_FAILED,
277 "key=%d,in=%d,out=%d",
278 keySize, inSize, outSize);
283 ret = xmlSecOpenSSLKWDes3Decode(xmlSecBufferGetData(key), keySize,
284 xmlSecBufferGetData(in), inSize,
285 xmlSecBufferGetData(out), outSize);
287 xmlSecError(XMLSEC_ERRORS_HERE,
288 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
289 "xmlSecOpenSSLKWDes3Decode",
290 XMLSEC_ERRORS_R_XMLSEC_FAILED,
291 "key=%d,in=%d,out=%d",
292 keySize, inSize, outSize);
298 ret = xmlSecBufferSetSize(out, outSize);
300 xmlSecError(XMLSEC_ERRORS_HERE,
301 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
302 "xmlSecBufferSetSize",
303 XMLSEC_ERRORS_R_XMLSEC_FAILED,
308 ret = xmlSecBufferRemoveHead(in, inSize);
310 xmlSecError(XMLSEC_ERRORS_HERE,
311 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
312 "xmlSecBufferRemoveHead",
313 XMLSEC_ERRORS_R_XMLSEC_FAILED,
318 transform->status = xmlSecTransformStatusFinished;
319 } else if(transform->status == xmlSecTransformStatusFinished) {
320 /* the only way we can get here is if there is no input */
321 xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1);
323 xmlSecError(XMLSEC_ERRORS_HERE,
324 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
326 XMLSEC_ERRORS_R_INVALID_STATUS,
327 "status=%d", transform->status);
333 static xmlSecByte xmlSecOpenSSLKWDes3Iv[XMLSEC_OPENSSL_DES3_IV_LENGTH] = {
334 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05
337 * CMS Triple DES Key Wrap
339 * http://www.w3.org/TR/xmlenc-core/#sec-Alg-SymmetricKeyWrap
341 * The following algorithm wraps (encrypts) a key (the wrapped key, WK)
342 * under a TRIPLEDES key-encryption-key (KEK) as specified in [CMS-Algorithms]:
344 * 1. Represent the key being wrapped as an octet sequence. If it is a
345 * TRIPLEDES key, this is 24 octets (192 bits) with odd parity bit as
346 * the bottom bit of each octet.
347 * 2. Compute the CMS key checksum (section 5.6.1) call this CKS.
348 * 3. Let WKCKS = WK || CKS, where || is concatenation.
349 * 4. Generate 8 random octets [RANDOM] and call this IV.
350 * 5. Encrypt WKCKS in CBC mode using KEK as the key and IV as the
351 * initialization vector. Call the results TEMP1.
352 * 6. Left TEMP2 = IV || TEMP1.
353 * 7. Reverse the order of the octets in TEMP2 and call the result TEMP3.
354 * 8. Encrypt TEMP3 in CBC mode using the KEK and an initialization vector
355 * of 0x4adda22c79e82105. The resulting cipher text is the desired result.
356 * It is 40 octets long if a 168 bit key is being wrapped.
360 xmlSecOpenSSLKWDes3Encode(const xmlSecByte *key, xmlSecSize keySize,
361 const xmlSecByte *in, xmlSecSize inSize,
362 xmlSecByte *out, xmlSecSize outSize) {
363 xmlSecByte sha1[SHA_DIGEST_LENGTH];
364 xmlSecByte iv[XMLSEC_OPENSSL_DES3_IV_LENGTH];
368 xmlSecAssert2(key != NULL, -1);
369 xmlSecAssert2(keySize == XMLSEC_OPENSSL_DES3_KEY_LENGTH, -1);
370 xmlSecAssert2(in != NULL, -1);
371 xmlSecAssert2(inSize > 0, -1);
372 xmlSecAssert2(out != NULL, -1);
373 xmlSecAssert2(outSize >= inSize + 16, -1);
375 /* step 2: calculate sha1 and CMS */
376 if(SHA1(in, inSize, sha1) == NULL) {
377 xmlSecError(XMLSEC_ERRORS_HERE,
380 XMLSEC_ERRORS_R_CRYPTO_FAILED,
381 XMLSEC_ERRORS_NO_MESSAGE);
385 /* step 3: construct WKCKS */
386 memcpy(out, in, inSize);
387 memcpy(out + inSize, sha1, XMLSEC_OPENSSL_DES3_BLOCK_LENGTH);
389 /* step 4: generate random iv */
390 ret = RAND_bytes(iv, XMLSEC_OPENSSL_DES3_IV_LENGTH);
392 xmlSecError(XMLSEC_ERRORS_HERE,
395 XMLSEC_ERRORS_R_CRYPTO_FAILED,
400 /* step 5: first encryption, result is TEMP1 */
401 ret = xmlSecOpenSSLKWDes3Encrypt(key, keySize,
402 iv, XMLSEC_OPENSSL_DES3_IV_LENGTH,
403 out, inSize + XMLSEC_OPENSSL_DES3_BLOCK_LENGTH,
406 xmlSecError(XMLSEC_ERRORS_HERE,
408 "xmlSecOpenSSLKWDes3Encrypt",
409 XMLSEC_ERRORS_R_XMLSEC_FAILED,
410 XMLSEC_ERRORS_NO_MESSAGE);
414 /* step 6: construct TEMP2=IV || TEMP1 */
415 memmove(out + XMLSEC_OPENSSL_DES3_IV_LENGTH, out,
416 inSize + XMLSEC_OPENSSL_DES3_IV_LENGTH);
417 memcpy(out, iv, XMLSEC_OPENSSL_DES3_IV_LENGTH);
418 s = ret + XMLSEC_OPENSSL_DES3_IV_LENGTH;
420 /* step 7: reverse octets order, result is TEMP3 */
421 ret = xmlSecOpenSSLKWDes3BufferReverse(out, s);
423 xmlSecError(XMLSEC_ERRORS_HERE,
425 "xmlSecOpenSSLKWDes3BufferReverse",
426 XMLSEC_ERRORS_R_XMLSEC_FAILED,
427 XMLSEC_ERRORS_NO_MESSAGE);
431 /* step 8: second encryption with static IV */
432 ret = xmlSecOpenSSLKWDes3Encrypt(key, keySize,
433 xmlSecOpenSSLKWDes3Iv, XMLSEC_OPENSSL_DES3_IV_LENGTH,
434 out, s, out, outSize, 1);
436 xmlSecError(XMLSEC_ERRORS_HERE,
438 "xmlSecOpenSSLKWDes3Encrypt",
439 XMLSEC_ERRORS_R_XMLSEC_FAILED,
440 XMLSEC_ERRORS_NO_MESSAGE);
448 * CMS Triple DES Key Wrap
450 * http://www.w3.org/TR/xmlenc-core/#sec-Alg-SymmetricKeyWrap
452 * The following algorithm unwraps (decrypts) a key as specified in
455 * 1. Check if the length of the cipher text is reasonable given the key type.
456 * It must be 40 bytes for a 168 bit key and either 32, 40, or 48 bytes for
457 * a 128, 192, or 256 bit key. If the length is not supported or inconsistent
458 * with the algorithm for which the key is intended, return error.
459 * 2. Decrypt the cipher text with TRIPLEDES in CBC mode using the KEK and
460 * an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3.
461 * 3. Reverse the order of the octets in TEMP3 and call the result TEMP2.
462 * 4. Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining
464 * 5. Decrypt TEMP1 using TRIPLEDES in CBC mode using the KEK and the IV found
465 * in the previous step. Call the result WKCKS.
466 * 6. Decompose WKCKS. CKS is the last 8 octets and WK, the wrapped key, are
467 * those octets before the CKS.
468 * 7. Calculate a CMS key checksum (section 5.6.1) over the WK and compare
469 * with the CKS extracted in the above step. If they are not equal, return
471 * 8. WK is the wrapped key, now extracted for use in data decryption.
474 xmlSecOpenSSLKWDes3Decode(const xmlSecByte *key, xmlSecSize keySize,
475 const xmlSecByte *in, xmlSecSize inSize,
476 xmlSecByte *out, xmlSecSize outSize) {
477 xmlSecByte sha1[SHA_DIGEST_LENGTH];
481 xmlSecAssert2(key != NULL, -1);
482 xmlSecAssert2(keySize == XMLSEC_OPENSSL_DES3_KEY_LENGTH, -1);
483 xmlSecAssert2(in != NULL, -1);
484 xmlSecAssert2(inSize > 0, -1);
485 xmlSecAssert2(out != NULL, -1);
486 xmlSecAssert2(outSize >= inSize, -1);
488 /* step 2: first decryption with static IV, result is TEMP3 */
489 ret = xmlSecOpenSSLKWDes3Encrypt(key, keySize,
490 xmlSecOpenSSLKWDes3Iv, XMLSEC_OPENSSL_DES3_IV_LENGTH,
491 in, inSize, out, outSize, 0);
492 if((ret < 0) || (ret < XMLSEC_OPENSSL_DES3_IV_LENGTH)) {
493 xmlSecError(XMLSEC_ERRORS_HERE,
495 "xmlSecOpenSSLKWDes3Encrypt",
496 XMLSEC_ERRORS_R_XMLSEC_FAILED,
497 XMLSEC_ERRORS_NO_MESSAGE);
502 /* step 3: reverse octets order in TEMP3, result is TEMP2 */
503 ret = xmlSecOpenSSLKWDes3BufferReverse(out, s);
505 xmlSecError(XMLSEC_ERRORS_HERE,
507 "xmlSecOpenSSLKWDes3BufferReverse",
508 XMLSEC_ERRORS_R_XMLSEC_FAILED,
509 XMLSEC_ERRORS_NO_MESSAGE);
513 /* steps 4 and 5: get IV and decrypt second time, result is WKCKS */
514 ret = xmlSecOpenSSLKWDes3Encrypt(key, keySize,
515 out, XMLSEC_OPENSSL_DES3_IV_LENGTH,
516 out + XMLSEC_OPENSSL_DES3_IV_LENGTH,
517 s - XMLSEC_OPENSSL_DES3_IV_LENGTH,
519 if((ret < 0) || (ret < XMLSEC_OPENSSL_DES3_BLOCK_LENGTH)) {
520 xmlSecError(XMLSEC_ERRORS_HERE,
522 "xmlSecOpenSSLKWDes3Encrypt",
523 XMLSEC_ERRORS_R_XMLSEC_FAILED,
524 XMLSEC_ERRORS_NO_MESSAGE);
527 s = ret - XMLSEC_OPENSSL_DES3_BLOCK_LENGTH;
529 /* steps 6 and 7: calculate SHA1 and validate it */
530 if(SHA1(out, s, sha1) == NULL) {
531 xmlSecError(XMLSEC_ERRORS_HERE,
534 XMLSEC_ERRORS_R_CRYPTO_FAILED,
535 XMLSEC_ERRORS_NO_MESSAGE);
539 if(memcmp(sha1, out + s, XMLSEC_OPENSSL_DES3_BLOCK_LENGTH) != 0) {
540 xmlSecError(XMLSEC_ERRORS_HERE,
543 XMLSEC_ERRORS_R_INVALID_DATA,
544 "SHA1 does not match");
552 xmlSecOpenSSLKWDes3Encrypt(const xmlSecByte *key, xmlSecSize keySize,
553 const xmlSecByte *iv, xmlSecSize ivSize,
554 const xmlSecByte *in, xmlSecSize inSize,
555 xmlSecByte *out, xmlSecSize outSize, int enc) {
556 EVP_CIPHER_CTX cipherCtx;
561 xmlSecAssert2(key != NULL, -1);
562 xmlSecAssert2(keySize == (xmlSecSize)EVP_CIPHER_key_length(EVP_des_ede3_cbc()), -1);
563 xmlSecAssert2(iv != NULL, -1);
564 xmlSecAssert2(ivSize == (xmlSecSize)EVP_CIPHER_iv_length(EVP_des_ede3_cbc()), -1);
565 xmlSecAssert2(in != NULL, -1);
566 xmlSecAssert2(inSize > 0, -1);
567 xmlSecAssert2(out != NULL, -1);
568 xmlSecAssert2(outSize >= inSize, -1);
570 EVP_CIPHER_CTX_init(&cipherCtx);
571 ret = EVP_CipherInit(&cipherCtx, EVP_des_ede3_cbc(), key, iv, enc);
573 xmlSecError(XMLSEC_ERRORS_HERE,
576 XMLSEC_ERRORS_R_CRYPTO_FAILED,
577 XMLSEC_ERRORS_NO_MESSAGE);
581 #ifndef XMLSEC_OPENSSL_096
582 EVP_CIPHER_CTX_set_padding(&cipherCtx, 0);
583 #endif /* XMLSEC_OPENSSL_096 */
585 ret = EVP_CipherUpdate(&cipherCtx, out, &updateLen, in, inSize);
587 xmlSecError(XMLSEC_ERRORS_HERE,
590 XMLSEC_ERRORS_R_CRYPTO_FAILED,
591 XMLSEC_ERRORS_NO_MESSAGE);
595 ret = EVP_CipherFinal(&cipherCtx, out + updateLen, &finalLen);
597 xmlSecError(XMLSEC_ERRORS_HERE,
600 XMLSEC_ERRORS_R_CRYPTO_FAILED,
601 XMLSEC_ERRORS_NO_MESSAGE);
604 EVP_CIPHER_CTX_cleanup(&cipherCtx);
606 return(updateLen + finalLen);
610 xmlSecOpenSSLKWDes3BufferReverse(xmlSecByte *buf, xmlSecSize size) {
615 xmlSecAssert2(buf != NULL, -1);
619 for(i = 0; i < s; ++i) {
621 buf[i] = buf[size - i];
627 #endif /* XMLSEC_NO_DES */