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