netwerk/srtp/src/crypto/cipher/aes_icm.c

changeset 0
6474c204b198
     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 +

mercurial