]> git.saurik.com Git - apple/security.git/blob - libsecurity_smime/lib/cmscipher.c
Security-57740.60.18.tar.gz
[apple/security.git] / libsecurity_smime / lib / cmscipher.c
1 /*
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/
6 *
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.
11 *
12 * The Original Code is the Netscape security libraries.
13 *
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
17 * Rights Reserved.
18 *
19 * Contributor(s):
20 *
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
31 * GPL.
32 */
33
34 /*
35 * Encryption/decryption routines for CMS implementation, none of which are exported.
36 *
37 */
38 #include <limits.h>
39
40 #include "cmslocal.h"
41
42 #include "secoid.h"
43 #include <security_asn1/secerr.h>
44 #include <security_asn1/secasn1.h>
45 #include <security_asn1/secport.h>
46
47 #include <Security/SecAsn1Templates.h>
48 #include <Security/SecRandom.h>
49 #include <CommonCrypto/CommonCryptor.h>
50
51 /*
52 * -------------------------------------------------------------------
53 * Cipher stuff.
54 */
55
56 #if 0
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);
60 #endif
61
62 #define BLOCK_SIZE 4096
63
64 struct SecCmsCipherContextStr {
65 #if 1
66 void * cc; /* CSP CONTEXT */
67 Boolean encrypt; /* encrypt / decrypt switch */
68 int block_size; /* block & pad sizes for cipher */
69 #else
70 void * cx; /* PK11 cipher context */
71 nss_cms_cipher_function doit;
72 nss_cms_cipher_destroy destroy;
73 Boolean encrypt; /* encrypt / decrypt switch */
74 int pad_size;
75 int pending_count; /* pending data (not yet en/decrypted */
76 unsigned char pending_buf[BLOCK_SIZE];/* because of blocking */
77 #endif
78 };
79
80 typedef struct sec_rc2cbcParameterStr {
81 SecAsn1Item rc2ParameterVersion;
82 SecAsn1Item iv;
83 } sec_rc2cbcParameter;
84
85 __unused static const SecAsn1Template sec_rc2cbc_parameter_template[] = {
86 { SEC_ASN1_SEQUENCE,
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) },
92 { 0 }
93 };
94
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
101
102 #ifndef kCCKeySizeMaxRC2
103 #define kCCKeySizeMaxRC2 16
104 #endif
105 #ifndef kCCBlockSizeRC2
106 #define kCCBlockSizeRC2 8
107 #endif
108
109 static SecCmsCipherContextRef
110 SecCmsCipherContextStart(PRArenaPool *poolp, SecSymmetricKeyRef key, SECAlgorithmID *algid, Boolean encrypt)
111 {
112 SecCmsCipherContextRef cc;
113 SECOidData *oidData;
114 SECOidTag algtag;
115 OSStatus rv;
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
122
123 oidData = SECOID_FindOID(&algid->algorithm);
124 if (!oidData)
125 goto loser;
126 algtag = oidData->offset;
127
128 CCAlgorithm alg = -1;
129 switch (algtag) {
130 case SEC_OID_DES_CBC:
131 alg = kCCAlgorithmDES;
132 cipher_blocksize = kCCBlockSizeDES;
133 break;
134 case SEC_OID_DES_EDE3_CBC:
135 alg = kCCAlgorithm3DES;
136 cipher_blocksize = kCCBlockSize3DES;
137 break;
138 case SEC_OID_RC2_CBC:
139 alg = kCCAlgorithmRC2;
140 cipher_blocksize = kCCBlockSizeRC2;
141 break;
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;
148 break;
149 default:
150 goto loser;
151 }
152
153 if (encrypt)
154 {
155 if (SecRandomCopyBytes(kSecRandomDefault,
156 initVector.Length, initVector.Data))
157 goto loser;
158
159 // Put IV into algid.parameters
160 switch (algtag)
161 {
162 case SEC_OID_RC4:
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))
179 goto loser;
180 break;
181 case SEC_OID_RC2_CBC:
182 case SEC_OID_RC5_CBC_PAD:
183 default:
184 // @@@ Implement rc5 params stuff.
185 goto loser;
186 break;
187 }
188 }
189 else
190 {
191 // Extract IV from algid.parameters
192 // Put IV into algid.parameters
193 switch (algtag)
194 {
195 case SEC_OID_RC4:
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:
209 {
210 SecAsn1Item iv = {};
211 /* Just decode the initVector from an octet string. */
212 rv = SEC_ASN1DecodeItem(NULL, &iv, kSecAsn1OctetStringTemplate, &(algid->parameters));
213 if (rv)
214 goto loser;
215 if (initVector.Length != iv.Length) {
216 PORT_Free(iv.Data);
217 goto loser;
218 }
219 memcpy(initVector.Data, iv.Data, initVector.Length);
220 PORT_Free(iv.Data);
221 break;
222 }
223 case SEC_OID_RC2_CBC:
224 case SEC_OID_RC5_CBC_PAD:
225 default:
226 // @@@ Implement rc5 params stuff.
227 goto loser;
228 break;
229 }
230 }
231
232 if (CCCryptorCreate(encrypt ? kCCEncrypt : kCCDecrypt,
233 alg, cipheroptions, CFDataGetBytePtr(key), CFDataGetLength(key),
234 initVector.Data, &ciphercc))
235 goto loser;
236
237 cc = (SecCmsCipherContextRef)PORT_ZAlloc(sizeof(SecCmsCipherContext));
238 if (cc == NULL)
239 goto loser;
240
241 cc->cc = ciphercc;
242 cc->encrypt = encrypt;
243 cc->block_size =cipher_blocksize;
244 return cc;
245 loser:
246 if (ciphercc)
247 CCCryptorRelease(ciphercc);
248
249 return NULL;
250 }
251
252 /*
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).
255 *
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.
259 */
260 SecCmsCipherContextRef
261 SecCmsCipherContextStartDecrypt(SecSymmetricKeyRef key, SECAlgorithmID *algid)
262 {
263 return SecCmsCipherContextStart(NULL, key, algid, PR_FALSE);
264 }
265
266 /*
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.
270 *
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.
274 */
275 SecCmsCipherContextRef
276 SecCmsCipherContextStartEncrypt(PRArenaPool *poolp, SecSymmetricKeyRef key, SECAlgorithmID *algid)
277 {
278 return SecCmsCipherContextStart(poolp, key, algid, PR_TRUE);
279 }
280
281 void
282 SecCmsCipherContextDestroy(SecCmsCipherContextRef cc)
283 {
284 PORT_Assert(cc != NULL);
285 if (cc == NULL)
286 return;
287
288 CCCryptorRelease(cc->cc);
289
290 PORT_Free(cc);
291 }
292
293 static unsigned int
294 SecCmsCipherContextLength(SecCmsCipherContextRef cc, unsigned int input_len, Boolean final, Boolean encrypt)
295 {
296 return ((input_len + cc->block_size - 1) / cc->block_size * cc->block_size) + (final ? cc->block_size : 0);
297 }
298
299 /*
300 * SecCmsCipherContextDecryptLength - find the output length of the next call to decrypt.
301 *
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
305 *
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).
311 *
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
318 * will be stored.
319 */
320 unsigned int
321 SecCmsCipherContextDecryptLength(SecCmsCipherContextRef cc, unsigned int input_len, Boolean final)
322 {
323 return SecCmsCipherContextLength(cc, input_len, final, PR_FALSE);
324 }
325
326 /*
327 * SecCmsCipherContextEncryptLength - find the output length of the next call to encrypt.
328 *
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
332 *
333 * Result can be used to perform memory allocations.
334 *
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
341 * will be stored.
342 */
343 unsigned int
344 SecCmsCipherContextEncryptLength(SecCmsCipherContextRef cc, unsigned int input_len, Boolean final)
345 {
346 return SecCmsCipherContextLength(cc, input_len, final, PR_TRUE);
347 }
348
349
350 static OSStatus
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)
355 {
356 size_t bytes_output = 0;
357 OSStatus rv = 0;
358
359 if (input_len)
360 {
361 rv = CCCryptorUpdate(cc->cc, input, input_len, output, max_output_len, &bytes_output);
362 }
363
364 if (!rv && final)
365 {
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;
369 }
370
371 if (rv)
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 */
375
376 return rv;
377 }
378
379 /*
380 * SecCmsCipherContextDecrypt - do the decryption
381 *
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
389 *
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.
395 *
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.)
408 */
409 OSStatus
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,
413 Boolean final)
414 {
415 return SecCmsCipherContextCrypt(cc, output,
416 output_len_p, max_output_len,
417 input, input_len,
418 final, PR_FALSE);
419 }
420
421 /*
422 * SecCmsCipherContextEncrypt - do the encryption
423 *
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
431 *
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.
437 *
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.)
449 *
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.
455 */
456 OSStatus
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,
460 Boolean final)
461 {
462 return SecCmsCipherContextCrypt(cc, output,
463 output_len_p, max_output_len,
464 input, input_len,
465 final, PR_TRUE);
466 }