Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1380)

Side by Side Diff: libsrtp/crypto/cipher/aes_cbc.c

Issue 3423016: Add current version of libSRTP from CVS. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/
Patch Set: '' Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « libsrtp/crypto/cipher/aes.c ('k') | libsrtp/crypto/cipher/aes_icm.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /*
2 * aes_cbc.c
3 *
4 * AES Cipher Block Chaining Mode
5 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 */
9
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 */
45
46
47 #include "aes_cbc.h"
48 #include "alloc.h"
49
50 debug_module_t mod_aes_cbc = {
51 0, /* debugging is off by default */
52 "aes cbc" /* printable module name */
53 };
54
55
56
57 err_status_t
58 aes_cbc_alloc(cipher_t **c, int key_len) {
59 extern cipher_type_t aes_cbc;
60 uint8_t *pointer;
61 int tmp;
62
63 debug_print(mod_aes_cbc,
64 "allocating cipher with key length %d", key_len);
65
66 if (key_len != 16 && key_len != 24 && key_len != 32)
67 return err_status_bad_param;
68
69 /* allocate memory a cipher of type aes_cbc */
70 tmp = (sizeof(aes_cbc_ctx_t) + sizeof(cipher_t));
71 pointer = (uint8_t*)crypto_alloc(tmp);
72 if (pointer == NULL)
73 return err_status_alloc_fail;
74
75 /* set pointers */
76 *c = (cipher_t *)pointer;
77 (*c)->type = &aes_cbc;
78 (*c)->state = pointer + sizeof(cipher_t);
79
80 /* increment ref_count */
81 aes_cbc.ref_count++;
82
83 /* set key size */
84 (*c)->key_len = key_len;
85
86 return err_status_ok;
87 }
88
89 err_status_t
90 aes_cbc_dealloc(cipher_t *c) {
91 extern cipher_type_t aes_cbc;
92
93 /* zeroize entire state*/
94 octet_string_set_to_zero((uint8_t *)c,
95 sizeof(aes_cbc_ctx_t) + sizeof(cipher_t));
96
97 /* free memory */
98 crypto_free(c);
99
100 /* decrement ref_count */
101 aes_cbc.ref_count--;
102
103 return err_status_ok;
104 }
105
106 err_status_t
107 aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, int key_len,
108 cipher_direction_t dir) {
109 err_status_t status;
110
111 debug_print(mod_aes_cbc,
112 "key: %s", octet_string_hex_string(key, key_len));
113
114 /* expand key for the appropriate direction */
115 switch (dir) {
116 case (direction_encrypt):
117 status = aes_expand_encryption_key(key, key_len, &c->expanded_key);
118 if (status)
119 return status;
120 break;
121 case (direction_decrypt):
122 status = aes_expand_decryption_key(key, key_len, &c->expanded_key);
123 if (status)
124 return status;
125 break;
126 default:
127 return err_status_bad_param;
128 }
129
130
131 return err_status_ok;
132 }
133
134
135 err_status_t
136 aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv) {
137 int i;
138 /* v128_t *input = iv; */
139 uint8_t *input = (uint8_t*) iv;
140
141 /* set state and 'previous' block to iv */
142 for (i=0; i < 16; i++)
143 c->previous.v8[i] = c->state.v8[i] = input[i];
144
145 debug_print(mod_aes_cbc, "setting iv: %s", v128_hex_string(&c->state));
146
147 return err_status_ok;
148 }
149
150 err_status_t
151 aes_cbc_encrypt(aes_cbc_ctx_t *c,
152 unsigned char *data,
153 unsigned int *bytes_in_data) {
154 int i;
155 unsigned char *input = data; /* pointer to data being read */
156 unsigned char *output = data; /* pointer to data being written */
157 int bytes_to_encr = *bytes_in_data;
158
159 /*
160 * verify that we're 16-octet aligned
161 */
162 if (*bytes_in_data & 0xf)
163 return err_status_bad_param;
164
165 /*
166 * note that we assume that the initialization vector has already
167 * been set, e.g. by calling aes_cbc_set_iv()
168 */
169 debug_print(mod_aes_cbc, "iv: %s",
170 v128_hex_string(&c->state));
171
172 /*
173 * loop over plaintext blocks, exoring state into plaintext then
174 * encrypting and writing to output
175 */
176 while (bytes_to_encr > 0) {
177
178 /* exor plaintext into state */
179 for (i=0; i < 16; i++)
180 c->state.v8[i] ^= *input++;
181
182 debug_print(mod_aes_cbc, "inblock: %s",
183 v128_hex_string(&c->state));
184
185 aes_encrypt(&c->state, &c->expanded_key);
186
187 debug_print(mod_aes_cbc, "outblock: %s",
188 v128_hex_string(&c->state));
189
190 /* copy ciphertext to output */
191 for (i=0; i < 16; i++)
192 *output++ = c->state.v8[i];
193
194 bytes_to_encr -= 16;
195 }
196
197 return err_status_ok;
198 }
199
200 err_status_t
201 aes_cbc_decrypt(aes_cbc_ctx_t *c,
202 unsigned char *data,
203 unsigned int *bytes_in_data) {
204 int i;
205 v128_t state, previous;
206 unsigned char *input = data; /* pointer to data being read */
207 unsigned char *output = data; /* pointer to data being written */
208 int bytes_to_encr = *bytes_in_data;
209 uint8_t tmp;
210
211 /*
212 * verify that we're 16-octet aligned
213 */
214 if (*bytes_in_data & 0x0f)
215 return err_status_bad_param;
216
217 /* set 'previous' block to iv*/
218 for (i=0; i < 16; i++) {
219 previous.v8[i] = c->previous.v8[i];
220 }
221
222 debug_print(mod_aes_cbc, "iv: %s",
223 v128_hex_string(&previous));
224
225 /*
226 * loop over ciphertext blocks, decrypting then exoring with state
227 * then writing plaintext to output
228 */
229 while (bytes_to_encr > 0) {
230
231 /* set state to ciphertext input block */
232 for (i=0; i < 16; i++) {
233 state.v8[i] = *input++;
234 }
235
236 debug_print(mod_aes_cbc, "inblock: %s",
237 v128_hex_string(&state));
238
239 /* decrypt state */
240 aes_decrypt(&state, &c->expanded_key);
241
242 debug_print(mod_aes_cbc, "outblock: %s",
243 v128_hex_string(&state));
244
245 /*
246 * exor previous ciphertext block out of plaintext, and write new
247 * plaintext block to output, while copying old ciphertext block
248 * to the 'previous' block
249 */
250 for (i=0; i < 16; i++) {
251 tmp = *output;
252 *output++ = state.v8[i] ^ previous.v8[i];
253 previous.v8[i] = tmp;
254 }
255
256 bytes_to_encr -= 16;
257 }
258
259 return err_status_ok;
260 }
261
262
263 err_status_t
264 aes_cbc_nist_encrypt(aes_cbc_ctx_t *c,
265 unsigned char *data,
266 unsigned int *bytes_in_data) {
267 int i;
268 unsigned char *pad_start;
269 int num_pad_bytes;
270 err_status_t status;
271
272 /*
273 * determine the number of padding bytes that we need to add -
274 * this value is always between 1 and 16, inclusive.
275 */
276 num_pad_bytes = 16 - (*bytes_in_data & 0xf);
277 pad_start = data;
278 pad_start += *bytes_in_data;
279 *pad_start++ = 0xa0;
280 for (i=0; i < num_pad_bytes; i++)
281 *pad_start++ = 0x00;
282
283 /*
284 * increment the data size
285 */
286 *bytes_in_data += num_pad_bytes;
287
288 /*
289 * now cbc encrypt the padded data
290 */
291 status = aes_cbc_encrypt(c, data, bytes_in_data);
292 if (status)
293 return status;
294
295 return err_status_ok;
296 }
297
298
299 err_status_t
300 aes_cbc_nist_decrypt(aes_cbc_ctx_t *c,
301 unsigned char *data,
302 unsigned int *bytes_in_data) {
303 unsigned char *pad_end;
304 int num_pad_bytes;
305 err_status_t status;
306
307 /*
308 * cbc decrypt the padded data
309 */
310 status = aes_cbc_decrypt(c, data, bytes_in_data);
311 if (status)
312 return status;
313
314 /*
315 * determine the number of padding bytes in the decrypted plaintext
316 * - this value is always between 1 and 16, inclusive.
317 */
318 num_pad_bytes = 1;
319 pad_end = data + (*bytes_in_data - 1);
320 while (*pad_end != 0xa0) { /* note: should check padding correctness */
321 pad_end--;
322 num_pad_bytes++;
323 }
324
325 /* decrement data size */
326 *bytes_in_data -= num_pad_bytes;
327
328 return err_status_ok;
329 }
330
331
332 char
333 aes_cbc_description[] = "aes cipher block chaining (cbc) mode";
334
335 /*
336 * Test case 0 is derived from FIPS 197 Appendix C; it uses an
337 * all-zero IV, so that the first block encryption matches the test
338 * case in that appendix. This property provides a check of the base
339 * AES encryption and decryption algorithms; if CBC fails on some
340 * particular platform, then you should print out AES intermediate
341 * data and compare with the detailed info provided in that appendix.
342 *
343 */
344
345
346 uint8_t aes_cbc_test_case_0_key[16] = {
347 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
348 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
349 };
350
351 uint8_t aes_cbc_test_case_0_plaintext[64] = {
352 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
353 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
354 };
355
356 uint8_t aes_cbc_test_case_0_ciphertext[80] = {
357 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
358 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a,
359 0x03, 0x35, 0xed, 0x27, 0x67, 0xf2, 0x6d, 0xf1,
360 0x64, 0x83, 0x2e, 0x23, 0x44, 0x38, 0x70, 0x8b
361
362 };
363
364 uint8_t aes_cbc_test_case_0_iv[16] = {
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
367 };
368
369
370 cipher_test_case_t aes_cbc_test_case_0 = {
371 16, /* octets in key */
372 aes_cbc_test_case_0_key, /* key */
373 aes_cbc_test_case_0_iv, /* initialization vector */
374 16, /* octets in plaintext */
375 aes_cbc_test_case_0_plaintext, /* plaintext */
376 32, /* octets in ciphertext */
377 aes_cbc_test_case_0_ciphertext, /* ciphertext */
378 NULL /* pointer to next testcase */
379 };
380
381
382 /*
383 * this test case is taken directly from Appendix F.2 of NIST Special
384 * Publication SP 800-38A
385 */
386
387 uint8_t aes_cbc_test_case_1_key[16] = {
388 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
389 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
390 };
391
392 uint8_t aes_cbc_test_case_1_plaintext[64] = {
393 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
394 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
395 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
396 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
397 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
398 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
399 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
400 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
401 };
402
403 uint8_t aes_cbc_test_case_1_ciphertext[80] = {
404 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
405 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
406 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee,
407 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
408 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b,
409 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16,
410 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09,
411 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7,
412 0x39, 0x34, 0x07, 0x03, 0x36, 0xd0, 0x77, 0x99,
413 0xe0, 0xc4, 0x2f, 0xdd, 0xa8, 0xdf, 0x4c, 0xa3
414 };
415
416 uint8_t aes_cbc_test_case_1_iv[16] = {
417 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
418 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
419 };
420
421 cipher_test_case_t aes_cbc_test_case_1 = {
422 16, /* octets in key */
423 aes_cbc_test_case_1_key, /* key */
424 aes_cbc_test_case_1_iv, /* initialization vector */
425 64, /* octets in plaintext */
426 aes_cbc_test_case_1_plaintext, /* plaintext */
427 80, /* octets in ciphertext */
428 aes_cbc_test_case_1_ciphertext, /* ciphertext */
429 &aes_cbc_test_case_0 /* pointer to next testcase */
430 };
431
432 /*
433 * Test case 2 is like test case 0, but for 256-bit keys. (FIPS 197
434 * appendix C.3).
435 */
436
437
438 uint8_t aes_cbc_test_case_2_key[32] = {
439 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
440 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
441 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
442 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
443 };
444
445 uint8_t aes_cbc_test_case_2_plaintext[64] = {
446 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
447 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
448 };
449
450 uint8_t aes_cbc_test_case_2_ciphertext[80] = {
451 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
452 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89,
453 0x72, 0x72, 0x6e, 0xe7, 0x71, 0x39, 0xbf, 0x11,
454 0xe5, 0x40, 0xe2, 0x7c, 0x54, 0x65, 0x1d, 0xee
455 };
456
457 uint8_t aes_cbc_test_case_2_iv[16] = {
458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
460 };
461
462 cipher_test_case_t aes_cbc_test_case_2 = {
463 32, /* octets in key */
464 aes_cbc_test_case_2_key, /* key */
465 aes_cbc_test_case_2_iv, /* initialization vector */
466 16, /* octets in plaintext */
467 aes_cbc_test_case_2_plaintext, /* plaintext */
468 32, /* octets in ciphertext */
469 aes_cbc_test_case_2_ciphertext, /* ciphertext */
470 &aes_cbc_test_case_1 /* pointer to next testcase */
471 };
472
473
474 /*
475 * this test case is taken directly from Appendix F.2 of NIST Special
476 * Publication SP 800-38A
477 */
478
479 uint8_t aes_cbc_test_case_3_key[32] = {
480 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
481 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
482 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
483 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
484 };
485
486 uint8_t aes_cbc_test_case_3_plaintext[64] = {
487 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
488 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
489 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
490 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
491 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
492 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
493 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
494 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
495 };
496
497 uint8_t aes_cbc_test_case_3_ciphertext[80] = {
498 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
499 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
500 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
501 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
502 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
503 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
504 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
505 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b,
506 0xfb, 0x98, 0x20, 0x2c, 0x45, 0xb2, 0xe4, 0xa0,
507 0x63, 0xc4, 0x68, 0xba, 0x84, 0x39, 0x16, 0x5a
508 };
509
510 uint8_t aes_cbc_test_case_3_iv[16] = {
511 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
512 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
513 };
514
515 cipher_test_case_t aes_cbc_test_case_3 = {
516 32, /* octets in key */
517 aes_cbc_test_case_3_key, /* key */
518 aes_cbc_test_case_3_iv, /* initialization vector */
519 64, /* octets in plaintext */
520 aes_cbc_test_case_3_plaintext, /* plaintext */
521 80, /* octets in ciphertext */
522 aes_cbc_test_case_3_ciphertext, /* ciphertext */
523 &aes_cbc_test_case_2 /* pointer to next testcase */
524 };
525
526 cipher_type_t aes_cbc = {
527 (cipher_alloc_func_t) aes_cbc_alloc,
528 (cipher_dealloc_func_t) aes_cbc_dealloc,
529 (cipher_init_func_t) aes_cbc_context_init,
530 (cipher_encrypt_func_t) aes_cbc_nist_encrypt,
531 (cipher_decrypt_func_t) aes_cbc_nist_decrypt,
532 (cipher_set_iv_func_t) aes_cbc_set_iv,
533 (char *) aes_cbc_description,
534 (int) 0, /* instance count */
535 (cipher_test_case_t *) &aes_cbc_test_case_3,
536 (debug_module_t *) &mod_aes_cbc,
537 (cipher_type_id_t) AES_CBC
538 };
539
540
OLDNEW
« no previous file with comments | « libsrtp/crypto/cipher/aes.c ('k') | libsrtp/crypto/cipher/aes_icm.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698