bfa2d4604caf4ed8eb6f7981fc0470966897ad0d
[openssl.git] / crypto / modes / ccm128.c
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 <openssl/crypto.h>
11 #include "modes_lcl.h"
12 #include <string.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  */
18 void 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 */
32 int 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 */
60 void 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  */
113 static 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
129 int 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
213 int 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
286 static 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
300 int 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
364 int 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
422 size_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 }