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"
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
)
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;
73 /* !!! Following interfaces are to be called *once* per packet !!! */
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
)
79 unsigned int L
= ctx
->nonce
.c
[0]&7; /* the L parameter */
81 if (nlen
<(14-L
)) return -1; /* nonce is too short */
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)));
90 *(u32
*)(&ctx
->nonce
.c
[8]) = 0;
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
;
97 ctx
->nonce
.c
[0] &= ~0x40; /* clear Adata flag */
98 memcpy(&ctx
->nonce
.c
[1],nonce
,14-L
);
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
)
107 block128_f block
= ctx
->block
;
111 ctx
->nonce
.c
[0] |= 0x40; /* set Adata flag */
112 (*block
)(ctx
->nonce
.c
,ctx
->cmac
.c
,ctx
->key
),
115 if (alen
<(0x10000-0x100)) {
116 ctx
->cmac
.c
[0] ^= (u8
)(alen
>>8);
117 ctx
->cmac
.c
[1] ^= (u8
)alen
;
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
;
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
;
144 for(;i
<16 && alen
;++i
,++aad
,--alen
)
145 ctx
->cmac
.c
[i
] ^= *aad
;
146 (*block
)(ctx
->cmac
.c
,ctx
->cmac
.c
,ctx
->key
),
152 /* Finally you encrypt or decrypt the message */
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
) {
170 int CRYPTO_ccm128_encrypt(CCM128_CONTEXT
*ctx
,
171 const unsigned char *inp
, unsigned char *out
,
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
;
182 (*block
)(ctx
->nonce
.c
,ctx
->cmac
.c
,key
),
185 ctx
->nonce
.c
[0] = L
= flags0
&7;
186 for (n
=0,i
=15-L
;i
<15;++i
) {
187 n
|= ctx
->nonce
.c
[i
];
191 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
194 if (n
!=len
) return -1; /* length mismatch */
196 ctx
->blocks
+= ((len
+15)>>3)|1;
197 if (ctx
->blocks
> (U64(1)<<61)) return -2; /* too much data */
200 #if defined(STRICT_ALIGNMENT)
201 union { u64 u
[2]; u8 c
[16]; } temp
;
203 memcpy (temp
.c
,inp
,16);
204 ctx
->cmac
.u
[0] ^= temp
.u
[0];
205 ctx
->cmac
.u
[1] ^= temp
.u
[1];
207 ctx
->cmac
.u
[0] ^= ((u64
*)inp
)[0];
208 ctx
->cmac
.u
[1] ^= ((u64
*)inp
)[1];
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);
218 ((u64
*)out
)[0] = scratch
.u
[0]^((u64
*)inp
)[0];
219 ((u64
*)out
)[1] = scratch
.u
[1]^((u64
*)inp
)[1];
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
];
233 for (i
=15-L
;i
<16;++i
)
236 (*block
)(ctx
->nonce
.c
,scratch
.c
,key
);
237 ctx
->cmac
.u
[0] ^= scratch
.u
[0];
238 ctx
->cmac
.u
[1] ^= scratch
.u
[1];
240 ctx
->nonce
.c
[0] = flags0
;
245 int CRYPTO_ccm128_decrypt(CCM128_CONTEXT
*ctx
,
246 const unsigned char *inp
, unsigned char *out
,
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
;
257 (*block
)(ctx
->nonce
.c
,ctx
->cmac
.c
,key
);
259 ctx
->nonce
.c
[0] = L
= flags0
&7;
260 for (n
=0,i
=15-L
;i
<15;++i
) {
261 n
|= ctx
->nonce
.c
[i
];
265 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
268 if (n
!=len
) return -1;
271 #if defined(STRICT_ALIGNMENT)
272 union { u64 u
[2]; u8 c
[16]; } temp
;
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);
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]);
285 (*block
)(ctx
->cmac
.c
,ctx
->cmac
.c
,key
);
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
);
299 for (i
=15-L
;i
<16;++i
)
302 (*block
)(ctx
->nonce
.c
,scratch
.c
,key
);
303 ctx
->cmac
.u
[0] ^= scratch
.u
[0];
304 ctx
->cmac
.u
[1] ^= scratch
.u
[1];
306 ctx
->nonce
.c
[0] = flags0
;
311 static void ctr64_add (unsigned char *counter
,size_t inc
)
317 val
+= counter
[n
] + (inc
&0xff);
318 counter
[n
] = (unsigned char)val
;
319 val
>>= 8; /* carry bit */
321 } while(n
&& (inc
|| val
));
324 int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT
*ctx
,
325 const unsigned char *inp
, unsigned char *out
,
326 size_t len
,ccm128_f stream
)
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
;
336 (*block
)(ctx
->nonce
.c
,ctx
->cmac
.c
,key
),
339 ctx
->nonce
.c
[0] = L
= flags0
&7;
340 for (n
=0,i
=15-L
;i
<15;++i
) {
341 n
|= ctx
->nonce
.c
[i
];
345 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
348 if (n
!=len
) return -1; /* length mismatch */
350 ctx
->blocks
+= ((len
+15)>>3)|1;
351 if (ctx
->blocks
> (U64(1)<<61)) return -2; /* too much data */
354 (*stream
)(inp
,out
,n
,key
,ctx
->nonce
.c
,ctx
->cmac
.c
);
359 if (len
) ctr64_add(ctx
->nonce
.c
,n
/16);
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
];
369 for (i
=15-L
;i
<16;++i
)
372 (*block
)(ctx
->nonce
.c
,scratch
.c
,key
);
373 ctx
->cmac
.u
[0] ^= scratch
.u
[0];
374 ctx
->cmac
.u
[1] ^= scratch
.u
[1];
376 ctx
->nonce
.c
[0] = flags0
;
381 int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT
*ctx
,
382 const unsigned char *inp
, unsigned char *out
,
383 size_t len
,ccm128_f stream
)
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
;
393 (*block
)(ctx
->nonce
.c
,ctx
->cmac
.c
,key
);
395 ctx
->nonce
.c
[0] = L
= flags0
&7;
396 for (n
=0,i
=15-L
;i
<15;++i
) {
397 n
|= ctx
->nonce
.c
[i
];
401 n
|= ctx
->nonce
.c
[15]; /* reconstructed length */
404 if (n
!=len
) return -1;
407 (*stream
)(inp
,out
,n
,key
,ctx
->nonce
.c
,ctx
->cmac
.c
);
412 if (len
) ctr64_add(ctx
->nonce
.c
,n
/16);
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
);
422 for (i
=15-L
;i
<16;++i
)
425 (*block
)(ctx
->nonce
.c
,scratch
.c
,key
);
426 ctx
->cmac
.u
[0] ^= scratch
.u
[0];
427 ctx
->cmac
.u
[1] ^= scratch
.u
[1];
429 ctx
->nonce
.c
[0] = flags0
;
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 */
439 memcpy(tag
,ctx
->cmac
.c
,M
);