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