1/*
2 * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <string.h>
11#include <openssl/crypto.h>
12#include "crypto/modes.h"
13
14/*
15 * First you setup M and L parameters and pass the key schedule. This is
16 * called once per session setup...
17 */
18void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
19 unsigned int M, unsigned int L, void *key,
20 block128_f block)
21{
22 memset(ctx->nonce.c, 0, sizeof(ctx->nonce.c));
23 ctx->nonce.c[0] = ((u8)(L - 1) & 7) | (u8)(((M - 2) / 2) & 7) << 3;
24 ctx->blocks = 0;
25 ctx->block = block;
26 ctx->key = key;
27}
28
29/* !!! Following interfaces are to be called *once* per packet !!! */
30
31/* Then you setup per-message nonce and pass the length of the message */
32int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
33 const unsigned char *nonce, size_t nlen, size_t mlen)
34{
35 unsigned int L = ctx->nonce.c[0] & 7; /* the L parameter */
36
37 if (nlen < (14 - L))
38 return -1; /* nonce is too short */
39
40 if (sizeof(mlen) == 8 && L >= 3) {
41 ctx->nonce.c[8] = (u8)(mlen >> (56 % (sizeof(mlen) * 8)));
42 ctx->nonce.c[9] = (u8)(mlen >> (48 % (sizeof(mlen) * 8)));
43 ctx->nonce.c[10] = (u8)(mlen >> (40 % (sizeof(mlen) * 8)));
44 ctx->nonce.c[11] = (u8)(mlen >> (32 % (sizeof(mlen) * 8)));
45 } else
46 ctx->nonce.u[1] = 0;
47
48 ctx->nonce.c[12] = (u8)(mlen >> 24);
49 ctx->nonce.c[13] = (u8)(mlen >> 16);
50 ctx->nonce.c[14] = (u8)(mlen >> 8);
51 ctx->nonce.c[15] = (u8)mlen;
52
53 ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */
54 memcpy(&ctx->nonce.c[1], nonce, 14 - L);
55
56 return 0;
57}
58
59/* Then you pass additional authentication data, this is optional */
60void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
61 const unsigned char *aad, size_t alen)
62{
63 unsigned int i;
64 block128_f block = ctx->block;
65
66 if (alen == 0)
67 return;
68
69 ctx->nonce.c[0] |= 0x40; /* set Adata flag */
70 (*block) (ctx->nonce.c, ctx->cmac.c, ctx->key), ctx->blocks++;
71
72 if (alen < (0x10000 - 0x100)) {
73 ctx->cmac.c[0] ^= (u8)(alen >> 8);
74 ctx->cmac.c[1] ^= (u8)alen;
75 i = 2;
76 } else if (sizeof(alen) == 8
77 && alen >= (size_t)1 << (32 % (sizeof(alen) * 8))) {
78 ctx->cmac.c[0] ^= 0xFF;
79 ctx->cmac.c[1] ^= 0xFF;
80 ctx->cmac.c[2] ^= (u8)(alen >> (56 % (sizeof(alen) * 8)));
81 ctx->cmac.c[3] ^= (u8)(alen >> (48 % (sizeof(alen) * 8)));
82 ctx->cmac.c[4] ^= (u8)(alen >> (40 % (sizeof(alen) * 8)));
83 ctx->cmac.c[5] ^= (u8)(alen >> (32 % (sizeof(alen) * 8)));
84 ctx->cmac.c[6] ^= (u8)(alen >> 24);
85 ctx->cmac.c[7] ^= (u8)(alen >> 16);
86 ctx->cmac.c[8] ^= (u8)(alen >> 8);
87 ctx->cmac.c[9] ^= (u8)alen;
88 i = 10;
89 } else {
90 ctx->cmac.c[0] ^= 0xFF;
91 ctx->cmac.c[1] ^= 0xFE;
92 ctx->cmac.c[2] ^= (u8)(alen >> 24);
93 ctx->cmac.c[3] ^= (u8)(alen >> 16);
94 ctx->cmac.c[4] ^= (u8)(alen >> 8);
95 ctx->cmac.c[5] ^= (u8)alen;
96 i = 6;
97 }
98
99 do {
100 for (; i < 16 && alen; ++i, ++aad, --alen)
101 ctx->cmac.c[i] ^= *aad;
102 (*block) (ctx->cmac.c, ctx->cmac.c, ctx->key), ctx->blocks++;
103 i = 0;
104 } while (alen);
105}
106
107/* Finally you encrypt or decrypt the message */
108
109/*
110 * counter part of nonce may not be larger than L*8 bits, L is not larger
111 * than 8, therefore 64-bit counter...
112 */
113static void ctr64_inc(unsigned char *counter)
114{
115 unsigned int n = 8;
116 u8 c;
117
118 counter += 8;
119 do {
120 --n;
121 c = counter[n];
122 ++c;
123 counter[n] = c;
124 if (c)
125 return;
126 } while (n);
127}
128
129int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
130 const unsigned char *inp, unsigned char *out,
131 size_t len)
132{
133 size_t n;
134 unsigned int i, L;
135 unsigned char flags0 = ctx->nonce.c[0];
136 block128_f block = ctx->block;
137 void *key = ctx->key;
138 union {
139 u64 u[2];
140 u8 c[16];
141 } scratch;
142
143 if (!(flags0 & 0x40))
144 (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
145
146 ctx->nonce.c[0] = L = flags0 & 7;
147 for (n = 0, i = 15 - L; i < 15; ++i) {
148 n |= ctx->nonce.c[i];
149 ctx->nonce.c[i] = 0;
150 n <<= 8;
151 }
152 n |= ctx->nonce.c[15]; /* reconstructed length */
153 ctx->nonce.c[15] = 1;
154
155 if (n != len)
156 return -1; /* length mismatch */
157
158 ctx->blocks += ((len + 15) >> 3) | 1;
159 if (ctx->blocks > (U64(1) << 61))
160 return -2; /* too much data */
161
162 while (len >= 16) {
163#if defined(STRICT_ALIGNMENT)
164 union {
165 u64 u[2];
166 u8 c[16];
167 } temp;
168
169 memcpy(temp.c, inp, 16);
170 ctx->cmac.u[0] ^= temp.u[0];
171 ctx->cmac.u[1] ^= temp.u[1];
172#else
173 ctx->cmac.u[0] ^= ((u64 *)inp)[0];
174 ctx->cmac.u[1] ^= ((u64 *)inp)[1];
175#endif
176 (*block) (ctx->cmac.c, ctx->cmac.c, key);
177 (*block) (ctx->nonce.c, scratch.c, key);
178 ctr64_inc(ctx->nonce.c);
179#if defined(STRICT_ALIGNMENT)
180 temp.u[0] ^= scratch.u[0];
181 temp.u[1] ^= scratch.u[1];
182 memcpy(out, temp.c, 16);
183#else
184 ((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0];
185 ((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1];
186#endif
187 inp += 16;
188 out += 16;
189 len -= 16;
190 }
191
192 if (len) {
193 for (i = 0; i < len; ++i)
194 ctx->cmac.c[i] ^= inp[i];
195 (*block) (ctx->cmac.c, ctx->cmac.c, key);
196 (*block) (ctx->nonce.c, scratch.c, key);
197 for (i = 0; i < len; ++i)
198 out[i] = scratch.c[i] ^ inp[i];
199 }
200
201 for (i = 15 - L; i < 16; ++i)
202 ctx->nonce.c[i] = 0;
203
204 (*block) (ctx->nonce.c, scratch.c, key);
205 ctx->cmac.u[0] ^= scratch.u[0];
206 ctx->cmac.u[1] ^= scratch.u[1];
207
208 ctx->nonce.c[0] = flags0;
209
210 return 0;
211}
212
213int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
214 const unsigned char *inp, unsigned char *out,
215 size_t len)
216{
217 size_t n;
218 unsigned int i, L;
219 unsigned char flags0 = ctx->nonce.c[0];
220 block128_f block = ctx->block;
221 void *key = ctx->key;
222 union {
223 u64 u[2];
224 u8 c[16];
225 } scratch;
226
227 if (!(flags0 & 0x40))
228 (*block) (ctx->nonce.c, ctx->cmac.c, key);
229
230 ctx->nonce.c[0] = L = flags0 & 7;
231 for (n = 0, i = 15 - L; i < 15; ++i) {
232 n |= ctx->nonce.c[i];
233 ctx->nonce.c[i] = 0;
234 n <<= 8;
235 }
236 n |= ctx->nonce.c[15]; /* reconstructed length */
237 ctx->nonce.c[15] = 1;
238
239 if (n != len)
240 return -1;
241
242 while (len >= 16) {
243#if defined(STRICT_ALIGNMENT)
244 union {
245 u64 u[2];
246 u8 c[16];
247 } temp;
248#endif
249 (*block) (ctx->nonce.c, scratch.c, key);
250 ctr64_inc(ctx->nonce.c);
251#if defined(STRICT_ALIGNMENT)
252 memcpy(temp.c, inp, 16);
253 ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]);
254 ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]);
255 memcpy(out, scratch.c, 16);
256#else
257 ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]);
258 ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]);
259#endif
260 (*block) (ctx->cmac.c, ctx->cmac.c, key);
261
262 inp += 16;
263 out += 16;
264 len -= 16;
265 }
266
267 if (len) {
268 (*block) (ctx->nonce.c, scratch.c, key);
269 for (i = 0; i < len; ++i)
270 ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
271 (*block) (ctx->cmac.c, ctx->cmac.c, key);
272 }
273
274 for (i = 15 - L; i < 16; ++i)
275 ctx->nonce.c[i] = 0;
276
277 (*block) (ctx->nonce.c, scratch.c, key);
278 ctx->cmac.u[0] ^= scratch.u[0];
279 ctx->cmac.u[1] ^= scratch.u[1];
280
281 ctx->nonce.c[0] = flags0;
282
283 return 0;
284}
285
286static void ctr64_add(unsigned char *counter, size_t inc)
287{
288 size_t n = 8, val = 0;
289
290 counter += 8;
291 do {
292 --n;
293 val += counter[n] + (inc & 0xff);
294 counter[n] = (unsigned char)val;
295 val >>= 8; /* carry bit */
296 inc >>= 8;
297 } while (n && (inc || val));
298}
299
300int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
301 const unsigned char *inp, unsigned char *out,
302 size_t len, ccm128_f stream)
303{
304 size_t n;
305 unsigned int i, L;
306 unsigned char flags0 = ctx->nonce.c[0];
307 block128_f block = ctx->block;
308 void *key = ctx->key;
309 union {
310 u64 u[2];
311 u8 c[16];
312 } scratch;
313
314 if (!(flags0 & 0x40))
315 (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
316
317 ctx->nonce.c[0] = L = flags0 & 7;
318 for (n = 0, i = 15 - L; i < 15; ++i) {
319 n |= ctx->nonce.c[i];
320 ctx->nonce.c[i] = 0;
321 n <<= 8;
322 }
323 n |= ctx->nonce.c[15]; /* reconstructed length */
324 ctx->nonce.c[15] = 1;
325
326 if (n != len)
327 return -1; /* length mismatch */
328
329 ctx->blocks += ((len + 15) >> 3) | 1;
330 if (ctx->blocks > (U64(1) << 61))
331 return -2; /* too much data */
332
333 if ((n = len / 16)) {
334 (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
335 n *= 16;
336 inp += n;
337 out += n;
338 len -= n;
339 if (len)
340 ctr64_add(ctx->nonce.c, n / 16);
341 }
342
343 if (len) {
344 for (i = 0; i < len; ++i)
345 ctx->cmac.c[i] ^= inp[i];
346 (*block) (ctx->cmac.c, ctx->cmac.c, key);
347 (*block) (ctx->nonce.c, scratch.c, key);
348 for (i = 0; i < len; ++i)
349 out[i] = scratch.c[i] ^ inp[i];
350 }
351
352 for (i = 15 - L; i < 16; ++i)
353 ctx->nonce.c[i] = 0;
354
355 (*block) (ctx->nonce.c, scratch.c, key);
356 ctx->cmac.u[0] ^= scratch.u[0];
357 ctx->cmac.u[1] ^= scratch.u[1];
358
359 ctx->nonce.c[0] = flags0;
360
361 return 0;
362}
363
364int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
365 const unsigned char *inp, unsigned char *out,
366 size_t len, ccm128_f stream)
367{
368 size_t n;
369 unsigned int i, L;
370 unsigned char flags0 = ctx->nonce.c[0];
371 block128_f block = ctx->block;
372 void *key = ctx->key;
373 union {
374 u64 u[2];
375 u8 c[16];
376 } scratch;
377
378 if (!(flags0 & 0x40))
379 (*block) (ctx->nonce.c, ctx->cmac.c, key);
380
381 ctx->nonce.c[0] = L = flags0 & 7;
382 for (n = 0, i = 15 - L; i < 15; ++i) {
383 n |= ctx->nonce.c[i];
384 ctx->nonce.c[i] = 0;
385 n <<= 8;
386 }
387 n |= ctx->nonce.c[15]; /* reconstructed length */
388 ctx->nonce.c[15] = 1;
389
390 if (n != len)
391 return -1;
392
393 if ((n = len / 16)) {
394 (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
395 n *= 16;
396 inp += n;
397 out += n;
398 len -= n;
399 if (len)
400 ctr64_add(ctx->nonce.c, n / 16);
401 }
402
403 if (len) {
404 (*block) (ctx->nonce.c, scratch.c, key);
405 for (i = 0; i < len; ++i)
406 ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
407 (*block) (ctx->cmac.c, ctx->cmac.c, key);
408 }
409
410 for (i = 15 - L; i < 16; ++i)
411 ctx->nonce.c[i] = 0;
412
413 (*block) (ctx->nonce.c, scratch.c, key);
414 ctx->cmac.u[0] ^= scratch.u[0];
415 ctx->cmac.u[1] ^= scratch.u[1];
416
417 ctx->nonce.c[0] = flags0;
418
419 return 0;
420}
421
422size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
423{
424 unsigned int M = (ctx->nonce.c[0] >> 3) & 7; /* the M parameter */
425
426 M *= 2;
427 M += 2;
428 if (len != M)
429 return 0;
430 memcpy(tag, ctx->cmac.c, M);
431 return M;
432}
433