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
aes_cbc_alloc(cipher_t ** c,int key_len)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)
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 
89 err_status_t
aes_cbc_dealloc(cipher_t * c)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
aes_cbc_context_init(aes_cbc_ctx_t * c,const uint8_t * key,cipher_direction_t dir)107 aes_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 
134 err_status_t
aes_cbc_set_iv(aes_cbc_ctx_t * c,void * iv)135 aes_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 
149 err_status_t
aes_cbc_encrypt(aes_cbc_ctx_t * c,unsigned char * data,unsigned int * bytes_in_data)150 aes_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 
199 err_status_t
aes_cbc_decrypt(aes_cbc_ctx_t * c,unsigned char * data,unsigned int * bytes_in_data)200 aes_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 
262 err_status_t
aes_cbc_nist_encrypt(aes_cbc_ctx_t * c,unsigned char * data,unsigned int * bytes_in_data)263 aes_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 
298 err_status_t
aes_cbc_nist_decrypt(aes_cbc_ctx_t * c,unsigned char * data,unsigned int * bytes_in_data)299 aes_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 
331 char
332 aes_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 
345 uint8_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 
350 uint8_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 
355 uint8_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 
363 uint8_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 
369 cipher_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 
386 uint8_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 
391 uint8_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 
402 uint8_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 
415 uint8_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 
420 cipher_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 
431 cipher_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 
445