1 /* ====================================================================
2 * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 */
49
50 #include <openssl/crypto.h>
51 #include "modes_lcl.h"
52 #include <string.h>
53
54 #ifndef MODES_DEBUG
55 # ifndef NDEBUG
56 # define NDEBUG
57 # endif
58 #endif
59 #include <assert.h>
60
61 /*
62 * First you setup M and L parameters and pass the key schedule. This is
63 * called once per session setup...
64 */
CRYPTO_ccm128_init(CCM128_CONTEXT * ctx,unsigned int M,unsigned int L,void * key,block128_f block)65 void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
66 unsigned int M, unsigned int L, void *key,
67 block128_f block)
68 {
69 memset(ctx->nonce.c, 0, sizeof(ctx->nonce.c));
70 ctx->nonce.c[0] = ((u8)(L - 1) & 7) | (u8)(((M - 2) / 2) & 7) << 3;
71 ctx->blocks = 0;
72 ctx->block = block;
73 ctx->key = key;
74 }
75
76 /* !!! Following interfaces are to be called *once* per packet !!! */
77
78 /* Then you setup per-message nonce and pass the length of the message */
CRYPTO_ccm128_setiv(CCM128_CONTEXT * ctx,const unsigned char * nonce,size_t nlen,size_t mlen)79 int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
80 const unsigned char *nonce, size_t nlen, size_t mlen)
81 {
82 unsigned int L = ctx->nonce.c[0] & 7; /* the L parameter */
83
84 if (nlen < (14 - L))
85 return -1; /* nonce is too short */
86
87 if (sizeof(mlen) == 8 && L >= 3) {
88 ctx->nonce.c[8] = (u8)(mlen >> (56 % (sizeof(mlen) * 8)));
89 ctx->nonce.c[9] = (u8)(mlen >> (48 % (sizeof(mlen) * 8)));
90 ctx->nonce.c[10] = (u8)(mlen >> (40 % (sizeof(mlen) * 8)));
91 ctx->nonce.c[11] = (u8)(mlen >> (32 % (sizeof(mlen) * 8)));
92 } else
93 ctx->nonce.u[1] = 0;
94
95 ctx->nonce.c[12] = (u8)(mlen >> 24);
96 ctx->nonce.c[13] = (u8)(mlen >> 16);
97 ctx->nonce.c[14] = (u8)(mlen >> 8);
98 ctx->nonce.c[15] = (u8)mlen;
99
100 ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */
101 memcpy(&ctx->nonce.c[1], nonce, 14 - L);
102
103 return 0;
104 }
105
106 /* Then you pass additional authentication data, this is optional */
CRYPTO_ccm128_aad(CCM128_CONTEXT * ctx,const unsigned char * aad,size_t alen)107 void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
108 const unsigned char *aad, size_t alen)
109 {
110 unsigned int i;
111 block128_f block = ctx->block;
112
113 if (alen == 0)
114 return;
115
116 ctx->nonce.c[0] |= 0x40; /* set Adata flag */
117 (*block) (ctx->nonce.c, ctx->cmac.c, ctx->key), ctx->blocks++;
118
119 if (alen < (0x10000 - 0x100)) {
120 ctx->cmac.c[0] ^= (u8)(alen >> 8);
121 ctx->cmac.c[1] ^= (u8)alen;
122 i = 2;
123 } else if (sizeof(alen) == 8
124 && alen >= (size_t)1 << (32 % (sizeof(alen) * 8))) {
125 ctx->cmac.c[0] ^= 0xFF;
126 ctx->cmac.c[1] ^= 0xFF;
127 ctx->cmac.c[2] ^= (u8)(alen >> (56 % (sizeof(alen) * 8)));
128 ctx->cmac.c[3] ^= (u8)(alen >> (48 % (sizeof(alen) * 8)));
129 ctx->cmac.c[4] ^= (u8)(alen >> (40 % (sizeof(alen) * 8)));
130 ctx->cmac.c[5] ^= (u8)(alen >> (32 % (sizeof(alen) * 8)));
131 ctx->cmac.c[6] ^= (u8)(alen >> 24);
132 ctx->cmac.c[7] ^= (u8)(alen >> 16);
133 ctx->cmac.c[8] ^= (u8)(alen >> 8);
134 ctx->cmac.c[9] ^= (u8)alen;
135 i = 10;
136 } else {
137 ctx->cmac.c[0] ^= 0xFF;
138 ctx->cmac.c[1] ^= 0xFE;
139 ctx->cmac.c[2] ^= (u8)(alen >> 24);
140 ctx->cmac.c[3] ^= (u8)(alen >> 16);
141 ctx->cmac.c[4] ^= (u8)(alen >> 8);
142 ctx->cmac.c[5] ^= (u8)alen;
143 i = 6;
144 }
145
146 do {
147 for (; i < 16 && alen; ++i, ++aad, --alen)
148 ctx->cmac.c[i] ^= *aad;
149 (*block) (ctx->cmac.c, ctx->cmac.c, ctx->key), ctx->blocks++;
150 i = 0;
151 } while (alen);
152 }
153
154 /* Finally you encrypt or decrypt the message */
155
156 /*
157 * counter part of nonce may not be larger than L*8 bits, L is not larger
158 * than 8, therefore 64-bit counter...
159 */
ctr64_inc(unsigned char * counter)160 static void ctr64_inc(unsigned char *counter)
161 {
162 unsigned int n = 8;
163 u8 c;
164
165 counter += 8;
166 do {
167 --n;
168 c = counter[n];
169 ++c;
170 counter[n] = c;
171 if (c)
172 return;
173 } while (n);
174 }
175
CRYPTO_ccm128_encrypt(CCM128_CONTEXT * ctx,const unsigned char * inp,unsigned char * out,size_t len)176 int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
177 const unsigned char *inp, unsigned char *out,
178 size_t len)
179 {
180 size_t n;
181 unsigned int i, L;
182 unsigned char flags0 = ctx->nonce.c[0];
183 block128_f block = ctx->block;
184 void *key = ctx->key;
185 union {
186 u64 u[2];
187 u8 c[16];
188 } scratch;
189
190 if (!(flags0 & 0x40))
191 (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
192
193 ctx->nonce.c[0] = L = flags0 & 7;
194 for (n = 0, i = 15 - L; i < 15; ++i) {
195 n |= ctx->nonce.c[i];
196 ctx->nonce.c[i] = 0;
197 n <<= 8;
198 }
199 n |= ctx->nonce.c[15]; /* reconstructed length */
200 ctx->nonce.c[15] = 1;
201
202 if (n != len)
203 return -1; /* length mismatch */
204
205 ctx->blocks += ((len + 15) >> 3) | 1;
206 if (ctx->blocks > (U64(1) << 61))
207 return -2; /* too much data */
208
209 while (len >= 16) {
210 #if defined(STRICT_ALIGNMENT)
211 union {
212 u64 u[2];
213 u8 c[16];
214 } temp;
215
216 memcpy(temp.c, inp, 16);
217 ctx->cmac.u[0] ^= temp.u[0];
218 ctx->cmac.u[1] ^= temp.u[1];
219 #else
220 ctx->cmac.u[0] ^= ((u64 *)inp)[0];
221 ctx->cmac.u[1] ^= ((u64 *)inp)[1];
222 #endif
223 (*block) (ctx->cmac.c, ctx->cmac.c, key);
224 (*block) (ctx->nonce.c, scratch.c, key);
225 ctr64_inc(ctx->nonce.c);
226 #if defined(STRICT_ALIGNMENT)
227 temp.u[0] ^= scratch.u[0];
228 temp.u[1] ^= scratch.u[1];
229 memcpy(out, temp.c, 16);
230 #else
231 ((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0];
232 ((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1];
233 #endif
234 inp += 16;
235 out += 16;
236 len -= 16;
237 }
238
239 if (len) {
240 for (i = 0; i < len; ++i)
241 ctx->cmac.c[i] ^= inp[i];
242 (*block) (ctx->cmac.c, ctx->cmac.c, key);
243 (*block) (ctx->nonce.c, scratch.c, key);
244 for (i = 0; i < len; ++i)
245 out[i] = scratch.c[i] ^ inp[i];
246 }
247
248 for (i = 15 - L; i < 16; ++i)
249 ctx->nonce.c[i] = 0;
250
251 (*block) (ctx->nonce.c, scratch.c, key);
252 ctx->cmac.u[0] ^= scratch.u[0];
253 ctx->cmac.u[1] ^= scratch.u[1];
254
255 ctx->nonce.c[0] = flags0;
256
257 return 0;
258 }
259
CRYPTO_ccm128_decrypt(CCM128_CONTEXT * ctx,const unsigned char * inp,unsigned char * out,size_t len)260 int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
261 const unsigned char *inp, unsigned char *out,
262 size_t len)
263 {
264 size_t n;
265 unsigned int i, L;
266 unsigned char flags0 = ctx->nonce.c[0];
267 block128_f block = ctx->block;
268 void *key = ctx->key;
269 union {
270 u64 u[2];
271 u8 c[16];
272 } scratch;
273
274 if (!(flags0 & 0x40))
275 (*block) (ctx->nonce.c, ctx->cmac.c, key);
276
277 ctx->nonce.c[0] = L = flags0 & 7;
278 for (n = 0, i = 15 - L; i < 15; ++i) {
279 n |= ctx->nonce.c[i];
280 ctx->nonce.c[i] = 0;
281 n <<= 8;
282 }
283 n |= ctx->nonce.c[15]; /* reconstructed length */
284 ctx->nonce.c[15] = 1;
285
286 if (n != len)
287 return -1;
288
289 while (len >= 16) {
290 #if defined(STRICT_ALIGNMENT)
291 union {
292 u64 u[2];
293 u8 c[16];
294 } temp;
295 #endif
296 (*block) (ctx->nonce.c, scratch.c, key);
297 ctr64_inc(ctx->nonce.c);
298 #if defined(STRICT_ALIGNMENT)
299 memcpy(temp.c, inp, 16);
300 ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]);
301 ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]);
302 memcpy(out, scratch.c, 16);
303 #else
304 ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]);
305 ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]);
306 #endif
307 (*block) (ctx->cmac.c, ctx->cmac.c, key);
308
309 inp += 16;
310 out += 16;
311 len -= 16;
312 }
313
314 if (len) {
315 (*block) (ctx->nonce.c, scratch.c, key);
316 for (i = 0; i < len; ++i)
317 ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
318 (*block) (ctx->cmac.c, ctx->cmac.c, key);
319 }
320
321 for (i = 15 - L; i < 16; ++i)
322 ctx->nonce.c[i] = 0;
323
324 (*block) (ctx->nonce.c, scratch.c, key);
325 ctx->cmac.u[0] ^= scratch.u[0];
326 ctx->cmac.u[1] ^= scratch.u[1];
327
328 ctx->nonce.c[0] = flags0;
329
330 return 0;
331 }
332
ctr64_add(unsigned char * counter,size_t inc)333 static void ctr64_add(unsigned char *counter, size_t inc)
334 {
335 size_t n = 8, val = 0;
336
337 counter += 8;
338 do {
339 --n;
340 val += counter[n] + (inc & 0xff);
341 counter[n] = (unsigned char)val;
342 val >>= 8; /* carry bit */
343 inc >>= 8;
344 } while (n && (inc || val));
345 }
346
CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT * ctx,const unsigned char * inp,unsigned char * out,size_t len,ccm128_f stream)347 int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
348 const unsigned char *inp, unsigned char *out,
349 size_t len, ccm128_f stream)
350 {
351 size_t n;
352 unsigned int i, L;
353 unsigned char flags0 = ctx->nonce.c[0];
354 block128_f block = ctx->block;
355 void *key = ctx->key;
356 union {
357 u64 u[2];
358 u8 c[16];
359 } scratch;
360
361 if (!(flags0 & 0x40))
362 (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
363
364 ctx->nonce.c[0] = L = flags0 & 7;
365 for (n = 0, i = 15 - L; i < 15; ++i) {
366 n |= ctx->nonce.c[i];
367 ctx->nonce.c[i] = 0;
368 n <<= 8;
369 }
370 n |= ctx->nonce.c[15]; /* reconstructed length */
371 ctx->nonce.c[15] = 1;
372
373 if (n != len)
374 return -1; /* length mismatch */
375
376 ctx->blocks += ((len + 15) >> 3) | 1;
377 if (ctx->blocks > (U64(1) << 61))
378 return -2; /* too much data */
379
380 if ((n = len / 16)) {
381 (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
382 n *= 16;
383 inp += n;
384 out += n;
385 len -= n;
386 if (len)
387 ctr64_add(ctx->nonce.c, n / 16);
388 }
389
390 if (len) {
391 for (i = 0; i < len; ++i)
392 ctx->cmac.c[i] ^= inp[i];
393 (*block) (ctx->cmac.c, ctx->cmac.c, key);
394 (*block) (ctx->nonce.c, scratch.c, key);
395 for (i = 0; i < len; ++i)
396 out[i] = scratch.c[i] ^ inp[i];
397 }
398
399 for (i = 15 - L; i < 16; ++i)
400 ctx->nonce.c[i] = 0;
401
402 (*block) (ctx->nonce.c, scratch.c, key);
403 ctx->cmac.u[0] ^= scratch.u[0];
404 ctx->cmac.u[1] ^= scratch.u[1];
405
406 ctx->nonce.c[0] = flags0;
407
408 return 0;
409 }
410
CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT * ctx,const unsigned char * inp,unsigned char * out,size_t len,ccm128_f stream)411 int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
412 const unsigned char *inp, unsigned char *out,
413 size_t len, ccm128_f stream)
414 {
415 size_t n;
416 unsigned int i, L;
417 unsigned char flags0 = ctx->nonce.c[0];
418 block128_f block = ctx->block;
419 void *key = ctx->key;
420 union {
421 u64 u[2];
422 u8 c[16];
423 } scratch;
424
425 if (!(flags0 & 0x40))
426 (*block) (ctx->nonce.c, ctx->cmac.c, key);
427
428 ctx->nonce.c[0] = L = flags0 & 7;
429 for (n = 0, i = 15 - L; i < 15; ++i) {
430 n |= ctx->nonce.c[i];
431 ctx->nonce.c[i] = 0;
432 n <<= 8;
433 }
434 n |= ctx->nonce.c[15]; /* reconstructed length */
435 ctx->nonce.c[15] = 1;
436
437 if (n != len)
438 return -1;
439
440 if ((n = len / 16)) {
441 (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
442 n *= 16;
443 inp += n;
444 out += n;
445 len -= n;
446 if (len)
447 ctr64_add(ctx->nonce.c, n / 16);
448 }
449
450 if (len) {
451 (*block) (ctx->nonce.c, scratch.c, key);
452 for (i = 0; i < len; ++i)
453 ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
454 (*block) (ctx->cmac.c, ctx->cmac.c, key);
455 }
456
457 for (i = 15 - L; i < 16; ++i)
458 ctx->nonce.c[i] = 0;
459
460 (*block) (ctx->nonce.c, scratch.c, key);
461 ctx->cmac.u[0] ^= scratch.u[0];
462 ctx->cmac.u[1] ^= scratch.u[1];
463
464 ctx->nonce.c[0] = flags0;
465
466 return 0;
467 }
468
CRYPTO_ccm128_tag(CCM128_CONTEXT * ctx,unsigned char * tag,size_t len)469 size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
470 {
471 unsigned int M = (ctx->nonce.c[0] >> 3) & 7; /* the M parameter */
472
473 M *= 2;
474 M += 2;
475 if (len < M)
476 return 0;
477 memcpy(tag, ctx->cmac.c, M);
478 return M;
479 }
480