]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/modes/ccm128.c
1 /* ====================================================================
2 * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
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
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/)"
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.
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.
30 * 6. Redistributions of any form whatsoever must retain the following
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
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 * ====================================================================
50 #include <openssl/crypto.h>
51 #include "modes_lcl.h"
55 * First you setup M and L parameters and pass the key schedule. This is
56 * called once per session setup...
58 void CRYPTO_ccm128_init(CCM128_CONTEXT
*ctx
,
59 unsigned int M
, unsigned int L
, void *key
,
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;
69 /* !!! Following interfaces are to be called *once* per packet !!! */
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
)
75 unsigned int L
= ctx
->nonce
.c
[0] & 7; /* the L parameter */
78 return -1; /* nonce is too short */
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)));
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
;
93 ctx
->nonce
.c
[0] &= ~0x40; /* clear Adata flag */
94 memcpy(&ctx
->nonce
.c
[1], nonce
, 14 - L
);
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
)
104 block128_f block
= ctx
->block
;
109 ctx
->nonce
.c
[0] |= 0x40; /* set Adata flag */
110 (*block
) (ctx
->nonce
.c
, ctx
->cmac
.c
, ctx
->key
), ctx
->blocks
++;
112 if (alen
< (0x10000 - 0x100)) {
113 ctx
->cmac
.c
[0] ^= (u8
)(alen
>> 8);
114 ctx
->cmac
.c
[1] ^= (u8
)alen
;
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
;
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
;
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
++;
147 /* Finally you encrypt or decrypt the message */
150 * counter part of nonce may not be larger than L*8 bits, L is not larger
151 * than 8, therefore 64-bit counter...
153 static void ctr64_inc(unsigned char *counter
)
169 int CRYPTO_ccm128_encrypt(CCM128_CONTEXT
*ctx
,
170 const unsigned char *inp
, unsigned char *out
,
175 unsigned char flags0
= ctx
->nonce
.c
[0];
176 block128_f block
= ctx
->block
;
177 void *key
= ctx
->key
;
183 if (!(flags0
& 0x40))
184 (*block
) (ctx
->nonce
.c
, ctx
->cmac
.c
, key
), ctx
->blocks
++;
186 ctx
->nonce
.c
[0] = L
= flags0
& 7;
187 for (n
= 0, i
= 15 - L
; i
< 15; ++i
) {
188 n
|= ctx
->nonce
.c
[i
];
192 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
193 ctx
->nonce
.c
[15] = 1;
196 return -1; /* length mismatch */
198 ctx
->blocks
+= ((len
+ 15) >> 3) | 1;
199 if (ctx
->blocks
> (U64(1) << 61))
200 return -2; /* too much data */
203 #if defined(STRICT_ALIGNMENT)
209 memcpy(temp
.c
, inp
, 16);
210 ctx
->cmac
.u
[0] ^= temp
.u
[0];
211 ctx
->cmac
.u
[1] ^= temp
.u
[1];
213 ctx
->cmac
.u
[0] ^= ((u64
*)inp
)[0];
214 ctx
->cmac
.u
[1] ^= ((u64
*)inp
)[1];
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);
224 ((u64
*)out
)[0] = scratch
.u
[0] ^ ((u64
*)inp
)[0];
225 ((u64
*)out
)[1] = scratch
.u
[1] ^ ((u64
*)inp
)[1];
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
];
241 for (i
= 15 - L
; i
< 16; ++i
)
244 (*block
) (ctx
->nonce
.c
, scratch
.c
, key
);
245 ctx
->cmac
.u
[0] ^= scratch
.u
[0];
246 ctx
->cmac
.u
[1] ^= scratch
.u
[1];
248 ctx
->nonce
.c
[0] = flags0
;
253 int CRYPTO_ccm128_decrypt(CCM128_CONTEXT
*ctx
,
254 const unsigned char *inp
, unsigned char *out
,
259 unsigned char flags0
= ctx
->nonce
.c
[0];
260 block128_f block
= ctx
->block
;
261 void *key
= ctx
->key
;
267 if (!(flags0
& 0x40))
268 (*block
) (ctx
->nonce
.c
, ctx
->cmac
.c
, key
);
270 ctx
->nonce
.c
[0] = L
= flags0
& 7;
271 for (n
= 0, i
= 15 - L
; i
< 15; ++i
) {
272 n
|= ctx
->nonce
.c
[i
];
276 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
277 ctx
->nonce
.c
[15] = 1;
283 #if defined(STRICT_ALIGNMENT)
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);
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]);
300 (*block
) (ctx
->cmac
.c
, ctx
->cmac
.c
, key
);
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
);
314 for (i
= 15 - L
; i
< 16; ++i
)
317 (*block
) (ctx
->nonce
.c
, scratch
.c
, key
);
318 ctx
->cmac
.u
[0] ^= scratch
.u
[0];
319 ctx
->cmac
.u
[1] ^= scratch
.u
[1];
321 ctx
->nonce
.c
[0] = flags0
;
326 static void ctr64_add(unsigned char *counter
, size_t inc
)
328 size_t n
= 8, val
= 0;
333 val
+= counter
[n
] + (inc
& 0xff);
334 counter
[n
] = (unsigned char)val
;
335 val
>>= 8; /* carry bit */
337 } while (n
&& (inc
|| val
));
340 int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT
*ctx
,
341 const unsigned char *inp
, unsigned char *out
,
342 size_t len
, ccm128_f stream
)
346 unsigned char flags0
= ctx
->nonce
.c
[0];
347 block128_f block
= ctx
->block
;
348 void *key
= ctx
->key
;
354 if (!(flags0
& 0x40))
355 (*block
) (ctx
->nonce
.c
, ctx
->cmac
.c
, key
), ctx
->blocks
++;
357 ctx
->nonce
.c
[0] = L
= flags0
& 7;
358 for (n
= 0, i
= 15 - L
; i
< 15; ++i
) {
359 n
|= ctx
->nonce
.c
[i
];
363 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
364 ctx
->nonce
.c
[15] = 1;
367 return -1; /* length mismatch */
369 ctx
->blocks
+= ((len
+ 15) >> 3) | 1;
370 if (ctx
->blocks
> (U64(1) << 61))
371 return -2; /* too much data */
373 if ((n
= len
/ 16)) {
374 (*stream
) (inp
, out
, n
, key
, ctx
->nonce
.c
, ctx
->cmac
.c
);
380 ctr64_add(ctx
->nonce
.c
, n
/ 16);
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
];
392 for (i
= 15 - L
; i
< 16; ++i
)
395 (*block
) (ctx
->nonce
.c
, scratch
.c
, key
);
396 ctx
->cmac
.u
[0] ^= scratch
.u
[0];
397 ctx
->cmac
.u
[1] ^= scratch
.u
[1];
399 ctx
->nonce
.c
[0] = flags0
;
404 int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT
*ctx
,
405 const unsigned char *inp
, unsigned char *out
,
406 size_t len
, ccm128_f stream
)
410 unsigned char flags0
= ctx
->nonce
.c
[0];
411 block128_f block
= ctx
->block
;
412 void *key
= ctx
->key
;
418 if (!(flags0
& 0x40))
419 (*block
) (ctx
->nonce
.c
, ctx
->cmac
.c
, key
);
421 ctx
->nonce
.c
[0] = L
= flags0
& 7;
422 for (n
= 0, i
= 15 - L
; i
< 15; ++i
) {
423 n
|= ctx
->nonce
.c
[i
];
427 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
428 ctx
->nonce
.c
[15] = 1;
433 if ((n
= len
/ 16)) {
434 (*stream
) (inp
, out
, n
, key
, ctx
->nonce
.c
, ctx
->cmac
.c
);
440 ctr64_add(ctx
->nonce
.c
, n
/ 16);
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
);
450 for (i
= 15 - L
; i
< 16; ++i
)
453 (*block
) (ctx
->nonce
.c
, scratch
.c
, key
);
454 ctx
->cmac
.u
[0] ^= scratch
.u
[0];
455 ctx
->cmac
.u
[1] ^= scratch
.u
[1];
457 ctx
->nonce
.c
[0] = flags0
;
462 size_t CRYPTO_ccm128_tag(CCM128_CONTEXT
*ctx
, unsigned char *tag
, size_t len
)
464 unsigned int M
= (ctx
->nonce
.c
[0] >> 3) & 7; /* the M parameter */
470 memcpy(tag
, ctx
->cmac
.c
, M
);