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