blob: 8fc6a327010f45dbb67aa47b62467bab873d7529 [file] [log] [blame]
Alexandre Lision67916dd2014-01-24 13:33:04 -05001/*
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
50debug_module_t mod_aes_cbc = {
51 0, /* debugging is off by default */
52 "aes cbc" /* printable module name */
53};
54
55
56
57err_status_t
58aes_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)
67 return err_status_bad_param;
68
69 /* allocate memory a cipher of type aes_icm */
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
89err_status_t
90aes_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
106err_status_t
107aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key,
108 cipher_direction_t dir) {
109 v128_t tmp_key;
110
111 /* set tmp_key (for alignment) */
112 v128_copy_octet_string(&tmp_key, key);
113
114 debug_print(mod_aes_cbc,
115 "key: %s", v128_hex_string(&tmp_key));
116
117 /* expand key for the appropriate direction */
118 switch (dir) {
119 case (direction_encrypt):
120 aes_expand_encryption_key(&tmp_key, c->expanded_key);
121 break;
122 case (direction_decrypt):
123 aes_expand_decryption_key(&tmp_key, c->expanded_key);
124 break;
125 default:
126 return err_status_bad_param;
127 }
128
129
130 return err_status_ok;
131}
132
133
134err_status_t
135aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv) {
136 int i;
137/* v128_t *input = iv; */
138 uint8_t *input = (uint8_t*) iv;
139
140 /* set state and 'previous' block to iv */
141 for (i=0; i < 16; i++)
142 c->previous.v8[i] = c->state.v8[i] = input[i];
143
144 debug_print(mod_aes_cbc, "setting iv: %s", v128_hex_string(&c->state));
145
146 return err_status_ok;
147}
148
149err_status_t
150aes_cbc_encrypt(aes_cbc_ctx_t *c,
151 unsigned char *data,
152 unsigned int *bytes_in_data) {
153 int i;
154 unsigned char *input = data; /* pointer to data being read */
155 unsigned char *output = data; /* pointer to data being written */
156 int bytes_to_encr = *bytes_in_data;
157
158 /*
159 * verify that we're 16-octet aligned
160 */
161 if (*bytes_in_data & 0xf)
162 return err_status_bad_param;
163
164 /*
165 * note that we assume that the initialization vector has already
166 * been set, e.g. by calling aes_cbc_set_iv()
167 */
168 debug_print(mod_aes_cbc, "iv: %s",
169 v128_hex_string(&c->state));
170
171 /*
172 * loop over plaintext blocks, exoring state into plaintext then
173 * encrypting and writing to output
174 */
175 while (bytes_to_encr > 0) {
176
177 /* exor plaintext into state */
178 for (i=0; i < 16; i++)
179 c->state.v8[i] ^= *input++;
180
181 debug_print(mod_aes_cbc, "inblock: %s",
182 v128_hex_string(&c->state));
183
184 aes_encrypt(&c->state, c->expanded_key);
185
186 debug_print(mod_aes_cbc, "outblock: %s",
187 v128_hex_string(&c->state));
188
189 /* copy ciphertext to output */
190 for (i=0; i < 16; i++)
191 *output++ = c->state.v8[i];
192
193 bytes_to_encr -= 16;
194 }
195
196 return err_status_ok;
197}
198
199err_status_t
200aes_cbc_decrypt(aes_cbc_ctx_t *c,
201 unsigned char *data,
202 unsigned int *bytes_in_data) {
203 int i;
204 v128_t state, previous;
205 unsigned char *input = data; /* pointer to data being read */
206 unsigned char *output = data; /* pointer to data being written */
207 int bytes_to_encr = *bytes_in_data;
208 uint8_t tmp;
209
210 /*
211 * verify that we're 16-octet aligned
212 */
213 if (*bytes_in_data & 0x0f)
214 return err_status_bad_param;
215
216 /* set 'previous' block to iv*/
217 for (i=0; i < 16; i++) {
218 previous.v8[i] = c->previous.v8[i];
219 }
220
221 debug_print(mod_aes_cbc, "iv: %s",
222 v128_hex_string(&previous));
223
224 /*
225 * loop over ciphertext blocks, decrypting then exoring with state
226 * then writing plaintext to output
227 */
228 while (bytes_to_encr > 0) {
229
230 /* set state to ciphertext input block */
231 for (i=0; i < 16; i++) {
232 state.v8[i] = *input++;
233 }
234
235 debug_print(mod_aes_cbc, "inblock: %s",
236 v128_hex_string(&state));
237
238 /* decrypt state */
239 aes_decrypt(&state, c->expanded_key);
240
241 debug_print(mod_aes_cbc, "outblock: %s",
242 v128_hex_string(&state));
243
244 /*
245 * exor previous ciphertext block out of plaintext, and write new
246 * plaintext block to output, while copying old ciphertext block
247 * to the 'previous' block
248 */
249 for (i=0; i < 16; i++) {
250 tmp = *output;
251 *output++ = state.v8[i] ^ previous.v8[i];
252 previous.v8[i] = tmp;
253 }
254
255 bytes_to_encr -= 16;
256 }
257
258 return err_status_ok;
259}
260
261
262err_status_t
263aes_cbc_nist_encrypt(aes_cbc_ctx_t *c,
264 unsigned char *data,
265 unsigned int *bytes_in_data) {
266 int i;
267 unsigned char *pad_start;
268 int num_pad_bytes;
269 err_status_t status;
270
271 /*
272 * determine the number of padding bytes that we need to add -
273 * this value is always between 1 and 16, inclusive.
274 */
275 num_pad_bytes = 16 - (*bytes_in_data & 0xf);
276 pad_start = data;
277 pad_start += *bytes_in_data;
278 *pad_start++ = 0xa0;
279 for (i=0; i < num_pad_bytes; i++)
280 *pad_start++ = 0x00;
281
282 /*
283 * increment the data size
284 */
285 *bytes_in_data += num_pad_bytes;
286
287 /*
288 * now cbc encrypt the padded data
289 */
290 status = aes_cbc_encrypt(c, data, bytes_in_data);
291 if (status)
292 return status;
293
294 return err_status_ok;
295}
296
297
298err_status_t
299aes_cbc_nist_decrypt(aes_cbc_ctx_t *c,
300 unsigned char *data,
301 unsigned int *bytes_in_data) {
302 unsigned char *pad_end;
303 int num_pad_bytes;
304 err_status_t status;
305
306 /*
307 * cbc decrypt the padded data
308 */
309 status = aes_cbc_decrypt(c, data, bytes_in_data);
310 if (status)
311 return status;
312
313 /*
314 * determine the number of padding bytes in the decrypted plaintext
315 * - this value is always between 1 and 16, inclusive.
316 */
317 num_pad_bytes = 1;
318 pad_end = data + (*bytes_in_data - 1);
319 while (*pad_end != 0xa0) { /* note: should check padding correctness */
320 pad_end--;
321 num_pad_bytes++;
322 }
323
324 /* decrement data size */
325 *bytes_in_data -= num_pad_bytes;
326
327 return err_status_ok;
328}
329
330
331char
332aes_cbc_description[] = "aes cipher block chaining (cbc) mode";
333
334/*
335 * Test case 0 is derived from FIPS 197 Appendix A; it uses an
336 * all-zero IV, so that the first block encryption matches the test
337 * case in that appendix. This property provides a check of the base
338 * AES encryption and decryption algorithms; if CBC fails on some
339 * particular platform, then you should print out AES intermediate
340 * data and compare with the detailed info provided in that appendix.
341 *
342 */
343
344
345uint8_t aes_cbc_test_case_0_key[16] = {
346 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
347 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
348};
349
350uint8_t aes_cbc_test_case_0_plaintext[64] = {
351 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
352 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
353};
354
355uint8_t aes_cbc_test_case_0_ciphertext[80] = {
356 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
357 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a,
358 0x03, 0x35, 0xed, 0x27, 0x67, 0xf2, 0x6d, 0xf1,
359 0x64, 0x83, 0x2e, 0x23, 0x44, 0x38, 0x70, 0x8b
360
361};
362
363uint8_t aes_cbc_test_case_0_iv[16] = {
364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
366};
367
368
369cipher_test_case_t aes_cbc_test_case_0 = {
370 16, /* octets in key */
371 aes_cbc_test_case_0_key, /* key */
372 aes_cbc_test_case_0_iv, /* initialization vector */
373 16, /* octets in plaintext */
374 aes_cbc_test_case_0_plaintext, /* plaintext */
375 32, /* octets in ciphertext */
376 aes_cbc_test_case_0_ciphertext, /* ciphertext */
377 NULL /* pointer to next testcase */
378};
379
380
381/*
382 * this test case is taken directly from Appendix F.2 of NIST Special
383 * Publication SP 800-38A
384 */
385
386uint8_t aes_cbc_test_case_1_key[16] = {
387 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
388 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
389};
390
391uint8_t aes_cbc_test_case_1_plaintext[64] = {
392 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
393 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
394 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
395 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
396 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
397 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
398 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
399 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
400};
401
402uint8_t aes_cbc_test_case_1_ciphertext[80] = {
403 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
404 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
405 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee,
406 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
407 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b,
408 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16,
409 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09,
410 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7,
411 0x39, 0x34, 0x07, 0x03, 0x36, 0xd0, 0x77, 0x99,
412 0xe0, 0xc4, 0x2f, 0xdd, 0xa8, 0xdf, 0x4c, 0xa3
413};
414
415uint8_t aes_cbc_test_case_1_iv[16] = {
416 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
417 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
418};
419
420cipher_test_case_t aes_cbc_test_case_1 = {
421 16, /* octets in key */
422 aes_cbc_test_case_1_key, /* key */
423 aes_cbc_test_case_1_iv, /* initialization vector */
424 64, /* octets in plaintext */
425 aes_cbc_test_case_1_plaintext, /* plaintext */
426 80, /* octets in ciphertext */
427 aes_cbc_test_case_1_ciphertext, /* ciphertext */
428 &aes_cbc_test_case_0 /* pointer to next testcase */
429};
430
431cipher_type_t aes_cbc = {
432 (cipher_alloc_func_t) aes_cbc_alloc,
433 (cipher_dealloc_func_t) aes_cbc_dealloc,
434 (cipher_init_func_t) aes_cbc_context_init,
435 (cipher_encrypt_func_t) aes_cbc_nist_encrypt,
436 (cipher_decrypt_func_t) aes_cbc_nist_decrypt,
437 (cipher_set_iv_func_t) aes_cbc_set_iv,
438 (char *) aes_cbc_description,
439 (int) 0, /* instance count */
440 (cipher_test_case_t *) &aes_cbc_test_case_0,
441 (debug_module_t *) &mod_aes_cbc
442};
443
444