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.
43 #include <security_asn1/secerr.h>
44 #include <security_asn1/secasn1.h>
45 #include <security_asn1/secport.h>
47 #include <Security/SecAsn1Templates.h>
49 #include <Security/cssmapi.h>
50 #include <Security/cssmapple.h>
51 #include <Security/SecKeyPriv.h>
53 #include <Security/SecRandom.h>
54 #include <CommonCrypto/CommonCryptor.h>
58 * -------------------------------------------------------------------
63 typedef OSStatus (*nss_cms_cipher_function
) (void *, unsigned char *, unsigned int *,
64 unsigned int, const unsigned char *, unsigned int);
65 typedef OSStatus (*nss_cms_cipher_destroy
) (void *, Boolean
);
68 #define BLOCK_SIZE 4096
70 struct SecCmsCipherContextStr
{
72 void * cc
; /* CSP CONTEXT */
73 Boolean encrypt
; /* encrypt / decrypt switch */
74 int block_size
; /* block & pad sizes for cipher */
76 void * cx
; /* PK11 cipher context */
77 nss_cms_cipher_function doit
;
78 nss_cms_cipher_destroy destroy
;
79 Boolean encrypt
; /* encrypt / decrypt switch */
81 int pending_count
; /* pending data (not yet en/decrypted */
82 unsigned char pending_buf
[BLOCK_SIZE
];/* because of blocking */
86 typedef struct sec_rc2cbcParameterStr
{
87 SecAsn1Item rc2ParameterVersion
;
89 } sec_rc2cbcParameter
;
91 __unused
static const SecAsn1Template sec_rc2cbc_parameter_template
[] = {
93 0, NULL
, sizeof(sec_rc2cbcParameter
) },
94 { SEC_ASN1_INTEGER
| SEC_ASN1_SIGNED_INT
,
95 offsetof(sec_rc2cbcParameter
,rc2ParameterVersion
) },
96 { SEC_ASN1_OCTET_STRING
,
97 offsetof(sec_rc2cbcParameter
,iv
) },
101 // TODO: get rid of this?
104 ** Convert a der encoded *signed* integer into a machine integral value.
105 ** If an underflow/overflow occurs, sets error code and returns min/max.
108 DER_GetInteger(SecAsn1Item
*it
)
111 unsigned len
= it
->Length
;
112 unsigned char *cp
= it
->Data
;
113 unsigned long overflow
= 0x1ffUL
<< (((sizeof(ival
) - 1) * 8) - 1);
114 unsigned long ofloinit
;
118 ofloinit
= ival
& overflow
;
121 if ((ival
& overflow
) != ofloinit
) {
122 PORT_SetError(SEC_ERROR_BAD_DER
);
135 /* S/MIME picked id values to represent differnt keysizes */
136 /* I do have a formula, but it ain't pretty, and it only works because you
137 * can always match three points to a parabola:) */
138 static unsigned char rc2_map(SecAsn1Item
*version
)
142 x
= DER_GetInteger(version
);
152 static unsigned long rc2_unmap(unsigned long x
)
161 #endif /* USE_CDSA_CRYPTO */
163 /* default IV size in bytes */
164 #define DEFAULT_IV_SIZE 8
165 /* IV/block size for AES */
166 #define AES_BLOCK_SIZE 16
167 /* max IV size in bytes */
168 #define MAX_IV_SIZE AES_BLOCK_SIZE
171 #ifndef kCCKeySizeMaxRC2
172 #define kCCKeySizeMaxRC2 16
174 #ifndef kCCBlockSizeRC2
175 #define kCCBlockSizeRC2 8
177 #ifndef kCCAlgorithmRC2
178 #define kCCAlgorithmRC2 -1
182 static SecCmsCipherContextRef
183 SecCmsCipherContextStart(PRArenaPool
*poolp
, SecSymmetricKeyRef key
, SECAlgorithmID
*algid
, Boolean encrypt
)
185 SecCmsCipherContextRef cc
;
189 uint8_t ivbuf
[MAX_IV_SIZE
];
190 SecAsn1Item initVector
= { DEFAULT_IV_SIZE
, ivbuf
};
192 CSSM_CC_HANDLE ciphercc
= 0;
193 CSSM_ALGORITHMS algorithm
;
194 CSSM_PADDING padding
= CSSM_PADDING_PKCS7
;
195 CSSM_ENCRYPT_MODE mode
;
196 CSSM_CSP_HANDLE cspHandle
;
197 const CSSM_KEY
*cssmKey
;
198 //CSSM_CONTEXT_ATTRIBUTE contextAttribute = { CSSM_ATTRIBUTE_ALG_PARAMS, sizeof(SecAsn1Item *) };
200 CCCryptorRef ciphercc
= NULL
;
201 CCOptions cipheroptions
= kCCOptionPKCS7Padding
;
202 int cipher_blocksize
= 0;
206 rv
= SecKeyGetCSPHandle(key
, &cspHandle
);
209 rv
= SecKeyGetCSSMKey(key
, &cssmKey
);
214 // @@@ Add support for PBE based stuff
216 oidData
= SECOID_FindOID(&algid
->algorithm
);
219 algtag
= oidData
->offset
;
221 algorithm
= oidData
->cssmAlgorithm
;
227 case SEC_OID_RC2_CBC
:
229 case SEC_OID_DES_EDE3_CBC
:
230 case SEC_OID_DES_EDE
:
231 case SEC_OID_DES_CBC
:
232 case SEC_OID_RC5_CBC_PAD
:
233 case SEC_OID_FORTEZZA_SKIPJACK
:
234 mode
= CSSM_ALGMODE_CBCPadIV8
;
237 /* RFC 3565 says that these sizes refer to key size, NOT block size */
238 case SEC_OID_AES_128_CBC
:
239 case SEC_OID_AES_192_CBC
:
240 case SEC_OID_AES_256_CBC
:
241 initVector
.Length
= AES_BLOCK_SIZE
;
242 mode
= CSSM_ALGMODE_CBCPadIV8
;
245 case SEC_OID_DES_ECB
:
246 case SEC_OID_AES_128_ECB
:
247 case SEC_OID_AES_192_ECB
:
248 case SEC_OID_AES_256_ECB
:
249 mode
= CSSM_ALGMODE_ECBPad
;
252 case SEC_OID_DES_OFB
:
253 mode
= CSSM_ALGMODE_OFBPadIV8
;
256 case SEC_OID_DES_CFB
:
257 mode
= CSSM_ALGMODE_CFBPadIV8
;
264 CCAlgorithm alg
= -1;
266 case SEC_OID_DES_CBC
:
267 alg
= kCCAlgorithmDES
;
268 cipher_blocksize
= kCCBlockSizeDES
;
270 case SEC_OID_DES_EDE3_CBC
:
271 alg
= kCCAlgorithm3DES
;
272 cipher_blocksize
= kCCBlockSize3DES
;
274 case SEC_OID_RC2_CBC
:
275 alg
= kCCAlgorithmRC2
;
276 cipher_blocksize
= kCCBlockSizeRC2
;
278 case SEC_OID_AES_128_CBC
:
279 case SEC_OID_AES_192_CBC
:
280 case SEC_OID_AES_256_CBC
:
281 alg
= kCCAlgorithmAES128
;
282 cipher_blocksize
= kCCBlockSizeAES128
;
283 initVector
.Length
= AES_BLOCK_SIZE
;
293 CSSM_CC_HANDLE randomcc
;
294 //SecAsn1Item *parameters;
296 // Generate random initVector
297 if (CSSM_CSP_CreateRandomGenContext(cspHandle
,
298 CSSM_ALGID_APPLE_YARROW
,
304 if (CSSM_GenerateRandom(randomcc
, &initVector
))
306 CSSM_DeleteContext(randomcc
);
308 if (SecRandomCopyBytes(kSecRandomDefault
,
309 initVector
.Length
, initVector
.Data
))
313 // Put IV into algid.parameters
317 case SEC_OID_DES_EDE3_CBC
:
318 case SEC_OID_DES_EDE
:
319 case SEC_OID_DES_CBC
:
320 case SEC_OID_AES_128_CBC
:
321 case SEC_OID_AES_192_CBC
:
322 case SEC_OID_AES_256_CBC
:
323 case SEC_OID_FORTEZZA_SKIPJACK
:
324 case SEC_OID_DES_ECB
:
325 case SEC_OID_AES_128_ECB
:
326 case SEC_OID_AES_192_ECB
:
327 case SEC_OID_AES_256_ECB
:
328 case SEC_OID_DES_OFB
:
329 case SEC_OID_DES_CFB
:
330 /* Just encode the initVector as an octet string. */
331 if (!SEC_ASN1EncodeItem(poolp
, &algid
->parameters
,
332 &initVector
, kSecAsn1OctetStringTemplate
))
335 case SEC_OID_RC2_CBC
:
338 sec_rc2cbcParameter rc2
= {};
339 unsigned long rc2version
;
340 SecAsn1Item
*newParams
;
343 rc2version
= rc2_unmap(cssmKey
->KeyHeader
.LogicalKeySizeInBits
);
344 if (!SEC_ASN1EncodeUnsignedInteger (NULL
, &(rc2
.rc2ParameterVersion
),
347 newParams
= SEC_ASN1EncodeItem (poolp
, &algid
->parameters
, &rc2
,
348 sec_rc2cbc_parameter_template
);
349 PORT_Free(rc2
.rc2ParameterVersion
.Data
);
350 if (newParams
== NULL
)
355 case SEC_OID_RC5_CBC_PAD
:
357 // @@@ Implement rc5 params stuff.
364 // Extract IV from algid.parameters
365 // Put IV into algid.parameters
369 case SEC_OID_DES_EDE3_CBC
:
370 case SEC_OID_DES_EDE
:
371 case SEC_OID_DES_CBC
:
372 case SEC_OID_AES_128_CBC
:
373 case SEC_OID_AES_192_CBC
:
374 case SEC_OID_AES_256_CBC
:
375 case SEC_OID_FORTEZZA_SKIPJACK
:
376 case SEC_OID_DES_ECB
:
377 case SEC_OID_AES_128_ECB
:
378 case SEC_OID_AES_192_ECB
:
379 case SEC_OID_AES_256_ECB
:
380 case SEC_OID_DES_OFB
:
381 case SEC_OID_DES_CFB
:
384 /* Just decode the initVector from an octet string. */
385 rv
= SEC_ASN1DecodeItem(NULL
, &iv
, kSecAsn1OctetStringTemplate
, &(algid
->parameters
));
388 if (initVector
.Length
!= iv
.Length
) {
392 memcpy(initVector
.Data
, iv
.Data
, initVector
.Length
);
396 case SEC_OID_RC2_CBC
:
399 sec_rc2cbcParameter rc2
= {};
400 unsigned long ulEffectiveBits
;
402 rv
= SEC_ASN1DecodeItem(NULL
, &rc2
,sec_rc2cbc_parameter_template
,
403 &(algid
->parameters
));
407 if (initVector
.Length
!= rc2
.iv
.Length
) {
408 PORT_Free(rc2
.iv
.Data
);
409 PORT_Free(rc2
.rc2ParameterVersion
.Data
);
412 memcpy(initVector
.Data
, rc2
.iv
.Data
, initVector
.Length
);
413 PORT_Free(rc2
.iv
.Data
);
415 ulEffectiveBits
= rc2_map(&rc2
.rc2ParameterVersion
);
416 PORT_Free(rc2
.rc2ParameterVersion
.Data
);
417 if (ulEffectiveBits
!= cssmKey
->KeyHeader
.LogicalKeySizeInBits
)
422 case SEC_OID_RC5_CBC_PAD
:
424 // @@@ Implement rc5 params stuff.
431 if (CSSM_CSP_CreateSymmetricContext(cspHandle
,
434 NULL
, /* accessCred */
443 rv
= CSSM_EncryptDataInit(ciphercc
);
445 rv
= CSSM_DecryptDataInit(ciphercc
);
449 if (CCCryptorCreate(encrypt
? kCCEncrypt
: kCCDecrypt
,
450 alg
, cipheroptions
, CFDataGetBytePtr(key
), CFDataGetLength(key
),
451 initVector
.Data
, &ciphercc
))
455 cc
= (SecCmsCipherContextRef
)PORT_ZAlloc(sizeof(SecCmsCipherContext
));
460 cc
->encrypt
= encrypt
;
462 cc
->block_size
=cipher_blocksize
;
468 CSSM_DeleteContext(ciphercc
);
470 CCCryptorRelease(ciphercc
);
477 * SecCmsCipherContextStartDecrypt - create a cipher context to do decryption
478 * based on the given bulk * encryption key and algorithm identifier (which may include an iv).
480 * XXX Once both are working, it might be nice to combine this and the
481 * function below (for starting up encryption) into one routine, and just
482 * have two simple cover functions which call it.
484 SecCmsCipherContextRef
485 SecCmsCipherContextStartDecrypt(SecSymmetricKeyRef key
, SECAlgorithmID
*algid
)
487 return SecCmsCipherContextStart(NULL
, key
, algid
, PR_FALSE
);
489 SecCmsCipherContextRef cc
;
491 CK_MECHANISM_TYPE mechanism
;
496 algtag
= SECOID_GetAlgorithmTag(algid
);
498 /* set param and mechanism */
499 if (SEC_PKCS5IsAlgorithmPBEAlg(algid
)) {
500 CK_MECHANISM pbeMech
, cryptoMech
;
501 SecAsn1Item
* pbeParams
;
502 SEC_PKCS5KeyAndPassword
*keyPwd
;
504 PORT_Memset(&pbeMech
, 0, sizeof(CK_MECHANISM
));
505 PORT_Memset(&cryptoMech
, 0, sizeof(CK_MECHANISM
));
508 * in this case, key is not actually a SecSymmetricKeyRef, but a SEC_PKCS5KeyAndPassword *
510 keyPwd
= (SEC_PKCS5KeyAndPassword
*)key
;
513 /* find correct PK11 mechanism and parameters to initialize pbeMech */
514 pbeMech
.mechanism
= PK11_AlgtagToMechanism(algtag
);
515 pbeParams
= PK11_ParamFromAlgid(algid
);
518 pbeMech
.pParameter
= pbeParams
->Data
;
519 pbeMech
.ulParameterLen
= pbeParams
->Length
;
521 /* now map pbeMech to cryptoMech */
522 if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech
, &cryptoMech
, keyPwd
->pwitem
,
523 PR_FALSE
) != CKR_OK
) {
524 SECITEM_ZfreeItem(pbeParams
, PR_TRUE
);
527 SECITEM_ZfreeItem(pbeParams
, PR_TRUE
);
529 /* and use it to initialize param & mechanism */
530 if ((param
= (SecAsn1Item
*)PORT_ZAlloc(sizeof(SecAsn1Item
))) == NULL
)
533 param
->Data
= (unsigned char *)cryptoMech
.pParameter
;
534 param
->Length
= cryptoMech
.ulParameterLen
;
535 mechanism
= cryptoMech
.mechanism
;
537 mechanism
= PK11_AlgtagToMechanism(algtag
);
538 if ((param
= PK11_ParamFromAlgid(algid
)) == NULL
)
542 cc
= (SecCmsCipherContextRef
)PORT_ZAlloc(sizeof(SecCmsCipherContext
));
544 SECITEM_FreeItem(param
,PR_TRUE
);
548 /* figure out pad and block sizes */
549 cc
->pad_size
= PK11_GetBlockSize(mechanism
, param
);
550 slot
= PK11_GetSlotFromKey(key
);
551 cc
->block_size
= PK11_IsHW(slot
) ? BLOCK_SIZE
: cc
->pad_size
;
554 /* create PK11 cipher context */
555 ciphercx
= PK11_CreateContextBySymKey(mechanism
, CKA_DECRYPT
, key
, param
);
556 SECITEM_FreeItem(param
, PR_TRUE
);
557 if (ciphercx
== NULL
) {
563 cc
->doit
= (nss_cms_cipher_function
) PK11_CipherOp
;
564 cc
->destroy
= (nss_cms_cipher_destroy
) PK11_DestroyContext
;
565 cc
->encrypt
= PR_FALSE
;
566 cc
->pending_count
= 0;
573 * SecCmsCipherContextStartEncrypt - create a cipher object to do encryption,
574 * based on the given bulk encryption key and algorithm tag. Fill in the algorithm
575 * identifier (which may include an iv) appropriately.
577 * XXX Once both are working, it might be nice to combine this and the
578 * function above (for starting up decryption) into one routine, and just
579 * have two simple cover functions which call it.
581 SecCmsCipherContextRef
582 SecCmsCipherContextStartEncrypt(PRArenaPool
*poolp
, SecSymmetricKeyRef key
, SECAlgorithmID
*algid
)
584 return SecCmsCipherContextStart(poolp
, key
, algid
, PR_TRUE
);
586 SecCmsCipherContextRef cc
;
590 CK_MECHANISM_TYPE mechanism
;
592 Boolean needToEncodeAlgid
= PR_FALSE
;
593 SECOidTag algtag
= SECOID_GetAlgorithmTag(algid
);
595 /* set param and mechanism */
596 if (SEC_PKCS5IsAlgorithmPBEAlg(algid
)) {
597 CK_MECHANISM pbeMech
, cryptoMech
;
598 SecAsn1Item
* pbeParams
;
599 SEC_PKCS5KeyAndPassword
*keyPwd
;
601 PORT_Memset(&pbeMech
, 0, sizeof(CK_MECHANISM
));
602 PORT_Memset(&cryptoMech
, 0, sizeof(CK_MECHANISM
));
605 * in this case, key is not actually a SecSymmetricKeyRef, but a SEC_PKCS5KeyAndPassword *
607 keyPwd
= (SEC_PKCS5KeyAndPassword
*)key
;
610 /* find correct PK11 mechanism and parameters to initialize pbeMech */
611 pbeMech
.mechanism
= PK11_AlgtagToMechanism(algtag
);
612 pbeParams
= PK11_ParamFromAlgid(algid
);
615 pbeMech
.pParameter
= pbeParams
->Data
;
616 pbeMech
.ulParameterLen
= pbeParams
->Length
;
618 /* now map pbeMech to cryptoMech */
619 if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech
, &cryptoMech
, keyPwd
->pwitem
,
620 PR_FALSE
) != CKR_OK
) {
621 SECITEM_ZfreeItem(pbeParams
, PR_TRUE
);
624 SECITEM_ZfreeItem(pbeParams
, PR_TRUE
);
626 /* and use it to initialize param & mechanism */
627 if ((param
= (SecAsn1Item
*)PORT_ZAlloc(sizeof(SecAsn1Item
))) == NULL
)
630 param
->Data
= (unsigned char *)cryptoMech
.pParameter
;
631 param
->Length
= cryptoMech
.ulParameterLen
;
632 mechanism
= cryptoMech
.mechanism
;
634 mechanism
= PK11_AlgtagToMechanism(algtag
);
635 if ((param
= PK11_GenerateNewParam(mechanism
, key
)) == NULL
)
637 needToEncodeAlgid
= PR_TRUE
;
640 cc
= (SecCmsCipherContextRef
)PORT_ZAlloc(sizeof(SecCmsCipherContext
));
644 /* now find pad and block sizes for our mechanism */
645 cc
->pad_size
= PK11_GetBlockSize(mechanism
,param
);
646 slot
= PK11_GetSlotFromKey(key
);
647 cc
->block_size
= PK11_IsHW(slot
) ? BLOCK_SIZE
: cc
->pad_size
;
650 /* and here we go, creating a PK11 cipher context */
651 ciphercx
= PK11_CreateContextBySymKey(mechanism
, CKA_ENCRYPT
, key
, param
);
652 if (ciphercx
== NULL
) {
659 * These are placed after the CreateContextBySymKey() because some
660 * mechanisms have to generate their IVs from their card (i.e. FORTEZZA).
661 * Don't move it from here.
662 * XXX is that right? the purpose of this is to get the correct algid
663 * containing the IVs etc. for encoding. this means we need to set this up
664 * BEFORE encoding the algid in the contentInfo, right?
666 if (needToEncodeAlgid
) {
667 rv
= PK11_ParamToAlgid(algtag
, param
, poolp
, algid
);
668 if(rv
!= SECSuccess
) {
676 cc
->doit
= (nss_cms_cipher_function
)PK11_CipherOp
;
677 cc
->destroy
= (nss_cms_cipher_destroy
)PK11_DestroyContext
;
678 cc
->encrypt
= PR_TRUE
;
679 cc
->pending_count
= 0;
682 SECITEM_FreeItem(param
, PR_TRUE
);
689 SecCmsCipherContextDestroy(SecCmsCipherContextRef cc
)
691 PORT_Assert(cc
!= NULL
);
695 CSSM_DeleteContext(cc
->cc
);
697 CCCryptorRelease(cc
->cc
);
703 SecCmsCipherContextLength(SecCmsCipherContextRef cc
, unsigned int input_len
, Boolean final
, Boolean encrypt
)
706 CSSM_QUERY_SIZE_DATA dataBlockSize
[2] = { { input_len
, 0 }, { input_len
, 0 } };
707 /* 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. */
708 OSStatus rv
= CSSM_QuerySize(cc
->cc
, cc
->encrypt
, final
? 1 : 2, dataBlockSize
);
715 return dataBlockSize
[0].SizeOutputBlock
;
717 return ((input_len
+ cc
->block_size
- 1) / cc
->block_size
* cc
->block_size
) + (final
? cc
->block_size
: 0);
722 * SecCmsCipherContextDecryptLength - find the output length of the next call to decrypt.
724 * cc - the cipher context
725 * input_len - number of bytes used as input
726 * final - true if this is the final chunk of data
728 * Result can be used to perform memory allocations. Note that the amount
729 * is exactly accurate only when not doing a block cipher or when final
730 * is false, otherwise it is an upper bound on the amount because until
731 * we see the data we do not know how many padding bytes there are
732 * (always between 1 and bsize).
734 * Note that this can return zero, which does not mean that the decrypt
735 * operation can be skipped! (It simply means that there are not enough
736 * bytes to make up an entire block; the bytes will be reserved until
737 * there are enough to encrypt/decrypt at least one block.) However,
738 * if zero is returned it *does* mean that no output buffer need be
739 * passed in to the subsequent decrypt operation, as no output bytes
743 SecCmsCipherContextDecryptLength(SecCmsCipherContextRef cc
, unsigned int input_len
, Boolean final
)
746 return SecCmsCipherContextLength(cc
, input_len
, final
, PR_FALSE
);
748 int blocks
, block_size
;
750 PORT_Assert (! cc
->encrypt
);
752 block_size
= cc
->block_size
;
755 * If this is not a block cipher, then we always have the same
756 * number of output bytes as we had input bytes.
762 * On the final call, we will always use up all of the pending
763 * bytes plus all of the input bytes, *but*, there will be padding
764 * at the end and we cannot predict how many bytes of padding we
765 * will end up removing. The amount given here is actually known
766 * to be at least 1 byte too long (because we know we will have
767 * at least 1 byte of padding), but seemed clearer/better to me.
770 return cc
->pending_count
+ input_len
;
773 * Okay, this amount is exactly what we will output on the
774 * next cipher operation. We will always hang onto the last
775 * 1 - block_size bytes for non-final operations. That is,
776 * we will do as many complete blocks as we can *except* the
777 * last block (complete or partial). (This is because until
778 * we know we are at the end, we cannot know when to interpret
779 * and removing the padding byte(s), which are guaranteed to
782 blocks
= (cc
->pending_count
+ input_len
- 1) / block_size
;
783 return blocks
* block_size
;
788 * SecCmsCipherContextEncryptLength - find the output length of the next call to encrypt.
790 * cc - the cipher context
791 * input_len - number of bytes used as input
792 * final - true if this is the final chunk of data
794 * Result can be used to perform memory allocations.
796 * Note that this can return zero, which does not mean that the encrypt
797 * operation can be skipped! (It simply means that there are not enough
798 * bytes to make up an entire block; the bytes will be reserved until
799 * there are enough to encrypt/decrypt at least one block.) However,
800 * if zero is returned it *does* mean that no output buffer need be
801 * passed in to the subsequent encrypt operation, as no output bytes
805 SecCmsCipherContextEncryptLength(SecCmsCipherContextRef cc
, unsigned int input_len
, Boolean final
)
808 return SecCmsCipherContextLength(cc
, input_len
, final
, PR_TRUE
);
810 int blocks
, block_size
;
813 PORT_Assert (cc
->encrypt
);
815 block_size
= cc
->block_size
;
816 pad_size
= cc
->pad_size
;
819 * If this is not a block cipher, then we always have the same
820 * number of output bytes as we had input bytes.
826 * On the final call, we only send out what we need for
827 * remaining bytes plus the padding. (There is always padding,
828 * so even if we have an exact number of blocks as input, we
829 * will add another full block that is just padding.)
833 return cc
->pending_count
+ input_len
;
835 blocks
= (cc
->pending_count
+ input_len
) / pad_size
;
837 return blocks
*pad_size
;
842 * Now, count the number of complete blocks of data we have.
844 blocks
= (cc
->pending_count
+ input_len
) / block_size
;
847 return blocks
* block_size
;
853 SecCmsCipherContextCrypt(SecCmsCipherContextRef cc
, unsigned char *output
,
854 unsigned int *output_len_p
, unsigned int max_output_len
,
855 const unsigned char *input
, unsigned int input_len
,
856 Boolean final
, Boolean encrypt
)
858 size_t bytes_output
= 0;
865 SecAsn1Item inputBuf
= { input_len
, (uint8_t *)input
};
866 SecAsn1Item outputBuf
= { max_output_len
, output
};
868 rv
= CSSM_EncryptDataUpdate(cc
->cc
, &inputBuf
, 1, &outputBuf
, 1, &bytes_output
);
870 rv
= CSSM_DecryptDataUpdate(cc
->cc
, &inputBuf
, 1, &outputBuf
, 1, &bytes_output
);
872 rv
= CCCryptorUpdate(cc
->cc
, input
, input_len
, output
, max_output_len
, &bytes_output
);
879 SecAsn1Item remainderBuf
= { max_output_len
- bytes_output
, output
+ bytes_output
};
881 rv
= CSSM_EncryptDataFinal(cc
->cc
, &remainderBuf
);
883 rv
= CSSM_DecryptDataFinal(cc
->cc
, &remainderBuf
);
884 bytes_output
+= remainderBuf
.Length
;
886 size_t bytes_output_final
= 0;
887 rv
= CCCryptorFinal(cc
->cc
, output
+bytes_output
, max_output_len
-bytes_output
, &bytes_output_final
);
888 bytes_output
+= bytes_output_final
;
892 PORT_SetError(SEC_ERROR_BAD_DATA
);
893 else if (output_len_p
)
894 *output_len_p
= (unsigned int)bytes_output
; /* This cast is safe since bytes_output can't be bigger than max_output_len */
900 * SecCmsCipherContextDecrypt - do the decryption
902 * cc - the cipher context
903 * output - buffer for decrypted result bytes
904 * output_len_p - number of bytes in output
905 * max_output_len - upper bound on bytes to put into output
906 * input - pointer to input bytes
907 * input_len - number of input bytes
908 * final - true if this is the final chunk of data
910 * Decrypts a given length of input buffer (starting at "input" and
911 * containing "input_len" bytes), placing the decrypted bytes in
912 * "output" and storing the output length in "*output_len_p".
913 * "cc" is the return value from SecCmsCipherStartDecrypt.
914 * When "final" is true, this is the last of the data to be decrypted.
916 * This is much more complicated than it sounds when the cipher is
917 * a block-type, meaning that the decryption function will only
918 * operate on whole blocks. But our caller is operating stream-wise,
919 * and can pass in any number of bytes. So we need to keep track
920 * of block boundaries. We save excess bytes between calls in "cc".
921 * We also need to determine which bytes are padding, and remove
922 * them from the output. We can only do this step when we know we
923 * have the final block of data. PKCS #7 specifies that the padding
924 * used for a block cipher is a string of bytes, each of whose value is
925 * the same as the length of the padding, and that all data is padded.
926 * (Even data that starts out with an exact multiple of blocks gets
927 * added to it another block, all of which is padding.)
930 SecCmsCipherContextDecrypt(SecCmsCipherContextRef cc
, unsigned char *output
,
931 unsigned int *output_len_p
, unsigned int max_output_len
,
932 const unsigned char *input
, unsigned int input_len
,
936 return SecCmsCipherContextCrypt(cc
, output
,
937 output_len_p
, max_output_len
,
941 int blocks
, bsize
, pcount
, padsize
;
942 unsigned int max_needed
, ifraglen
, ofraglen
, output_len
;
946 PORT_Assert (! cc
->encrypt
);
949 * Check that we have enough room for the output. Our caller should
950 * already handle this; failure is really an internal error (i.e. bug).
952 max_needed
= SecCmsCipherContextDecryptLength(cc
, input_len
, final
);
953 PORT_Assert (max_output_len
>= max_needed
);
954 if (max_output_len
< max_needed
) {
955 /* PORT_SetError (XXX); */
960 * hardware encryption does not like small decryption sizes here, so we
961 * allow both blocking and padding.
963 bsize
= cc
->block_size
;
964 padsize
= cc
->pad_size
;
967 * When no blocking or padding work to do, we can simply call the
968 * cipher function and we are done.
971 return (* cc
->doit
) (cc
->cx
, output
, output_len_p
, max_output_len
,
975 pcount
= cc
->pending_count
;
976 pbuf
= cc
->pending_buf
;
982 * Try to fill in an entire block, starting with the bytes
983 * we already have saved away.
985 while (input_len
&& pcount
< bsize
) {
986 pbuf
[pcount
++] = *input
++;
990 * If we have at most a whole block and this is not our last call,
991 * then we are done for now. (We do not try to decrypt a lone
992 * single block because we cannot interpret the padding bytes
993 * until we know we are handling the very last block of all input.)
995 if (input_len
== 0 && !final
) {
996 cc
->pending_count
= pcount
;
1002 * Given the logic above, we expect to have a full block by now.
1003 * If we do not, there is something wrong, either with our own
1004 * logic or with (length of) the data given to us.
1006 if ((padsize
!= 0) && (pcount
% padsize
) != 0) {
1007 PORT_Assert (final
);
1008 PORT_SetError (SEC_ERROR_BAD_DATA
);
1012 * Decrypt the block.
1014 rv
= (*cc
->doit
)(cc
->cx
, output
, &ofraglen
, max_output_len
,
1016 if (rv
!= SECSuccess
)
1020 * For now anyway, all of our ciphers have the same number of
1021 * bytes of output as they do input. If this ever becomes untrue,
1022 * then SecCmsCipherContextDecryptLength needs to be made smarter!
1024 PORT_Assert(ofraglen
== pcount
);
1027 * Account for the bytes now in output.
1029 max_output_len
-= ofraglen
;
1030 output_len
+= ofraglen
;
1035 * If this is our last call, we expect to have an exact number of
1036 * blocks left to be decrypted; we will decrypt them all.
1038 * If not our last call, we always save between 1 and bsize bytes
1039 * until next time. (We must do this because we cannot be sure
1040 * that none of the decrypted bytes are padding bytes until we
1041 * have at least another whole block of data. You cannot tell by
1042 * looking -- the data could be anything -- you can only tell by
1043 * context, knowing you are looking at the last block.) We could
1044 * decrypt a whole block now but it is easier if we just treat it
1045 * the same way we treat partial block bytes.
1049 blocks
= input_len
/ padsize
;
1050 ifraglen
= blocks
* padsize
;
1051 } else ifraglen
= input_len
;
1052 PORT_Assert (ifraglen
== input_len
);
1054 if (ifraglen
!= input_len
) {
1055 PORT_SetError(SEC_ERROR_BAD_DATA
);
1059 blocks
= (input_len
- 1) / bsize
;
1060 ifraglen
= blocks
* bsize
;
1061 PORT_Assert (ifraglen
< input_len
);
1063 pcount
= input_len
- ifraglen
;
1064 PORT_Memcpy (pbuf
, input
+ ifraglen
, pcount
);
1065 cc
->pending_count
= pcount
;
1069 rv
= (* cc
->doit
)(cc
->cx
, output
, &ofraglen
, max_output_len
,
1071 if (rv
!= SECSuccess
)
1075 * For now anyway, all of our ciphers have the same number of
1076 * bytes of output as they do input. If this ever becomes untrue,
1077 * then sec_PKCS7DecryptLength needs to be made smarter!
1079 PORT_Assert (ifraglen
== ofraglen
);
1080 if (ifraglen
!= ofraglen
) {
1081 PORT_SetError(SEC_ERROR_BAD_DATA
);
1085 output_len
+= ofraglen
;
1091 * If we just did our very last block, "remove" the padding by
1092 * adjusting the output length.
1094 if (final
&& (padsize
!= 0)) {
1095 unsigned int padlen
= *(output
+ ofraglen
- 1);
1097 if (padlen
== 0 || padlen
> padsize
) {
1098 PORT_SetError(SEC_ERROR_BAD_DATA
);
1101 output_len
-= padlen
;
1104 PORT_Assert (output_len_p
!= NULL
|| output_len
== 0);
1105 if (output_len_p
!= NULL
)
1106 *output_len_p
= output_len
;
1113 * SecCmsCipherContextEncrypt - do the encryption
1115 * cc - the cipher context
1116 * output - buffer for decrypted result bytes
1117 * output_len_p - number of bytes in output
1118 * max_output_len - upper bound on bytes to put into output
1119 * input - pointer to input bytes
1120 * input_len - number of input bytes
1121 * final - true if this is the final chunk of data
1123 * Encrypts a given length of input buffer (starting at "input" and
1124 * containing "input_len" bytes), placing the encrypted bytes in
1125 * "output" and storing the output length in "*output_len_p".
1126 * "cc" is the return value from SecCmsCipherStartEncrypt.
1127 * When "final" is true, this is the last of the data to be encrypted.
1129 * This is much more complicated than it sounds when the cipher is
1130 * a block-type, meaning that the encryption function will only
1131 * operate on whole blocks. But our caller is operating stream-wise,
1132 * and can pass in any number of bytes. So we need to keep track
1133 * of block boundaries. We save excess bytes between calls in "cc".
1134 * We also need to add padding bytes at the end. PKCS #7 specifies
1135 * that the padding used for a block cipher is a string of bytes,
1136 * each of whose value is the same as the length of the padding,
1137 * and that all data is padded. (Even data that starts out with
1138 * an exact multiple of blocks gets added to it another block,
1139 * all of which is padding.)
1141 * XXX I would kind of like to combine this with the function above
1142 * which does decryption, since they have a lot in common. But the
1143 * tricky parts about padding and filling blocks would be much
1144 * harder to read that way, so I left them separate. At least for
1145 * now until it is clear that they are right.
1148 SecCmsCipherContextEncrypt(SecCmsCipherContextRef cc
, unsigned char *output
,
1149 unsigned int *output_len_p
, unsigned int max_output_len
,
1150 const unsigned char *input
, unsigned int input_len
,
1154 return SecCmsCipherContextCrypt(cc
, output
,
1155 output_len_p
, max_output_len
,
1159 int blocks
, bsize
, padlen
, pcount
, padsize
;
1160 unsigned int max_needed
, ifraglen
, ofraglen
, output_len
;
1161 unsigned char *pbuf
;
1164 PORT_Assert (cc
->encrypt
);
1167 * Check that we have enough room for the output. Our caller should
1168 * already handle this; failure is really an internal error (i.e. bug).
1170 max_needed
= SecCmsCipherContextEncryptLength (cc
, input_len
, final
);
1171 PORT_Assert (max_output_len
>= max_needed
);
1172 if (max_output_len
< max_needed
) {
1173 /* PORT_SetError (XXX); */
1177 bsize
= cc
->block_size
;
1178 padsize
= cc
->pad_size
;
1181 * When no blocking and padding work to do, we can simply call the
1182 * cipher function and we are done.
1185 return (*cc
->doit
)(cc
->cx
, output
, output_len_p
, max_output_len
,
1189 pcount
= cc
->pending_count
;
1190 pbuf
= cc
->pending_buf
;
1196 * Try to fill in an entire block, starting with the bytes
1197 * we already have saved away.
1199 while (input_len
&& pcount
< bsize
) {
1200 pbuf
[pcount
++] = *input
++;
1204 * If we do not have a full block and we know we will be
1205 * called again, then we are done for now.
1207 if (pcount
< bsize
&& !final
) {
1208 cc
->pending_count
= pcount
;
1209 if (output_len_p
!= NULL
)
1214 * If we have a whole block available, encrypt it.
1216 if ((padsize
== 0) || (pcount
% padsize
) == 0) {
1217 rv
= (* cc
->doit
) (cc
->cx
, output
, &ofraglen
, max_output_len
,
1219 if (rv
!= SECSuccess
)
1223 * For now anyway, all of our ciphers have the same number of
1224 * bytes of output as they do input. If this ever becomes untrue,
1225 * then sec_PKCS7EncryptLength needs to be made smarter!
1227 PORT_Assert (ofraglen
== pcount
);
1230 * Account for the bytes now in output.
1232 max_output_len
-= ofraglen
;
1233 output_len
+= ofraglen
;
1241 PORT_Assert (pcount
== 0);
1243 blocks
= input_len
/ bsize
;
1244 ifraglen
= blocks
* bsize
;
1247 rv
= (* cc
->doit
) (cc
->cx
, output
, &ofraglen
, max_output_len
,
1249 if (rv
!= SECSuccess
)
1253 * For now anyway, all of our ciphers have the same number of
1254 * bytes of output as they do input. If this ever becomes untrue,
1255 * then sec_PKCS7EncryptLength needs to be made smarter!
1257 PORT_Assert (ifraglen
== ofraglen
);
1259 max_output_len
-= ofraglen
;
1260 output_len
+= ofraglen
;
1264 pcount
= input_len
- ifraglen
;
1265 PORT_Assert (pcount
< bsize
);
1267 PORT_Memcpy (pbuf
, input
+ ifraglen
, pcount
);
1271 padlen
= padsize
- (pcount
% padsize
);
1272 PORT_Memset (pbuf
+ pcount
, padlen
, padlen
);
1273 rv
= (* cc
->doit
) (cc
->cx
, output
, &ofraglen
, max_output_len
,
1274 pbuf
, pcount
+padlen
);
1275 if (rv
!= SECSuccess
)
1279 * For now anyway, all of our ciphers have the same number of
1280 * bytes of output as they do input. If this ever becomes untrue,
1281 * then sec_PKCS7EncryptLength needs to be made smarter!
1283 PORT_Assert (ofraglen
== (pcount
+padlen
));
1284 output_len
+= ofraglen
;
1286 cc
->pending_count
= pcount
;
1289 PORT_Assert (output_len_p
!= NULL
|| output_len
== 0);
1290 if (output_len_p
!= NULL
)
1291 *output_len_p
= output_len
;