1 /* $OpenBSD: ccm128.c,v 1.3 2014/06/12 15:49:30 deraadt Exp $ */ 2 /* ==================================================================== 3 * Copyright (c) 2011 The OpenSSL Project. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. All advertising materials mentioning features or use of this 18 * software must display the following acknowledgment: 19 * "This product includes software developed by the OpenSSL Project 20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21 * 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23 * endorse or promote products derived from this software without 24 * prior written permission. For written permission, please contact 25 * openssl-core@openssl.org. 26 * 27 * 5. Products derived from this software may not be called "OpenSSL" 28 * nor may "OpenSSL" appear in their names without prior written 29 * permission of the OpenSSL Project. 30 * 31 * 6. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by the OpenSSL Project 34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47 * OF THE POSSIBILITY OF SUCH DAMAGE. 48 * ==================================================================== 49 */ 50 51 #include <openssl/crypto.h> 52 #include "modes_lcl.h" 53 #include <string.h> 54 55 #ifndef MODES_DEBUG 56 # ifndef NDEBUG 57 # define NDEBUG 58 # endif 59 #endif 60 #include <assert.h> 61 62 /* First you setup M and L parameters and pass the key schedule. 63 * This is called once per session setup... */ 64 void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, 65 unsigned int M,unsigned int L,void *key,block128_f block) 66 { 67 memset(ctx->nonce.c,0,sizeof(ctx->nonce.c)); 68 ctx->nonce.c[0] = ((u8)(L-1)&7) | (u8)(((M-2)/2)&7)<<3; 69 ctx->blocks = 0; 70 ctx->block = block; 71 ctx->key = key; 72 } 73 74 /* !!! Following interfaces are to be called *once* per packet !!! */ 75 76 /* Then you setup per-message nonce and pass the length of the message */ 77 int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, 78 const unsigned char *nonce,size_t nlen,size_t mlen) 79 { 80 unsigned int L = ctx->nonce.c[0]&7; /* the L parameter */ 81 82 if (nlen<(14-L)) return -1; /* nonce is too short */ 83 84 if (sizeof(mlen)==8 && L>=3) { 85 ctx->nonce.c[8] = (u8)(mlen>>(56%(sizeof(mlen)*8))); 86 ctx->nonce.c[9] = (u8)(mlen>>(48%(sizeof(mlen)*8))); 87 ctx->nonce.c[10] = (u8)(mlen>>(40%(sizeof(mlen)*8))); 88 ctx->nonce.c[11] = (u8)(mlen>>(32%(sizeof(mlen)*8))); 89 } 90 else 91 ctx->nonce.u[1] = 0; 92 93 ctx->nonce.c[12] = (u8)(mlen>>24); 94 ctx->nonce.c[13] = (u8)(mlen>>16); 95 ctx->nonce.c[14] = (u8)(mlen>>8); 96 ctx->nonce.c[15] = (u8)mlen; 97 98 ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */ 99 memcpy(&ctx->nonce.c[1],nonce,14-L); 100 101 return 0; 102 } 103 104 /* Then you pass additional authentication data, this is optional */ 105 void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, 106 const unsigned char *aad,size_t alen) 107 { unsigned int i; 108 block128_f block = ctx->block; 109 110 if (alen==0) return; 111 112 ctx->nonce.c[0] |= 0x40; /* set Adata flag */ 113 (*block)(ctx->nonce.c,ctx->cmac.c,ctx->key), 114 ctx->blocks++; 115 116 if (alen<(0x10000-0x100)) { 117 ctx->cmac.c[0] ^= (u8)(alen>>8); 118 ctx->cmac.c[1] ^= (u8)alen; 119 i=2; 120 } 121 else if (sizeof(alen)==8 && alen>=(size_t)1<<(32%(sizeof(alen)*8))) { 122 ctx->cmac.c[0] ^= 0xFF; 123 ctx->cmac.c[1] ^= 0xFF; 124 ctx->cmac.c[2] ^= (u8)(alen>>(56%(sizeof(alen)*8))); 125 ctx->cmac.c[3] ^= (u8)(alen>>(48%(sizeof(alen)*8))); 126 ctx->cmac.c[4] ^= (u8)(alen>>(40%(sizeof(alen)*8))); 127 ctx->cmac.c[5] ^= (u8)(alen>>(32%(sizeof(alen)*8))); 128 ctx->cmac.c[6] ^= (u8)(alen>>24); 129 ctx->cmac.c[7] ^= (u8)(alen>>16); 130 ctx->cmac.c[8] ^= (u8)(alen>>8); 131 ctx->cmac.c[9] ^= (u8)alen; 132 i=10; 133 } 134 else { 135 ctx->cmac.c[0] ^= 0xFF; 136 ctx->cmac.c[1] ^= 0xFE; 137 ctx->cmac.c[2] ^= (u8)(alen>>24); 138 ctx->cmac.c[3] ^= (u8)(alen>>16); 139 ctx->cmac.c[4] ^= (u8)(alen>>8); 140 ctx->cmac.c[5] ^= (u8)alen; 141 i=6; 142 } 143 144 do { 145 for(;i<16 && alen;++i,++aad,--alen) 146 ctx->cmac.c[i] ^= *aad; 147 (*block)(ctx->cmac.c,ctx->cmac.c,ctx->key), 148 ctx->blocks++; 149 i=0; 150 } while (alen); 151 } 152 153 /* Finally you encrypt or decrypt the message */ 154 155 /* counter part of nonce may not be larger than L*8 bits, 156 * L is not larger than 8, therefore 64-bit counter... */ 157 static void ctr64_inc(unsigned char *counter) { 158 unsigned int n=8; 159 u8 c; 160 161 counter += 8; 162 do { 163 --n; 164 c = counter[n]; 165 ++c; 166 counter[n] = c; 167 if (c) return; 168 } while (n); 169 } 170 171 int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, 172 const unsigned char *inp, unsigned char *out, 173 size_t len) 174 { 175 size_t n; 176 unsigned int i,L; 177 unsigned char flags0 = ctx->nonce.c[0]; 178 block128_f block = ctx->block; 179 void * key = ctx->key; 180 union { u64 u[2]; u8 c[16]; } scratch; 181 182 if (!(flags0&0x40)) 183 (*block)(ctx->nonce.c,ctx->cmac.c,key), 184 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) return -1; /* length mismatch */ 196 197 ctx->blocks += ((len+15)>>3)|1; 198 if (ctx->blocks > (U64(1)<<61)) return -2; /* too much data */ 199 200 while (len>=16) { 201 #ifdef __STRICT_ALIGNMENT 202 union { u64 u[2]; u8 c[16]; } temp; 203 204 memcpy (temp.c,inp,16); 205 ctx->cmac.u[0] ^= temp.u[0]; 206 ctx->cmac.u[1] ^= temp.u[1]; 207 #else 208 ctx->cmac.u[0] ^= ((u64*)inp)[0]; 209 ctx->cmac.u[1] ^= ((u64*)inp)[1]; 210 #endif 211 (*block)(ctx->cmac.c,ctx->cmac.c,key); 212 (*block)(ctx->nonce.c,scratch.c,key); 213 ctr64_inc(ctx->nonce.c); 214 #ifdef __STRICT_ALIGNMENT 215 temp.u[0] ^= scratch.u[0]; 216 temp.u[1] ^= scratch.u[1]; 217 memcpy(out,temp.c,16); 218 #else 219 ((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0]; 220 ((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1]; 221 #endif 222 inp += 16; 223 out += 16; 224 len -= 16; 225 } 226 227 if (len) { 228 for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i]; 229 (*block)(ctx->cmac.c,ctx->cmac.c,key); 230 (*block)(ctx->nonce.c,scratch.c,key); 231 for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i]; 232 } 233 234 for (i=15-L;i<16;++i) 235 ctx->nonce.c[i]=0; 236 237 (*block)(ctx->nonce.c,scratch.c,key); 238 ctx->cmac.u[0] ^= scratch.u[0]; 239 ctx->cmac.u[1] ^= scratch.u[1]; 240 241 ctx->nonce.c[0] = flags0; 242 243 return 0; 244 } 245 246 int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, 247 const unsigned char *inp, unsigned char *out, 248 size_t len) 249 { 250 size_t n; 251 unsigned int i,L; 252 unsigned char flags0 = ctx->nonce.c[0]; 253 block128_f block = ctx->block; 254 void * key = ctx->key; 255 union { u64 u[2]; u8 c[16]; } scratch; 256 257 if (!(flags0&0x40)) 258 (*block)(ctx->nonce.c,ctx->cmac.c,key); 259 260 ctx->nonce.c[0] = L = flags0&7; 261 for (n=0,i=15-L;i<15;++i) { 262 n |= ctx->nonce.c[i]; 263 ctx->nonce.c[i]=0; 264 n <<= 8; 265 } 266 n |= ctx->nonce.c[15]; /* reconstructed length */ 267 ctx->nonce.c[15]=1; 268 269 if (n!=len) return -1; 270 271 while (len>=16) { 272 #ifdef __STRICT_ALIGNMENT 273 union { u64 u[2]; u8 c[16]; } temp; 274 #endif 275 (*block)(ctx->nonce.c,scratch.c,key); 276 ctr64_inc(ctx->nonce.c); 277 #ifdef __STRICT_ALIGNMENT 278 memcpy (temp.c,inp,16); 279 ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]); 280 ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]); 281 memcpy (out,scratch.c,16); 282 #else 283 ctx->cmac.u[0] ^= (((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0]); 284 ctx->cmac.u[1] ^= (((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1]); 285 #endif 286 (*block)(ctx->cmac.c,ctx->cmac.c,key); 287 288 inp += 16; 289 out += 16; 290 len -= 16; 291 } 292 293 if (len) { 294 (*block)(ctx->nonce.c,scratch.c,key); 295 for (i=0; i<len; ++i) 296 ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]); 297 (*block)(ctx->cmac.c,ctx->cmac.c,key); 298 } 299 300 for (i=15-L;i<16;++i) 301 ctx->nonce.c[i]=0; 302 303 (*block)(ctx->nonce.c,scratch.c,key); 304 ctx->cmac.u[0] ^= scratch.u[0]; 305 ctx->cmac.u[1] ^= scratch.u[1]; 306 307 ctx->nonce.c[0] = flags0; 308 309 return 0; 310 } 311 312 static void ctr64_add (unsigned char *counter,size_t inc) 313 { size_t n=8, val=0; 314 315 counter += 8; 316 do { 317 --n; 318 val += counter[n] + (inc&0xff); 319 counter[n] = (unsigned char)val; 320 val >>= 8; /* carry bit */ 321 inc >>= 8; 322 } while(n && (inc || val)); 323 } 324 325 int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, 326 const unsigned char *inp, unsigned char *out, 327 size_t len,ccm128_f stream) 328 { 329 size_t n; 330 unsigned int i,L; 331 unsigned char flags0 = ctx->nonce.c[0]; 332 block128_f block = ctx->block; 333 void * key = ctx->key; 334 union { u64 u[2]; u8 c[16]; } scratch; 335 336 if (!(flags0&0x40)) 337 (*block)(ctx->nonce.c,ctx->cmac.c,key), 338 ctx->blocks++; 339 340 ctx->nonce.c[0] = L = flags0&7; 341 for (n=0,i=15-L;i<15;++i) { 342 n |= ctx->nonce.c[i]; 343 ctx->nonce.c[i]=0; 344 n <<= 8; 345 } 346 n |= ctx->nonce.c[15]; /* reconstructed length */ 347 ctx->nonce.c[15]=1; 348 349 if (n!=len) return -1; /* length mismatch */ 350 351 ctx->blocks += ((len+15)>>3)|1; 352 if (ctx->blocks > (U64(1)<<61)) return -2; /* too much data */ 353 354 if ((n=len/16)) { 355 (*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c); 356 n *= 16; 357 inp += n; 358 out += n; 359 len -= n; 360 if (len) ctr64_add(ctx->nonce.c,n/16); 361 } 362 363 if (len) { 364 for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i]; 365 (*block)(ctx->cmac.c,ctx->cmac.c,key); 366 (*block)(ctx->nonce.c,scratch.c,key); 367 for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i]; 368 } 369 370 for (i=15-L;i<16;++i) 371 ctx->nonce.c[i]=0; 372 373 (*block)(ctx->nonce.c,scratch.c,key); 374 ctx->cmac.u[0] ^= scratch.u[0]; 375 ctx->cmac.u[1] ^= scratch.u[1]; 376 377 ctx->nonce.c[0] = flags0; 378 379 return 0; 380 } 381 382 int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, 383 const unsigned char *inp, unsigned char *out, 384 size_t len,ccm128_f stream) 385 { 386 size_t n; 387 unsigned int i,L; 388 unsigned char flags0 = ctx->nonce.c[0]; 389 block128_f block = ctx->block; 390 void * key = ctx->key; 391 union { u64 u[2]; u8 c[16]; } scratch; 392 393 if (!(flags0&0x40)) 394 (*block)(ctx->nonce.c,ctx->cmac.c,key); 395 396 ctx->nonce.c[0] = L = flags0&7; 397 for (n=0,i=15-L;i<15;++i) { 398 n |= ctx->nonce.c[i]; 399 ctx->nonce.c[i]=0; 400 n <<= 8; 401 } 402 n |= ctx->nonce.c[15]; /* reconstructed length */ 403 ctx->nonce.c[15]=1; 404 405 if (n!=len) return -1; 406 407 if ((n=len/16)) { 408 (*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c); 409 n *= 16; 410 inp += n; 411 out += n; 412 len -= n; 413 if (len) ctr64_add(ctx->nonce.c,n/16); 414 } 415 416 if (len) { 417 (*block)(ctx->nonce.c,scratch.c,key); 418 for (i=0; i<len; ++i) 419 ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]); 420 (*block)(ctx->cmac.c,ctx->cmac.c,key); 421 } 422 423 for (i=15-L;i<16;++i) 424 ctx->nonce.c[i]=0; 425 426 (*block)(ctx->nonce.c,scratch.c,key); 427 ctx->cmac.u[0] ^= scratch.u[0]; 428 ctx->cmac.u[1] ^= scratch.u[1]; 429 430 ctx->nonce.c[0] = flags0; 431 432 return 0; 433 } 434 435 size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx,unsigned char *tag,size_t len) 436 { unsigned int M = (ctx->nonce.c[0]>>3)&7; /* the M parameter */ 437 438 M *= 2; M += 2; 439 if (len<M) return 0; 440 memcpy(tag,ctx->cmac.c,M); 441 return M; 442 } 443