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-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 #define ALIGN_32 0 48 49 #include "aes_icm.h" 50 #include "alloc.h" 51 52 53 debug_module_t mod_aes_icm = { 54 0, /* debugging is off by default */ 55 "aes icm" /* printable module name */ 56 }; 57 58 /* 59 * integer counter mode works as follows: 60 * 61 * 16 bits 62 * <-----> 63 * +------+------+------+------+------+------+------+------+ 64 * | nonce | pakcet index | ctr |---+ 65 * +------+------+------+------+------+------+------+------+ | 66 * | 67 * +------+------+------+------+------+------+------+------+ v 68 * | salt |000000|->(+) 69 * +------+------+------+------+------+------+------+------+ | 70 * | 71 * +---------+ 72 * | encrypt | 73 * +---------+ 74 * | 75 * +------+------+------+------+------+------+------+------+ | 76 * | keystream block |<--+ 77 * +------+------+------+------+------+------+------+------+ 78 * 79 * All fields are big-endian 80 * 81 * ctr is the block counter, which increments from zero for 82 * each packet (16 bits wide) 83 * 84 * packet index is distinct for each packet (48 bits wide) 85 * 86 * nonce can be distinct across many uses of the same key, or 87 * can be a fixed value per key, or can be per-packet randomness 88 * (64 bits) 89 * 90 */ 91 92 err_status_t 93 aes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) { 94 extern cipher_type_t aes_icm; 95 uint8_t *pointer; 96 int tmp; 97 98 debug_print(mod_aes_icm, 99 "allocating cipher with key length %d", key_len); 100 101 /* 102 * Ismacryp, for example, uses 16 byte key + 8 byte 103 * salt so this function is called with key_len = 24. 104 * The check for key_len = 30 does not apply. Our usage 105 * of aes functions with key_len = values other than 30 106 * has not broken anything. Don't know what would be the 107 * effect of skipping this check for srtp in general. 108 */ 109 if (!forIsmacryp && key_len != 30) 110 return err_status_bad_param; 111 112 /* allocate memory a cipher of type aes_icm */ 113 tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t)); 114 pointer = (uint8_t*)crypto_alloc(tmp); 115 if (pointer == NULL) 116 return err_status_alloc_fail; 117 118 /* set pointers */ 119 *c = (cipher_t *)pointer; 120 (*c)->type = &aes_icm; 121 (*c)->state = pointer + sizeof(cipher_t); 122 123 /* increment ref_count */ 124 aes_icm.ref_count++; 125 126 /* set key size */ 127 (*c)->key_len = key_len; 128 129 return err_status_ok; 130 } 131 132 err_status_t aes_icm_alloc(cipher_t **c, int key_len, int forIsmacryp) { 133 return aes_icm_alloc_ismacryp(c, key_len, 0); 134 } 135 136 err_status_t 137 aes_icm_dealloc(cipher_t *c) { 138 extern cipher_type_t aes_icm; 139 140 /* zeroize entire state*/ 141 octet_string_set_to_zero((uint8_t *)c, 142 sizeof(aes_icm_ctx_t) + sizeof(cipher_t)); 143 144 /* free memory */ 145 crypto_free(c); 146 147 /* decrement ref_count */ 148 aes_icm.ref_count--; 149 150 return err_status_ok; 151 } 152 153 154 /* 155 * aes_icm_context_init(...) initializes the aes_icm_context 156 * using the value in key[]. 157 * 158 * the key is the secret key 159 * 160 * the salt is unpredictable (but not necessarily secret) data which 161 * randomizes the starting point in the keystream 162 */ 163 164 err_status_t 165 aes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key) { 166 v128_t tmp_key; 167 int i; 168 169 /* set counter and initial values to 'offset' value */ 170 /* FIX!!! this assumes the salt is at key + 16, and thus that the */ 171 /* FIX!!! cipher key length is 16! */ 172 for (i = 0; i < 14; i++) { 173 c->counter.v8[i] = key[16 + i]; 174 c->offset.v8[i] = key[16 + i]; 175 } 176 177 /* force last two octets of the offset to zero (for srtp compatibility) */ 178 c->offset.v8[14] = c->offset.v8[15] = 0; 179 c->counter.v8[14] = c->counter.v8[15] = 0; 180 181 /* set tmp_key (for alignment) */ 182 v128_copy_octet_string(&tmp_key, key); 183 184 debug_print(mod_aes_icm, 185 "key: %s", v128_hex_string(&tmp_key)); 186 debug_print(mod_aes_icm, 187 "offset: %s", v128_hex_string(&c->offset)); 188 189 /* expand key */ 190 aes_expand_encryption_key(&tmp_key, c->expanded_key); 191 192 /* indicate that the keystream_buffer is empty */ 193 c->bytes_in_buffer = 0; 194 195 return err_status_ok; 196 } 197 198 /* 199 * aes_icm_set_octet(c, i) sets the counter of the context which it is 200 * passed so that the next octet of keystream that will be generated 201 * is the ith octet 202 */ 203 204 err_status_t 205 aes_icm_set_octet(aes_icm_ctx_t *c, 206 uint64_t octet_num) { 207 208 #ifdef NO_64BIT_MATH 209 int tail_num = low32(octet_num) & 0x0f; 210 /* 64-bit right-shift 4 */ 211 uint64_t block_num = make64(high32(octet_num) >> 4, 212 ((high32(octet_num) & 0x0f)<<(32-4)) | 213 (low32(octet_num) >> 4)); 214 #else 215 int tail_num = (int)(octet_num % 16); 216 uint64_t block_num = octet_num / 16; 217 #endif 218 219 220 /* set counter value */ 221 /* FIX - There's no way this is correct */ 222 c->counter.v64[0] = c->offset.v64[0]; 223 #ifdef NO_64BIT_MATH 224 c->counter.v64[0] = make64(high32(c->offset.v64[0]) ^ high32(block_num), 225 low32(c->offset.v64[0]) ^ low32(block_num)); 226 #else 227 c->counter.v64[0] = c->offset.v64[0] ^ block_num; 228 #endif 229 230 debug_print(mod_aes_icm, 231 "set_octet: %s", v128_hex_string(&c->counter)); 232 233 /* fill keystream buffer, if needed */ 234 if (tail_num) { 235 v128_copy(&c->keystream_buffer, &c->counter); 236 aes_encrypt(&c->keystream_buffer, c->expanded_key); 237 c->bytes_in_buffer = sizeof(v128_t); 238 239 debug_print(mod_aes_icm, "counter: %s", 240 v128_hex_string(&c->counter)); 241 debug_print(mod_aes_icm, "ciphertext: %s", 242 v128_hex_string(&c->keystream_buffer)); 243 244 /* indicate number of bytes in keystream_buffer */ 245 c->bytes_in_buffer = sizeof(v128_t) - tail_num; 246 247 } else { 248 249 /* indicate that keystream_buffer is empty */ 250 c->bytes_in_buffer = 0; 251 } 252 253 return err_status_ok; 254 } 255 256 /* 257 * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with 258 * the offset 259 */ 260 261 err_status_t 262 aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) { 263 v128_t *nonce = (v128_t *) iv; 264 265 debug_print(mod_aes_icm, 266 "setting iv: %s", v128_hex_string(nonce)); 267 268 v128_xor(&c->counter, &c->offset, nonce); 269 270 debug_print(mod_aes_icm, 271 "set_counter: %s", v128_hex_string(&c->counter)); 272 273 /* indicate that the keystream_buffer is empty */ 274 c->bytes_in_buffer = 0; 275 276 return err_status_ok; 277 } 278 279 280 281 /* 282 * aes_icm_advance(...) refills the keystream_buffer and 283 * advances the block index of the sicm_context forward by one 284 * 285 * this is an internal, hopefully inlined function 286 */ 287 288 static inline void 289 aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) { 290 /* fill buffer with new keystream */ 291 v128_copy(&c->keystream_buffer, &c->counter); 292 aes_encrypt(&c->keystream_buffer, c->expanded_key); 293 c->bytes_in_buffer = sizeof(v128_t); 294 295 debug_print(mod_aes_icm, "counter: %s", 296 v128_hex_string(&c->counter)); 297 debug_print(mod_aes_icm, "ciphertext: %s", 298 v128_hex_string(&c->keystream_buffer)); 299 300 /* clock counter forward */ 301 302 if (forIsmacryp) { 303 uint32_t temp; 304 //alex's clock counter forward 305 temp = ntohl(c->counter.v32[3]); 306 c->counter.v32[3] = htonl(++temp); 307 } else { 308 if (!++(c->counter.v8[15])) 309 ++(c->counter.v8[14]); 310 } 311 } 312 313 inline void aes_icm_advance(aes_icm_ctx_t *c) { 314 aes_icm_advance_ismacryp(c, 0); 315 } 316 317 318 /*e 319 * icm_encrypt deals with the following cases: 320 * 321 * bytes_to_encr < bytes_in_buffer 322 * - add keystream into data 323 * 324 * bytes_to_encr > bytes_in_buffer 325 * - add keystream into data until keystream_buffer is depleted 326 * - loop over blocks, filling keystream_buffer and then 327 * adding keystream into data 328 * - fill buffer then add in remaining (< 16) bytes of keystream 329 */ 330 331 err_status_t 332 aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c, 333 unsigned char *buf, unsigned int *enc_len, 334 int forIsmacryp) { 335 unsigned int bytes_to_encr = *enc_len; 336 unsigned int i; 337 uint32_t *b; 338 339 /* check that there's enough segment left but not for ismacryp*/ 340 if (!forIsmacryp && (bytes_to_encr + htons(c->counter.v16[7])) > 0xffff) 341 return err_status_terminus; 342 343 debug_print(mod_aes_icm, "block index: %d", 344 htons(c->counter.v16[7])); 345 if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) { 346 347 /* deal with odd case of small bytes_to_encr */ 348 for (i = (sizeof(v128_t) - c->bytes_in_buffer); 349 i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++) 350 { 351 *buf++ ^= c->keystream_buffer.v8[i]; 352 } 353 354 c->bytes_in_buffer -= bytes_to_encr; 355 356 /* return now to avoid the main loop */ 357 return err_status_ok; 358 359 } else { 360 361 /* encrypt bytes until the remaining data is 16-byte aligned */ 362 for (i=(sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++) 363 *buf++ ^= c->keystream_buffer.v8[i]; 364 365 bytes_to_encr -= c->bytes_in_buffer; 366 c->bytes_in_buffer = 0; 367 368 } 369 370 /* now loop over entire 16-byte blocks of keystream */ 371 for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) { 372 373 /* fill buffer with new keystream */ 374 aes_icm_advance_ismacryp(c, forIsmacryp); 375 376 /* 377 * add keystream into the data buffer (this would be a lot faster 378 * if we could assume 32-bit alignment!) 379 */ 380 381 #if ALIGN_32 382 b = (uint32_t *)buf; 383 *b++ ^= c->keystream_buffer.v32[0]; 384 *b++ ^= c->keystream_buffer.v32[1]; 385 *b++ ^= c->keystream_buffer.v32[2]; 386 *b++ ^= c->keystream_buffer.v32[3]; 387 buf = (uint8_t *)b; 388 #else 389 if ((((unsigned long) buf) & 0x03) != 0) { 390 *buf++ ^= c->keystream_buffer.v8[0]; 391 *buf++ ^= c->keystream_buffer.v8[1]; 392 *buf++ ^= c->keystream_buffer.v8[2]; 393 *buf++ ^= c->keystream_buffer.v8[3]; 394 *buf++ ^= c->keystream_buffer.v8[4]; 395 *buf++ ^= c->keystream_buffer.v8[5]; 396 *buf++ ^= c->keystream_buffer.v8[6]; 397 *buf++ ^= c->keystream_buffer.v8[7]; 398 *buf++ ^= c->keystream_buffer.v8[8]; 399 *buf++ ^= c->keystream_buffer.v8[9]; 400 *buf++ ^= c->keystream_buffer.v8[10]; 401 *buf++ ^= c->keystream_buffer.v8[11]; 402 *buf++ ^= c->keystream_buffer.v8[12]; 403 *buf++ ^= c->keystream_buffer.v8[13]; 404 *buf++ ^= c->keystream_buffer.v8[14]; 405 *buf++ ^= c->keystream_buffer.v8[15]; 406 } else { 407 b = (uint32_t *)buf; 408 *b++ ^= c->keystream_buffer.v32[0]; 409 *b++ ^= c->keystream_buffer.v32[1]; 410 *b++ ^= c->keystream_buffer.v32[2]; 411 *b++ ^= c->keystream_buffer.v32[3]; 412 buf = (uint8_t *)b; 413 } 414 #endif /* #if ALIGN_32 */ 415 416 } 417 418 /* if there is a tail end of the data, process it */ 419 if ((bytes_to_encr & 0xf) != 0) { 420 421 /* fill buffer with new keystream */ 422 aes_icm_advance_ismacryp(c, forIsmacryp); 423 424 for (i=0; i < (bytes_to_encr & 0xf); i++) 425 *buf++ ^= c->keystream_buffer.v8[i]; 426 427 /* reset the keystream buffer size to right value */ 428 c->bytes_in_buffer = sizeof(v128_t) - i; 429 } else { 430 431 /* no tail, so just reset the keystream buffer size to zero */ 432 c->bytes_in_buffer = 0; 433 434 } 435 436 return err_status_ok; 437 } 438 439 err_status_t 440 aes_icm_encrypt(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) { 441 return aes_icm_encrypt_ismacryp(c, buf, enc_len, 0); 442 } 443 444 err_status_t 445 aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output) { 446 unsigned int len = num_octets_to_output; 447 448 /* zeroize the buffer */ 449 octet_string_set_to_zero(buffer, num_octets_to_output); 450 451 /* exor keystream into buffer */ 452 return aes_icm_encrypt(c, buffer, &len); 453 } 454 455 456 char 457 aes_icm_description[] = "aes integer counter mode"; 458 459 uint8_t aes_icm_test_case_0_key[30] = { 460 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 461 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, 462 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 463 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd 464 }; 465 466 uint8_t aes_icm_test_case_0_nonce[16] = { 467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 469 }; 470 471 uint8_t aes_icm_test_case_0_plaintext[32] = { 472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 473 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 474 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 476 }; 477 478 uint8_t aes_icm_test_case_0_ciphertext[32] = { 479 0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80, 480 0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4, 481 0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7, 482 0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab 483 }; 484 485 cipher_test_case_t aes_icm_test_case_0 = { 486 30, /* octets in key */ 487 aes_icm_test_case_0_key, /* key */ 488 aes_icm_test_case_0_nonce, /* packet index */ 489 32, /* octets in plaintext */ 490 aes_icm_test_case_0_plaintext, /* plaintext */ 491 32, /* octets in ciphertext */ 492 aes_icm_test_case_0_ciphertext, /* ciphertext */ 493 NULL /* pointer to next testcase */ 494 }; 495 496 497 /* 498 * note: the encrypt function is identical to the decrypt function 499 */ 500 501 cipher_type_t aes_icm = { 502 (cipher_alloc_func_t) aes_icm_alloc, 503 (cipher_dealloc_func_t) aes_icm_dealloc, 504 (cipher_init_func_t) aes_icm_context_init, 505 (cipher_encrypt_func_t) aes_icm_encrypt, 506 (cipher_decrypt_func_t) aes_icm_encrypt, 507 (cipher_set_iv_func_t) aes_icm_set_iv, 508 (char *) aes_icm_description, 509 (int) 0, /* instance count */ 510 (cipher_test_case_t *) &aes_icm_test_case_0, 511 (debug_module_t *) &mod_aes_icm 512 }; 513