1 /*
2  * aes_icm.c
3  *
4  * AES Integer Counter Mode
5  *
6  * David A. McGrew
7  * Cisco Systems, Inc.
8  */
9 
10 /*
11  *
12  * Copyright (c) 2001-2017 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 #ifdef HAVE_CONFIG_H
47 #include <config.h>
48 #endif
49 
50 #define ALIGN_32 0
51 
52 #include "aes_icm.h"
53 #include "alloc.h"
54 #include "cipher_types.h"
55 
56 srtp_debug_module_t srtp_mod_aes_icm = {
57     0,        /* debugging is off by default */
58     "aes icm" /* printable module name       */
59 };
60 
61 /*
62  * integer counter mode works as follows:
63  *
64  * 16 bits
65  * <----->
66  * +------+------+------+------+------+------+------+------+
67  * |           nonce           |    pakcet index    |  ctr |---+
68  * +------+------+------+------+------+------+------+------+   |
69  *                                                             |
70  * +------+------+------+------+------+------+------+------+   v
71  * |                      salt                      |000000|->(+)
72  * +------+------+------+------+------+------+------+------+   |
73  *                                                             |
74  *                                                        +---------+
75  *							  | encrypt |
76  *							  +---------+
77  *							       |
78  * +------+------+------+------+------+------+------+------+   |
79  * |                    keystream block                    |<--+
80  * +------+------+------+------+------+------+------+------+
81  *
82  * All fields are big-endian
83  *
84  * ctr is the block counter, which increments from zero for
85  * each packet (16 bits wide)
86  *
87  * packet index is distinct for each packet (48 bits wide)
88  *
89  * nonce can be distinct across many uses of the same key, or
90  * can be a fixed value per key, or can be per-packet randomness
91  * (64 bits)
92  *
93  */
94 
srtp_aes_icm_alloc(srtp_cipher_t ** c,int key_len,int tlen)95 static srtp_err_status_t srtp_aes_icm_alloc(srtp_cipher_t **c,
96                                             int key_len,
97                                             int tlen)
98 {
99     srtp_aes_icm_ctx_t *icm;
100 
101     debug_print(srtp_mod_aes_icm, "allocating cipher with key length %d",
102                 key_len);
103 
104     /*
105      * The check for key_len = 30/46 does not apply. Our usage
106      * of aes functions with key_len = values other than 30
107      * has not broken anything. Don't know what would be the
108      * effect of skipping this check for srtp in general.
109      */
110     if (key_len != SRTP_AES_ICM_128_KEY_LEN_WSALT &&
111         key_len != SRTP_AES_ICM_256_KEY_LEN_WSALT) {
112         return srtp_err_status_bad_param;
113     }
114 
115     /* allocate memory a cipher of type aes_icm */
116     *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
117     if (*c == NULL) {
118         return srtp_err_status_alloc_fail;
119     }
120 
121     icm = (srtp_aes_icm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_icm_ctx_t));
122     if (icm == NULL) {
123         srtp_crypto_free(*c);
124         *c = NULL;
125         return srtp_err_status_alloc_fail;
126     }
127 
128     /* set pointers */
129     (*c)->state = icm;
130 
131     switch (key_len) {
132     case SRTP_AES_ICM_256_KEY_LEN_WSALT:
133         (*c)->algorithm = SRTP_AES_ICM_256;
134         (*c)->type = &srtp_aes_icm_256;
135         break;
136     default:
137         (*c)->algorithm = SRTP_AES_ICM_128;
138         (*c)->type = &srtp_aes_icm_128;
139         break;
140     }
141 
142     /* set key size        */
143     icm->key_size = key_len;
144     (*c)->key_len = key_len;
145 
146     return srtp_err_status_ok;
147 }
148 
srtp_aes_icm_dealloc(srtp_cipher_t * c)149 static srtp_err_status_t srtp_aes_icm_dealloc(srtp_cipher_t *c)
150 {
151     srtp_aes_icm_ctx_t *ctx;
152 
153     if (c == NULL) {
154         return srtp_err_status_bad_param;
155     }
156 
157     ctx = (srtp_aes_icm_ctx_t *)c->state;
158     if (ctx) {
159         /* zeroize the key material */
160         octet_string_set_to_zero(ctx, sizeof(srtp_aes_icm_ctx_t));
161         srtp_crypto_free(ctx);
162     }
163 
164     /* free the cipher context */
165     srtp_crypto_free(c);
166 
167     return srtp_err_status_ok;
168 }
169 
170 /*
171  * aes_icm_context_init(...) initializes the aes_icm_context
172  * using the value in key[].
173  *
174  * the key is the secret key
175  *
176  * the salt is unpredictable (but not necessarily secret) data which
177  * randomizes the starting point in the keystream
178  */
179 
srtp_aes_icm_context_init(void * cv,const uint8_t * key)180 static srtp_err_status_t srtp_aes_icm_context_init(void *cv, const uint8_t *key)
181 {
182     srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
183     srtp_err_status_t status;
184     int base_key_len, copy_len;
185 
186     if (c->key_size == SRTP_AES_ICM_128_KEY_LEN_WSALT ||
187         c->key_size == SRTP_AES_ICM_256_KEY_LEN_WSALT) {
188         base_key_len = c->key_size - SRTP_SALT_LEN;
189     } else {
190         return srtp_err_status_bad_param;
191     }
192 
193     /*
194      * set counter and initial values to 'offset' value, being careful not to
195      * go past the end of the key buffer
196      */
197     v128_set_to_zero(&c->counter);
198     v128_set_to_zero(&c->offset);
199 
200     copy_len = c->key_size - base_key_len;
201     /* force last two octets of the offset to be left zero (for srtp
202      * compatibility) */
203     if (copy_len > SRTP_SALT_LEN) {
204         copy_len = SRTP_SALT_LEN;
205     }
206 
207     memcpy(&c->counter, key + base_key_len, copy_len);
208     memcpy(&c->offset, key + base_key_len, copy_len);
209 
210     debug_print(srtp_mod_aes_icm, "key:  %s",
211                 srtp_octet_string_hex_string(key, base_key_len));
212     debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));
213 
214     /* expand key */
215     status =
216         srtp_aes_expand_encryption_key(key, base_key_len, &c->expanded_key);
217     if (status) {
218         v128_set_to_zero(&c->counter);
219         v128_set_to_zero(&c->offset);
220         return status;
221     }
222 
223     /* indicate that the keystream_buffer is empty */
224     c->bytes_in_buffer = 0;
225 
226     return srtp_err_status_ok;
227 }
228 
229 /*
230  * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
231  * the offset
232  */
233 
srtp_aes_icm_set_iv(void * cv,uint8_t * iv,srtp_cipher_direction_t direction)234 static srtp_err_status_t srtp_aes_icm_set_iv(void *cv,
235                                              uint8_t *iv,
236                                              srtp_cipher_direction_t direction)
237 {
238     srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
239     v128_t nonce;
240 
241     /* set nonce (for alignment) */
242     v128_copy_octet_string(&nonce, iv);
243 
244     debug_print(srtp_mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce));
245 
246     v128_xor(&c->counter, &c->offset, &nonce);
247 
248     debug_print(srtp_mod_aes_icm, "set_counter: %s",
249                 v128_hex_string(&c->counter));
250 
251     /* indicate that the keystream_buffer is empty */
252     c->bytes_in_buffer = 0;
253 
254     return srtp_err_status_ok;
255 }
256 
257 /*
258  * aes_icm_advance(...) refills the keystream_buffer and
259  * advances the block index of the sicm_context forward by one
260  *
261  * this is an internal, hopefully inlined function
262  */
srtp_aes_icm_advance(srtp_aes_icm_ctx_t * c)263 static void srtp_aes_icm_advance(srtp_aes_icm_ctx_t *c)
264 {
265     /* fill buffer with new keystream */
266     v128_copy(&c->keystream_buffer, &c->counter);
267     srtp_aes_encrypt(&c->keystream_buffer, &c->expanded_key);
268     c->bytes_in_buffer = sizeof(v128_t);
269 
270     debug_print(srtp_mod_aes_icm, "counter:    %s",
271                 v128_hex_string(&c->counter));
272     debug_print(srtp_mod_aes_icm, "ciphertext: %s",
273                 v128_hex_string(&c->keystream_buffer));
274 
275     /* clock counter forward */
276     if (!++(c->counter.v8[15])) {
277         ++(c->counter.v8[14]);
278     }
279 }
280 
281 /*
282  * icm_encrypt deals with the following cases:
283  *
284  * bytes_to_encr < bytes_in_buffer
285  *  - add keystream into data
286  *
287  * bytes_to_encr > bytes_in_buffer
288  *  - add keystream into data until keystream_buffer is depleted
289  *  - loop over blocks, filling keystream_buffer and then
290  *    adding keystream into data
291  *  - fill buffer then add in remaining (< 16) bytes of keystream
292  */
293 
srtp_aes_icm_encrypt(void * cv,unsigned char * buf,unsigned int * enc_len)294 static srtp_err_status_t srtp_aes_icm_encrypt(void *cv,
295                                               unsigned char *buf,
296                                               unsigned int *enc_len)
297 {
298     srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
299     unsigned int bytes_to_encr = *enc_len;
300     unsigned int i;
301     uint32_t *b;
302 
303     /* check that there's enough segment left*/
304     if ((bytes_to_encr + htons(c->counter.v16[7])) > 0xffff) {
305         return srtp_err_status_terminus;
306     }
307 
308     debug_print(srtp_mod_aes_icm, "block index: %d", htons(c->counter.v16[7]));
309     if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) {
310         /* deal with odd case of small bytes_to_encr */
311         for (i = (sizeof(v128_t) - c->bytes_in_buffer);
312              i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++) {
313             *buf++ ^= c->keystream_buffer.v8[i];
314         }
315 
316         c->bytes_in_buffer -= bytes_to_encr;
317 
318         /* return now to avoid the main loop */
319         return srtp_err_status_ok;
320 
321     } else {
322         /* encrypt bytes until the remaining data is 16-byte aligned */
323         for (i = (sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t);
324              i++) {
325             *buf++ ^= c->keystream_buffer.v8[i];
326         }
327 
328         bytes_to_encr -= c->bytes_in_buffer;
329         c->bytes_in_buffer = 0;
330     }
331 
332     /* now loop over entire 16-byte blocks of keystream */
333     for (i = 0; i < (bytes_to_encr / sizeof(v128_t)); i++) {
334         /* fill buffer with new keystream */
335         srtp_aes_icm_advance(c);
336 
337 /*
338  * add keystream into the data buffer (this would be a lot faster
339  * if we could assume 32-bit alignment!)
340  */
341 
342 #if ALIGN_32
343         b = (uint32_t *)buf;
344         *b++ ^= c->keystream_buffer.v32[0];
345         *b++ ^= c->keystream_buffer.v32[1];
346         *b++ ^= c->keystream_buffer.v32[2];
347         *b++ ^= c->keystream_buffer.v32[3];
348         buf = (uint8_t *)b;
349 #else
350         if ((((uintptr_t)buf) & 0x03) != 0) {
351             *buf++ ^= c->keystream_buffer.v8[0];
352             *buf++ ^= c->keystream_buffer.v8[1];
353             *buf++ ^= c->keystream_buffer.v8[2];
354             *buf++ ^= c->keystream_buffer.v8[3];
355             *buf++ ^= c->keystream_buffer.v8[4];
356             *buf++ ^= c->keystream_buffer.v8[5];
357             *buf++ ^= c->keystream_buffer.v8[6];
358             *buf++ ^= c->keystream_buffer.v8[7];
359             *buf++ ^= c->keystream_buffer.v8[8];
360             *buf++ ^= c->keystream_buffer.v8[9];
361             *buf++ ^= c->keystream_buffer.v8[10];
362             *buf++ ^= c->keystream_buffer.v8[11];
363             *buf++ ^= c->keystream_buffer.v8[12];
364             *buf++ ^= c->keystream_buffer.v8[13];
365             *buf++ ^= c->keystream_buffer.v8[14];
366             *buf++ ^= c->keystream_buffer.v8[15];
367         } else {
368             b = (uint32_t *)buf;
369             *b++ ^= c->keystream_buffer.v32[0];
370             *b++ ^= c->keystream_buffer.v32[1];
371             *b++ ^= c->keystream_buffer.v32[2];
372             *b++ ^= c->keystream_buffer.v32[3];
373             buf = (uint8_t *)b;
374         }
375 #endif /* #if ALIGN_32 */
376     }
377 
378     /* if there is a tail end of the data, process it */
379     if ((bytes_to_encr & 0xf) != 0) {
380         /* fill buffer with new keystream */
381         srtp_aes_icm_advance(c);
382 
383         for (i = 0; i < (bytes_to_encr & 0xf); i++) {
384             *buf++ ^= c->keystream_buffer.v8[i];
385         }
386 
387         /* reset the keystream buffer size to right value */
388         c->bytes_in_buffer = sizeof(v128_t) - i;
389     } else {
390         /* no tail, so just reset the keystream buffer size to zero */
391         c->bytes_in_buffer = 0;
392     }
393 
394     return srtp_err_status_ok;
395 }
396 
397 static const char srtp_aes_icm_128_description[] =
398     "AES-128 integer counter mode";
399 static const char srtp_aes_icm_256_description[] =
400     "AES-256 integer counter mode";
401 
402 /* clang-format off */
403 static const uint8_t srtp_aes_icm_128_test_case_0_key[SRTP_AES_ICM_128_KEY_LEN_WSALT] = {
404     0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
405     0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
406     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
407     0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
408 };
409 /* clang-format on */
410 
411 /* clang-format off */
412 static uint8_t srtp_aes_icm_128_test_case_0_nonce[16] = {
413     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
415 };
416 /* clang-format on */
417 
418 /* clang-format off */
419 static const uint8_t srtp_aes_icm_128_test_case_0_plaintext[32] =  {
420     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
423     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424 };
425 /* clang-format on */
426 
427 /* clang-format off */
428 static const uint8_t srtp_aes_icm_128_test_case_0_ciphertext[32] = {
429     0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
430     0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
431     0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
432     0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
433 };
434 /* clang-format on */
435 
436 static const srtp_cipher_test_case_t srtp_aes_icm_128_test_case_0 = {
437     SRTP_AES_ICM_128_KEY_LEN_WSALT,          /* octets in key            */
438     srtp_aes_icm_128_test_case_0_key,        /* key                      */
439     srtp_aes_icm_128_test_case_0_nonce,      /* packet index             */
440     32,                                      /* octets in plaintext      */
441     srtp_aes_icm_128_test_case_0_plaintext,  /* plaintext                */
442     32,                                      /* octets in ciphertext     */
443     srtp_aes_icm_128_test_case_0_ciphertext, /* ciphertext               */
444     0,                                       /* */
445     NULL,                                    /* */
446     0,                                       /* */
447     NULL                                     /* pointer to next testcase */
448 };
449 
450 /* clang-format off */
451 static const uint8_t srtp_aes_icm_256_test_case_0_key[SRTP_AES_ICM_256_KEY_LEN_WSALT] = {
452     0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
453     0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
454     0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82,
455     0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98,
456     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
457     0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
458 };
459 /* clang-format on */
460 
461 /* clang-format off */
462 static uint8_t srtp_aes_icm_256_test_case_0_nonce[16] = {
463     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
464     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
465 };
466 /* clang-format on */
467 
468 /* clang-format off */
469 static const uint8_t srtp_aes_icm_256_test_case_0_plaintext[32] =  {
470     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
471     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474 };
475 /* clang-format on */
476 
477 /* clang-format off */
478 static const uint8_t srtp_aes_icm_256_test_case_0_ciphertext[32] = {
479     0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
480     0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
481     0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
482     0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
483 };
484 /* clang-format on */
485 
486 static const srtp_cipher_test_case_t srtp_aes_icm_256_test_case_0 = {
487     SRTP_AES_ICM_256_KEY_LEN_WSALT,          /* octets in key            */
488     srtp_aes_icm_256_test_case_0_key,        /* key                      */
489     srtp_aes_icm_256_test_case_0_nonce,      /* packet index             */
490     32,                                      /* octets in plaintext      */
491     srtp_aes_icm_256_test_case_0_plaintext,  /* plaintext                */
492     32,                                      /* octets in ciphertext     */
493     srtp_aes_icm_256_test_case_0_ciphertext, /* ciphertext               */
494     0,                                       /* */
495     NULL,                                    /* */
496     0,                                       /* */
497     NULL,                                    /* pointer to next testcase */
498 };
499 
500 /*
501  * note: the encrypt function is identical to the decrypt function
502  */
503 
504 const srtp_cipher_type_t srtp_aes_icm_128 = {
505     srtp_aes_icm_alloc,            /* */
506     srtp_aes_icm_dealloc,          /* */
507     srtp_aes_icm_context_init,     /* */
508     0,                             /* set_aad */
509     srtp_aes_icm_encrypt,          /* */
510     srtp_aes_icm_encrypt,          /* */
511     srtp_aes_icm_set_iv,           /* */
512     0,                             /* get_tag */
513     srtp_aes_icm_128_description,  /* */
514     &srtp_aes_icm_128_test_case_0, /* */
515     SRTP_AES_ICM_128               /* */
516 };
517 
518 const srtp_cipher_type_t srtp_aes_icm_256 = {
519     srtp_aes_icm_alloc,            /* */
520     srtp_aes_icm_dealloc,          /* */
521     srtp_aes_icm_context_init,     /* */
522     0,                             /* set_aad */
523     srtp_aes_icm_encrypt,          /* */
524     srtp_aes_icm_encrypt,          /* */
525     srtp_aes_icm_set_iv,           /* */
526     0,                             /* get_tag */
527     srtp_aes_icm_256_description,  /* */
528     &srtp_aes_icm_256_test_case_0, /* */
529     SRTP_AES_ICM_256               /* */
530 };
531