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>
48 #include <Security/SecRandom.h>
49 #include <CommonCrypto/CommonCryptor.h>
52 * -------------------------------------------------------------------
57 typedef OSStatus (*nss_cms_cipher_function
) (void *, unsigned char *, unsigned int *,
58 unsigned int, const unsigned char *, unsigned int);
59 typedef OSStatus (*nss_cms_cipher_destroy
) (void *, Boolean
);
62 #define BLOCK_SIZE 4096
64 struct SecCmsCipherContextStr
{
66 void * cc
; /* CSP CONTEXT */
67 Boolean encrypt
; /* encrypt / decrypt switch */
68 int block_size
; /* block & pad sizes for cipher */
70 void * cx
; /* PK11 cipher context */
71 nss_cms_cipher_function doit
;
72 nss_cms_cipher_destroy destroy
;
73 Boolean encrypt
; /* encrypt / decrypt switch */
75 int pending_count
; /* pending data (not yet en/decrypted */
76 unsigned char pending_buf
[BLOCK_SIZE
];/* because of blocking */
80 typedef struct sec_rc2cbcParameterStr
{
81 SecAsn1Item rc2ParameterVersion
;
83 } sec_rc2cbcParameter
;
85 __unused
static const SecAsn1Template sec_rc2cbc_parameter_template
[] = {
87 0, NULL
, sizeof(sec_rc2cbcParameter
) },
88 { SEC_ASN1_INTEGER
| SEC_ASN1_SIGNED_INT
,
89 offsetof(sec_rc2cbcParameter
,rc2ParameterVersion
) },
90 { SEC_ASN1_OCTET_STRING
,
91 offsetof(sec_rc2cbcParameter
,iv
) },
95 /* default IV size in bytes */
96 #define DEFAULT_IV_SIZE 8
97 /* IV/block size for AES */
98 #define AES_BLOCK_SIZE 16
99 /* max IV size in bytes */
100 #define MAX_IV_SIZE AES_BLOCK_SIZE
102 #ifndef kCCKeySizeMaxRC2
103 #define kCCKeySizeMaxRC2 16
105 #ifndef kCCBlockSizeRC2
106 #define kCCBlockSizeRC2 8
109 static SecCmsCipherContextRef
110 SecCmsCipherContextStart(PRArenaPool
*poolp
, SecSymmetricKeyRef key
, SECAlgorithmID
*algid
, Boolean encrypt
)
112 SecCmsCipherContextRef cc
;
116 uint8_t ivbuf
[MAX_IV_SIZE
];
117 SecAsn1Item initVector
= { DEFAULT_IV_SIZE
, ivbuf
};
118 CCCryptorRef ciphercc
= NULL
;
119 CCOptions cipheroptions
= kCCOptionPKCS7Padding
;
120 int cipher_blocksize
= 0;
121 // @@@ Add support for PBE based stuff
123 oidData
= SECOID_FindOID(&algid
->algorithm
);
126 algtag
= oidData
->offset
;
128 CCAlgorithm alg
= -1;
130 case SEC_OID_DES_CBC
:
131 alg
= kCCAlgorithmDES
;
132 cipher_blocksize
= kCCBlockSizeDES
;
134 case SEC_OID_DES_EDE3_CBC
:
135 alg
= kCCAlgorithm3DES
;
136 cipher_blocksize
= kCCBlockSize3DES
;
138 case SEC_OID_RC2_CBC
:
139 alg
= kCCAlgorithmRC2
;
140 cipher_blocksize
= kCCBlockSizeRC2
;
142 case SEC_OID_AES_128_CBC
:
143 case SEC_OID_AES_192_CBC
:
144 case SEC_OID_AES_256_CBC
:
145 alg
= kCCAlgorithmAES128
;
146 cipher_blocksize
= kCCBlockSizeAES128
;
147 initVector
.Length
= AES_BLOCK_SIZE
;
155 if (SecRandomCopyBytes(kSecRandomDefault
,
156 initVector
.Length
, initVector
.Data
))
159 // Put IV into algid.parameters
163 case SEC_OID_DES_EDE3_CBC
:
164 case SEC_OID_DES_EDE
:
165 case SEC_OID_DES_CBC
:
166 case SEC_OID_AES_128_CBC
:
167 case SEC_OID_AES_192_CBC
:
168 case SEC_OID_AES_256_CBC
:
169 case SEC_OID_FORTEZZA_SKIPJACK
:
170 case SEC_OID_DES_ECB
:
171 case SEC_OID_AES_128_ECB
:
172 case SEC_OID_AES_192_ECB
:
173 case SEC_OID_AES_256_ECB
:
174 case SEC_OID_DES_OFB
:
175 case SEC_OID_DES_CFB
:
176 /* Just encode the initVector as an octet string. */
177 if (!SEC_ASN1EncodeItem(poolp
, &algid
->parameters
,
178 &initVector
, kSecAsn1OctetStringTemplate
))
181 case SEC_OID_RC2_CBC
:
182 case SEC_OID_RC5_CBC_PAD
:
184 // @@@ Implement rc5 params stuff.
191 // Extract IV from algid.parameters
192 // Put IV into algid.parameters
196 case SEC_OID_DES_EDE3_CBC
:
197 case SEC_OID_DES_EDE
:
198 case SEC_OID_DES_CBC
:
199 case SEC_OID_AES_128_CBC
:
200 case SEC_OID_AES_192_CBC
:
201 case SEC_OID_AES_256_CBC
:
202 case SEC_OID_FORTEZZA_SKIPJACK
:
203 case SEC_OID_DES_ECB
:
204 case SEC_OID_AES_128_ECB
:
205 case SEC_OID_AES_192_ECB
:
206 case SEC_OID_AES_256_ECB
:
207 case SEC_OID_DES_OFB
:
208 case SEC_OID_DES_CFB
:
211 /* Just decode the initVector from an octet string. */
212 rv
= SEC_ASN1DecodeItem(NULL
, &iv
, kSecAsn1OctetStringTemplate
, &(algid
->parameters
));
215 if (initVector
.Length
!= iv
.Length
) {
219 memcpy(initVector
.Data
, iv
.Data
, initVector
.Length
);
223 case SEC_OID_RC2_CBC
:
224 case SEC_OID_RC5_CBC_PAD
:
226 // @@@ Implement rc5 params stuff.
232 if (CCCryptorCreate(encrypt
? kCCEncrypt
: kCCDecrypt
,
233 alg
, cipheroptions
, CFDataGetBytePtr(key
), CFDataGetLength(key
),
234 initVector
.Data
, &ciphercc
))
237 cc
= (SecCmsCipherContextRef
)PORT_ZAlloc(sizeof(SecCmsCipherContext
));
242 cc
->encrypt
= encrypt
;
243 cc
->block_size
=cipher_blocksize
;
247 CCCryptorRelease(ciphercc
);
253 * SecCmsCipherContextStartDecrypt - create a cipher context to do decryption
254 * based on the given bulk * encryption key and algorithm identifier (which may include an iv).
256 * XXX Once both are working, it might be nice to combine this and the
257 * function below (for starting up encryption) into one routine, and just
258 * have two simple cover functions which call it.
260 SecCmsCipherContextRef
261 SecCmsCipherContextStartDecrypt(SecSymmetricKeyRef key
, SECAlgorithmID
*algid
)
263 return SecCmsCipherContextStart(NULL
, key
, algid
, PR_FALSE
);
267 * SecCmsCipherContextStartEncrypt - create a cipher object to do encryption,
268 * based on the given bulk encryption key and algorithm tag. Fill in the algorithm
269 * identifier (which may include an iv) appropriately.
271 * XXX Once both are working, it might be nice to combine this and the
272 * function above (for starting up decryption) into one routine, and just
273 * have two simple cover functions which call it.
275 SecCmsCipherContextRef
276 SecCmsCipherContextStartEncrypt(PRArenaPool
*poolp
, SecSymmetricKeyRef key
, SECAlgorithmID
*algid
)
278 return SecCmsCipherContextStart(poolp
, key
, algid
, PR_TRUE
);
282 SecCmsCipherContextDestroy(SecCmsCipherContextRef cc
)
284 PORT_Assert(cc
!= NULL
);
288 CCCryptorRelease(cc
->cc
);
294 SecCmsCipherContextLength(SecCmsCipherContextRef cc
, unsigned int input_len
, Boolean final
, Boolean encrypt
)
296 return ((input_len
+ cc
->block_size
- 1) / cc
->block_size
* cc
->block_size
) + (final
? cc
->block_size
: 0);
300 * SecCmsCipherContextDecryptLength - find the output length of the next call to decrypt.
302 * cc - the cipher context
303 * input_len - number of bytes used as input
304 * final - true if this is the final chunk of data
306 * Result can be used to perform memory allocations. Note that the amount
307 * is exactly accurate only when not doing a block cipher or when final
308 * is false, otherwise it is an upper bound on the amount because until
309 * we see the data we do not know how many padding bytes there are
310 * (always between 1 and bsize).
312 * Note that this can return zero, which does not mean that the decrypt
313 * operation can be skipped! (It simply means that there are not enough
314 * bytes to make up an entire block; the bytes will be reserved until
315 * there are enough to encrypt/decrypt at least one block.) However,
316 * if zero is returned it *does* mean that no output buffer need be
317 * passed in to the subsequent decrypt operation, as no output bytes
321 SecCmsCipherContextDecryptLength(SecCmsCipherContextRef cc
, unsigned int input_len
, Boolean final
)
323 return SecCmsCipherContextLength(cc
, input_len
, final
, PR_FALSE
);
327 * SecCmsCipherContextEncryptLength - find the output length of the next call to encrypt.
329 * cc - the cipher context
330 * input_len - number of bytes used as input
331 * final - true if this is the final chunk of data
333 * Result can be used to perform memory allocations.
335 * Note that this can return zero, which does not mean that the encrypt
336 * operation can be skipped! (It simply means that there are not enough
337 * bytes to make up an entire block; the bytes will be reserved until
338 * there are enough to encrypt/decrypt at least one block.) However,
339 * if zero is returned it *does* mean that no output buffer need be
340 * passed in to the subsequent encrypt operation, as no output bytes
344 SecCmsCipherContextEncryptLength(SecCmsCipherContextRef cc
, unsigned int input_len
, Boolean final
)
346 return SecCmsCipherContextLength(cc
, input_len
, final
, PR_TRUE
);
351 SecCmsCipherContextCrypt(SecCmsCipherContextRef cc
, unsigned char *output
,
352 unsigned int *output_len_p
, unsigned int max_output_len
,
353 const unsigned char *input
, unsigned int input_len
,
354 Boolean final
, Boolean encrypt
)
356 size_t bytes_output
= 0;
361 rv
= CCCryptorUpdate(cc
->cc
, input
, input_len
, output
, max_output_len
, &bytes_output
);
366 size_t bytes_output_final
= 0;
367 rv
= CCCryptorFinal(cc
->cc
, output
+bytes_output
, max_output_len
-bytes_output
, &bytes_output_final
);
368 bytes_output
+= bytes_output_final
;
372 PORT_SetError(SEC_ERROR_BAD_DATA
);
373 else if (output_len_p
)
374 *output_len_p
= (unsigned int)bytes_output
; /* This cast is safe since bytes_output can't be bigger than max_output_len */
380 * SecCmsCipherContextDecrypt - do the decryption
382 * cc - the cipher context
383 * output - buffer for decrypted result bytes
384 * output_len_p - number of bytes in output
385 * max_output_len - upper bound on bytes to put into output
386 * input - pointer to input bytes
387 * input_len - number of input bytes
388 * final - true if this is the final chunk of data
390 * Decrypts a given length of input buffer (starting at "input" and
391 * containing "input_len" bytes), placing the decrypted bytes in
392 * "output" and storing the output length in "*output_len_p".
393 * "cc" is the return value from SecCmsCipherStartDecrypt.
394 * When "final" is true, this is the last of the data to be decrypted.
396 * This is much more complicated than it sounds when the cipher is
397 * a block-type, meaning that the decryption function will only
398 * operate on whole blocks. But our caller is operating stream-wise,
399 * and can pass in any number of bytes. So we need to keep track
400 * of block boundaries. We save excess bytes between calls in "cc".
401 * We also need to determine which bytes are padding, and remove
402 * them from the output. We can only do this step when we know we
403 * have the final block of data. PKCS #7 specifies that the padding
404 * used for a block cipher is a string of bytes, each of whose value is
405 * the same as the length of the padding, and that all data is padded.
406 * (Even data that starts out with an exact multiple of blocks gets
407 * added to it another block, all of which is padding.)
410 SecCmsCipherContextDecrypt(SecCmsCipherContextRef cc
, unsigned char *output
,
411 unsigned int *output_len_p
, unsigned int max_output_len
,
412 const unsigned char *input
, unsigned int input_len
,
415 return SecCmsCipherContextCrypt(cc
, output
,
416 output_len_p
, max_output_len
,
422 * SecCmsCipherContextEncrypt - do the encryption
424 * cc - the cipher context
425 * output - buffer for decrypted result bytes
426 * output_len_p - number of bytes in output
427 * max_output_len - upper bound on bytes to put into output
428 * input - pointer to input bytes
429 * input_len - number of input bytes
430 * final - true if this is the final chunk of data
432 * Encrypts a given length of input buffer (starting at "input" and
433 * containing "input_len" bytes), placing the encrypted bytes in
434 * "output" and storing the output length in "*output_len_p".
435 * "cc" is the return value from SecCmsCipherStartEncrypt.
436 * When "final" is true, this is the last of the data to be encrypted.
438 * This is much more complicated than it sounds when the cipher is
439 * a block-type, meaning that the encryption function will only
440 * operate on whole blocks. But our caller is operating stream-wise,
441 * and can pass in any number of bytes. So we need to keep track
442 * of block boundaries. We save excess bytes between calls in "cc".
443 * We also need to add padding bytes at the end. PKCS #7 specifies
444 * that the padding used for a block cipher is a string of bytes,
445 * each of whose value is the same as the length of the padding,
446 * and that all data is padded. (Even data that starts out with
447 * an exact multiple of blocks gets added to it another block,
448 * all of which is padding.)
450 * XXX I would kind of like to combine this with the function above
451 * which does decryption, since they have a lot in common. But the
452 * tricky parts about padding and filling blocks would be much
453 * harder to read that way, so I left them separate. At least for
454 * now until it is clear that they are right.
457 SecCmsCipherContextEncrypt(SecCmsCipherContextRef cc
, unsigned char *output
,
458 unsigned int *output_len_p
, unsigned int max_output_len
,
459 const unsigned char *input
, unsigned int input_len
,
462 return SecCmsCipherContextCrypt(cc
, output
,
463 output_len_p
, max_output_len
,