gcm.c (41680B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 /* Thanks to Thomas Pornin for the ideas how to implement the constat time 5 * binary multiplication. */ 6 7 #ifdef FREEBL_NO_DEPEND 8 #include "stubs.h" 9 #endif 10 #include "blapii.h" 11 #include "blapit.h" 12 #include "blapi.h" 13 #include "gcm.h" 14 #include "ctr.h" 15 #include "secerr.h" 16 #include "prtypes.h" 17 #include "pkcs11t.h" 18 19 #include <limits.h> 20 21 /* old gcc doesn't support some poly64x2_t intrinsic */ 22 #if defined(__aarch64__) && defined(IS_LITTLE_ENDIAN) && \ 23 (defined(__clang__) || defined(__GNUC__) && __GNUC__ > 6) 24 #define USE_ARM_GCM 25 #elif defined(__arm__) && defined(IS_LITTLE_ENDIAN) && \ 26 !defined(NSS_DISABLE_ARM32_NEON) 27 /* We don't test on big endian platform, so disable this on big endian. */ 28 #define USE_ARM_GCM 29 #endif 30 31 #if defined(__ARM_NEON) || defined(__ARM_NEON__) 32 #include <arm_neon.h> 33 #endif 34 35 /* Forward declarations */ 36 SECStatus gcm_HashInit_hw(gcmHashContext *ghash); 37 SECStatus gcm_HashWrite_hw(gcmHashContext *ghash, unsigned char *outbuf); 38 SECStatus gcm_HashMult_hw(gcmHashContext *ghash, const unsigned char *buf, 39 unsigned int count); 40 SECStatus gcm_HashZeroX_hw(gcmHashContext *ghash); 41 SECStatus gcm_HashMult_sftw(gcmHashContext *ghash, const unsigned char *buf, 42 unsigned int count); 43 SECStatus gcm_HashMult_sftw32(gcmHashContext *ghash, const unsigned char *buf, 44 unsigned int count); 45 46 /* Stub definitions for the above *_hw functions, which shouldn't be 47 * used unless NSS_X86_OR_X64 is defined */ 48 #if !defined(NSS_X86_OR_X64) && !defined(USE_ARM_GCM) && !defined(USE_PPC_CRYPTO) 49 SECStatus 50 gcm_HashWrite_hw(gcmHashContext *ghash, unsigned char *outbuf) 51 { 52 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 53 return SECFailure; 54 } 55 56 SECStatus 57 gcm_HashMult_hw(gcmHashContext *ghash, const unsigned char *buf, 58 unsigned int count) 59 { 60 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 61 return SECFailure; 62 } 63 64 SECStatus 65 gcm_HashInit_hw(gcmHashContext *ghash) 66 { 67 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 68 return SECFailure; 69 } 70 71 SECStatus 72 gcm_HashZeroX_hw(gcmHashContext *ghash) 73 { 74 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 75 return SECFailure; 76 } 77 #endif /* !NSS_X86_OR_X64 && !USE_ARM_GCM && !USE_PPC_CRYPTO */ 78 79 uint64_t 80 get64(const unsigned char *bytes) 81 { 82 return ((uint64_t)bytes[0]) << 56 | 83 ((uint64_t)bytes[1]) << 48 | 84 ((uint64_t)bytes[2]) << 40 | 85 ((uint64_t)bytes[3]) << 32 | 86 ((uint64_t)bytes[4]) << 24 | 87 ((uint64_t)bytes[5]) << 16 | 88 ((uint64_t)bytes[6]) << 8 | 89 ((uint64_t)bytes[7]); 90 } 91 92 /* Initialize a gcmHashContext */ 93 SECStatus 94 gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H, PRBool sw) 95 { 96 SECStatus rv = SECSuccess; 97 98 ghash->cLen = 0; 99 ghash->bufLen = 0; 100 PORT_Memset(ghash->counterBuf, 0, sizeof(ghash->counterBuf)); 101 102 ghash->h_low = get64(H + 8); 103 ghash->h_high = get64(H); 104 #ifdef USE_ARM_GCM 105 #if defined(__aarch64__) 106 if (arm_pmull_support() && !sw) { 107 #else 108 if (arm_neon_support() && !sw) { 109 #endif 110 #elif defined(USE_PPC_CRYPTO) 111 if (ppc_crypto_support() && !sw) { 112 #else 113 if (clmul_support() && !sw) { 114 #endif 115 rv = gcm_HashInit_hw(ghash); 116 } else { 117 /* We fall back to the software implementation if we can't use / don't 118 * want to use pclmul. */ 119 #ifdef HAVE_INT128_SUPPORT 120 ghash->ghash_mul = gcm_HashMult_sftw; 121 #else 122 ghash->ghash_mul = gcm_HashMult_sftw32; 123 #endif 124 ghash->x_high = ghash->x_low = 0; 125 ghash->hw = PR_FALSE; 126 } 127 return rv; 128 } 129 130 #ifdef HAVE_INT128_SUPPORT 131 /* Binary multiplication x * y = r_high << 64 | r_low. */ 132 void 133 bmul(uint64_t x, uint64_t y, uint64_t *r_high, uint64_t *r_low) 134 { 135 uint128_t x1, x2, x3, x4, x5; 136 uint128_t y1, y2, y3, y4, y5; 137 uint128_t r, z; 138 139 uint128_t m1 = (uint128_t)0x2108421084210842 << 64 | 0x1084210842108421; 140 uint128_t m2 = (uint128_t)0x4210842108421084 << 64 | 0x2108421084210842; 141 uint128_t m3 = (uint128_t)0x8421084210842108 << 64 | 0x4210842108421084; 142 uint128_t m4 = (uint128_t)0x0842108421084210 << 64 | 0x8421084210842108; 143 uint128_t m5 = (uint128_t)0x1084210842108421 << 64 | 0x0842108421084210; 144 145 x1 = x & m1; 146 y1 = y & m1; 147 x2 = x & m2; 148 y2 = y & m2; 149 x3 = x & m3; 150 y3 = y & m3; 151 x4 = x & m4; 152 y4 = y & m4; 153 x5 = x & m5; 154 y5 = y & m5; 155 156 z = (x1 * y1) ^ (x2 * y5) ^ (x3 * y4) ^ (x4 * y3) ^ (x5 * y2); 157 r = z & m1; 158 z = (x1 * y2) ^ (x2 * y1) ^ (x3 * y5) ^ (x4 * y4) ^ (x5 * y3); 159 r |= z & m2; 160 z = (x1 * y3) ^ (x2 * y2) ^ (x3 * y1) ^ (x4 * y5) ^ (x5 * y4); 161 r |= z & m3; 162 z = (x1 * y4) ^ (x2 * y3) ^ (x3 * y2) ^ (x4 * y1) ^ (x5 * y5); 163 r |= z & m4; 164 z = (x1 * y5) ^ (x2 * y4) ^ (x3 * y3) ^ (x4 * y2) ^ (x5 * y1); 165 r |= z & m5; 166 167 *r_high = (uint64_t)(r >> 64); 168 *r_low = (uint64_t)r; 169 } 170 171 SECStatus 172 gcm_HashMult_sftw(gcmHashContext *ghash, const unsigned char *buf, 173 unsigned int count) 174 { 175 uint64_t ci_low, ci_high; 176 size_t i; 177 uint64_t z2_low, z2_high, z0_low, z0_high, z1a_low, z1a_high; 178 uint128_t z_high = 0, z_low = 0; 179 180 ci_low = ghash->x_low; 181 ci_high = ghash->x_high; 182 for (i = 0; i < count; i++, buf += 16) { 183 ci_low ^= get64(buf + 8); 184 ci_high ^= get64(buf); 185 186 /* Do binary mult ghash->X = C * ghash->H (Karatsuba). */ 187 bmul(ci_high, ghash->h_high, &z2_high, &z2_low); 188 bmul(ci_low, ghash->h_low, &z0_high, &z0_low); 189 bmul(ci_high ^ ci_low, ghash->h_high ^ ghash->h_low, &z1a_high, &z1a_low); 190 z1a_high ^= z2_high ^ z0_high; 191 z1a_low ^= z2_low ^ z0_low; 192 z_high = ((uint128_t)z2_high << 64) | (z2_low ^ z1a_high); 193 z_low = (((uint128_t)z0_high << 64) | z0_low) ^ (((uint128_t)z1a_low) << 64); 194 195 /* Shift one (multiply by x) as gcm spec is stupid. */ 196 z_high = (z_high << 1) | (z_low >> 127); 197 z_low <<= 1; 198 199 /* Reduce */ 200 z_low ^= (z_low << 127) ^ (z_low << 126) ^ (z_low << 121); 201 z_high ^= z_low ^ (z_low >> 1) ^ (z_low >> 2) ^ (z_low >> 7); 202 ci_low = (uint64_t)z_high; 203 ci_high = (uint64_t)(z_high >> 64); 204 } 205 ghash->x_low = ci_low; 206 ghash->x_high = ci_high; 207 return SECSuccess; 208 } 209 #else 210 /* Binary multiplication x * y = r_high << 32 | r_low. */ 211 void 212 bmul32(uint32_t x, uint32_t y, uint32_t *r_high, uint32_t *r_low) 213 { 214 uint32_t x0, x1, x2, x3; 215 uint32_t y0, y1, y2, y3; 216 uint32_t m1 = (uint32_t)0x11111111; 217 uint32_t m2 = (uint32_t)0x22222222; 218 uint32_t m4 = (uint32_t)0x44444444; 219 uint32_t m8 = (uint32_t)0x88888888; 220 uint64_t z0, z1, z2, z3; 221 uint64_t z; 222 223 x0 = x & m1; 224 x1 = x & m2; 225 x2 = x & m4; 226 x3 = x & m8; 227 y0 = y & m1; 228 y1 = y & m2; 229 y2 = y & m4; 230 y3 = y & m8; 231 z0 = ((uint64_t)x0 * y0) ^ ((uint64_t)x1 * y3) ^ 232 ((uint64_t)x2 * y2) ^ ((uint64_t)x3 * y1); 233 z1 = ((uint64_t)x0 * y1) ^ ((uint64_t)x1 * y0) ^ 234 ((uint64_t)x2 * y3) ^ ((uint64_t)x3 * y2); 235 z2 = ((uint64_t)x0 * y2) ^ ((uint64_t)x1 * y1) ^ 236 ((uint64_t)x2 * y0) ^ ((uint64_t)x3 * y3); 237 z3 = ((uint64_t)x0 * y3) ^ ((uint64_t)x1 * y2) ^ 238 ((uint64_t)x2 * y1) ^ ((uint64_t)x3 * y0); 239 z0 &= ((uint64_t)m1 << 32) | m1; 240 z1 &= ((uint64_t)m2 << 32) | m2; 241 z2 &= ((uint64_t)m4 << 32) | m4; 242 z3 &= ((uint64_t)m8 << 32) | m8; 243 z = z0 | z1 | z2 | z3; 244 *r_high = (uint32_t)(z >> 32); 245 *r_low = (uint32_t)z; 246 } 247 248 SECStatus 249 gcm_HashMult_sftw32(gcmHashContext *ghash, const unsigned char *buf, 250 unsigned int count) 251 { 252 size_t i; 253 uint64_t ci_low, ci_high; 254 uint64_t z_high_h, z_high_l, z_low_h, z_low_l; 255 uint32_t ci_high_h, ci_high_l, ci_low_h, ci_low_l; 256 uint32_t b_a_h, b_a_l, a_a_h, a_a_l, b_b_h, b_b_l; 257 uint32_t a_b_h, a_b_l, b_c_h, b_c_l, a_c_h, a_c_l, c_c_h, c_c_l; 258 uint32_t ci_highXlow_h, ci_highXlow_l, c_a_h, c_a_l, c_b_h, c_b_l; 259 260 uint32_t h_high_h = (uint32_t)(ghash->h_high >> 32); 261 uint32_t h_high_l = (uint32_t)ghash->h_high; 262 uint32_t h_low_h = (uint32_t)(ghash->h_low >> 32); 263 uint32_t h_low_l = (uint32_t)ghash->h_low; 264 uint32_t h_highXlow_h = h_high_h ^ h_low_h; 265 uint32_t h_highXlow_l = h_high_l ^ h_low_l; 266 uint32_t h_highX_xored = h_highXlow_h ^ h_highXlow_l; 267 268 for (i = 0; i < count; i++, buf += 16) { 269 ci_low = ghash->x_low ^ get64(buf + 8); 270 ci_high = ghash->x_high ^ get64(buf); 271 ci_low_h = (uint32_t)(ci_low >> 32); 272 ci_low_l = (uint32_t)ci_low; 273 ci_high_h = (uint32_t)(ci_high >> 32); 274 ci_high_l = (uint32_t)ci_high; 275 ci_highXlow_h = ci_high_h ^ ci_low_h; 276 ci_highXlow_l = ci_high_l ^ ci_low_l; 277 278 /* Do binary mult ghash->X = C * ghash->H (recursive Karatsuba). */ 279 bmul32(ci_high_h, h_high_h, &a_a_h, &a_a_l); 280 bmul32(ci_high_l, h_high_l, &a_b_h, &a_b_l); 281 bmul32(ci_high_h ^ ci_high_l, h_high_h ^ h_high_l, &a_c_h, &a_c_l); 282 a_c_h ^= a_a_h ^ a_b_h; 283 a_c_l ^= a_a_l ^ a_b_l; 284 a_a_l ^= a_c_h; 285 a_b_h ^= a_c_l; 286 /* ci_high * h_high = a_a_h:a_a_l:a_b_h:a_b_l */ 287 288 bmul32(ci_low_h, h_low_h, &b_a_h, &b_a_l); 289 bmul32(ci_low_l, h_low_l, &b_b_h, &b_b_l); 290 bmul32(ci_low_h ^ ci_low_l, h_low_h ^ h_low_l, &b_c_h, &b_c_l); 291 b_c_h ^= b_a_h ^ b_b_h; 292 b_c_l ^= b_a_l ^ b_b_l; 293 b_a_l ^= b_c_h; 294 b_b_h ^= b_c_l; 295 /* ci_low * h_low = b_a_h:b_a_l:b_b_h:b_b_l */ 296 297 bmul32(ci_highXlow_h, h_highXlow_h, &c_a_h, &c_a_l); 298 bmul32(ci_highXlow_l, h_highXlow_l, &c_b_h, &c_b_l); 299 bmul32(ci_highXlow_h ^ ci_highXlow_l, h_highX_xored, &c_c_h, &c_c_l); 300 c_c_h ^= c_a_h ^ c_b_h; 301 c_c_l ^= c_a_l ^ c_b_l; 302 c_a_l ^= c_c_h; 303 c_b_h ^= c_c_l; 304 /* (ci_high ^ ci_low) * (h_high ^ h_low) = c_a_h:c_a_l:c_b_h:c_b_l */ 305 306 c_a_h ^= b_a_h ^ a_a_h; 307 c_a_l ^= b_a_l ^ a_a_l; 308 c_b_h ^= b_b_h ^ a_b_h; 309 c_b_l ^= b_b_l ^ a_b_l; 310 z_high_h = ((uint64_t)a_a_h << 32) | a_a_l; 311 z_high_l = (((uint64_t)a_b_h << 32) | a_b_l) ^ 312 (((uint64_t)c_a_h << 32) | c_a_l); 313 z_low_h = (((uint64_t)b_a_h << 32) | b_a_l) ^ 314 (((uint64_t)c_b_h << 32) | c_b_l); 315 z_low_l = ((uint64_t)b_b_h << 32) | b_b_l; 316 317 /* Shift one (multiply by x) as gcm spec is stupid. */ 318 z_high_h = z_high_h << 1 | z_high_l >> 63; 319 z_high_l = z_high_l << 1 | z_low_h >> 63; 320 z_low_h = z_low_h << 1 | z_low_l >> 63; 321 z_low_l <<= 1; 322 323 /* Reduce */ 324 z_low_h ^= (z_low_l << 63) ^ (z_low_l << 62) ^ (z_low_l << 57); 325 z_high_h ^= z_low_h ^ (z_low_h >> 1) ^ (z_low_h >> 2) ^ (z_low_h >> 7); 326 z_high_l ^= z_low_l ^ (z_low_l >> 1) ^ (z_low_l >> 2) ^ (z_low_l >> 7) ^ 327 (z_low_h << 63) ^ (z_low_h << 62) ^ (z_low_h << 57); 328 ghash->x_high = z_high_h; 329 ghash->x_low = z_high_l; 330 } 331 return SECSuccess; 332 } 333 #endif /* HAVE_INT128_SUPPORT */ 334 335 static SECStatus 336 gcm_zeroX(gcmHashContext *ghash) 337 { 338 SECStatus rv = SECSuccess; 339 340 if (ghash->hw) { 341 rv = gcm_HashZeroX_hw(ghash); 342 } 343 344 ghash->x_high = ghash->x_low = 0; 345 return rv; 346 } 347 348 /* 349 * implement GCM GHASH using the freebl GHASH function. The gcm_HashMult 350 * function always takes AES_BLOCK_SIZE lengths of data. gcmHash_Update will 351 * format the data properly. 352 */ 353 SECStatus 354 gcmHash_Update(gcmHashContext *ghash, const unsigned char *buf, 355 unsigned int len) 356 { 357 unsigned int blocks; 358 SECStatus rv; 359 360 ghash->cLen += (len * PR_BITS_PER_BYTE); 361 362 /* first deal with the current buffer of data. Try to fill it out so 363 * we can hash it */ 364 if (ghash->bufLen) { 365 unsigned int needed = PR_MIN(len, AES_BLOCK_SIZE - ghash->bufLen); 366 if (needed != 0) { 367 PORT_Memcpy(ghash->buffer + ghash->bufLen, buf, needed); 368 } 369 buf += needed; 370 len -= needed; 371 ghash->bufLen += needed; 372 if (len == 0) { 373 /* didn't add enough to hash the data, nothing more do do */ 374 return SECSuccess; 375 } 376 PORT_Assert(ghash->bufLen == AES_BLOCK_SIZE); 377 /* hash the buffer and clear it */ 378 rv = ghash->ghash_mul(ghash, ghash->buffer, 1); 379 PORT_Memset(ghash->buffer, 0, AES_BLOCK_SIZE); 380 ghash->bufLen = 0; 381 if (rv != SECSuccess) { 382 return SECFailure; 383 } 384 } 385 /* now hash any full blocks remaining in the data stream */ 386 blocks = len / AES_BLOCK_SIZE; 387 if (blocks) { 388 rv = ghash->ghash_mul(ghash, buf, blocks); 389 if (rv != SECSuccess) { 390 return SECFailure; 391 } 392 buf += blocks * AES_BLOCK_SIZE; 393 len -= blocks * AES_BLOCK_SIZE; 394 } 395 396 /* save any remainder in the buffer to be hashed with the next call */ 397 if (len != 0) { 398 PORT_Memcpy(ghash->buffer, buf, len); 399 ghash->bufLen = len; 400 } 401 return SECSuccess; 402 } 403 404 /* 405 * write out any partial blocks zero padded through the GHASH engine, 406 * save the lengths for the final completion of the hash 407 */ 408 static SECStatus 409 gcmHash_Sync(gcmHashContext *ghash) 410 { 411 int i; 412 SECStatus rv; 413 414 /* copy the previous counter to the upper block */ 415 PORT_Memcpy(ghash->counterBuf, &ghash->counterBuf[GCM_HASH_LEN_LEN], 416 GCM_HASH_LEN_LEN); 417 /* copy the current counter in the lower block */ 418 for (i = 0; i < GCM_HASH_LEN_LEN; i++) { 419 ghash->counterBuf[GCM_HASH_LEN_LEN + i] = 420 (ghash->cLen >> ((GCM_HASH_LEN_LEN - 1 - i) * PR_BITS_PER_BYTE)) & 0xff; 421 } 422 ghash->cLen = 0; 423 424 /* now zero fill the buffer and hash the last block */ 425 if (ghash->bufLen) { 426 PORT_Memset(ghash->buffer + ghash->bufLen, 0, AES_BLOCK_SIZE - ghash->bufLen); 427 rv = ghash->ghash_mul(ghash, ghash->buffer, 1); 428 PORT_Memset(ghash->buffer, 0, AES_BLOCK_SIZE); 429 ghash->bufLen = 0; 430 if (rv != SECSuccess) { 431 return SECFailure; 432 } 433 } 434 return SECSuccess; 435 } 436 437 #define WRITE64(x, bytes) \ 438 (bytes)[0] = (x) >> 56; \ 439 (bytes)[1] = (x) >> 48; \ 440 (bytes)[2] = (x) >> 40; \ 441 (bytes)[3] = (x) >> 32; \ 442 (bytes)[4] = (x) >> 24; \ 443 (bytes)[5] = (x) >> 16; \ 444 (bytes)[6] = (x) >> 8; \ 445 (bytes)[7] = (x); 446 447 /* 448 * This does the final sync, hashes the lengths, then returns 449 * "T", the hashed output. 450 */ 451 SECStatus 452 gcmHash_Final(gcmHashContext *ghash, unsigned char *outbuf, 453 unsigned int *outlen, unsigned int maxout) 454 { 455 unsigned char T[MAX_BLOCK_SIZE]; 456 SECStatus rv; 457 458 rv = gcmHash_Sync(ghash); 459 if (rv != SECSuccess) { 460 goto cleanup; 461 } 462 463 rv = ghash->ghash_mul(ghash, ghash->counterBuf, 464 (GCM_HASH_LEN_LEN * 2) / AES_BLOCK_SIZE); 465 if (rv != SECSuccess) { 466 goto cleanup; 467 } 468 469 if (ghash->hw) { 470 rv = gcm_HashWrite_hw(ghash, T); 471 if (rv != SECSuccess) { 472 goto cleanup; 473 } 474 } else { 475 WRITE64(ghash->x_low, T + 8); 476 WRITE64(ghash->x_high, T); 477 } 478 479 if (maxout > AES_BLOCK_SIZE) { 480 maxout = AES_BLOCK_SIZE; 481 } 482 PORT_Memcpy(outbuf, T, maxout); 483 *outlen = maxout; 484 rv = SECSuccess; 485 486 cleanup: 487 PORT_SafeZero(T, sizeof(T)); 488 return rv; 489 } 490 491 SECStatus 492 gcmHash_Reset(gcmHashContext *ghash, const unsigned char *AAD, 493 unsigned int AADLen) 494 { 495 SECStatus rv; 496 497 // Limit AADLen in accordance with SP800-38D 498 if (sizeof(AADLen) >= 8) { 499 unsigned long long AADLen_ull = AADLen; 500 if (AADLen_ull > (1ULL << 61) - 1) { 501 PORT_SetError(SEC_ERROR_INPUT_LEN); 502 return SECFailure; 503 } 504 } 505 506 ghash->cLen = 0; 507 PORT_Memset(ghash->counterBuf, 0, GCM_HASH_LEN_LEN * 2); 508 ghash->bufLen = 0; 509 rv = gcm_zeroX(ghash); 510 if (rv != SECSuccess) { 511 return rv; 512 } 513 514 /* now kick things off by hashing the Additional Authenticated Data */ 515 if (AADLen != 0) { 516 rv = gcmHash_Update(ghash, AAD, AADLen); 517 if (rv != SECSuccess) { 518 return SECFailure; 519 } 520 rv = gcmHash_Sync(ghash); 521 if (rv != SECSuccess) { 522 return SECFailure; 523 } 524 } 525 return SECSuccess; 526 } 527 528 /************************************************************************** 529 * Now implement the GCM using gcmHash and CTR * 530 **************************************************************************/ 531 532 /* state to handle the full GCM operation (hash and counter) */ 533 struct GCMContextStr { 534 gcmHashContext *ghash_context; 535 CTRContext ctr_context; 536 freeblCipherFunc cipher; 537 void *cipher_context; 538 unsigned long tagBits; 539 unsigned char tagKey[MAX_BLOCK_SIZE]; 540 PRBool ctr_context_init; 541 gcmIVContext gcm_iv; 542 }; 543 544 SECStatus gcm_InitCounter(GCMContext *gcm, const unsigned char *iv, 545 unsigned int ivLen, unsigned int tagBits, 546 const unsigned char *aad, unsigned int aadLen); 547 548 GCMContext * 549 GCM_CreateContext(void *context, freeblCipherFunc cipher, 550 const unsigned char *params) 551 { 552 GCMContext *gcm = NULL; 553 gcmHashContext *ghash = NULL; 554 unsigned char H[MAX_BLOCK_SIZE]; 555 unsigned int tmp; 556 const CK_NSS_GCM_PARAMS *gcmParams = (const CK_NSS_GCM_PARAMS *)params; 557 SECStatus rv; 558 #ifdef DISABLE_HW_GCM 559 const PRBool sw = PR_TRUE; 560 #else 561 const PRBool sw = PR_FALSE; 562 #endif 563 564 gcm = PORT_ZNew(GCMContext); 565 if (gcm == NULL) { 566 return NULL; 567 } 568 gcm->cipher = cipher; 569 gcm->cipher_context = context; 570 ghash = PORT_ZNewAligned(gcmHashContext, 16, mem); 571 572 /* first plug in the ghash context */ 573 gcm->ghash_context = ghash; 574 PORT_Memset(H, 0, AES_BLOCK_SIZE); 575 rv = (*cipher)(context, H, &tmp, AES_BLOCK_SIZE, H, AES_BLOCK_SIZE, AES_BLOCK_SIZE); 576 if (rv != SECSuccess) { 577 goto loser; 578 } 579 rv = gcmHash_InitContext(ghash, H, sw); 580 if (rv != SECSuccess) { 581 goto loser; 582 } 583 584 gcm_InitIVContext(&gcm->gcm_iv); 585 gcm->ctr_context_init = PR_FALSE; 586 587 /* if gcmPara/ms is NULL, then we are creating an PKCS #11 MESSAGE 588 * style context, in which we initialize the key once, then do separate 589 * iv/aad's for each message. In that case we only initialize the key 590 * and ghash. We initialize the counter in each separate message */ 591 if (gcmParams == NULL) { 592 /* OK we are finished with init, if we are doing MESSAGE interface, 593 * return from here */ 594 return gcm; 595 } 596 597 rv = gcm_InitCounter(gcm, gcmParams->pIv, gcmParams->ulIvLen, 598 gcmParams->ulTagBits, gcmParams->pAAD, 599 gcmParams->ulAADLen); 600 if (rv != SECSuccess) { 601 goto loser; 602 } 603 PORT_SafeZero(H, AES_BLOCK_SIZE); 604 gcm->ctr_context_init = PR_TRUE; 605 return gcm; 606 607 loser: 608 PORT_SafeZero(H, AES_BLOCK_SIZE); 609 if (ghash && ghash->mem) { 610 void *mem = ghash->mem; 611 PORT_SafeZero(ghash, sizeof(gcmHashContext)); 612 PORT_Free(mem); 613 } 614 if (gcm) { 615 PORT_ZFree(gcm, sizeof(GCMContext)); 616 } 617 return NULL; 618 } 619 620 static inline unsigned int 621 load32_be(const unsigned char *p) 622 { 623 return ((unsigned int)p[0]) << 24 | p[1] << 16 | p[2] << 8 | p[3]; 624 } 625 626 static inline void 627 store32_be(unsigned char *p, const unsigned int c) 628 { 629 p[0] = (unsigned char)(c >> 24); 630 p[1] = (unsigned char)(c >> 16); 631 p[2] = (unsigned char)(c >> 8); 632 p[3] = (unsigned char)c; 633 } 634 635 static inline void 636 gcm_ctr_xor(unsigned char *target, const unsigned char *x, 637 const unsigned char *y, unsigned int count) 638 { 639 for (unsigned int i = 0; i < count; i++) { 640 target[i] = x[i] ^ y[i]; 641 } 642 } 643 644 static inline void 645 gcm_ctr_xor_block(unsigned char *target, const unsigned char *x, 646 const unsigned char *y) 647 { 648 #if defined(__ARM_NEON) || defined(__ARM_NEON__) 649 vst1q_u8(target, veorq_u8(vld1q_u8(x), vld1q_u8(y))); 650 #else 651 gcm_ctr_xor(target, x, y, AES_BLOCK_SIZE); 652 #endif 653 } 654 655 static SECStatus 656 gcm_CTR_Update(CTRContext *ctr, unsigned char *outbuf, 657 unsigned int *outlen, unsigned int maxout, 658 const unsigned char *inbuf, unsigned int inlen) 659 { 660 PORT_Assert(ctr->counterBits == 32); 661 PORT_Assert(0 < ctr->bufPtr && ctr->bufPtr <= AES_BLOCK_SIZE); 662 663 // The AES-GCM message length limit is 2^32 - 2 blocks. 664 const unsigned int blockLimit = 0xFFFFFFFEUL; 665 666 unsigned char *const pCounter = ctr->counter + AES_BLOCK_SIZE - 4; 667 unsigned int counter = load32_be(pCounter); 668 669 // Calculate the number of times that the counter has already been incremented. 670 unsigned char *const pCounterFirst = ctr->counterFirst + AES_BLOCK_SIZE - 4; 671 unsigned int ticks = (counter - load32_be(pCounterFirst)) & 0xFFFFFFFFUL; 672 673 // Get the number of bytes of keystream that are available in the internal buffer. 674 const unsigned int bufBytes = AES_BLOCK_SIZE - ctr->bufPtr; 675 676 // Calculate the number of times that we will increment the counter while 677 // encrypting inbuf. We can encrypt bufBytes bytes of the input without 678 // incrementing the counter. 679 unsigned int newTicks; 680 if (inlen < bufBytes) { 681 newTicks = 0; 682 } else if ((inlen - bufBytes) % AES_BLOCK_SIZE) { 683 newTicks = ((inlen - bufBytes) / AES_BLOCK_SIZE) + 1; 684 } else { 685 newTicks = ((inlen - bufBytes) / AES_BLOCK_SIZE); 686 } 687 688 // Ensure that the counter will not exceed the limit. 689 if (ticks > blockLimit - newTicks) { 690 PORT_SetError(SEC_ERROR_INPUT_LEN); 691 return SECFailure; 692 } 693 694 *outlen = inlen; 695 if (maxout < inlen) { 696 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 697 return SECFailure; 698 } 699 700 if (bufBytes) { 701 unsigned int needed = PR_MIN(bufBytes, inlen); 702 gcm_ctr_xor(outbuf, inbuf, ctr->buffer + ctr->bufPtr, needed); 703 ctr->bufPtr += needed; 704 outbuf += needed; 705 inbuf += needed; 706 inlen -= needed; 707 PORT_Assert(inlen == 0 || ctr->bufPtr == AES_BLOCK_SIZE); 708 } 709 while (inlen >= AES_BLOCK_SIZE) { 710 unsigned int tmp; 711 SECStatus rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, AES_BLOCK_SIZE, 712 ctr->counter, AES_BLOCK_SIZE, AES_BLOCK_SIZE); 713 PORT_Assert(rv == SECSuccess); 714 (void)rv; 715 store32_be(pCounter, ++counter); 716 gcm_ctr_xor_block(outbuf, inbuf, ctr->buffer); 717 outbuf += AES_BLOCK_SIZE; 718 inbuf += AES_BLOCK_SIZE; 719 inlen -= AES_BLOCK_SIZE; 720 } 721 if (inlen) { 722 unsigned int tmp; 723 SECStatus rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, AES_BLOCK_SIZE, 724 ctr->counter, AES_BLOCK_SIZE, AES_BLOCK_SIZE); 725 PORT_Assert(rv == SECSuccess); 726 (void)rv; 727 store32_be(pCounter, ++counter); 728 gcm_ctr_xor(outbuf, inbuf, ctr->buffer, inlen); 729 ctr->bufPtr = inlen; 730 } 731 return SECSuccess; 732 } 733 734 SECStatus 735 gcm_InitCounter(GCMContext *gcm, const unsigned char *iv, unsigned int ivLen, 736 unsigned int tagBits, const unsigned char *aad, 737 unsigned int aadLen) 738 { 739 gcmHashContext *ghash = gcm->ghash_context; 740 unsigned int tmp; 741 PRBool freeCtr = PR_FALSE; 742 CK_AES_CTR_PARAMS ctrParams; 743 SECStatus rv; 744 745 /* Verify our parameters here */ 746 if (ivLen == 0) { 747 PORT_SetError(SEC_ERROR_INVALID_ARGS); 748 goto loser; 749 } 750 751 if (tagBits != 128 && tagBits != 120 && 752 tagBits != 112 && tagBits != 104 && 753 tagBits != 96 && tagBits != 64 && 754 tagBits != 32) { 755 PORT_SetError(SEC_ERROR_INVALID_ARGS); 756 goto loser; 757 } 758 759 /* fill in the Counter context */ 760 ctrParams.ulCounterBits = 32; 761 PORT_Memset(ctrParams.cb, 0, sizeof(ctrParams.cb)); 762 if (ivLen == 12) { 763 PORT_Memcpy(ctrParams.cb, iv, ivLen); 764 ctrParams.cb[AES_BLOCK_SIZE - 1] = 1; 765 } else { 766 rv = gcmHash_Reset(ghash, NULL, 0); 767 if (rv != SECSuccess) { 768 goto loser; 769 } 770 rv = gcmHash_Update(ghash, iv, ivLen); 771 if (rv != SECSuccess) { 772 goto loser; 773 } 774 rv = gcmHash_Final(ghash, ctrParams.cb, &tmp, AES_BLOCK_SIZE); 775 if (rv != SECSuccess) { 776 goto loser; 777 } 778 } 779 rv = CTR_InitContext(&gcm->ctr_context, gcm->cipher_context, gcm->cipher, 780 (unsigned char *)&ctrParams); 781 if (rv != SECSuccess) { 782 goto loser; 783 } 784 freeCtr = PR_TRUE; 785 786 /* fill in the gcm structure */ 787 gcm->tagBits = tagBits; /* save for final step */ 788 /* calculate the final tag key. NOTE: gcm->tagKey is zero to start with. 789 * if this assumption changes, we would need to explicitly clear it here */ 790 PORT_Memset(gcm->tagKey, 0, sizeof(gcm->tagKey)); 791 rv = gcm_CTR_Update(&gcm->ctr_context, gcm->tagKey, &tmp, AES_BLOCK_SIZE, 792 gcm->tagKey, AES_BLOCK_SIZE); 793 if (rv != SECSuccess) { 794 goto loser; 795 } 796 797 /* finally mix in the AAD data */ 798 rv = gcmHash_Reset(ghash, aad, aadLen); 799 if (rv != SECSuccess) { 800 goto loser; 801 } 802 803 PORT_SafeZero(&ctrParams, sizeof ctrParams); 804 return SECSuccess; 805 806 loser: 807 PORT_SafeZero(&ctrParams, sizeof ctrParams); 808 if (freeCtr) { 809 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE); 810 } 811 return SECFailure; 812 } 813 814 void 815 GCM_DestroyContext(GCMContext *gcm, PRBool freeit) 816 { 817 void *mem = gcm->ghash_context->mem; 818 /* ctr_context is statically allocated and will be freed when we free 819 * gcm. call their destroy functions to free up any locally 820 * allocated data (like mp_int's) */ 821 if (gcm->ctr_context_init) { 822 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE); 823 } 824 PORT_Memset(gcm->ghash_context, 0, sizeof(gcmHashContext)); 825 PORT_Free(mem); 826 PORT_Memset(&gcm->tagBits, 0, sizeof(gcm->tagBits)); 827 PORT_Memset(gcm->tagKey, 0, sizeof(gcm->tagKey)); 828 if (freeit) { 829 PORT_Free(gcm); 830 } 831 } 832 833 static SECStatus 834 gcm_GetTag(GCMContext *gcm, unsigned char *outbuf, 835 unsigned int *outlen, unsigned int maxout) 836 { 837 unsigned int tagBytes; 838 unsigned int extra; 839 unsigned int i; 840 SECStatus rv; 841 842 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE; 843 extra = tagBytes * PR_BITS_PER_BYTE - gcm->tagBits; 844 845 if (outbuf == NULL) { 846 *outlen = tagBytes; 847 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 848 return SECFailure; 849 } 850 851 if (maxout < tagBytes) { 852 *outlen = tagBytes; 853 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 854 return SECFailure; 855 } 856 maxout = tagBytes; 857 rv = gcmHash_Final(gcm->ghash_context, outbuf, outlen, maxout); 858 if (rv != SECSuccess) { 859 return SECFailure; 860 } 861 862 for (i = 0; i < *outlen; i++) { 863 outbuf[i] ^= gcm->tagKey[i]; 864 } 865 /* mask off any extra bits we got */ 866 if (extra) { 867 outbuf[tagBytes - 1] &= ~((1 << extra) - 1); 868 } 869 return SECSuccess; 870 } 871 872 /* 873 * See The Galois/Counter Mode of Operation, McGrew and Viega. 874 * GCM is basically counter mode with a specific initialization and 875 * built in macing operation. 876 */ 877 SECStatus 878 GCM_EncryptUpdate(GCMContext *gcm, unsigned char *outbuf, 879 unsigned int *outlen, unsigned int maxout, 880 const unsigned char *inbuf, unsigned int inlen, 881 unsigned int blocksize) 882 { 883 SECStatus rv; 884 unsigned int tagBytes; 885 unsigned int len; 886 887 PORT_Assert(blocksize == AES_BLOCK_SIZE); 888 if (blocksize != AES_BLOCK_SIZE) { 889 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 890 return SECFailure; 891 } 892 893 if (!gcm->ctr_context_init) { 894 PORT_SetError(SEC_ERROR_NOT_INITIALIZED); 895 return SECFailure; 896 } 897 898 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE; 899 if (UINT_MAX - inlen < tagBytes) { 900 PORT_SetError(SEC_ERROR_INPUT_LEN); 901 return SECFailure; 902 } 903 if (maxout < inlen + tagBytes) { 904 *outlen = inlen + tagBytes; 905 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 906 return SECFailure; 907 } 908 909 rv = gcm_CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout, 910 inbuf, inlen); 911 if (rv != SECSuccess) { 912 return SECFailure; 913 } 914 rv = gcmHash_Update(gcm->ghash_context, outbuf, *outlen); 915 if (rv != SECSuccess) { 916 PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */ 917 *outlen = 0; 918 return SECFailure; 919 } 920 rv = gcm_GetTag(gcm, outbuf + *outlen, &len, maxout - *outlen); 921 if (rv != SECSuccess) { 922 PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */ 923 *outlen = 0; 924 return SECFailure; 925 }; 926 *outlen += len; 927 return SECSuccess; 928 } 929 930 /* 931 * See The Galois/Counter Mode of Operation, McGrew and Viega. 932 * GCM is basically counter mode with a specific initialization and 933 * built in macing operation. NOTE: the only difference between Encrypt 934 * and Decrypt is when we calculate the mac. That is because the mac must 935 * always be calculated on the cipher text, not the plain text, so for 936 * encrypt, we do the CTR update first and for decrypt we do the mac first. 937 */ 938 SECStatus 939 GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf, 940 unsigned int *outlen, unsigned int maxout, 941 const unsigned char *inbuf, unsigned int inlen, 942 unsigned int blocksize) 943 { 944 SECStatus rv; 945 unsigned int tagBytes; 946 unsigned char tag[MAX_BLOCK_SIZE]; 947 const unsigned char *intag; 948 unsigned int len; 949 950 PORT_Assert(blocksize == AES_BLOCK_SIZE); 951 if (blocksize != AES_BLOCK_SIZE) { 952 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 953 return SECFailure; 954 } 955 956 if (!gcm->ctr_context_init) { 957 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 958 return SECFailure; 959 } 960 961 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE; 962 963 /* get the authentication block */ 964 if (inlen < tagBytes) { 965 PORT_SetError(SEC_ERROR_INPUT_LEN); 966 return SECFailure; 967 } 968 969 inlen -= tagBytes; 970 intag = inbuf + inlen; 971 972 /* verify the block */ 973 rv = gcmHash_Update(gcm->ghash_context, inbuf, inlen); 974 if (rv != SECSuccess) { 975 return SECFailure; 976 } 977 rv = gcm_GetTag(gcm, tag, &len, AES_BLOCK_SIZE); 978 if (rv != SECSuccess) { 979 return SECFailure; 980 } 981 /* Don't decrypt if we can't authenticate the encrypted data! 982 * This assumes that if tagBits is not a multiple of 8, intag will 983 * preserve the masked off missing bits. */ 984 if (NSS_SecureMemcmp(tag, intag, tagBytes) != 0) { 985 /* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */ 986 PORT_SetError(SEC_ERROR_BAD_DATA); 987 PORT_SafeZero(tag, sizeof(tag)); 988 return SECFailure; 989 } 990 PORT_SafeZero(tag, sizeof(tag)); 991 /* finish the decryption */ 992 return gcm_CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout, 993 inbuf, inlen); 994 } 995 996 void 997 gcm_InitIVContext(gcmIVContext *gcmIv) 998 { 999 gcmIv->counter = 0; 1000 gcmIv->max_count = 0; 1001 gcmIv->ivGen = CKG_GENERATE; 1002 gcmIv->ivLen = 0; 1003 gcmIv->fixedBits = 0; 1004 } 1005 1006 /* 1007 * generate the IV on the fly and return it to the application. 1008 * This function keeps a counter, which may be used in the IV 1009 * generation, or may be used in simply to make sure we don't 1010 * generate to many IV's from this same key. 1011 * PKCS #11 defines 4 generating values: 1012 * 1) CKG_NO_GENERATE: just use the passed in IV as it. 1013 * 2) CKG_GENERATE: the application doesn't care what generation 1014 * scheme is use (we default to counter in this code). 1015 * 3) CKG_GENERATE_COUNTER: The IV is the value of a counter. 1016 * 4) CKG_GENERATE_RANDOM: The IV is randomly generated. 1017 * We add a fifth rule: 1018 * 5) CKG_GENERATE_COUNTER_XOR: The Counter value is xor'ed with 1019 * the IV. 1020 * The value fixedBits specifies the number of bits that will be passed 1021 * on from the original IV. The counter or the random data is is loaded 1022 * in the remainder of the IV not covered by fixedBits, overwriting any 1023 * data there. In the xor case the counter is xor'ed with the data in the 1024 * IV. In all cases only bits outside of fixedBits is modified. 1025 * The number of IV's we can generate is restricted by the size of the 1026 * variable part of the IV and the generation algorithm used. Because of 1027 * this, we require subsequent calls on this context to use the same 1028 * generator, IV len, and fixed bits as the first call. 1029 */ 1030 SECStatus 1031 gcm_GenerateIV(gcmIVContext *gcmIv, unsigned char *iv, unsigned int ivLen, 1032 unsigned int fixedBits, CK_GENERATOR_FUNCTION ivGen) 1033 { 1034 unsigned int i; 1035 unsigned int flexBits; 1036 unsigned int ivOffset; 1037 unsigned int ivNewCount; 1038 unsigned char ivMask; 1039 unsigned char ivSave; 1040 SECStatus rv; 1041 1042 if (gcmIv->counter != 0) { 1043 /* If we've already generated a message, make sure all subsequent 1044 * messages are using the same generator */ 1045 if ((gcmIv->ivGen != ivGen) || (gcmIv->fixedBits != fixedBits) || 1046 (gcmIv->ivLen != ivLen)) { 1047 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1048 return SECFailure; 1049 } 1050 } else { 1051 /* remember these values */ 1052 gcmIv->ivGen = ivGen; 1053 gcmIv->fixedBits = fixedBits; 1054 gcmIv->ivLen = ivLen; 1055 /* now calculate how may bits of IV we have to supply */ 1056 flexBits = ivLen * PR_BITS_PER_BYTE; /* bytes->bits */ 1057 /* first make sure we aren't going to overflow */ 1058 if (flexBits < fixedBits) { 1059 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1060 return SECFailure; 1061 } 1062 flexBits -= fixedBits; 1063 /* if we are generating a random number reduce the acceptable bits to 1064 * avoid birthday attacks */ 1065 if (ivGen == CKG_GENERATE_RANDOM) { 1066 if (flexBits <= GCMIV_RANDOM_BIRTHDAY_BITS) { 1067 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1068 return SECFailure; 1069 } 1070 /* see freebl/blapit.h for how we calculate 1071 * GCMIV_RANDOM_BIRTHDAY_BITS */ 1072 flexBits -= GCMIV_RANDOM_BIRTHDAY_BITS; 1073 flexBits = flexBits >> 1; 1074 } 1075 if (flexBits == 0) { 1076 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1077 return SECFailure; 1078 } 1079 /* Turn those bits into the number of IV's we can safely return */ 1080 if (flexBits >= sizeof(gcmIv->max_count) * PR_BITS_PER_BYTE) { 1081 gcmIv->max_count = PR_UINT64(0xffffffffffffffff); 1082 } else { 1083 gcmIv->max_count = PR_UINT64(1) << flexBits; 1084 } 1085 } 1086 1087 /* no generate, accept the IV from the source */ 1088 if (ivGen == CKG_NO_GENERATE) { 1089 gcmIv->counter = 1; 1090 return SECSuccess; 1091 } 1092 1093 /* make sure we haven't exceeded the number of IVs we can return 1094 * for this key, generator, and IV size */ 1095 if (gcmIv->counter >= gcmIv->max_count) { 1096 /* use a unique error from just bad user input */ 1097 PORT_SetError(SEC_ERROR_EXTRA_INPUT); 1098 return SECFailure; 1099 } 1100 1101 /* build to mask to handle the first byte of the IV */ 1102 ivOffset = fixedBits / PR_BITS_PER_BYTE; 1103 ivMask = 0xff >> ((8 - (fixedBits & 7)) & 7); 1104 ivNewCount = ivLen - ivOffset; 1105 1106 /* finally generate the IV */ 1107 switch (ivGen) { 1108 case CKG_GENERATE: /* default to counter */ 1109 case CKG_GENERATE_COUNTER: 1110 iv[ivOffset] = (iv[ivOffset] & ~ivMask) | 1111 (PORT_GET_BYTE_BE(gcmIv->counter, 0, ivNewCount) & ivMask); 1112 for (i = 1; i < ivNewCount; i++) { 1113 iv[ivOffset + i] = PORT_GET_BYTE_BE(gcmIv->counter, i, ivNewCount); 1114 } 1115 break; 1116 /* for TLS 1.3 */ 1117 case CKG_GENERATE_COUNTER_XOR: 1118 iv[ivOffset] ^= 1119 (PORT_GET_BYTE_BE(gcmIv->counter, 0, ivNewCount) & ivMask); 1120 for (i = 1; i < ivNewCount; i++) { 1121 iv[ivOffset + i] ^= PORT_GET_BYTE_BE(gcmIv->counter, i, ivNewCount); 1122 } 1123 break; 1124 case CKG_GENERATE_RANDOM: 1125 ivSave = iv[ivOffset] & ~ivMask; 1126 rv = RNG_GenerateGlobalRandomBytes(iv + ivOffset, ivNewCount); 1127 iv[ivOffset] = ivSave | (iv[ivOffset] & ivMask); 1128 if (rv != SECSuccess) { 1129 return rv; 1130 } 1131 break; 1132 } 1133 gcmIv->counter++; 1134 return SECSuccess; 1135 } 1136 1137 SECStatus 1138 GCM_EncryptAEAD(GCMContext *gcm, unsigned char *outbuf, 1139 unsigned int *outlen, unsigned int maxout, 1140 const unsigned char *inbuf, unsigned int inlen, 1141 void *params, unsigned int paramLen, 1142 const unsigned char *aad, unsigned int aadLen, 1143 unsigned int blocksize) 1144 { 1145 SECStatus rv; 1146 unsigned int tagBytes; 1147 unsigned int len; 1148 const CK_GCM_MESSAGE_PARAMS *gcmParams = 1149 (const CK_GCM_MESSAGE_PARAMS *)params; 1150 1151 PORT_Assert(blocksize == AES_BLOCK_SIZE); 1152 if (blocksize != AES_BLOCK_SIZE) { 1153 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 1154 return SECFailure; 1155 } 1156 1157 /* paramLen comes all the way from the application layer, make sure 1158 * it's correct */ 1159 if (paramLen != sizeof(CK_GCM_MESSAGE_PARAMS)) { 1160 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1161 return SECFailure; 1162 } 1163 /* if we were initialized with the C_EncryptInit, we shouldn't be in this 1164 * function */ 1165 if (gcm->ctr_context_init) { 1166 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 1167 return SECFailure; 1168 } 1169 1170 if (maxout < inlen) { 1171 *outlen = inlen; 1172 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 1173 return SECFailure; 1174 } 1175 1176 rv = gcm_GenerateIV(&gcm->gcm_iv, gcmParams->pIv, gcmParams->ulIvLen, 1177 gcmParams->ulIvFixedBits, gcmParams->ivGenerator); 1178 if (rv != SECSuccess) { 1179 return SECFailure; 1180 } 1181 1182 rv = gcm_InitCounter(gcm, gcmParams->pIv, gcmParams->ulIvLen, 1183 gcmParams->ulTagBits, aad, aadLen); 1184 if (rv != SECSuccess) { 1185 return SECFailure; 1186 } 1187 1188 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE; 1189 1190 rv = gcm_CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout, 1191 inbuf, inlen); 1192 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE); 1193 if (rv != SECSuccess) { 1194 return SECFailure; 1195 } 1196 rv = gcmHash_Update(gcm->ghash_context, outbuf, *outlen); 1197 if (rv != SECSuccess) { 1198 PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */ 1199 *outlen = 0; 1200 return SECFailure; 1201 } 1202 rv = gcm_GetTag(gcm, gcmParams->pTag, &len, tagBytes); 1203 if (rv != SECSuccess) { 1204 PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */ 1205 *outlen = 0; 1206 return SECFailure; 1207 }; 1208 return SECSuccess; 1209 } 1210 1211 SECStatus 1212 GCM_DecryptAEAD(GCMContext *gcm, unsigned char *outbuf, 1213 unsigned int *outlen, unsigned int maxout, 1214 const unsigned char *inbuf, unsigned int inlen, 1215 void *params, unsigned int paramLen, 1216 const unsigned char *aad, unsigned int aadLen, 1217 unsigned int blocksize) 1218 { 1219 SECStatus rv; 1220 unsigned int tagBytes; 1221 unsigned char tag[MAX_BLOCK_SIZE]; 1222 const unsigned char *intag; 1223 unsigned int len; 1224 const CK_GCM_MESSAGE_PARAMS *gcmParams = 1225 (const CK_GCM_MESSAGE_PARAMS *)params; 1226 1227 PORT_Assert(blocksize == AES_BLOCK_SIZE); 1228 if (blocksize != AES_BLOCK_SIZE) { 1229 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 1230 return SECFailure; 1231 } 1232 1233 /* paramLen comes all the way from the application layer, make sure 1234 * it's correct */ 1235 if (paramLen != sizeof(CK_GCM_MESSAGE_PARAMS)) { 1236 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1237 return SECFailure; 1238 } 1239 /* if we were initialized with the C_DecryptInit, we shouldn't be in this 1240 * function */ 1241 if (gcm->ctr_context_init) { 1242 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 1243 return SECFailure; 1244 } 1245 1246 if (maxout < inlen) { 1247 *outlen = inlen; 1248 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 1249 return SECFailure; 1250 } 1251 1252 rv = gcm_InitCounter(gcm, gcmParams->pIv, gcmParams->ulIvLen, 1253 gcmParams->ulTagBits, aad, aadLen); 1254 if (rv != SECSuccess) { 1255 return SECFailure; 1256 } 1257 1258 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE; 1259 intag = gcmParams->pTag; 1260 PORT_Assert(tagBytes != 0); 1261 1262 /* verify the block */ 1263 rv = gcmHash_Update(gcm->ghash_context, inbuf, inlen); 1264 if (rv != SECSuccess) { 1265 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE); 1266 return SECFailure; 1267 } 1268 rv = gcm_GetTag(gcm, tag, &len, AES_BLOCK_SIZE); 1269 if (rv != SECSuccess) { 1270 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE); 1271 return SECFailure; 1272 } 1273 /* Don't decrypt if we can't authenticate the encrypted data! 1274 * This assumes that if tagBits is may not be a multiple of 8, intag will 1275 * preserve the masked off missing bits. */ 1276 if (NSS_SecureMemcmp(tag, intag, tagBytes) != 0) { 1277 /* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */ 1278 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE); 1279 PORT_SetError(SEC_ERROR_BAD_DATA); 1280 PORT_SafeZero(tag, sizeof(tag)); 1281 return SECFailure; 1282 } 1283 PORT_SafeZero(tag, sizeof(tag)); 1284 /* finish the decryption */ 1285 rv = gcm_CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout, 1286 inbuf, inlen); 1287 CTR_DestroyContext(&gcm->ctr_context, PR_FALSE); 1288 return rv; 1289 }