Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /*
2 * aes_icm.c
3 *
4 * AES Integer Counter Mode
5 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 */
10 /*
11 *
12 * Copyright (c) 2001-2006, Cisco Systems, Inc.
13 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 *
22 * Redistributions in binary form must reproduce the above
23 * copyright notice, this list of conditions and the following
24 * disclaimer in the documentation and/or other materials provided
25 * with the distribution.
26 *
27 * Neither the name of the Cisco Systems, Inc. nor the names of its
28 * contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
34 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
35 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
36 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
38 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
42 * OF THE POSSIBILITY OF SUCH DAMAGE.
43 *
44 */
47 #define ALIGN_32 0
49 #include "aes_icm.h"
50 #include "alloc.h"
53 debug_module_t mod_aes_icm = {
54 0, /* debugging is off by default */
55 "aes icm" /* printable module name */
56 };
58 /*
59 * integer counter mode works as follows:
60 *
61 * 16 bits
62 * <----->
63 * +------+------+------+------+------+------+------+------+
64 * | nonce | pakcet index | ctr |---+
65 * +------+------+------+------+------+------+------+------+ |
66 * |
67 * +------+------+------+------+------+------+------+------+ v
68 * | salt |000000|->(+)
69 * +------+------+------+------+------+------+------+------+ |
70 * |
71 * +---------+
72 * | encrypt |
73 * +---------+
74 * |
75 * +------+------+------+------+------+------+------+------+ |
76 * | keystream block |<--+
77 * +------+------+------+------+------+------+------+------+
78 *
79 * All fields are big-endian
80 *
81 * ctr is the block counter, which increments from zero for
82 * each packet (16 bits wide)
83 *
84 * packet index is distinct for each packet (48 bits wide)
85 *
86 * nonce can be distinct across many uses of the same key, or
87 * can be a fixed value per key, or can be per-packet randomness
88 * (64 bits)
89 *
90 */
92 err_status_t
93 aes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) {
94 extern cipher_type_t aes_icm;
95 uint8_t *pointer;
96 int tmp;
98 debug_print(mod_aes_icm,
99 "allocating cipher with key length %d", key_len);
101 /*
102 * Ismacryp, for example, uses 16 byte key + 8 byte
103 * salt so this function is called with key_len = 24.
104 * The check for key_len = 30/38/46 does not apply. Our usage
105 * of aes functions with key_len = values other than 30
106 * has not broken anything. Don't know what would be the
107 * effect of skipping this check for srtp in general.
108 */
109 if (!(forIsmacryp && key_len > 16 && key_len < 30) &&
110 key_len != 30 && key_len != 38 && key_len != 46)
111 return err_status_bad_param;
113 /* allocate memory a cipher of type aes_icm */
114 tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
115 pointer = (uint8_t*)crypto_alloc(tmp);
116 if (pointer == NULL)
117 return err_status_alloc_fail;
119 /* set pointers */
120 *c = (cipher_t *)pointer;
121 (*c)->type = &aes_icm;
122 (*c)->state = pointer + sizeof(cipher_t);
124 /* increment ref_count */
125 aes_icm.ref_count++;
127 /* set key size */
128 (*c)->key_len = key_len;
130 return err_status_ok;
131 }
133 err_status_t aes_icm_alloc(cipher_t **c, int key_len, int forIsmacryp) {
134 return aes_icm_alloc_ismacryp(c, key_len, 0);
135 }
137 err_status_t
138 aes_icm_dealloc(cipher_t *c) {
139 extern cipher_type_t aes_icm;
141 /* zeroize entire state*/
142 octet_string_set_to_zero((uint8_t *)c,
143 sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
145 /* free memory */
146 crypto_free(c);
148 /* decrement ref_count */
149 aes_icm.ref_count--;
151 return err_status_ok;
152 }
155 /*
156 * aes_icm_context_init(...) initializes the aes_icm_context
157 * using the value in key[].
158 *
159 * the key is the secret key
160 *
161 * the salt is unpredictable (but not necessarily secret) data which
162 * randomizes the starting point in the keystream
163 */
165 err_status_t
166 aes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key, int key_len) {
167 err_status_t status;
168 int base_key_len, copy_len;
170 if (key_len > 16 && key_len < 30) /* Ismacryp */
171 base_key_len = 16;
172 else if (key_len == 30 || key_len == 38 || key_len == 46)
173 base_key_len = key_len - 14;
174 else
175 return err_status_bad_param;
177 /*
178 * set counter and initial values to 'offset' value, being careful not to
179 * go past the end of the key buffer
180 */
181 v128_set_to_zero(&c->counter);
182 v128_set_to_zero(&c->offset);
184 copy_len = key_len - base_key_len;
185 /* force last two octets of the offset to be left zero (for srtp compatibility) */
186 if (copy_len > 14)
187 copy_len = 14;
189 memcpy(&c->counter, key + base_key_len, copy_len);
190 memcpy(&c->offset, key + base_key_len, copy_len);
192 debug_print(mod_aes_icm,
193 "key: %s", octet_string_hex_string(key, base_key_len));
194 debug_print(mod_aes_icm,
195 "offset: %s", v128_hex_string(&c->offset));
197 /* expand key */
198 status = aes_expand_encryption_key(key, base_key_len, &c->expanded_key);
199 if (status) {
200 v128_set_to_zero(&c->counter);
201 v128_set_to_zero(&c->offset);
202 return status;
203 }
205 /* indicate that the keystream_buffer is empty */
206 c->bytes_in_buffer = 0;
208 return err_status_ok;
209 }
211 /*
212 * aes_icm_set_octet(c, i) sets the counter of the context which it is
213 * passed so that the next octet of keystream that will be generated
214 * is the ith octet
215 */
217 err_status_t
218 aes_icm_set_octet(aes_icm_ctx_t *c,
219 uint64_t octet_num) {
221 #ifdef NO_64BIT_MATH
222 int tail_num = low32(octet_num) & 0x0f;
223 /* 64-bit right-shift 4 */
224 uint64_t block_num = make64(high32(octet_num) >> 4,
225 ((high32(octet_num) & 0x0f)<<(32-4)) |
226 (low32(octet_num) >> 4));
227 #else
228 int tail_num = (int)(octet_num % 16);
229 uint64_t block_num = octet_num / 16;
230 #endif
233 /* set counter value */
234 /* FIX - There's no way this is correct */
235 c->counter.v64[0] = c->offset.v64[0];
236 #ifdef NO_64BIT_MATH
237 c->counter.v64[0] = make64(high32(c->offset.v64[0]) ^ high32(block_num),
238 low32(c->offset.v64[0]) ^ low32(block_num));
239 #else
240 c->counter.v64[0] = c->offset.v64[0] ^ block_num;
241 #endif
243 debug_print(mod_aes_icm,
244 "set_octet: %s", v128_hex_string(&c->counter));
246 /* fill keystream buffer, if needed */
247 if (tail_num) {
248 v128_copy(&c->keystream_buffer, &c->counter);
249 aes_encrypt(&c->keystream_buffer, &c->expanded_key);
250 c->bytes_in_buffer = sizeof(v128_t);
252 debug_print(mod_aes_icm, "counter: %s",
253 v128_hex_string(&c->counter));
254 debug_print(mod_aes_icm, "ciphertext: %s",
255 v128_hex_string(&c->keystream_buffer));
257 /* indicate number of bytes in keystream_buffer */
258 c->bytes_in_buffer = sizeof(v128_t) - tail_num;
260 } else {
262 /* indicate that keystream_buffer is empty */
263 c->bytes_in_buffer = 0;
264 }
266 return err_status_ok;
267 }
269 /*
270 * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
271 * the offset
272 */
274 err_status_t
275 aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) {
276 v128_t *nonce = (v128_t *) iv;
278 debug_print(mod_aes_icm,
279 "setting iv: %s", v128_hex_string(nonce));
281 v128_xor(&c->counter, &c->offset, nonce);
283 debug_print(mod_aes_icm,
284 "set_counter: %s", v128_hex_string(&c->counter));
286 /* indicate that the keystream_buffer is empty */
287 c->bytes_in_buffer = 0;
289 return err_status_ok;
290 }
294 /*
295 * aes_icm_advance(...) refills the keystream_buffer and
296 * advances the block index of the sicm_context forward by one
297 *
298 * this is an internal, hopefully inlined function
299 */
301 static inline void
302 aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) {
303 /* fill buffer with new keystream */
304 v128_copy(&c->keystream_buffer, &c->counter);
305 aes_encrypt(&c->keystream_buffer, &c->expanded_key);
306 c->bytes_in_buffer = sizeof(v128_t);
308 debug_print(mod_aes_icm, "counter: %s",
309 v128_hex_string(&c->counter));
310 debug_print(mod_aes_icm, "ciphertext: %s",
311 v128_hex_string(&c->keystream_buffer));
313 /* clock counter forward */
315 if (forIsmacryp) {
316 uint32_t temp;
317 //alex's clock counter forward
318 temp = ntohl(c->counter.v32[3]);
319 c->counter.v32[3] = htonl(++temp);
320 } else {
321 if (!++(c->counter.v8[15]))
322 ++(c->counter.v8[14]);
323 }
324 }
326 static inline void aes_icm_advance(aes_icm_ctx_t *c) {
327 aes_icm_advance_ismacryp(c, 0);
328 }
331 /*e
332 * icm_encrypt deals with the following cases:
333 *
334 * bytes_to_encr < bytes_in_buffer
335 * - add keystream into data
336 *
337 * bytes_to_encr > bytes_in_buffer
338 * - add keystream into data until keystream_buffer is depleted
339 * - loop over blocks, filling keystream_buffer and then
340 * adding keystream into data
341 * - fill buffer then add in remaining (< 16) bytes of keystream
342 */
344 err_status_t
345 aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c,
346 unsigned char *buf, unsigned int *enc_len,
347 int forIsmacryp) {
348 unsigned int bytes_to_encr = *enc_len;
349 unsigned int i;
350 uint32_t *b;
352 /* check that there's enough segment left but not for ismacryp*/
353 if (!forIsmacryp && (bytes_to_encr + htons(c->counter.v16[7])) > 0xffff)
354 return err_status_terminus;
356 debug_print(mod_aes_icm, "block index: %d",
357 htons(c->counter.v16[7]));
358 if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) {
360 /* deal with odd case of small bytes_to_encr */
361 for (i = (sizeof(v128_t) - c->bytes_in_buffer);
362 i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++)
363 {
364 *buf++ ^= c->keystream_buffer.v8[i];
365 }
367 c->bytes_in_buffer -= bytes_to_encr;
369 /* return now to avoid the main loop */
370 return err_status_ok;
372 } else {
374 /* encrypt bytes until the remaining data is 16-byte aligned */
375 for (i=(sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++)
376 *buf++ ^= c->keystream_buffer.v8[i];
378 bytes_to_encr -= c->bytes_in_buffer;
379 c->bytes_in_buffer = 0;
381 }
383 /* now loop over entire 16-byte blocks of keystream */
384 for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) {
386 /* fill buffer with new keystream */
387 aes_icm_advance_ismacryp(c, forIsmacryp);
389 /*
390 * add keystream into the data buffer (this would be a lot faster
391 * if we could assume 32-bit alignment!)
392 */
394 #if ALIGN_32
395 b = (uint32_t *)buf;
396 *b++ ^= c->keystream_buffer.v32[0];
397 *b++ ^= c->keystream_buffer.v32[1];
398 *b++ ^= c->keystream_buffer.v32[2];
399 *b++ ^= c->keystream_buffer.v32[3];
400 buf = (uint8_t *)b;
401 #else
402 if ((((unsigned long) buf) & 0x03) != 0) {
403 *buf++ ^= c->keystream_buffer.v8[0];
404 *buf++ ^= c->keystream_buffer.v8[1];
405 *buf++ ^= c->keystream_buffer.v8[2];
406 *buf++ ^= c->keystream_buffer.v8[3];
407 *buf++ ^= c->keystream_buffer.v8[4];
408 *buf++ ^= c->keystream_buffer.v8[5];
409 *buf++ ^= c->keystream_buffer.v8[6];
410 *buf++ ^= c->keystream_buffer.v8[7];
411 *buf++ ^= c->keystream_buffer.v8[8];
412 *buf++ ^= c->keystream_buffer.v8[9];
413 *buf++ ^= c->keystream_buffer.v8[10];
414 *buf++ ^= c->keystream_buffer.v8[11];
415 *buf++ ^= c->keystream_buffer.v8[12];
416 *buf++ ^= c->keystream_buffer.v8[13];
417 *buf++ ^= c->keystream_buffer.v8[14];
418 *buf++ ^= c->keystream_buffer.v8[15];
419 } else {
420 b = (uint32_t *)buf;
421 *b++ ^= c->keystream_buffer.v32[0];
422 *b++ ^= c->keystream_buffer.v32[1];
423 *b++ ^= c->keystream_buffer.v32[2];
424 *b++ ^= c->keystream_buffer.v32[3];
425 buf = (uint8_t *)b;
426 }
427 #endif /* #if ALIGN_32 */
429 }
431 /* if there is a tail end of the data, process it */
432 if ((bytes_to_encr & 0xf) != 0) {
434 /* fill buffer with new keystream */
435 aes_icm_advance_ismacryp(c, forIsmacryp);
437 for (i=0; i < (bytes_to_encr & 0xf); i++)
438 *buf++ ^= c->keystream_buffer.v8[i];
440 /* reset the keystream buffer size to right value */
441 c->bytes_in_buffer = sizeof(v128_t) - i;
442 } else {
444 /* no tail, so just reset the keystream buffer size to zero */
445 c->bytes_in_buffer = 0;
447 }
449 return err_status_ok;
450 }
452 err_status_t
453 aes_icm_encrypt(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) {
454 return aes_icm_encrypt_ismacryp(c, buf, enc_len, 0);
455 }
457 err_status_t
458 aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output) {
459 unsigned int len = num_octets_to_output;
461 /* zeroize the buffer */
462 octet_string_set_to_zero(buffer, num_octets_to_output);
464 /* exor keystream into buffer */
465 return aes_icm_encrypt(c, buffer, &len);
466 }
469 char
470 aes_icm_description[] = "aes integer counter mode";
472 uint8_t aes_icm_test_case_0_key[30] = {
473 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
474 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
475 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
476 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
477 };
479 uint8_t aes_icm_test_case_0_nonce[16] = {
480 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
482 };
484 uint8_t aes_icm_test_case_0_plaintext[32] = {
485 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
486 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
487 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489 };
491 uint8_t aes_icm_test_case_0_ciphertext[32] = {
492 0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
493 0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
494 0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
495 0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
496 };
498 cipher_test_case_t aes_icm_test_case_0 = {
499 30, /* octets in key */
500 aes_icm_test_case_0_key, /* key */
501 aes_icm_test_case_0_nonce, /* packet index */
502 32, /* octets in plaintext */
503 aes_icm_test_case_0_plaintext, /* plaintext */
504 32, /* octets in ciphertext */
505 aes_icm_test_case_0_ciphertext, /* ciphertext */
506 NULL /* pointer to next testcase */
507 };
509 uint8_t aes_icm_test_case_1_key[46] = {
510 0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
511 0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
512 0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82,
513 0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98,
514 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
515 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
516 };
518 uint8_t aes_icm_test_case_1_nonce[16] = {
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
521 };
523 uint8_t aes_icm_test_case_1_plaintext[32] = {
524 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
525 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
528 };
530 uint8_t aes_icm_test_case_1_ciphertext[32] = {
531 0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
532 0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
533 0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
534 0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
535 };
537 cipher_test_case_t aes_icm_test_case_1 = {
538 46, /* octets in key */
539 aes_icm_test_case_1_key, /* key */
540 aes_icm_test_case_1_nonce, /* packet index */
541 32, /* octets in plaintext */
542 aes_icm_test_case_1_plaintext, /* plaintext */
543 32, /* octets in ciphertext */
544 aes_icm_test_case_1_ciphertext, /* ciphertext */
545 &aes_icm_test_case_0 /* pointer to next testcase */
546 };
550 /*
551 * note: the encrypt function is identical to the decrypt function
552 */
554 cipher_type_t aes_icm = {
555 (cipher_alloc_func_t) aes_icm_alloc,
556 (cipher_dealloc_func_t) aes_icm_dealloc,
557 (cipher_init_func_t) aes_icm_context_init,
558 (cipher_encrypt_func_t) aes_icm_encrypt,
559 (cipher_decrypt_func_t) aes_icm_encrypt,
560 (cipher_set_iv_func_t) aes_icm_set_iv,
561 (char *) aes_icm_description,
562 (int) 0, /* instance count */
563 (cipher_test_case_t *) &aes_icm_test_case_1,
564 (debug_module_t *) &mod_aes_icm,
565 (cipher_type_id_t) AES_ICM
566 };