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