1386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*
2386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * aes_icm.c
3386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
4386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * AES Integer Counter Mode
5386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
6386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * David A. McGrew
7386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Cisco Systems, Inc.
8386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
9386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
10386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*
11386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
12386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Copyright (c) 2001-2006, Cisco Systems, Inc.
13386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * All rights reserved.
14386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
15386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * Redistribution and use in source and binary forms, with or without
16386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * modification, are permitted provided that the following conditions
17386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * are met:
18386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
19386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   Redistributions of source code must retain the above copyright
20386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   notice, this list of conditions and the following disclaimer.
21386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
22386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   Redistributions in binary form must reproduce the above
23386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   copyright notice, this list of conditions and the following
24386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   disclaimer in the documentation and/or other materials provided
25386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   with the distribution.
26386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
27386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   Neither the name of the Cisco Systems, Inc. nor the names of its
28386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   contributors may be used to endorse or promote products derived
29386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *   from this software without specific prior written permission.
30386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
31386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
34386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
35386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
36386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
38386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
42386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * OF THE POSSIBILITY OF SUCH DAMAGE.
43386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
44386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
45386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
46386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
47386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#define ALIGN_32 0
48386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
49386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "aes_icm.h"
50386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#include "alloc.h"
51386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
52386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
53386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaridebug_module_t mod_aes_icm = {
54386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0,                 /* debugging is off by default */
55386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  "aes icm"          /* printable module name       */
56386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari};
57386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
58386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*
59386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * integer counter mode works as follows:
60386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
61386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * 16 bits
62386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * <----->
63386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * +------+------+------+------+------+------+------+------+
64386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * |           nonce           |    pakcet index    |  ctr |---+
65386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * +------+------+------+------+------+------+------+------+   |
66386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *                                                             |
67386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * +------+------+------+------+------+------+------+------+   v
68386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * |                      salt                      |000000|->(+)
69386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * +------+------+------+------+------+------+------+------+   |
70386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *                                                             |
71386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *                                                        +---------+
72386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *							  | encrypt |
73386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *							  +---------+
74386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *							       |
75386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * +------+------+------+------+------+------+------+------+   |
76386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * |                    keystream block                    |<--+
77386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * +------+------+------+------+------+------+------+------+
78386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
79386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * All fields are big-endian
80386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
81386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * ctr is the block counter, which increments from zero for
82386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * each packet (16 bits wide)
83386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
84386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * packet index is distinct for each packet (48 bits wide)
85386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
86386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * nonce can be distinct across many uses of the same key, or
87386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * can be a fixed value per key, or can be per-packet randomness
88386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * (64 bits)
89386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
90386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
91386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
92386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t
93386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) {
94386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  extern cipher_type_t aes_icm;
95386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  uint8_t *pointer;
96386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  int tmp;
97386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
98386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  debug_print(mod_aes_icm,
99386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari            "allocating cipher with key length %d", key_len);
100386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
101386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /*
102386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari   * Ismacryp, for example, uses 16 byte key + 8 byte
103386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari   * salt  so this function is called with key_len = 24.
104386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari   * The check for key_len = 30 does not apply. Our usage
105386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari   * of aes functions with key_len = values other than 30
106386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari   * has not broken anything. Don't know what would be the
107386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari   * effect of skipping this check for srtp in general.
108386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari   */
109386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (!forIsmacryp && key_len != 30)
110386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    return err_status_bad_param;
111386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
112386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* allocate memory a cipher of type aes_icm */
113386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
114386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  pointer = (uint8_t*)crypto_alloc(tmp);
115386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (pointer == NULL)
116386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    return err_status_alloc_fail;
117386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
118386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* set pointers */
119386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  *c = (cipher_t *)pointer;
120386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  (*c)->type = &aes_icm;
121386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  (*c)->state = pointer + sizeof(cipher_t);
122386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
123386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* increment ref_count */
124386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  aes_icm.ref_count++;
125386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
126386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* set key size        */
127386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  (*c)->key_len = key_len;
128386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
129386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  return err_status_ok;
130386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
131386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
132386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t aes_icm_alloc(cipher_t **c, int key_len, int forIsmacryp) {
133386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  return aes_icm_alloc_ismacryp(c, key_len, 0);
134386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
135386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
136386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t
137386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_icm_dealloc(cipher_t *c) {
138386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  extern cipher_type_t aes_icm;
139386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
140386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* zeroize entire state*/
141386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  octet_string_set_to_zero((uint8_t *)c,
142386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari			   sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
143386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
144386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* free memory */
145386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  crypto_free(c);
146386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
147386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* decrement ref_count */
148386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  aes_icm.ref_count--;
149386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
150386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  return err_status_ok;
151386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
152386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
153386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
154386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*
155386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * aes_icm_context_init(...) initializes the aes_icm_context
156386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * using the value in key[].
157386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
158386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the key is the secret key
159386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
160386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the salt is unpredictable (but not necessarily secret) data which
161386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * randomizes the starting point in the keystream
162386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
163386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
164386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t
165386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key) {
166386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  v128_t tmp_key;
167386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  int i;
168386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
169386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* set counter and initial values to 'offset' value */
170386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* FIX!!! this assumes the salt is at key + 16, and thus that the */
171386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* FIX!!! cipher key length is 16! */
172386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  for (i = 0; i < 14; i++) {
173386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    c->counter.v8[i] = key[16 + i];
174386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    c->offset.v8[i] = key[16 + i];
175386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
176386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
177386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* force last two octets of the offset to zero (for srtp compatibility) */
178386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  c->offset.v8[14] = c->offset.v8[15] = 0;
179386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  c->counter.v8[14] = c->counter.v8[15] = 0;
180386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
181386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* set tmp_key (for alignment) */
182386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  v128_copy_octet_string(&tmp_key, key);
183386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
184386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  debug_print(mod_aes_icm,
185386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      "key:  %s", v128_hex_string(&tmp_key));
186386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  debug_print(mod_aes_icm,
187386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      "offset: %s", v128_hex_string(&c->offset));
188386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
189386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* expand key */
190386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  aes_expand_encryption_key(&tmp_key, c->expanded_key);
191386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
192386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* indicate that the keystream_buffer is empty */
193386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  c->bytes_in_buffer = 0;
194386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
195386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  return err_status_ok;
196386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
197386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
198386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*
199386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * aes_icm_set_octet(c, i) sets the counter of the context which it is
200386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * passed so that the next octet of keystream that will be generated
201386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * is the ith octet
202386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
203386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
204386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t
205386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_icm_set_octet(aes_icm_ctx_t *c,
206386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari		  uint64_t octet_num) {
207386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
208386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef NO_64BIT_MATH
209386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  int tail_num       = low32(octet_num) & 0x0f;
210386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* 64-bit right-shift 4 */
211386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  uint64_t block_num = make64(high32(octet_num) >> 4,
212386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari							  ((high32(octet_num) & 0x0f)<<(32-4)) |
213386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari							   (low32(octet_num) >> 4));
214386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else
215386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  int tail_num       = (int)(octet_num % 16);
216386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  uint64_t block_num = octet_num / 16;
217386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif
218386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
219386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
220386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* set counter value */
221386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* FIX - There's no way this is correct */
222386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  c->counter.v64[0] = c->offset.v64[0];
223386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#ifdef NO_64BIT_MATH
224386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  c->counter.v64[0] = make64(high32(c->offset.v64[0]) ^ high32(block_num),
225386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari							 low32(c->offset.v64[0])  ^ low32(block_num));
226386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else
227386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  c->counter.v64[0] = c->offset.v64[0] ^ block_num;
228386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif
229386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
230386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  debug_print(mod_aes_icm,
231386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      "set_octet: %s", v128_hex_string(&c->counter));
232386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
233386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* fill keystream buffer, if needed */
234386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (tail_num) {
235386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    v128_copy(&c->keystream_buffer, &c->counter);
236386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    aes_encrypt(&c->keystream_buffer, c->expanded_key);
237386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    c->bytes_in_buffer = sizeof(v128_t);
238386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
239386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    debug_print(mod_aes_icm, "counter:    %s",
240386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      v128_hex_string(&c->counter));
241386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    debug_print(mod_aes_icm, "ciphertext: %s",
242386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      v128_hex_string(&c->keystream_buffer));
243386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
244386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /*  indicate number of bytes in keystream_buffer  */
245386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    c->bytes_in_buffer = sizeof(v128_t) - tail_num;
246386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
247386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  } else {
248386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
249386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* indicate that keystream_buffer is empty */
250386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    c->bytes_in_buffer = 0;
251386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
252386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
253386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  return err_status_ok;
254386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
255386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
256386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*
257386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
258386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * the offset
259386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
260386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
261386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t
262386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_icm_set_iv(aes_icm_ctx_t *c, void *iv) {
263386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  v128_t *nonce = (v128_t *) iv;
264386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
265386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  debug_print(mod_aes_icm,
266386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      "setting iv: %s", v128_hex_string(nonce));
267386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
268386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  v128_xor(&c->counter, &c->offset, nonce);
269386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
270386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  debug_print(mod_aes_icm,
271386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      "set_counter: %s", v128_hex_string(&c->counter));
272386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
273386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* indicate that the keystream_buffer is empty */
274386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  c->bytes_in_buffer = 0;
275386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
276386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  return err_status_ok;
277386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
278386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
279386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
280386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
281386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*
282386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * aes_icm_advance(...) refills the keystream_buffer and
283386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * advances the block index of the sicm_context forward by one
284386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
285386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * this is an internal, hopefully inlined function
286386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
287386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
288386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaristatic inline void
289386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) {
290386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* fill buffer with new keystream */
291386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  v128_copy(&c->keystream_buffer, &c->counter);
292386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  aes_encrypt(&c->keystream_buffer, c->expanded_key);
293386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  c->bytes_in_buffer = sizeof(v128_t);
294386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
295386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  debug_print(mod_aes_icm, "counter:    %s",
296386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      v128_hex_string(&c->counter));
297386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  debug_print(mod_aes_icm, "ciphertext: %s",
298386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	      v128_hex_string(&c->keystream_buffer));
299386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
300386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* clock counter forward */
301386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
302386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (forIsmacryp) {
303386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    uint32_t temp;
304386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    //alex's clock counter forward
305386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    temp = ntohl(c->counter.v32[3]);
306386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    c->counter.v32[3] = htonl(++temp);
307386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  } else {
308386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if (!++(c->counter.v8[15]))
309386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      ++(c->counter.v8[14]);
310386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
311386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
312386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
313386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariinline void aes_icm_advance(aes_icm_ctx_t *c) {
314386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  aes_icm_advance_ismacryp(c, 0);
315386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
316386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
317386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
318386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*e
319386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * icm_encrypt deals with the following cases:
320386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
321386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * bytes_to_encr < bytes_in_buffer
322386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *  - add keystream into data
323386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *
324386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * bytes_to_encr > bytes_in_buffer
325386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *  - add keystream into data until keystream_buffer is depleted
326386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *  - loop over blocks, filling keystream_buffer and then
327386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *    adding keystream into data
328386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari *  - fill buffer then add in remaining (< 16) bytes of keystream
329386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
330386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
331386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t
332386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_icm_encrypt_ismacryp(aes_icm_ctx_t *c,
333386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari              unsigned char *buf, unsigned int *enc_len,
334386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari              int forIsmacryp) {
335386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  unsigned int bytes_to_encr = *enc_len;
336386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  unsigned int i;
337386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  uint32_t *b;
338386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
339386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* check that there's enough segment left but not for ismacryp*/
340386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (!forIsmacryp && (bytes_to_encr + htons(c->counter.v16[7])) > 0xffff)
341386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    return err_status_terminus;
342386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
343386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari debug_print(mod_aes_icm, "block index: %d",
344386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari           htons(c->counter.v16[7]));
345386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) {
346386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
347386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* deal with odd case of small bytes_to_encr */
348386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    for (i = (sizeof(v128_t) - c->bytes_in_buffer);
349386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari		 i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++)
350386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	{
351386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[i];
352386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari	}
353386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
354386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    c->bytes_in_buffer -= bytes_to_encr;
355386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
356386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* return now to avoid the main loop */
357386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    return err_status_ok;
358386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
359386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  } else {
360386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
361386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* encrypt bytes until the remaining data is 16-byte aligned */
362386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    for (i=(sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++)
363386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[i];
364386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
365386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    bytes_to_encr -= c->bytes_in_buffer;
366386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    c->bytes_in_buffer = 0;
367386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
368386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
369386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
370386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* now loop over entire 16-byte blocks of keystream */
371386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) {
372386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
373386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* fill buffer with new keystream */
374386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    aes_icm_advance_ismacryp(c, forIsmacryp);
375386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
376386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /*
377386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * add keystream into the data buffer (this would be a lot faster
378386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     * if we could assume 32-bit alignment!)
379386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari     */
380386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
381386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#if ALIGN_32
382386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    b = (uint32_t *)buf;
383386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    *b++ ^= c->keystream_buffer.v32[0];
384386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    *b++ ^= c->keystream_buffer.v32[1];
385386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    *b++ ^= c->keystream_buffer.v32[2];
386386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    *b++ ^= c->keystream_buffer.v32[3];
387386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    buf = (uint8_t *)b;
388386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#else
389386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    if ((((unsigned long) buf) & 0x03) != 0) {
390386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[0];
391386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[1];
392386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[2];
393386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[3];
394386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[4];
395386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[5];
396386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[6];
397386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[7];
398386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[8];
399386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[9];
400386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[10];
401386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[11];
402386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[12];
403386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[13];
404386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[14];
405386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[15];
406386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    } else {
407386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      b = (uint32_t *)buf;
408386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *b++ ^= c->keystream_buffer.v32[0];
409386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *b++ ^= c->keystream_buffer.v32[1];
410386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *b++ ^= c->keystream_buffer.v32[2];
411386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *b++ ^= c->keystream_buffer.v32[3];
412386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      buf = (uint8_t *)b;
413386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    }
414386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari#endif /* #if ALIGN_32 */
415386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
416386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
417386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
418386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* if there is a tail end of the data, process it */
419386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  if ((bytes_to_encr & 0xf) != 0) {
420386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
421386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* fill buffer with new keystream */
422386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    aes_icm_advance_ismacryp(c, forIsmacryp);
423386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
424386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    for (i=0; i < (bytes_to_encr & 0xf); i++)
425386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari      *buf++ ^= c->keystream_buffer.v8[i];
426386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
427386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* reset the keystream buffer size to right value */
428386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    c->bytes_in_buffer = sizeof(v128_t) - i;
429386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  } else {
430386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
431386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    /* no tail, so just reset the keystream buffer size to zero */
432386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari    c->bytes_in_buffer = 0;
433386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
434386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  }
435386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
436386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  return err_status_ok;
437386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
438386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
439386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t
440386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_icm_encrypt(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) {
441386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  return aes_icm_encrypt_ismacryp(c, buf, enc_len, 0);
442386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
443386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
444386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarierr_status_t
445386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output) {
446386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  unsigned int len = num_octets_to_output;
447386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
448386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* zeroize the buffer */
449386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  octet_string_set_to_zero(buffer, num_octets_to_output);
450386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
451386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  /* exor keystream into buffer */
452386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  return aes_icm_encrypt(c, buffer, &len);
453386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari}
454386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
455386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
456386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagarichar
457386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariaes_icm_description[] = "aes integer counter mode";
458386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
459386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariuint8_t aes_icm_test_case_0_key[30] = {
460386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
461386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
462386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
463386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
464386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari};
465386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
466386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariuint8_t aes_icm_test_case_0_nonce[16] = {
467386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
469386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari};
470386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
471386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariuint8_t aes_icm_test_case_0_plaintext[32] =  {
472386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
476386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari};
477386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
478386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagariuint8_t aes_icm_test_case_0_ciphertext[32] = {
479386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
480386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
481386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
482386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
483386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari};
484386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
485386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricipher_test_case_t aes_icm_test_case_0 = {
486386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  30,                                    /* octets in key            */
487386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  aes_icm_test_case_0_key,               /* key                      */
488386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  aes_icm_test_case_0_nonce,             /* packet index             */
489386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  32,                                    /* octets in plaintext      */
490386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  aes_icm_test_case_0_plaintext,         /* plaintext                */
491386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  32,                                    /* octets in ciphertext     */
492386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  aes_icm_test_case_0_ciphertext,        /* ciphertext               */
493386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  NULL                                   /* pointer to next testcase */
494386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari};
495386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
496386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
497386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari/*
498386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari * note: the encrypt function is identical to the decrypt function
499386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari */
500386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari
501386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagaricipher_type_t aes_icm = {
502386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  (cipher_alloc_func_t)          aes_icm_alloc,
503386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  (cipher_dealloc_func_t)        aes_icm_dealloc,
504386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  (cipher_init_func_t)           aes_icm_context_init,
505386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  (cipher_encrypt_func_t)        aes_icm_encrypt,
506386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  (cipher_decrypt_func_t)        aes_icm_encrypt,
507386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  (cipher_set_iv_func_t)         aes_icm_set_iv,
508386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  (char *)                       aes_icm_description,
509386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  (int)                          0,   /* instance count */
510386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  (cipher_test_case_t *)        &aes_icm_test_case_0,
511386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari  (debug_module_t *)            &mod_aes_icm
512386ce4d9144fc190797f4e43a31aeaf76ca2e373Param Reddappagari};
513