1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/srtp/src/crypto/cipher/aes_icm.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,567 @@ 1.4 +/* 1.5 + * aes_icm.c 1.6 + * 1.7 + * AES Integer Counter Mode 1.8 + * 1.9 + * David A. McGrew 1.10 + * Cisco Systems, Inc. 1.11 + */ 1.12 + 1.13 +/* 1.14 + * 1.15 + * Copyright (c) 2001-2006, Cisco Systems, Inc. 1.16 + * All rights reserved. 1.17 + * 1.18 + * Redistribution and use in source and binary forms, with or without 1.19 + * modification, are permitted provided that the following conditions 1.20 + * are met: 1.21 + * 1.22 + * Redistributions of source code must retain the above copyright 1.23 + * notice, this list of conditions and the following disclaimer. 1.24 + * 1.25 + * Redistributions in binary form must reproduce the above 1.26 + * copyright notice, this list of conditions and the following 1.27 + * disclaimer in the documentation and/or other materials provided 1.28 + * with the distribution. 1.29 + * 1.30 + * Neither the name of the Cisco Systems, Inc. nor the names of its 1.31 + * contributors may be used to endorse or promote products derived 1.32 + * from this software without specific prior written permission. 1.33 + * 1.34 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.35 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.36 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 1.37 + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 1.38 + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 1.39 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 1.40 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 1.41 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1.42 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 1.43 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.44 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 1.45 + * OF THE POSSIBILITY OF SUCH DAMAGE. 1.46 + * 1.47 + */ 1.48 + 1.49 + 1.50 +#define ALIGN_32 0 1.51 + 1.52 +#include "aes_icm.h" 1.53 +#include "alloc.h" 1.54 + 1.55 + 1.56 +debug_module_t mod_aes_icm = { 1.57 + 0, /* debugging is off by default */ 1.58 + "aes icm" /* printable module name */ 1.59 +}; 1.60 + 1.61 +/* 1.62 + * integer counter mode works as follows: 1.63 + * 1.64 + * 16 bits 1.65 + * <-----> 1.66 + * +------+------+------+------+------+------+------+------+ 1.67 + * | nonce | pakcet index | ctr |---+ 1.68 + * +------+------+------+------+------+------+------+------+ | 1.69 + * | 1.70 + * +------+------+------+------+------+------+------+------+ v 1.71 + * | salt |000000|->(+) 1.72 + * +------+------+------+------+------+------+------+------+ | 1.73 + * | 1.74 + * +---------+ 1.75 + * | encrypt | 1.76 + * +---------+ 1.77 + * | 1.78 + * +------+------+------+------+------+------+------+------+ | 1.79 + * | keystream block |<--+ 1.80 + * +------+------+------+------+------+------+------+------+ 1.81 + * 1.82 + * All fields are big-endian 1.83 + * 1.84 + * ctr is the block counter, which increments from zero for 1.85 + * each packet (16 bits wide) 1.86 + * 1.87 + * packet index is distinct for each packet (48 bits wide) 1.88 + * 1.89 + * nonce can be distinct across many uses of the same key, or 1.90 + * can be a fixed value per key, or can be per-packet randomness 1.91 + * (64 bits) 1.92 + * 1.93 + */ 1.94 + 1.95 +err_status_t 1.96 +aes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) { 1.97 + extern cipher_type_t aes_icm; 1.98 + uint8_t *pointer; 1.99 + int tmp; 1.100 + 1.101 + debug_print(mod_aes_icm, 1.102 + "allocating cipher with key length %d", key_len); 1.103 + 1.104 + /* 1.105 + * Ismacryp, for example, uses 16 byte key + 8 byte 1.106 + * salt so this function is called with key_len = 24. 1.107 + * The check for key_len = 30/38/46 does not apply. Our usage 1.108 + * of aes functions with key_len = values other than 30 1.109 + * has not broken anything. Don't know what would be the 1.110 + * effect of skipping this check for srtp in general. 1.111 + */ 1.112 + if (!(forIsmacryp && key_len > 16 && key_len < 30) && 1.113 + key_len != 30 && key_len != 38 && key_len != 46) 1.114 + return err_status_bad_param; 1.115 + 1.116 + /* allocate memory a cipher of type aes_icm */ 1.117 + tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t)); 1.118 + pointer = (uint8_t*)crypto_alloc(tmp); 1.119 + if (pointer == NULL) 1.120 + return err_status_alloc_fail; 1.121 + 1.122 + /* set pointers */ 1.123 + *c = (cipher_t *)pointer; 1.124 + (*c)->type = &aes_icm; 1.125 + (*c)->state = pointer + sizeof(cipher_t); 1.126 + 1.127 + /* increment ref_count */ 1.128 + aes_icm.ref_count++; 1.129 + 1.130 + /* set key size */ 1.131 + (*c)->key_len = key_len; 1.132 + 1.133 + return err_status_ok; 1.134 +} 1.135 + 1.136 +err_status_t aes_icm_alloc(cipher_t **c, int key_len, int forIsmacryp) { 1.137 + return aes_icm_alloc_ismacryp(c, key_len, 0); 1.138 +} 1.139 + 1.140 +err_status_t 1.141 +aes_icm_dealloc(cipher_t *c) { 1.142 + extern cipher_type_t aes_icm; 1.143 + 1.144 + /* zeroize entire state*/ 1.145 + octet_string_set_to_zero((uint8_t *)c, 1.146 + sizeof(aes_icm_ctx_t) + sizeof(cipher_t)); 1.147 + 1.148 + /* free memory */ 1.149 + crypto_free(c); 1.150 + 1.151 + /* decrement ref_count */ 1.152 + aes_icm.ref_count--; 1.153 + 1.154 + return err_status_ok; 1.155 +} 1.156 + 1.157 + 1.158 +/* 1.159 + * aes_icm_context_init(...) initializes the aes_icm_context 1.160 + * using the value in key[]. 1.161 + * 1.162 + * the key is the secret key 1.163 + * 1.164 + * the salt is unpredictable (but not necessarily secret) data which 1.165 + * randomizes the starting point in the keystream 1.166 + */ 1.167 + 1.168 +err_status_t 1.169 +aes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key, int key_len) { 1.170 + err_status_t status; 1.171 + int base_key_len, copy_len; 1.172 + 1.173 + if (key_len > 16 && key_len < 30) /* Ismacryp */ 1.174 + base_key_len = 16; 1.175 + else if (key_len == 30 || key_len == 38 || key_len == 46) 1.176 + base_key_len = key_len - 14; 1.177 + else 1.178 + return err_status_bad_param; 1.179 + 1.180 + /* 1.181 + * set counter and initial values to 'offset' value, being careful not to 1.182 + * go past the end of the key buffer 1.183 + */ 1.184 + v128_set_to_zero(&c->counter); 1.185 + v128_set_to_zero(&c->offset); 1.186 + 1.187 + copy_len = key_len - base_key_len; 1.188 + /* force last two octets of the offset to be left zero (for srtp compatibility) */ 1.189 + if (copy_len > 14) 1.190 + copy_len = 14; 1.191 + 1.192 + memcpy(&c->counter, key + base_key_len, copy_len); 1.193 + memcpy(&c->offset, key + base_key_len, copy_len); 1.194 + 1.195 + debug_print(mod_aes_icm, 1.196 + "key: %s", octet_string_hex_string(key, base_key_len)); 1.197 + debug_print(mod_aes_icm, 1.198 + "offset: %s", v128_hex_string(&c->offset)); 1.199 + 1.200 + /* expand key */ 1.201 + status = aes_expand_encryption_key(key, base_key_len, &c->expanded_key); 1.202 + if (status) { 1.203 + v128_set_to_zero(&c->counter); 1.204 + v128_set_to_zero(&c->offset); 1.205 + return status; 1.206 + } 1.207 + 1.208 + /* indicate that the keystream_buffer is empty */ 1.209 + c->bytes_in_buffer = 0; 1.210 + 1.211 + return err_status_ok; 1.212 +} 1.213 + 1.214 +/* 1.215 + * aes_icm_set_octet(c, i) sets the counter of the context which it is 1.216 + * passed so that the next octet of keystream that will be generated 1.217 + * is the ith octet 1.218 + */ 1.219 + 1.220 +err_status_t 1.221 +aes_icm_set_octet(aes_icm_ctx_t *c, 1.222 + uint64_t octet_num) { 1.223 + 1.224 +#ifdef NO_64BIT_MATH 1.225 + int tail_num = low32(octet_num) & 0x0f; 1.226 + /* 64-bit right-shift 4 */ 1.227 + uint64_t block_num = make64(high32(octet_num) >> 4, 1.228 + ((high32(octet_num) & 0x0f)<<(32-4)) | 1.229 + (low32(octet_num) >> 4)); 1.230 +#else 1.231 + int tail_num = (int)(octet_num % 16); 1.232 + uint64_t block_num = octet_num / 16; 1.233 +#endif 1.234 + 1.235 + 1.236 + /* set counter value */ 1.237 + /* FIX - There's no way this is correct */ 1.238 + c->counter.v64[0] = c->offset.v64[0]; 1.239 +#ifdef NO_64BIT_MATH 1.240 + c->counter.v64[0] = make64(high32(c->offset.v64[0]) ^ high32(block_num), 1.241 + low32(c->offset.v64[0]) ^ low32(block_num)); 1.242 +#else 1.243 + c->counter.v64[0] = c->offset.v64[0] ^ block_num; 1.244 +#endif 1.245 + 1.246 + debug_print(mod_aes_icm, 1.247 + "set_octet: %s", v128_hex_string(&c->counter)); 1.248 + 1.249 + /* fill keystream buffer, if needed */ 1.250 + if (tail_num) { 1.251 + v128_copy(&c->keystream_buffer, &c->counter); 1.252 + aes_encrypt(&c->keystream_buffer, &c->expanded_key); 1.253 + c->bytes_in_buffer = sizeof(v128_t); 1.254 + 1.255 + debug_print(mod_aes_icm, "counter: %s", 1.256 + v128_hex_string(&c->counter)); 1.257 + debug_print(mod_aes_icm, "ciphertext: %s", 1.258 + v128_hex_string(&c->keystream_buffer)); 1.259 + 1.260 + /* indicate number of bytes in keystream_buffer */ 1.261 + c->bytes_in_buffer = sizeof(v128_t) - tail_num; 1.262 + 1.263 + } else { 1.264 + 1.265 + /* indicate that keystream_buffer is empty */ 1.266 + c->bytes_in_buffer = 0; 1.267 + } 1.268 + 1.269 + return err_status_ok; 1.270 +} 1.271 + 1.272 +/* 1.273 + * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with 1.274 + * the offset 1.275 + */ 1.276 + 1.277 +err_status_t 1.278 +aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) { 1.279 + v128_t *nonce = (v128_t *) iv; 1.280 + 1.281 + debug_print(mod_aes_icm, 1.282 + "setting iv: %s", v128_hex_string(nonce)); 1.283 + 1.284 + v128_xor(&c->counter, &c->offset, nonce); 1.285 + 1.286 + debug_print(mod_aes_icm, 1.287 + "set_counter: %s", v128_hex_string(&c->counter)); 1.288 + 1.289 + /* indicate that the keystream_buffer is empty */ 1.290 + c->bytes_in_buffer = 0; 1.291 + 1.292 + return err_status_ok; 1.293 +} 1.294 + 1.295 + 1.296 + 1.297 +/* 1.298 + * aes_icm_advance(...) refills the keystream_buffer and 1.299 + * advances the block index of the sicm_context forward by one 1.300 + * 1.301 + * this is an internal, hopefully inlined function 1.302 + */ 1.303 + 1.304 +static inline void 1.305 +aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) { 1.306 + /* fill buffer with new keystream */ 1.307 + v128_copy(&c->keystream_buffer, &c->counter); 1.308 + aes_encrypt(&c->keystream_buffer, &c->expanded_key); 1.309 + c->bytes_in_buffer = sizeof(v128_t); 1.310 + 1.311 + debug_print(mod_aes_icm, "counter: %s", 1.312 + v128_hex_string(&c->counter)); 1.313 + debug_print(mod_aes_icm, "ciphertext: %s", 1.314 + v128_hex_string(&c->keystream_buffer)); 1.315 + 1.316 + /* clock counter forward */ 1.317 + 1.318 + if (forIsmacryp) { 1.319 + uint32_t temp; 1.320 + //alex's clock counter forward 1.321 + temp = ntohl(c->counter.v32[3]); 1.322 + c->counter.v32[3] = htonl(++temp); 1.323 + } else { 1.324 + if (!++(c->counter.v8[15])) 1.325 + ++(c->counter.v8[14]); 1.326 + } 1.327 +} 1.328 + 1.329 +static inline void aes_icm_advance(aes_icm_ctx_t *c) { 1.330 + aes_icm_advance_ismacryp(c, 0); 1.331 +} 1.332 + 1.333 + 1.334 +/*e 1.335 + * icm_encrypt deals with the following cases: 1.336 + * 1.337 + * bytes_to_encr < bytes_in_buffer 1.338 + * - add keystream into data 1.339 + * 1.340 + * bytes_to_encr > bytes_in_buffer 1.341 + * - add keystream into data until keystream_buffer is depleted 1.342 + * - loop over blocks, filling keystream_buffer and then 1.343 + * adding keystream into data 1.344 + * - fill buffer then add in remaining (< 16) bytes of keystream 1.345 + */ 1.346 + 1.347 +err_status_t 1.348 +aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c, 1.349 + unsigned char *buf, unsigned int *enc_len, 1.350 + int forIsmacryp) { 1.351 + unsigned int bytes_to_encr = *enc_len; 1.352 + unsigned int i; 1.353 + uint32_t *b; 1.354 + 1.355 + /* check that there's enough segment left but not for ismacryp*/ 1.356 + if (!forIsmacryp && (bytes_to_encr + htons(c->counter.v16[7])) > 0xffff) 1.357 + return err_status_terminus; 1.358 + 1.359 + debug_print(mod_aes_icm, "block index: %d", 1.360 + htons(c->counter.v16[7])); 1.361 + if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) { 1.362 + 1.363 + /* deal with odd case of small bytes_to_encr */ 1.364 + for (i = (sizeof(v128_t) - c->bytes_in_buffer); 1.365 + i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++) 1.366 + { 1.367 + *buf++ ^= c->keystream_buffer.v8[i]; 1.368 + } 1.369 + 1.370 + c->bytes_in_buffer -= bytes_to_encr; 1.371 + 1.372 + /* return now to avoid the main loop */ 1.373 + return err_status_ok; 1.374 + 1.375 + } else { 1.376 + 1.377 + /* encrypt bytes until the remaining data is 16-byte aligned */ 1.378 + for (i=(sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++) 1.379 + *buf++ ^= c->keystream_buffer.v8[i]; 1.380 + 1.381 + bytes_to_encr -= c->bytes_in_buffer; 1.382 + c->bytes_in_buffer = 0; 1.383 + 1.384 + } 1.385 + 1.386 + /* now loop over entire 16-byte blocks of keystream */ 1.387 + for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) { 1.388 + 1.389 + /* fill buffer with new keystream */ 1.390 + aes_icm_advance_ismacryp(c, forIsmacryp); 1.391 + 1.392 + /* 1.393 + * add keystream into the data buffer (this would be a lot faster 1.394 + * if we could assume 32-bit alignment!) 1.395 + */ 1.396 + 1.397 +#if ALIGN_32 1.398 + b = (uint32_t *)buf; 1.399 + *b++ ^= c->keystream_buffer.v32[0]; 1.400 + *b++ ^= c->keystream_buffer.v32[1]; 1.401 + *b++ ^= c->keystream_buffer.v32[2]; 1.402 + *b++ ^= c->keystream_buffer.v32[3]; 1.403 + buf = (uint8_t *)b; 1.404 +#else 1.405 + if ((((unsigned long) buf) & 0x03) != 0) { 1.406 + *buf++ ^= c->keystream_buffer.v8[0]; 1.407 + *buf++ ^= c->keystream_buffer.v8[1]; 1.408 + *buf++ ^= c->keystream_buffer.v8[2]; 1.409 + *buf++ ^= c->keystream_buffer.v8[3]; 1.410 + *buf++ ^= c->keystream_buffer.v8[4]; 1.411 + *buf++ ^= c->keystream_buffer.v8[5]; 1.412 + *buf++ ^= c->keystream_buffer.v8[6]; 1.413 + *buf++ ^= c->keystream_buffer.v8[7]; 1.414 + *buf++ ^= c->keystream_buffer.v8[8]; 1.415 + *buf++ ^= c->keystream_buffer.v8[9]; 1.416 + *buf++ ^= c->keystream_buffer.v8[10]; 1.417 + *buf++ ^= c->keystream_buffer.v8[11]; 1.418 + *buf++ ^= c->keystream_buffer.v8[12]; 1.419 + *buf++ ^= c->keystream_buffer.v8[13]; 1.420 + *buf++ ^= c->keystream_buffer.v8[14]; 1.421 + *buf++ ^= c->keystream_buffer.v8[15]; 1.422 + } else { 1.423 + b = (uint32_t *)buf; 1.424 + *b++ ^= c->keystream_buffer.v32[0]; 1.425 + *b++ ^= c->keystream_buffer.v32[1]; 1.426 + *b++ ^= c->keystream_buffer.v32[2]; 1.427 + *b++ ^= c->keystream_buffer.v32[3]; 1.428 + buf = (uint8_t *)b; 1.429 + } 1.430 +#endif /* #if ALIGN_32 */ 1.431 + 1.432 + } 1.433 + 1.434 + /* if there is a tail end of the data, process it */ 1.435 + if ((bytes_to_encr & 0xf) != 0) { 1.436 + 1.437 + /* fill buffer with new keystream */ 1.438 + aes_icm_advance_ismacryp(c, forIsmacryp); 1.439 + 1.440 + for (i=0; i < (bytes_to_encr & 0xf); i++) 1.441 + *buf++ ^= c->keystream_buffer.v8[i]; 1.442 + 1.443 + /* reset the keystream buffer size to right value */ 1.444 + c->bytes_in_buffer = sizeof(v128_t) - i; 1.445 + } else { 1.446 + 1.447 + /* no tail, so just reset the keystream buffer size to zero */ 1.448 + c->bytes_in_buffer = 0; 1.449 + 1.450 + } 1.451 + 1.452 + return err_status_ok; 1.453 +} 1.454 + 1.455 +err_status_t 1.456 +aes_icm_encrypt(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) { 1.457 + return aes_icm_encrypt_ismacryp(c, buf, enc_len, 0); 1.458 +} 1.459 + 1.460 +err_status_t 1.461 +aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output) { 1.462 + unsigned int len = num_octets_to_output; 1.463 + 1.464 + /* zeroize the buffer */ 1.465 + octet_string_set_to_zero(buffer, num_octets_to_output); 1.466 + 1.467 + /* exor keystream into buffer */ 1.468 + return aes_icm_encrypt(c, buffer, &len); 1.469 +} 1.470 + 1.471 + 1.472 +char 1.473 +aes_icm_description[] = "aes integer counter mode"; 1.474 + 1.475 +uint8_t aes_icm_test_case_0_key[30] = { 1.476 + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 1.477 + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, 1.478 + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 1.479 + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd 1.480 +}; 1.481 + 1.482 +uint8_t aes_icm_test_case_0_nonce[16] = { 1.483 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.484 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 1.485 +}; 1.486 + 1.487 +uint8_t aes_icm_test_case_0_plaintext[32] = { 1.488 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.489 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.490 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.491 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.492 +}; 1.493 + 1.494 +uint8_t aes_icm_test_case_0_ciphertext[32] = { 1.495 + 0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80, 1.496 + 0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4, 1.497 + 0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7, 1.498 + 0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab 1.499 +}; 1.500 + 1.501 +cipher_test_case_t aes_icm_test_case_0 = { 1.502 + 30, /* octets in key */ 1.503 + aes_icm_test_case_0_key, /* key */ 1.504 + aes_icm_test_case_0_nonce, /* packet index */ 1.505 + 32, /* octets in plaintext */ 1.506 + aes_icm_test_case_0_plaintext, /* plaintext */ 1.507 + 32, /* octets in ciphertext */ 1.508 + aes_icm_test_case_0_ciphertext, /* ciphertext */ 1.509 + NULL /* pointer to next testcase */ 1.510 +}; 1.511 + 1.512 +uint8_t aes_icm_test_case_1_key[46] = { 1.513 + 0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70, 1.514 + 0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92, 1.515 + 0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82, 1.516 + 0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98, 1.517 + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 1.518 + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd 1.519 +}; 1.520 + 1.521 +uint8_t aes_icm_test_case_1_nonce[16] = { 1.522 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.523 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 1.524 +}; 1.525 + 1.526 +uint8_t aes_icm_test_case_1_plaintext[32] = { 1.527 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.528 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.529 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.530 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.531 +}; 1.532 + 1.533 +uint8_t aes_icm_test_case_1_ciphertext[32] = { 1.534 + 0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25, 1.535 + 0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4, 1.536 + 0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6, 1.537 + 0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac 1.538 +}; 1.539 + 1.540 +cipher_test_case_t aes_icm_test_case_1 = { 1.541 + 46, /* octets in key */ 1.542 + aes_icm_test_case_1_key, /* key */ 1.543 + aes_icm_test_case_1_nonce, /* packet index */ 1.544 + 32, /* octets in plaintext */ 1.545 + aes_icm_test_case_1_plaintext, /* plaintext */ 1.546 + 32, /* octets in ciphertext */ 1.547 + aes_icm_test_case_1_ciphertext, /* ciphertext */ 1.548 + &aes_icm_test_case_0 /* pointer to next testcase */ 1.549 +}; 1.550 + 1.551 + 1.552 + 1.553 +/* 1.554 + * note: the encrypt function is identical to the decrypt function 1.555 + */ 1.556 + 1.557 +cipher_type_t aes_icm = { 1.558 + (cipher_alloc_func_t) aes_icm_alloc, 1.559 + (cipher_dealloc_func_t) aes_icm_dealloc, 1.560 + (cipher_init_func_t) aes_icm_context_init, 1.561 + (cipher_encrypt_func_t) aes_icm_encrypt, 1.562 + (cipher_decrypt_func_t) aes_icm_encrypt, 1.563 + (cipher_set_iv_func_t) aes_icm_set_iv, 1.564 + (char *) aes_icm_description, 1.565 + (int) 0, /* instance count */ 1.566 + (cipher_test_case_t *) &aes_icm_test_case_1, 1.567 + (debug_module_t *) &mod_aes_icm, 1.568 + (cipher_type_id_t) AES_ICM 1.569 +}; 1.570 +