Run util/openssl-format-source -v -c .
[openssl.git] / crypto / modes / ccm128.c
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  */
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 */
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 */
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  */
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
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
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
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
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
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
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 }