]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/modes/ccm128.c
2 * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
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
10 #include <openssl/crypto.h>
11 #include "modes_lcl.h"
15 * First you setup M and L parameters and pass the key schedule. This is
16 * called once per session setup...
18 void CRYPTO_ccm128_init(CCM128_CONTEXT
*ctx
,
19 unsigned int M
, unsigned int L
, void *key
,
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;
29 /* !!! Following interfaces are to be called *once* per packet !!! */
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
)
35 unsigned int L
= ctx
->nonce
.c
[0] & 7; /* the L parameter */
38 return -1; /* nonce is too short */
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)));
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
;
53 ctx
->nonce
.c
[0] &= ~0x40; /* clear Adata flag */
54 memcpy(&ctx
->nonce
.c
[1], nonce
, 14 - L
);
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
)
64 block128_f block
= ctx
->block
;
69 ctx
->nonce
.c
[0] |= 0x40; /* set Adata flag */
70 (*block
) (ctx
->nonce
.c
, ctx
->cmac
.c
, ctx
->key
), ctx
->blocks
++;
72 if (alen
< (0x10000 - 0x100)) {
73 ctx
->cmac
.c
[0] ^= (u8
)(alen
>> 8);
74 ctx
->cmac
.c
[1] ^= (u8
)alen
;
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
;
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
;
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
++;
107 /* Finally you encrypt or decrypt the message */
110 * counter part of nonce may not be larger than L*8 bits, L is not larger
111 * than 8, therefore 64-bit counter...
113 static void ctr64_inc(unsigned char *counter
)
129 int CRYPTO_ccm128_encrypt(CCM128_CONTEXT
*ctx
,
130 const unsigned char *inp
, unsigned char *out
,
135 unsigned char flags0
= ctx
->nonce
.c
[0];
136 block128_f block
= ctx
->block
;
137 void *key
= ctx
->key
;
143 if (!(flags0
& 0x40))
144 (*block
) (ctx
->nonce
.c
, ctx
->cmac
.c
, key
), ctx
->blocks
++;
146 ctx
->nonce
.c
[0] = L
= flags0
& 7;
147 for (n
= 0, i
= 15 - L
; i
< 15; ++i
) {
148 n
|= ctx
->nonce
.c
[i
];
152 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
153 ctx
->nonce
.c
[15] = 1;
156 return -1; /* length mismatch */
158 ctx
->blocks
+= ((len
+ 15) >> 3) | 1;
159 if (ctx
->blocks
> (U64(1) << 61))
160 return -2; /* too much data */
163 #if defined(STRICT_ALIGNMENT)
169 memcpy(temp
.c
, inp
, 16);
170 ctx
->cmac
.u
[0] ^= temp
.u
[0];
171 ctx
->cmac
.u
[1] ^= temp
.u
[1];
173 ctx
->cmac
.u
[0] ^= ((u64
*)inp
)[0];
174 ctx
->cmac
.u
[1] ^= ((u64
*)inp
)[1];
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);
184 ((u64
*)out
)[0] = scratch
.u
[0] ^ ((u64
*)inp
)[0];
185 ((u64
*)out
)[1] = scratch
.u
[1] ^ ((u64
*)inp
)[1];
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
];
201 for (i
= 15 - L
; i
< 16; ++i
)
204 (*block
) (ctx
->nonce
.c
, scratch
.c
, key
);
205 ctx
->cmac
.u
[0] ^= scratch
.u
[0];
206 ctx
->cmac
.u
[1] ^= scratch
.u
[1];
208 ctx
->nonce
.c
[0] = flags0
;
213 int CRYPTO_ccm128_decrypt(CCM128_CONTEXT
*ctx
,
214 const unsigned char *inp
, unsigned char *out
,
219 unsigned char flags0
= ctx
->nonce
.c
[0];
220 block128_f block
= ctx
->block
;
221 void *key
= ctx
->key
;
227 if (!(flags0
& 0x40))
228 (*block
) (ctx
->nonce
.c
, ctx
->cmac
.c
, key
);
230 ctx
->nonce
.c
[0] = L
= flags0
& 7;
231 for (n
= 0, i
= 15 - L
; i
< 15; ++i
) {
232 n
|= ctx
->nonce
.c
[i
];
236 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
237 ctx
->nonce
.c
[15] = 1;
243 #if defined(STRICT_ALIGNMENT)
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);
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]);
260 (*block
) (ctx
->cmac
.c
, ctx
->cmac
.c
, key
);
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
);
274 for (i
= 15 - L
; i
< 16; ++i
)
277 (*block
) (ctx
->nonce
.c
, scratch
.c
, key
);
278 ctx
->cmac
.u
[0] ^= scratch
.u
[0];
279 ctx
->cmac
.u
[1] ^= scratch
.u
[1];
281 ctx
->nonce
.c
[0] = flags0
;
286 static void ctr64_add(unsigned char *counter
, size_t inc
)
288 size_t n
= 8, val
= 0;
293 val
+= counter
[n
] + (inc
& 0xff);
294 counter
[n
] = (unsigned char)val
;
295 val
>>= 8; /* carry bit */
297 } while (n
&& (inc
|| val
));
300 int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT
*ctx
,
301 const unsigned char *inp
, unsigned char *out
,
302 size_t len
, ccm128_f stream
)
306 unsigned char flags0
= ctx
->nonce
.c
[0];
307 block128_f block
= ctx
->block
;
308 void *key
= ctx
->key
;
314 if (!(flags0
& 0x40))
315 (*block
) (ctx
->nonce
.c
, ctx
->cmac
.c
, key
), ctx
->blocks
++;
317 ctx
->nonce
.c
[0] = L
= flags0
& 7;
318 for (n
= 0, i
= 15 - L
; i
< 15; ++i
) {
319 n
|= ctx
->nonce
.c
[i
];
323 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
324 ctx
->nonce
.c
[15] = 1;
327 return -1; /* length mismatch */
329 ctx
->blocks
+= ((len
+ 15) >> 3) | 1;
330 if (ctx
->blocks
> (U64(1) << 61))
331 return -2; /* too much data */
333 if ((n
= len
/ 16)) {
334 (*stream
) (inp
, out
, n
, key
, ctx
->nonce
.c
, ctx
->cmac
.c
);
340 ctr64_add(ctx
->nonce
.c
, n
/ 16);
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
];
352 for (i
= 15 - L
; i
< 16; ++i
)
355 (*block
) (ctx
->nonce
.c
, scratch
.c
, key
);
356 ctx
->cmac
.u
[0] ^= scratch
.u
[0];
357 ctx
->cmac
.u
[1] ^= scratch
.u
[1];
359 ctx
->nonce
.c
[0] = flags0
;
364 int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT
*ctx
,
365 const unsigned char *inp
, unsigned char *out
,
366 size_t len
, ccm128_f stream
)
370 unsigned char flags0
= ctx
->nonce
.c
[0];
371 block128_f block
= ctx
->block
;
372 void *key
= ctx
->key
;
378 if (!(flags0
& 0x40))
379 (*block
) (ctx
->nonce
.c
, ctx
->cmac
.c
, key
);
381 ctx
->nonce
.c
[0] = L
= flags0
& 7;
382 for (n
= 0, i
= 15 - L
; i
< 15; ++i
) {
383 n
|= ctx
->nonce
.c
[i
];
387 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
388 ctx
->nonce
.c
[15] = 1;
393 if ((n
= len
/ 16)) {
394 (*stream
) (inp
, out
, n
, key
, ctx
->nonce
.c
, ctx
->cmac
.c
);
400 ctr64_add(ctx
->nonce
.c
, n
/ 16);
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
);
410 for (i
= 15 - L
; i
< 16; ++i
)
413 (*block
) (ctx
->nonce
.c
, scratch
.c
, key
);
414 ctx
->cmac
.u
[0] ^= scratch
.u
[0];
415 ctx
->cmac
.u
[1] ^= scratch
.u
[1];
417 ctx
->nonce
.c
[0] = flags0
;
422 size_t CRYPTO_ccm128_tag(CCM128_CONTEXT
*ctx
, unsigned char *tag
, size_t len
)
424 unsigned int M
= (ctx
->nonce
.c
[0] >> 3) & 7; /* the M parameter */
430 memcpy(tag
, ctx
->cmac
.c
, M
);