blob: 79d59ae38fd7a5f22d1f4e10abc944559a674faf [file] [log] [blame]
Cullen Jennings235513a2005-09-21 22:51:36 +00001/*
2 * aes_icm.c
3 *
4 * AES Integer Counter Mode
5 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 */
9
10/*
jfigus5a2b2d02014-11-19 14:34:20 -050011 *
jfigus7882dd92013-08-02 16:08:23 -040012 * Copyright (c) 2001-2006,2013 Cisco Systems, Inc.
Cullen Jennings235513a2005-09-21 22:51:36 +000013 * All rights reserved.
jfigus5a2b2d02014-11-19 14:34:20 -050014 *
Cullen Jennings235513a2005-09-21 22:51:36 +000015 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
jfigus5a2b2d02014-11-19 14:34:20 -050018 *
Cullen Jennings235513a2005-09-21 22:51:36 +000019 * Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
jfigus5a2b2d02014-11-19 14:34:20 -050021 *
Cullen Jennings235513a2005-09-21 22:51:36 +000022 * 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.
jfigus5a2b2d02014-11-19 14:34:20 -050026 *
Cullen Jennings235513a2005-09-21 22:51:36 +000027 * 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.
jfigus5a2b2d02014-11-19 14:34:20 -050030 *
Cullen Jennings235513a2005-09-21 22:51:36 +000031 * 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
Teerapap Changwichukarn6cffe242014-09-24 11:24:07 +080046#ifdef HAVE_CONFIG_H
47 #include <config.h>
48#endif
Cullen Jennings235513a2005-09-21 22:51:36 +000049
50#define ALIGN_32 0
51
52#include "aes_icm.h"
53#include "alloc.h"
54
Marcus Sundberg417469e2005-10-02 20:27:47 +000055
jfigus5a2b2d02014-11-19 14:34:20 -050056debug_module_t srtp_mod_aes_icm = {
57 0, /* debugging is off by default */
58 "aes icm" /* printable module name */
Cullen Jennings235513a2005-09-21 22:51:36 +000059};
60
61/*
62 * integer counter mode works as follows:
63 *
64 * 16 bits
65 * <----->
jfigus5a2b2d02014-11-19 14:34:20 -050066 * +------+------+------+------+------+------+------+------+
Cullen Jennings235513a2005-09-21 22:51:36 +000067 * | nonce | pakcet index | ctr |---+
68 * +------+------+------+------+------+------+------+------+ |
69 * |
70 * +------+------+------+------+------+------+------+------+ v
71 * | salt |000000|->(+)
72 * +------+------+------+------+------+------+------+------+ |
73 * |
74 * +---------+
75 * | encrypt |
76 * +---------+
jfigus5a2b2d02014-11-19 14:34:20 -050077 * |
Cullen Jennings235513a2005-09-21 22:51:36 +000078 * +------+------+------+------+------+------+------+------+ |
jfigus5a2b2d02014-11-19 14:34:20 -050079 * | keystream block |<--+
80 * +------+------+------+------+------+------+------+------+
Cullen Jennings235513a2005-09-21 22:51:36 +000081 *
82 * All fields are big-endian
83 *
84 * ctr is the block counter, which increments from zero for
85 * each packet (16 bits wide)
jfigus5a2b2d02014-11-19 14:34:20 -050086 *
Cullen Jennings235513a2005-09-21 22:51:36 +000087 * 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
jfigus5a2b2d02014-11-19 14:34:20 -050095srtp_err_status_t srtp_aes_icm_alloc_ismacryp (cipher_t **c, int key_len, int forIsmacryp)
96{
97 extern cipher_type_t srtp_aes_icm;
98 uint8_t *pointer;
99 int tmp;
Cullen Jennings235513a2005-09-21 22:51:36 +0000100
jfigus5a2b2d02014-11-19 14:34:20 -0500101 debug_print(srtp_mod_aes_icm,
102 "allocating cipher with key length %d", key_len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000103
jfigus5a2b2d02014-11-19 14:34:20 -0500104 /*
105 * Ismacryp, for example, uses 16 byte key + 8 byte
106 * salt so this function is called with key_len = 24.
107 * The check for key_len = 30/38/46 does not apply. Our usage
108 * of aes functions with key_len = values other than 30
109 * has not broken anything. Don't know what would be the
110 * effect of skipping this check for srtp in general.
111 */
112 if (!(forIsmacryp && key_len > 16 && key_len < 30) &&
113 key_len != 30 && key_len != 38 && key_len != 46) {
114 return srtp_err_status_bad_param;
115 }
David McGrew52ed07b2006-03-16 17:11:29 +0000116
jfigus5a2b2d02014-11-19 14:34:20 -0500117 /* allocate memory a cipher of type aes_icm */
118 tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
119 pointer = (uint8_t*)crypto_alloc(tmp);
120 if (pointer == NULL) {
121 return srtp_err_status_alloc_fail;
122 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000123
jfigus5a2b2d02014-11-19 14:34:20 -0500124 /* set pointers */
125 *c = (cipher_t*)pointer;
126 switch (key_len) {
127 case 46:
128 (*c)->algorithm = AES_256_ICM;
129 break;
130 case 38:
131 (*c)->algorithm = AES_192_ICM;
132 break;
133 default:
134 (*c)->algorithm = AES_128_ICM;
135 break;
136 }
137 (*c)->type = &srtp_aes_icm;
138 (*c)->state = pointer + sizeof(cipher_t);
Cullen Jennings235513a2005-09-21 22:51:36 +0000139
jfigus5a2b2d02014-11-19 14:34:20 -0500140 /* set key size */
141 (*c)->key_len = key_len;
Cullen Jennings235513a2005-09-21 22:51:36 +0000142
jfigus5a2b2d02014-11-19 14:34:20 -0500143 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000144}
145
jfigus5a2b2d02014-11-19 14:34:20 -0500146srtp_err_status_t srtp_aes_icm_alloc (cipher_t **c, int key_len, int forIsmacryp)
147{
148 return srtp_aes_icm_alloc_ismacryp(c, key_len, 0);
David McGrew52ed07b2006-03-16 17:11:29 +0000149}
150
jfigus5a2b2d02014-11-19 14:34:20 -0500151srtp_err_status_t srtp_aes_icm_dealloc (cipher_t *c)
152{
153 /* zeroize entire state*/
154 octet_string_set_to_zero((uint8_t*)c,
155 sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
Cullen Jennings235513a2005-09-21 22:51:36 +0000156
jfigus5a2b2d02014-11-19 14:34:20 -0500157 /* free memory */
158 crypto_free(c);
Cullen Jennings235513a2005-09-21 22:51:36 +0000159
jfigus5a2b2d02014-11-19 14:34:20 -0500160 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000161}
162
163
164/*
165 * aes_icm_context_init(...) initializes the aes_icm_context
166 * using the value in key[].
167 *
jfigus5a2b2d02014-11-19 14:34:20 -0500168 * the key is the secret key
Cullen Jennings235513a2005-09-21 22:51:36 +0000169 *
170 * the salt is unpredictable (but not necessarily secret) data which
171 * randomizes the starting point in the keystream
172 */
173
jfigus5a2b2d02014-11-19 14:34:20 -0500174srtp_err_status_t srtp_aes_icm_context_init (aes_icm_ctx_t *c, const uint8_t *key, int key_len)
175{
176 srtp_err_status_t status;
177 int base_key_len, copy_len;
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000178
jfigus5a2b2d02014-11-19 14:34:20 -0500179 if (key_len > 16 && key_len < 30) { /* Ismacryp */
180 base_key_len = 16;
181 } else if (key_len == 30 || key_len == 38 || key_len == 46) {
182 base_key_len = key_len - 14;
183 } else{
184 return srtp_err_status_bad_param;
185 }
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000186
jfigus5a2b2d02014-11-19 14:34:20 -0500187 /*
188 * set counter and initial values to 'offset' value, being careful not to
189 * go past the end of the key buffer
190 */
Jonathan Lennox507c03f2010-05-20 00:54:50 +0000191 v128_set_to_zero(&c->counter);
192 v128_set_to_zero(&c->offset);
Cullen Jennings235513a2005-09-21 22:51:36 +0000193
jfigus5a2b2d02014-11-19 14:34:20 -0500194 copy_len = key_len - base_key_len;
195 /* force last two octets of the offset to be left zero (for srtp compatibility) */
196 if (copy_len > 14) {
197 copy_len = 14;
198 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000199
jfigus5a2b2d02014-11-19 14:34:20 -0500200 memcpy(&c->counter, key + base_key_len, copy_len);
201 memcpy(&c->offset, key + base_key_len, copy_len);
202
203 debug_print(srtp_mod_aes_icm,
204 "key: %s", srtp_octet_string_hex_string(key, base_key_len));
205 debug_print(srtp_mod_aes_icm,
206 "offset: %s", v128_hex_string(&c->offset));
207
208 /* expand key */
209 status = srtp_aes_expand_encryption_key(key, base_key_len, &c->expanded_key);
210 if (status) {
211 v128_set_to_zero(&c->counter);
212 v128_set_to_zero(&c->offset);
213 return status;
214 }
215
216 /* indicate that the keystream_buffer is empty */
217 c->bytes_in_buffer = 0;
218
219 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000220}
221
222/*
223 * aes_icm_set_octet(c, i) sets the counter of the context which it is
224 * passed so that the next octet of keystream that will be generated
225 * is the ith octet
226 */
227
jfigus5a2b2d02014-11-19 14:34:20 -0500228srtp_err_status_t srtp_aes_icm_set_octet (aes_icm_ctx_t *c, uint64_t octet_num)
229{
Cullen Jennings235513a2005-09-21 22:51:36 +0000230
Marcus Sundberg417469e2005-10-02 20:27:47 +0000231#ifdef NO_64BIT_MATH
jfigus5a2b2d02014-11-19 14:34:20 -0500232 int tail_num = low32(octet_num) & 0x0f;
233 /* 64-bit right-shift 4 */
234 uint64_t block_num = make64(high32(octet_num) >> 4,
235 ((high32(octet_num) & 0x0f) << (32 - 4)) |
236 (low32(octet_num) >> 4));
David McGrewfec49dd2005-09-23 19:34:11 +0000237#else
jfigus5a2b2d02014-11-19 14:34:20 -0500238 int tail_num = (int)(octet_num % 16);
239 uint64_t block_num = octet_num / 16;
David McGrewfec49dd2005-09-23 19:34:11 +0000240#endif
Cullen Jennings235513a2005-09-21 22:51:36 +0000241
jfigus5a2b2d02014-11-19 14:34:20 -0500242
243 /* set counter value */
244 /* FIX - There's no way this is correct */
245 c->counter.v64[0] = c->offset.v64[0];
Marcus Sundberg417469e2005-10-02 20:27:47 +0000246#ifdef NO_64BIT_MATH
jfigus5a2b2d02014-11-19 14:34:20 -0500247 c->counter.v64[0] = make64(high32(c->offset.v64[0]) ^ high32(block_num),
248 low32(c->offset.v64[0]) ^ low32(block_num));
David McGrewfec49dd2005-09-23 19:34:11 +0000249#else
jfigus5a2b2d02014-11-19 14:34:20 -0500250 c->counter.v64[0] = c->offset.v64[0] ^ block_num;
David McGrewfec49dd2005-09-23 19:34:11 +0000251#endif
Cullen Jennings235513a2005-09-21 22:51:36 +0000252
jfigus5a2b2d02014-11-19 14:34:20 -0500253 debug_print(srtp_mod_aes_icm,
254 "set_octet: %s", v128_hex_string(&c->counter));
Cullen Jennings235513a2005-09-21 22:51:36 +0000255
jfigus5a2b2d02014-11-19 14:34:20 -0500256 /* fill keystream buffer, if needed */
257 if (tail_num) {
258 v128_copy(&c->keystream_buffer, &c->counter);
259 srtp_aes_encrypt(&c->keystream_buffer, &c->expanded_key);
260 c->bytes_in_buffer = sizeof(v128_t);
Cullen Jennings235513a2005-09-21 22:51:36 +0000261
jfigus5a2b2d02014-11-19 14:34:20 -0500262 debug_print(srtp_mod_aes_icm, "counter: %s",
263 v128_hex_string(&c->counter));
264 debug_print(srtp_mod_aes_icm, "ciphertext: %s",
265 v128_hex_string(&c->keystream_buffer));
Cullen Jennings235513a2005-09-21 22:51:36 +0000266
jfigus5a2b2d02014-11-19 14:34:20 -0500267 /* indicate number of bytes in keystream_buffer */
268 c->bytes_in_buffer = sizeof(v128_t) - tail_num;
269
270 } else {
271
272 /* indicate that keystream_buffer is empty */
273 c->bytes_in_buffer = 0;
274 }
275
276 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000277}
278
279/*
280 * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
281 * the offset
282 */
283
jfigus5a2b2d02014-11-19 14:34:20 -0500284srtp_err_status_t srtp_aes_icm_set_iv (aes_icm_ctx_t *c, void *iv, int direction)
285{
286 v128_t nonce;
Jaap Keuter4d8430a2014-11-07 00:13:10 +0100287
jfigus5a2b2d02014-11-19 14:34:20 -0500288 /* set nonce (for alignment) */
289 v128_copy_octet_string(&nonce, iv);
Cullen Jennings235513a2005-09-21 22:51:36 +0000290
jfigus5a2b2d02014-11-19 14:34:20 -0500291 debug_print(srtp_mod_aes_icm,
292 "setting iv: %s", v128_hex_string(&nonce));
Cullen Jennings235513a2005-09-21 22:51:36 +0000293
jfigus5a2b2d02014-11-19 14:34:20 -0500294 v128_xor(&c->counter, &c->offset, &nonce);
Cullen Jennings235513a2005-09-21 22:51:36 +0000295
jfigus5a2b2d02014-11-19 14:34:20 -0500296 debug_print(srtp_mod_aes_icm,
297 "set_counter: %s", v128_hex_string(&c->counter));
298
299 /* indicate that the keystream_buffer is empty */
300 c->bytes_in_buffer = 0;
301
302 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000303}
304
305
306
307/*
308 * aes_icm_advance(...) refills the keystream_buffer and
309 * advances the block index of the sicm_context forward by one
310 *
311 * this is an internal, hopefully inlined function
312 */
Cullen Jennings235513a2005-09-21 22:51:36 +0000313
jfigus5a2b2d02014-11-19 14:34:20 -0500314static inline void srtp_aes_icm_advance_ismacryp (aes_icm_ctx_t *c, uint8_t forIsmacryp)
315{
316 /* fill buffer with new keystream */
317 v128_copy(&c->keystream_buffer, &c->counter);
318 srtp_aes_encrypt(&c->keystream_buffer, &c->expanded_key);
319 c->bytes_in_buffer = sizeof(v128_t);
David McGrew52ed07b2006-03-16 17:11:29 +0000320
jfigus5a2b2d02014-11-19 14:34:20 -0500321 debug_print(srtp_mod_aes_icm, "counter: %s",
322 v128_hex_string(&c->counter));
323 debug_print(srtp_mod_aes_icm, "ciphertext: %s",
324 v128_hex_string(&c->keystream_buffer));
325
326 /* clock counter forward */
327
328 if (forIsmacryp) {
329 uint32_t temp;
330 //alex's clock counter forward
331 temp = ntohl(c->counter.v32[3]);
332 c->counter.v32[3] = htonl(++temp);
333 } else {
334 if (!++(c->counter.v8[15])) {
335 ++(c->counter.v8[14]);
336 }
337 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000338}
339
David McGrew52ed07b2006-03-16 17:11:29 +0000340/*e
Cullen Jennings235513a2005-09-21 22:51:36 +0000341 * icm_encrypt deals with the following cases:
342 *
343 * bytes_to_encr < bytes_in_buffer
344 * - add keystream into data
345 *
346 * bytes_to_encr > bytes_in_buffer
347 * - add keystream into data until keystream_buffer is depleted
348 * - loop over blocks, filling keystream_buffer and then
349 * adding keystream into data
jfigus5a2b2d02014-11-19 14:34:20 -0500350 * - fill buffer then add in remaining (< 16) bytes of keystream
Cullen Jennings235513a2005-09-21 22:51:36 +0000351 */
352
jfigus5a2b2d02014-11-19 14:34:20 -0500353srtp_err_status_t srtp_aes_icm_encrypt_ismacryp (aes_icm_ctx_t *c,
354 unsigned char *buf, unsigned int *enc_len,
355 int forIsmacryp)
356{
357 unsigned int bytes_to_encr = *enc_len;
358 unsigned int i;
359 uint32_t *b;
Cullen Jennings235513a2005-09-21 22:51:36 +0000360
jfigus5a2b2d02014-11-19 14:34:20 -0500361 /* check that there's enough segment left but not for ismacryp*/
362 if (!forIsmacryp && (bytes_to_encr + htons(c->counter.v16[7])) > 0xffff) {
363 return srtp_err_status_terminus;
364 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000365
jfigus5a2b2d02014-11-19 14:34:20 -0500366 debug_print(srtp_mod_aes_icm, "block index: %d",
367 htons(c->counter.v16[7]));
368 if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000369
jfigus5a2b2d02014-11-19 14:34:20 -0500370 /* deal with odd case of small bytes_to_encr */
371 for (i = (sizeof(v128_t) - c->bytes_in_buffer);
372 i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++) {
373 *buf++ ^= c->keystream_buffer.v8[i];
374 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000375
jfigus5a2b2d02014-11-19 14:34:20 -0500376 c->bytes_in_buffer -= bytes_to_encr;
Cullen Jennings235513a2005-09-21 22:51:36 +0000377
jfigus5a2b2d02014-11-19 14:34:20 -0500378 /* return now to avoid the main loop */
379 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000380
jfigus5a2b2d02014-11-19 14:34:20 -0500381 } else {
Cullen Jennings235513a2005-09-21 22:51:36 +0000382
jfigus5a2b2d02014-11-19 14:34:20 -0500383 /* encrypt bytes until the remaining data is 16-byte aligned */
384 for (i = (sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++) {
385 *buf++ ^= c->keystream_buffer.v8[i];
386 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000387
jfigus5a2b2d02014-11-19 14:34:20 -0500388 bytes_to_encr -= c->bytes_in_buffer;
389 c->bytes_in_buffer = 0;
Cullen Jennings235513a2005-09-21 22:51:36 +0000390
jfigus5a2b2d02014-11-19 14:34:20 -0500391 }
392
393 /* now loop over entire 16-byte blocks of keystream */
394 for (i = 0; i < (bytes_to_encr / sizeof(v128_t)); i++) {
395
396 /* fill buffer with new keystream */
397 srtp_aes_icm_advance_ismacryp(c, forIsmacryp);
398
399 /*
400 * add keystream into the data buffer (this would be a lot faster
401 * if we could assume 32-bit alignment!)
402 */
Cullen Jennings235513a2005-09-21 22:51:36 +0000403
404#if ALIGN_32
jfigus5a2b2d02014-11-19 14:34:20 -0500405 b = (uint32_t*)buf;
406 *b++ ^= c->keystream_buffer.v32[0];
407 *b++ ^= c->keystream_buffer.v32[1];
408 *b++ ^= c->keystream_buffer.v32[2];
409 *b++ ^= c->keystream_buffer.v32[3];
410 buf = (uint8_t*)b;
411#else
412 if ((((unsigned long)buf) & 0x03) != 0) {
413 *buf++ ^= c->keystream_buffer.v8[0];
414 *buf++ ^= c->keystream_buffer.v8[1];
415 *buf++ ^= c->keystream_buffer.v8[2];
416 *buf++ ^= c->keystream_buffer.v8[3];
417 *buf++ ^= c->keystream_buffer.v8[4];
418 *buf++ ^= c->keystream_buffer.v8[5];
419 *buf++ ^= c->keystream_buffer.v8[6];
420 *buf++ ^= c->keystream_buffer.v8[7];
421 *buf++ ^= c->keystream_buffer.v8[8];
422 *buf++ ^= c->keystream_buffer.v8[9];
423 *buf++ ^= c->keystream_buffer.v8[10];
424 *buf++ ^= c->keystream_buffer.v8[11];
425 *buf++ ^= c->keystream_buffer.v8[12];
426 *buf++ ^= c->keystream_buffer.v8[13];
427 *buf++ ^= c->keystream_buffer.v8[14];
428 *buf++ ^= c->keystream_buffer.v8[15];
429 } else {
430 b = (uint32_t*)buf;
431 *b++ ^= c->keystream_buffer.v32[0];
432 *b++ ^= c->keystream_buffer.v32[1];
433 *b++ ^= c->keystream_buffer.v32[2];
434 *b++ ^= c->keystream_buffer.v32[3];
435 buf = (uint8_t*)b;
436 }
437#endif /* #if ALIGN_32 */
438
Cullen Jennings235513a2005-09-21 22:51:36 +0000439 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000440
jfigus5a2b2d02014-11-19 14:34:20 -0500441 /* if there is a tail end of the data, process it */
442 if ((bytes_to_encr & 0xf) != 0) {
Cullen Jennings235513a2005-09-21 22:51:36 +0000443
jfigus5a2b2d02014-11-19 14:34:20 -0500444 /* fill buffer with new keystream */
445 srtp_aes_icm_advance_ismacryp(c, forIsmacryp);
Cullen Jennings235513a2005-09-21 22:51:36 +0000446
jfigus5a2b2d02014-11-19 14:34:20 -0500447 for (i = 0; i < (bytes_to_encr & 0xf); i++) {
448 *buf++ ^= c->keystream_buffer.v8[i];
449 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000450
jfigus5a2b2d02014-11-19 14:34:20 -0500451 /* reset the keystream buffer size to right value */
452 c->bytes_in_buffer = sizeof(v128_t) - i;
453 } else {
454
455 /* no tail, so just reset the keystream buffer size to zero */
456 c->bytes_in_buffer = 0;
457
458 }
459
460 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000461}
462
jfigus5a2b2d02014-11-19 14:34:20 -0500463srtp_err_status_t srtp_aes_icm_encrypt (aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len)
464{
465 return srtp_aes_icm_encrypt_ismacryp(c, buf, enc_len, 0);
David McGrew52ed07b2006-03-16 17:11:29 +0000466}
467
jfigus5a2b2d02014-11-19 14:34:20 -0500468srtp_err_status_t srtp_aes_icm_output (aes_icm_ctx_t *c, uint8_t *buffer, unsigned int num_octets_to_output)
469{
470 unsigned int len = num_octets_to_output;
471
472 /* zeroize the buffer */
473 octet_string_set_to_zero(buffer, num_octets_to_output);
474
475 /* exor keystream into buffer */
476 return srtp_aes_icm_encrypt(c, buffer, &len);
Cullen Jennings235513a2005-09-21 22:51:36 +0000477}
478
jfigus5a2b2d02014-11-19 14:34:20 -0500479uint16_t srtp_aes_icm_bytes_encrypted (aes_icm_ctx_t *c)
480{
Rich Rodriguez29b152e2014-07-01 06:01:33 +0000481 return htons(c->counter.v16[7]);
482}
Cullen Jennings235513a2005-09-21 22:51:36 +0000483
jfigus5a2b2d02014-11-19 14:34:20 -0500484char srtp_aes_icm_description[] = "aes integer counter mode";
Cullen Jennings235513a2005-09-21 22:51:36 +0000485
jfigus5a2b2d02014-11-19 14:34:20 -0500486uint8_t srtp_aes_icm_test_case_0_key[30] = {
487 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
488 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
489 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
490 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
Cullen Jennings235513a2005-09-21 22:51:36 +0000491};
492
jfigus5a2b2d02014-11-19 14:34:20 -0500493uint8_t srtp_aes_icm_test_case_0_nonce[16] = {
494 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Cullen Jennings235513a2005-09-21 22:51:36 +0000496};
497
jfigus5a2b2d02014-11-19 14:34:20 -0500498uint8_t srtp_aes_icm_test_case_0_plaintext[32] = {
499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Cullen Jennings235513a2005-09-21 22:51:36 +0000503};
504
jfigus5a2b2d02014-11-19 14:34:20 -0500505uint8_t srtp_aes_icm_test_case_0_ciphertext[32] = {
506 0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
507 0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
508 0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
509 0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
Cullen Jennings235513a2005-09-21 22:51:36 +0000510};
511
jfigus5a2b2d02014-11-19 14:34:20 -0500512cipher_test_case_t srtp_aes_icm_test_case_0 = {
513 30, /* octets in key */
514 srtp_aes_icm_test_case_0_key, /* key */
515 srtp_aes_icm_test_case_0_nonce, /* packet index */
516 32, /* octets in plaintext */
517 srtp_aes_icm_test_case_0_plaintext, /* plaintext */
518 32, /* octets in ciphertext */
519 srtp_aes_icm_test_case_0_ciphertext, /* ciphertext */
520 0,
521 NULL,
522 0,
523 NULL /* pointer to next testcase */
Cullen Jennings235513a2005-09-21 22:51:36 +0000524};
525
jfigus5a2b2d02014-11-19 14:34:20 -0500526uint8_t srtp_aes_icm_test_case_1_key[46] = {
527 0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
528 0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
529 0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82,
530 0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98,
531 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
532 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000533};
534
jfigus5a2b2d02014-11-19 14:34:20 -0500535uint8_t srtp_aes_icm_test_case_1_nonce[16] = {
536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000538};
539
jfigus5a2b2d02014-11-19 14:34:20 -0500540uint8_t srtp_aes_icm_test_case_1_plaintext[32] = {
541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000545};
546
jfigus5a2b2d02014-11-19 14:34:20 -0500547uint8_t srtp_aes_icm_test_case_1_ciphertext[32] = {
548 0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
549 0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
550 0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
551 0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000552};
553
jfigus5a2b2d02014-11-19 14:34:20 -0500554cipher_test_case_t srtp_aes_icm_test_case_1 = {
555 46, /* octets in key */
556 srtp_aes_icm_test_case_1_key, /* key */
557 srtp_aes_icm_test_case_1_nonce, /* packet index */
558 32, /* octets in plaintext */
559 srtp_aes_icm_test_case_1_plaintext, /* plaintext */
560 32, /* octets in ciphertext */
561 srtp_aes_icm_test_case_1_ciphertext, /* ciphertext */
562 0,
563 NULL,
564 0,
565 &srtp_aes_icm_test_case_0 /* pointer to next testcase */
Jonathan Lennox5df951a2010-05-20 20:55:54 +0000566};
567
568
David McGrewfec49dd2005-09-23 19:34:11 +0000569
Cullen Jennings235513a2005-09-21 22:51:36 +0000570/*
571 * note: the encrypt function is identical to the decrypt function
572 */
573
jfigus5a2b2d02014-11-19 14:34:20 -0500574cipher_type_t srtp_aes_icm = {
575 (cipher_alloc_func_t)srtp_aes_icm_alloc,
576 (cipher_dealloc_func_t)srtp_aes_icm_dealloc,
577 (cipher_init_func_t)srtp_aes_icm_context_init,
578 (cipher_set_aad_func_t)0,
579 (cipher_encrypt_func_t)srtp_aes_icm_encrypt,
580 (cipher_decrypt_func_t)srtp_aes_icm_encrypt,
581 (cipher_set_iv_func_t)srtp_aes_icm_set_iv,
582 (cipher_get_tag_func_t)0,
583 (char*)srtp_aes_icm_description,
584 (cipher_test_case_t*)&srtp_aes_icm_test_case_1,
585 (debug_module_t*)&srtp_mod_aes_icm,
586 (srtp_cipher_type_id_t)AES_ICM
Cullen Jennings235513a2005-09-21 22:51:36 +0000587};
588