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