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