2 * The contents of this file are subject to the Mozilla Public
3 * License Version 1.1 (the "License"); you may not use this file
4 * except in compliance with the License. You may obtain a copy of
5 * the License at http://www.mozilla.org/MPL/
7 * Software distributed under the License is distributed on an "AS
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9 * implied. See the License for the specific language governing
10 * rights and limitations under the License.
12 * The Original Code is the Netscape security libraries.
14 * The Initial Developer of the Original Code is Netscape
15 * Communications Corporation. Portions created by Netscape are
16 * Copyright (C) 1994-2000 Netscape Communications Corporation. All
21 * Alternatively, the contents of this file may be used under the
22 * terms of the GNU General Public License Version 2 or later (the
23 * "GPL"), in which case the provisions of the GPL are applicable
24 * instead of those above. If you wish to allow use of your
25 * version of this file only under the terms of the GPL and not to
26 * allow others to use your version of this file under the MPL,
27 * indicate your decision by deleting the provisions above and
28 * replace them with the notice and other provisions required by
29 * the GPL. If you do not delete the provisions above, a recipient
30 * may use your version of this file under either the MPL or the
35 * Encryption/decryption routines for CMS implementation, none of which are exported.
42 #include <security_asn1/secerr.h>
43 #include <security_asn1/secasn1.h>
44 #include <Security/SecAsn1Templates.h>
45 #include <Security/cssmapi.h>
46 #include <Security/cssmapple.h>
47 #include <Security/SecKeyPriv.h>
50 * -------------------------------------------------------------------
55 typedef OSStatus (*nss_cms_cipher_function
) (void *, unsigned char *, unsigned int *,
56 unsigned int, const unsigned char *, unsigned int);
57 typedef OSStatus (*nss_cms_cipher_destroy
) (void *, Boolean
);
60 #define BLOCK_SIZE 4096
62 struct SecCmsCipherContextStr
{
64 CSSM_CC_HANDLE cc
; /* CSP CONTEXT */
65 Boolean encrypt
; /* encrypt / decrypt switch */
67 void * cx
; /* PK11 cipher context */
68 nss_cms_cipher_function doit
;
69 nss_cms_cipher_destroy destroy
;
70 Boolean encrypt
; /* encrypt / decrypt switch */
71 int block_size
; /* block & pad sizes for cipher */
73 int pending_count
; /* pending data (not yet en/decrypted */
74 unsigned char pending_buf
[BLOCK_SIZE
];/* because of blocking */
78 typedef struct sec_rc2cbcParameterStr
{
79 SECItem rc2ParameterVersion
;
81 } sec_rc2cbcParameter
;
83 static const SecAsn1Template sec_rc2cbc_parameter_template
[] = {
85 0, NULL
, sizeof(sec_rc2cbcParameter
) },
86 { SEC_ASN1_INTEGER
| SEC_ASN1_SIGNED_INT
,
87 offsetof(sec_rc2cbcParameter
,rc2ParameterVersion
) },
88 { SEC_ASN1_OCTET_STRING
,
89 offsetof(sec_rc2cbcParameter
,iv
) },
94 ** Convert a der encoded *signed* integer into a machine integral value.
95 ** If an underflow/overflow occurs, sets error code and returns min/max.
98 DER_GetInteger(SECItem
*it
)
101 CSSM_SIZE len
= it
->Length
;
102 unsigned char *cp
= it
->Data
;
103 unsigned long overflow
= 0x1ffUL
<< (((sizeof(ival
) - 1) * 8) - 1);
104 unsigned long ofloinit
;
105 bool isNegative
= false;
110 ofloinit
= ival
& overflow
;
113 if ((ival
& overflow
) != ofloinit
) {
114 PORT_SetError(SEC_ERROR_BAD_DER
);
131 /* S/MIME picked id values to represent differnt keysizes */
132 /* I do have a formula, but it ain't pretty, and it only works because you
133 * can always match three points to a parabola:) */
134 static unsigned char rc2_map(SECItem
*version
)
138 x
= DER_GetInteger(version
);
148 static unsigned long rc2_unmap(unsigned long x
)
158 /* default IV size in bytes */
159 #define DEFAULT_IV_SIZE 8
160 /* IV/block size for AES */
161 #define AES_BLOCK_SIZE 16
162 /* max IV size in bytes */
163 #define MAX_IV_SIZE AES_BLOCK_SIZE
165 static SecCmsCipherContextRef
166 SecCmsCipherContextStart(PRArenaPool
*poolp
, SecSymmetricKeyRef key
, SECAlgorithmID
*algid
, Boolean encrypt
)
168 SecCmsCipherContextRef cc
;
169 CSSM_CC_HANDLE ciphercc
= 0;
172 CSSM_ALGORITHMS algorithm
;
173 CSSM_PADDING padding
= CSSM_PADDING_PKCS7
;
174 CSSM_ENCRYPT_MODE mode
;
175 CSSM_CSP_HANDLE cspHandle
;
176 const CSSM_KEY
*cssmKey
;
178 uint8 ivbuf
[MAX_IV_SIZE
];
179 CSSM_DATA initVector
= { DEFAULT_IV_SIZE
, ivbuf
};
180 //CSSM_CONTEXT_ATTRIBUTE contextAttribute = { CSSM_ATTRIBUTE_ALG_PARAMS, sizeof(CSSM_DATA_PTR) };
182 rv
= SecKeyGetCSPHandle(key
, &cspHandle
);
185 rv
= SecKeyGetCSSMKey(key
, &cssmKey
);
189 // @@@ Add support for PBE based stuff
191 oidData
= SECOID_FindOID(&algid
->algorithm
);
194 algtag
= oidData
->offset
;
195 algorithm
= oidData
->cssmAlgorithm
;
201 case SEC_OID_RC2_CBC
:
203 case SEC_OID_DES_EDE3_CBC
:
204 case SEC_OID_DES_EDE
:
205 case SEC_OID_DES_CBC
:
206 case SEC_OID_RC5_CBC_PAD
:
207 case SEC_OID_FORTEZZA_SKIPJACK
:
208 mode
= CSSM_ALGMODE_CBCPadIV8
;
211 /* RFC 3565 says that these sizes refer to key size, NOT block size */
212 case SEC_OID_AES_128_CBC
:
213 case SEC_OID_AES_192_CBC
:
214 case SEC_OID_AES_256_CBC
:
215 initVector
.Length
= AES_BLOCK_SIZE
;
216 mode
= CSSM_ALGMODE_CBCPadIV8
;
219 case SEC_OID_DES_ECB
:
220 case SEC_OID_AES_128_ECB
:
221 case SEC_OID_AES_192_ECB
:
222 case SEC_OID_AES_256_ECB
:
223 mode
= CSSM_ALGMODE_ECBPad
;
226 case SEC_OID_DES_OFB
:
227 mode
= CSSM_ALGMODE_OFBPadIV8
;
230 case SEC_OID_DES_CFB
:
231 mode
= CSSM_ALGMODE_CFBPadIV8
;
240 CSSM_CC_HANDLE randomcc
;
241 //SECItem *parameters;
243 // Generate random initVector
244 if (CSSM_CSP_CreateRandomGenContext(cspHandle
,
245 CSSM_ALGID_APPLE_YARROW
,
251 if (CSSM_GenerateRandom(randomcc
, &initVector
))
253 CSSM_DeleteContext(randomcc
);
255 // Put IV into algid.parameters
259 case SEC_OID_DES_EDE3_CBC
:
260 case SEC_OID_DES_EDE
:
261 case SEC_OID_DES_CBC
:
262 case SEC_OID_AES_128_CBC
:
263 case SEC_OID_AES_192_CBC
:
264 case SEC_OID_AES_256_CBC
:
265 case SEC_OID_FORTEZZA_SKIPJACK
:
266 case SEC_OID_DES_ECB
:
267 case SEC_OID_AES_128_ECB
:
268 case SEC_OID_AES_192_ECB
:
269 case SEC_OID_AES_256_ECB
:
270 case SEC_OID_DES_OFB
:
271 case SEC_OID_DES_CFB
:
272 /* Just encode the initVector as an octet string. */
273 if (!SEC_ASN1EncodeItem(poolp
, &algid
->parameters
,
274 &initVector
, kSecAsn1OctetStringTemplate
))
278 case SEC_OID_RC2_CBC
:
280 sec_rc2cbcParameter rc2
= {};
281 unsigned long rc2version
;
285 rc2version
= rc2_unmap(cssmKey
->KeyHeader
.LogicalKeySizeInBits
);
286 if (!SEC_ASN1EncodeUnsignedInteger (NULL
, &(rc2
.rc2ParameterVersion
),
289 newParams
= SEC_ASN1EncodeItem (poolp
, &algid
->parameters
, &rc2
,
290 sec_rc2cbc_parameter_template
);
291 PORT_Free(rc2
.rc2ParameterVersion
.Data
);
292 rc2
.rc2ParameterVersion
.Data
= NULL
;
293 if (newParams
== NULL
)
297 case SEC_OID_RC5_CBC_PAD
:
299 // @@@ Implement rc5 params stuff.
306 // Extract IV from algid.parameters
307 // Put IV into algid.parameters
311 case SEC_OID_DES_EDE3_CBC
:
312 case SEC_OID_DES_EDE
:
313 case SEC_OID_DES_CBC
:
314 case SEC_OID_AES_128_CBC
:
315 case SEC_OID_AES_192_CBC
:
316 case SEC_OID_AES_256_CBC
:
317 case SEC_OID_FORTEZZA_SKIPJACK
:
318 case SEC_OID_DES_ECB
:
319 case SEC_OID_AES_128_ECB
:
320 case SEC_OID_AES_192_ECB
:
321 case SEC_OID_AES_256_ECB
:
322 case SEC_OID_DES_OFB
:
323 case SEC_OID_DES_CFB
:
326 /* Just decode the initVector from an octet string. */
327 rv
= SEC_ASN1DecodeItem(NULL
, &iv
, kSecAsn1OctetStringTemplate
, &(algid
->parameters
));
330 if (initVector
.Length
!= iv
.Length
) {
335 memcpy(initVector
.Data
, iv
.Data
, initVector
.Length
);
340 case SEC_OID_RC2_CBC
:
342 sec_rc2cbcParameter rc2
= {};
343 unsigned long ulEffectiveBits
;
345 rv
= SEC_ASN1DecodeItem(NULL
, &rc2
,sec_rc2cbc_parameter_template
,
346 &(algid
->parameters
));
350 if (initVector
.Length
!= rc2
.iv
.Length
) {
351 PORT_Free(rc2
.iv
.Data
);
353 PORT_Free(rc2
.rc2ParameterVersion
.Data
);
354 rc2
.rc2ParameterVersion
.Data
= NULL
;
357 memcpy(initVector
.Data
, rc2
.iv
.Data
, initVector
.Length
);
358 PORT_Free(rc2
.iv
.Data
);
361 ulEffectiveBits
= rc2_map(&rc2
.rc2ParameterVersion
);
362 PORT_Free(rc2
.rc2ParameterVersion
.Data
);
363 rc2
.rc2ParameterVersion
.Data
= NULL
;
364 if (ulEffectiveBits
!= cssmKey
->KeyHeader
.LogicalKeySizeInBits
)
368 case SEC_OID_RC5_CBC_PAD
:
370 // @@@ Implement rc5 params stuff.
376 if (CSSM_CSP_CreateSymmetricContext(cspHandle
,
379 NULL
, /* accessCred */
388 rv
= CSSM_EncryptDataInit(ciphercc
);
390 rv
= CSSM_DecryptDataInit(ciphercc
);
394 cc
= (SecCmsCipherContextRef
)PORT_ZAlloc(sizeof(SecCmsCipherContext
));
399 cc
->encrypt
= encrypt
;
404 CSSM_DeleteContext(ciphercc
);
410 * SecCmsCipherContextStartDecrypt - create a cipher context to do decryption
411 * based on the given bulk * encryption key and algorithm identifier (which may include an iv).
413 * XXX Once both are working, it might be nice to combine this and the
414 * function below (for starting up encryption) into one routine, and just
415 * have two simple cover functions which call it.
417 SecCmsCipherContextRef
418 SecCmsCipherContextStartDecrypt(SecSymmetricKeyRef key
, SECAlgorithmID
*algid
)
420 return SecCmsCipherContextStart(NULL
, key
, algid
, PR_FALSE
);
422 SecCmsCipherContextRef cc
;
424 CK_MECHANISM_TYPE mechanism
;
429 algtag
= SECOID_GetAlgorithmTag(algid
);
431 /* set param and mechanism */
432 if (SEC_PKCS5IsAlgorithmPBEAlg(algid
)) {
433 CK_MECHANISM pbeMech
, cryptoMech
;
434 CSSM_DATA_PTR pbeParams
;
435 SEC_PKCS5KeyAndPassword
*keyPwd
;
437 PORT_Memset(&pbeMech
, 0, sizeof(CK_MECHANISM
));
438 PORT_Memset(&cryptoMech
, 0, sizeof(CK_MECHANISM
));
441 * in this case, key is not actually a SecSymmetricKeyRef, but a SEC_PKCS5KeyAndPassword *
443 keyPwd
= (SEC_PKCS5KeyAndPassword
*)key
;
446 /* find correct PK11 mechanism and parameters to initialize pbeMech */
447 pbeMech
.mechanism
= PK11_AlgtagToMechanism(algtag
);
448 pbeParams
= PK11_ParamFromAlgid(algid
);
451 pbeMech
.pParameter
= pbeParams
->Data
;
452 pbeMech
.ulParameterLen
= pbeParams
->Length
;
454 /* now map pbeMech to cryptoMech */
455 if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech
, &cryptoMech
, keyPwd
->pwitem
,
456 PR_FALSE
) != CKR_OK
) {
457 SECITEM_ZfreeItem(pbeParams
, PR_TRUE
);
460 SECITEM_ZfreeItem(pbeParams
, PR_TRUE
);
462 /* and use it to initialize param & mechanism */
463 if ((param
= (CSSM_DATA_PTR
)PORT_ZAlloc(sizeof(CSSM_DATA
))) == NULL
)
466 param
->Data
= (unsigned char *)cryptoMech
.pParameter
;
467 param
->Length
= cryptoMech
.ulParameterLen
;
468 mechanism
= cryptoMech
.mechanism
;
470 mechanism
= PK11_AlgtagToMechanism(algtag
);
471 if ((param
= PK11_ParamFromAlgid(algid
)) == NULL
)
475 cc
= (SecCmsCipherContextRef
)PORT_ZAlloc(sizeof(SecCmsCipherContext
));
477 SECITEM_FreeItem(param
,PR_TRUE
);
481 /* figure out pad and block sizes */
482 cc
->pad_size
= PK11_GetBlockSize(mechanism
, param
);
483 slot
= PK11_GetSlotFromKey(key
);
484 cc
->block_size
= PK11_IsHW(slot
) ? BLOCK_SIZE
: cc
->pad_size
;
487 /* create PK11 cipher context */
488 ciphercx
= PK11_CreateContextBySymKey(mechanism
, CKA_DECRYPT
, key
, param
);
489 SECITEM_FreeItem(param
, PR_TRUE
);
490 if (ciphercx
== NULL
) {
496 cc
->doit
= (nss_cms_cipher_function
) PK11_CipherOp
;
497 cc
->destroy
= (nss_cms_cipher_destroy
) PK11_DestroyContext
;
498 cc
->encrypt
= PR_FALSE
;
499 cc
->pending_count
= 0;
506 * SecCmsCipherContextStartEncrypt - create a cipher object to do encryption,
507 * based on the given bulk encryption key and algorithm tag. Fill in the algorithm
508 * identifier (which may include an iv) appropriately.
510 * XXX Once both are working, it might be nice to combine this and the
511 * function above (for starting up decryption) into one routine, and just
512 * have two simple cover functions which call it.
514 SecCmsCipherContextRef
515 SecCmsCipherContextStartEncrypt(PRArenaPool
*poolp
, SecSymmetricKeyRef key
, SECAlgorithmID
*algid
)
517 return SecCmsCipherContextStart(poolp
, key
, algid
, PR_TRUE
);
519 SecCmsCipherContextRef cc
;
523 CK_MECHANISM_TYPE mechanism
;
525 Boolean needToEncodeAlgid
= PR_FALSE
;
526 SECOidTag algtag
= SECOID_GetAlgorithmTag(algid
);
528 /* set param and mechanism */
529 if (SEC_PKCS5IsAlgorithmPBEAlg(algid
)) {
530 CK_MECHANISM pbeMech
, cryptoMech
;
531 CSSM_DATA_PTR pbeParams
;
532 SEC_PKCS5KeyAndPassword
*keyPwd
;
534 PORT_Memset(&pbeMech
, 0, sizeof(CK_MECHANISM
));
535 PORT_Memset(&cryptoMech
, 0, sizeof(CK_MECHANISM
));
538 * in this case, key is not actually a SecSymmetricKeyRef, but a SEC_PKCS5KeyAndPassword *
540 keyPwd
= (SEC_PKCS5KeyAndPassword
*)key
;
543 /* find correct PK11 mechanism and parameters to initialize pbeMech */
544 pbeMech
.mechanism
= PK11_AlgtagToMechanism(algtag
);
545 pbeParams
= PK11_ParamFromAlgid(algid
);
548 pbeMech
.pParameter
= pbeParams
->Data
;
549 pbeMech
.ulParameterLen
= pbeParams
->Length
;
551 /* now map pbeMech to cryptoMech */
552 if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech
, &cryptoMech
, keyPwd
->pwitem
,
553 PR_FALSE
) != CKR_OK
) {
554 SECITEM_ZfreeItem(pbeParams
, PR_TRUE
);
557 SECITEM_ZfreeItem(pbeParams
, PR_TRUE
);
559 /* and use it to initialize param & mechanism */
560 if ((param
= (CSSM_DATA_PTR
)PORT_ZAlloc(sizeof(CSSM_DATA
))) == NULL
)
563 param
->Data
= (unsigned char *)cryptoMech
.pParameter
;
564 param
->Length
= cryptoMech
.ulParameterLen
;
565 mechanism
= cryptoMech
.mechanism
;
567 mechanism
= PK11_AlgtagToMechanism(algtag
);
568 if ((param
= PK11_GenerateNewParam(mechanism
, key
)) == NULL
)
570 needToEncodeAlgid
= PR_TRUE
;
573 cc
= (SecCmsCipherContextRef
)PORT_ZAlloc(sizeof(SecCmsCipherContext
));
577 /* now find pad and block sizes for our mechanism */
578 cc
->pad_size
= PK11_GetBlockSize(mechanism
,param
);
579 slot
= PK11_GetSlotFromKey(key
);
580 cc
->block_size
= PK11_IsHW(slot
) ? BLOCK_SIZE
: cc
->pad_size
;
583 /* and here we go, creating a PK11 cipher context */
584 ciphercx
= PK11_CreateContextBySymKey(mechanism
, CKA_ENCRYPT
, key
, param
);
585 if (ciphercx
== NULL
) {
592 * These are placed after the CreateContextBySymKey() because some
593 * mechanisms have to generate their IVs from their card (i.e. FORTEZZA).
594 * Don't move it from here.
595 * XXX is that right? the purpose of this is to get the correct algid
596 * containing the IVs etc. for encoding. this means we need to set this up
597 * BEFORE encoding the algid in the contentInfo, right?
599 if (needToEncodeAlgid
) {
600 rv
= PK11_ParamToAlgid(algtag
, param
, poolp
, algid
);
601 if(rv
!= SECSuccess
) {
609 cc
->doit
= (nss_cms_cipher_function
)PK11_CipherOp
;
610 cc
->destroy
= (nss_cms_cipher_destroy
)PK11_DestroyContext
;
611 cc
->encrypt
= PR_TRUE
;
612 cc
->pending_count
= 0;
615 SECITEM_FreeItem(param
, PR_TRUE
);
622 SecCmsCipherContextDestroy(SecCmsCipherContextRef cc
)
624 PORT_Assert(cc
!= NULL
);
627 CSSM_DeleteContext(cc
->cc
);
632 SecCmsCipherContextLength(SecCmsCipherContextRef cc
, unsigned int input_len
, Boolean final
, Boolean encrypt
)
634 CSSM_QUERY_SIZE_DATA dataBlockSize
[2] = { { input_len
, 0 }, { input_len
, 0 } };
635 /* Hack CDSA treats the last block as the final one. So unless we are being asked to report the final size we ask for 2 block and ignore the second (final) one. */
636 OSStatus rv
= CSSM_QuerySize(cc
->cc
, cc
->encrypt
, final
? 1 : 2, dataBlockSize
);
643 return dataBlockSize
[0].SizeOutputBlock
;
647 * SecCmsCipherContextDecryptLength - find the output length of the next call to decrypt.
649 * cc - the cipher context
650 * input_len - number of bytes used as input
651 * final - true if this is the final chunk of data
653 * Result can be used to perform memory allocations. Note that the amount
654 * is exactly accurate only when not doing a block cipher or when final
655 * is false, otherwise it is an upper bound on the amount because until
656 * we see the data we do not know how many padding bytes there are
657 * (always between 1 and bsize).
659 * Note that this can return zero, which does not mean that the decrypt
660 * operation can be skipped! (It simply means that there are not enough
661 * bytes to make up an entire block; the bytes will be reserved until
662 * there are enough to encrypt/decrypt at least one block.) However,
663 * if zero is returned it *does* mean that no output buffer need be
664 * passed in to the subsequent decrypt operation, as no output bytes
668 SecCmsCipherContextDecryptLength(SecCmsCipherContextRef cc
, size_t input_len
, Boolean final
)
671 return SecCmsCipherContextLength(cc
, (unsigned int)input_len
, final
, PR_FALSE
);
673 int blocks
, block_size
;
675 PORT_Assert (! cc
->encrypt
);
677 block_size
= cc
->block_size
;
680 * If this is not a block cipher, then we always have the same
681 * number of output bytes as we had input bytes.
687 * On the final call, we will always use up all of the pending
688 * bytes plus all of the input bytes, *but*, there will be padding
689 * at the end and we cannot predict how many bytes of padding we
690 * will end up removing. The amount given here is actually known
691 * to be at least 1 byte too long (because we know we will have
692 * at least 1 byte of padding), but seemed clearer/better to me.
695 return cc
->pending_count
+ input_len
;
698 * Okay, this amount is exactly what we will output on the
699 * next cipher operation. We will always hang onto the last
700 * 1 - block_size bytes for non-final operations. That is,
701 * we will do as many complete blocks as we can *except* the
702 * last block (complete or partial). (This is because until
703 * we know we are at the end, we cannot know when to interpret
704 * and removing the padding byte(s), which are guaranteed to
707 blocks
= (cc
->pending_count
+ input_len
- 1) / block_size
;
708 return blocks
* block_size
;
713 * SecCmsCipherContextEncryptLength - find the output length of the next call to encrypt.
715 * cc - the cipher context
716 * input_len - number of bytes used as input
717 * final - true if this is the final chunk of data
719 * Result can be used to perform memory allocations.
721 * Note that this can return zero, which does not mean that the encrypt
722 * operation can be skipped! (It simply means that there are not enough
723 * bytes to make up an entire block; the bytes will be reserved until
724 * there are enough to encrypt/decrypt at least one block.) However,
725 * if zero is returned it *does* mean that no output buffer need be
726 * passed in to the subsequent encrypt operation, as no output bytes
730 SecCmsCipherContextEncryptLength(SecCmsCipherContextRef cc
, size_t input_len
, Boolean final
)
733 return SecCmsCipherContextLength(cc
, (unsigned int)input_len
, final
, PR_TRUE
);
735 int blocks
, block_size
;
738 PORT_Assert (cc
->encrypt
);
740 block_size
= cc
->block_size
;
741 pad_size
= cc
->pad_size
;
744 * If this is not a block cipher, then we always have the same
745 * number of output bytes as we had input bytes.
751 * On the final call, we only send out what we need for
752 * remaining bytes plus the padding. (There is always padding,
753 * so even if we have an exact number of blocks as input, we
754 * will add another full block that is just padding.)
758 return cc
->pending_count
+ input_len
;
760 blocks
= (cc
->pending_count
+ input_len
) / pad_size
;
762 return blocks
*pad_size
;
767 * Now, count the number of complete blocks of data we have.
769 blocks
= (cc
->pending_count
+ input_len
) / block_size
;
772 return blocks
* block_size
;
778 SecCmsCipherContextCrypt(SecCmsCipherContextRef cc
, unsigned char *output
,
779 size_t *output_len_p
, size_t max_output_len
,
780 const unsigned char *input
, size_t input_len
,
781 Boolean final
, Boolean encrypt
)
783 CSSM_DATA outputBuf
= { max_output_len
, output
};
784 CSSM_SIZE bytes_output
= 0;
789 CSSM_DATA inputBuf
= { input_len
, (uint8
*)input
};
792 rv
= CSSM_EncryptDataUpdate(cc
->cc
, &inputBuf
, 1, &outputBuf
, 1, &bytes_output
);
794 rv
= CSSM_DecryptDataUpdate(cc
->cc
, &inputBuf
, 1, &outputBuf
, 1, &bytes_output
);
799 CSSM_DATA remainderBuf
= { max_output_len
- bytes_output
, output
+ bytes_output
};
801 rv
= CSSM_EncryptDataFinal(cc
->cc
, &remainderBuf
);
803 rv
= CSSM_DecryptDataFinal(cc
->cc
, &remainderBuf
);
805 bytes_output
+= remainderBuf
.Length
;
809 PORT_SetError(SEC_ERROR_BAD_DATA
);
810 else if (output_len_p
)
811 *output_len_p
= bytes_output
;
817 * SecCmsCipherContextDecrypt - do the decryption
819 * cc - the cipher context
820 * output - buffer for decrypted result bytes
821 * output_len_p - number of bytes in output
822 * max_output_len - upper bound on bytes to put into output
823 * input - pointer to input bytes
824 * input_len - number of input bytes
825 * final - true if this is the final chunk of data
827 * Decrypts a given length of input buffer (starting at "input" and
828 * containing "input_len" bytes), placing the decrypted bytes in
829 * "output" and storing the output length in "*output_len_p".
830 * "cc" is the return value from SecCmsCipherStartDecrypt.
831 * When "final" is true, this is the last of the data to be decrypted.
833 * This is much more complicated than it sounds when the cipher is
834 * a block-type, meaning that the decryption function will only
835 * operate on whole blocks. But our caller is operating stream-wise,
836 * and can pass in any number of bytes. So we need to keep track
837 * of block boundaries. We save excess bytes between calls in "cc".
838 * We also need to determine which bytes are padding, and remove
839 * them from the output. We can only do this step when we know we
840 * have the final block of data. PKCS #7 specifies that the padding
841 * used for a block cipher is a string of bytes, each of whose value is
842 * the same as the length of the padding, and that all data is padded.
843 * (Even data that starts out with an exact multiple of blocks gets
844 * added to it another block, all of which is padding.)
847 SecCmsCipherContextDecrypt(SecCmsCipherContextRef cc
, unsigned char *output
,
848 size_t *output_len_p
, size_t max_output_len
,
849 const unsigned char *input
, size_t input_len
,
853 return SecCmsCipherContextCrypt(cc
, output
,
854 output_len_p
, max_output_len
,
858 int blocks
, bsize
, pcount
, padsize
;
859 unsigned int max_needed
, ifraglen
, ofraglen
, output_len
;
863 PORT_Assert (! cc
->encrypt
);
866 * Check that we have enough room for the output. Our caller should
867 * already handle this; failure is really an internal error (i.e. bug).
869 max_needed
= SecCmsCipherContextDecryptLength(cc
, input_len
, final
);
870 PORT_Assert (max_output_len
>= max_needed
);
871 if (max_output_len
< max_needed
) {
872 /* PORT_SetError (XXX); */
877 * hardware encryption does not like small decryption sizes here, so we
878 * allow both blocking and padding.
880 bsize
= cc
->block_size
;
881 padsize
= cc
->pad_size
;
884 * When no blocking or padding work to do, we can simply call the
885 * cipher function and we are done.
888 return (* cc
->doit
) (cc
->cx
, output
, output_len_p
, max_output_len
,
892 pcount
= cc
->pending_count
;
893 pbuf
= cc
->pending_buf
;
899 * Try to fill in an entire block, starting with the bytes
900 * we already have saved away.
902 while (input_len
&& pcount
< bsize
) {
903 pbuf
[pcount
++] = *input
++;
907 * If we have at most a whole block and this is not our last call,
908 * then we are done for now. (We do not try to decrypt a lone
909 * single block because we cannot interpret the padding bytes
910 * until we know we are handling the very last block of all input.)
912 if (input_len
== 0 && !final
) {
913 cc
->pending_count
= pcount
;
919 * Given the logic above, we expect to have a full block by now.
920 * If we do not, there is something wrong, either with our own
921 * logic or with (length of) the data given to us.
923 if ((padsize
!= 0) && (pcount
% padsize
) != 0) {
925 PORT_SetError (SEC_ERROR_BAD_DATA
);
931 rv
= (*cc
->doit
)(cc
->cx
, output
, &ofraglen
, max_output_len
,
933 if (rv
!= SECSuccess
)
937 * For now anyway, all of our ciphers have the same number of
938 * bytes of output as they do input. If this ever becomes untrue,
939 * then SecCmsCipherContextDecryptLength needs to be made smarter!
941 PORT_Assert(ofraglen
== pcount
);
944 * Account for the bytes now in output.
946 max_output_len
-= ofraglen
;
947 output_len
+= ofraglen
;
952 * If this is our last call, we expect to have an exact number of
953 * blocks left to be decrypted; we will decrypt them all.
955 * If not our last call, we always save between 1 and bsize bytes
956 * until next time. (We must do this because we cannot be sure
957 * that none of the decrypted bytes are padding bytes until we
958 * have at least another whole block of data. You cannot tell by
959 * looking -- the data could be anything -- you can only tell by
960 * context, knowing you are looking at the last block.) We could
961 * decrypt a whole block now but it is easier if we just treat it
962 * the same way we treat partial block bytes.
966 blocks
= input_len
/ padsize
;
967 ifraglen
= blocks
* padsize
;
968 } else ifraglen
= input_len
;
969 PORT_Assert (ifraglen
== input_len
);
971 if (ifraglen
!= input_len
) {
972 PORT_SetError(SEC_ERROR_BAD_DATA
);
976 blocks
= (input_len
- 1) / bsize
;
977 ifraglen
= blocks
* bsize
;
978 PORT_Assert (ifraglen
< input_len
);
980 pcount
= input_len
- ifraglen
;
981 PORT_Memcpy (pbuf
, input
+ ifraglen
, pcount
);
982 cc
->pending_count
= pcount
;
986 rv
= (* cc
->doit
)(cc
->cx
, output
, &ofraglen
, max_output_len
,
988 if (rv
!= SECSuccess
)
992 * For now anyway, all of our ciphers have the same number of
993 * bytes of output as they do input. If this ever becomes untrue,
994 * then sec_PKCS7DecryptLength needs to be made smarter!
996 PORT_Assert (ifraglen
== ofraglen
);
997 if (ifraglen
!= ofraglen
) {
998 PORT_SetError(SEC_ERROR_BAD_DATA
);
1002 output_len
+= ofraglen
;
1008 * If we just did our very last block, "remove" the padding by
1009 * adjusting the output length.
1011 if (final
&& (padsize
!= 0)) {
1012 unsigned int padlen
= *(output
+ ofraglen
- 1);
1014 if (padlen
== 0 || padlen
> padsize
) {
1015 PORT_SetError(SEC_ERROR_BAD_DATA
);
1018 output_len
-= padlen
;
1021 PORT_Assert (output_len_p
!= NULL
|| output_len
== 0);
1022 if (output_len_p
!= NULL
)
1023 *output_len_p
= output_len
;
1030 * SecCmsCipherContextEncrypt - do the encryption
1032 * cc - the cipher context
1033 * output - buffer for decrypted result bytes
1034 * output_len_p - number of bytes in output
1035 * max_output_len - upper bound on bytes to put into output
1036 * input - pointer to input bytes
1037 * input_len - number of input bytes
1038 * final - true if this is the final chunk of data
1040 * Encrypts a given length of input buffer (starting at "input" and
1041 * containing "input_len" bytes), placing the encrypted bytes in
1042 * "output" and storing the output length in "*output_len_p".
1043 * "cc" is the return value from SecCmsCipherStartEncrypt.
1044 * When "final" is true, this is the last of the data to be encrypted.
1046 * This is much more complicated than it sounds when the cipher is
1047 * a block-type, meaning that the encryption function will only
1048 * operate on whole blocks. But our caller is operating stream-wise,
1049 * and can pass in any number of bytes. So we need to keep track
1050 * of block boundaries. We save excess bytes between calls in "cc".
1051 * We also need to add padding bytes at the end. PKCS #7 specifies
1052 * that the padding used for a block cipher is a string of bytes,
1053 * each of whose value is the same as the length of the padding,
1054 * and that all data is padded. (Even data that starts out with
1055 * an exact multiple of blocks gets added to it another block,
1056 * all of which is padding.)
1058 * XXX I would kind of like to combine this with the function above
1059 * which does decryption, since they have a lot in common. But the
1060 * tricky parts about padding and filling blocks would be much
1061 * harder to read that way, so I left them separate. At least for
1062 * now until it is clear that they are right.
1065 SecCmsCipherContextEncrypt(SecCmsCipherContextRef cc
, unsigned char *output
,
1066 size_t *output_len_p
, size_t max_output_len
,
1067 const unsigned char *input
, size_t input_len
,
1071 return SecCmsCipherContextCrypt(cc
, output
,
1072 output_len_p
, max_output_len
,
1076 int blocks
, bsize
, padlen
, pcount
, padsize
;
1077 unsigned int max_needed
, ifraglen
, ofraglen
, output_len
;
1078 unsigned char *pbuf
;
1081 PORT_Assert (cc
->encrypt
);
1084 * Check that we have enough room for the output. Our caller should
1085 * already handle this; failure is really an internal error (i.e. bug).
1087 max_needed
= SecCmsCipherContextEncryptLength (cc
, input_len
, final
);
1088 PORT_Assert (max_output_len
>= max_needed
);
1089 if (max_output_len
< max_needed
) {
1090 /* PORT_SetError (XXX); */
1094 bsize
= cc
->block_size
;
1095 padsize
= cc
->pad_size
;
1098 * When no blocking and padding work to do, we can simply call the
1099 * cipher function and we are done.
1102 return (*cc
->doit
)(cc
->cx
, output
, output_len_p
, max_output_len
,
1106 pcount
= cc
->pending_count
;
1107 pbuf
= cc
->pending_buf
;
1113 * Try to fill in an entire block, starting with the bytes
1114 * we already have saved away.
1116 while (input_len
&& pcount
< bsize
) {
1117 pbuf
[pcount
++] = *input
++;
1121 * If we do not have a full block and we know we will be
1122 * called again, then we are done for now.
1124 if (pcount
< bsize
&& !final
) {
1125 cc
->pending_count
= pcount
;
1126 if (output_len_p
!= NULL
)
1131 * If we have a whole block available, encrypt it.
1133 if ((padsize
== 0) || (pcount
% padsize
) == 0) {
1134 rv
= (* cc
->doit
) (cc
->cx
, output
, &ofraglen
, max_output_len
,
1136 if (rv
!= SECSuccess
)
1140 * For now anyway, all of our ciphers have the same number of
1141 * bytes of output as they do input. If this ever becomes untrue,
1142 * then sec_PKCS7EncryptLength needs to be made smarter!
1144 PORT_Assert (ofraglen
== pcount
);
1147 * Account for the bytes now in output.
1149 max_output_len
-= ofraglen
;
1150 output_len
+= ofraglen
;
1158 PORT_Assert (pcount
== 0);
1160 blocks
= input_len
/ bsize
;
1161 ifraglen
= blocks
* bsize
;
1164 rv
= (* cc
->doit
) (cc
->cx
, output
, &ofraglen
, max_output_len
,
1166 if (rv
!= SECSuccess
)
1170 * For now anyway, all of our ciphers have the same number of
1171 * bytes of output as they do input. If this ever becomes untrue,
1172 * then sec_PKCS7EncryptLength needs to be made smarter!
1174 PORT_Assert (ifraglen
== ofraglen
);
1176 max_output_len
-= ofraglen
;
1177 output_len
+= ofraglen
;
1181 pcount
= input_len
- ifraglen
;
1182 PORT_Assert (pcount
< bsize
);
1184 PORT_Memcpy (pbuf
, input
+ ifraglen
, pcount
);
1188 padlen
= padsize
- (pcount
% padsize
);
1189 PORT_Memset (pbuf
+ pcount
, padlen
, padlen
);
1190 rv
= (* cc
->doit
) (cc
->cx
, output
, &ofraglen
, max_output_len
,
1191 pbuf
, pcount
+padlen
);
1192 if (rv
!= SECSuccess
)
1196 * For now anyway, all of our ciphers have the same number of
1197 * bytes of output as they do input. If this ever becomes untrue,
1198 * then sec_PKCS7EncryptLength needs to be made smarter!
1200 PORT_Assert (ofraglen
== (pcount
+padlen
));
1201 output_len
+= ofraglen
;
1203 cc
->pending_count
= pcount
;
1206 PORT_Assert (output_len_p
!= NULL
|| output_len
== 0);
1207 if (output_len_p
!= NULL
)
1208 *output_len_p
= output_len
;