1 /* 2 * NIST SP800-38D compliant GCM implementation 3 * 4 * Copyright The Mbed TLS Contributors 5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6 */ 7 8 /* 9 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf 10 * 11 * See also: 12 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf 13 * 14 * We use the algorithm described as Shoup's method with 4-bit tables in 15 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. 16 */ 17 18 #include "common.h" 19 20 #if defined(MBEDTLS_GCM_C) 21 22 #include "mbedtls/gcm.h" 23 #include "mbedtls/platform.h" 24 #include "mbedtls/platform_util.h" 25 #include "mbedtls/error.h" 26 #include "mbedtls/constant_time.h" 27 28 #if defined(MBEDTLS_BLOCK_CIPHER_C) 29 #include "block_cipher_internal.h" 30 #endif 31 32 #include <string.h> 33 34 #if defined(MBEDTLS_AESNI_C) 35 #include "aesni.h" 36 #endif 37 38 #if defined(MBEDTLS_AESCE_C) 39 #include "aesce.h" 40 #endif 41 42 #if !defined(MBEDTLS_GCM_ALT) 43 44 /* Used to select the acceleration mechanism */ 45 #define MBEDTLS_GCM_ACC_SMALLTABLE 0 46 #define MBEDTLS_GCM_ACC_LARGETABLE 1 47 #define MBEDTLS_GCM_ACC_AESNI 2 48 #define MBEDTLS_GCM_ACC_AESCE 3 49 50 /* 51 * Initialize a context 52 */ 53 void mbedtls_gcm_init(mbedtls_gcm_context *ctx) 54 { 55 memset(ctx, 0, sizeof(mbedtls_gcm_context)); 56 } 57 58 static inline void gcm_set_acceleration(mbedtls_gcm_context *ctx) 59 { 60 #if defined(MBEDTLS_GCM_LARGE_TABLE) 61 ctx->acceleration = MBEDTLS_GCM_ACC_LARGETABLE; 62 #else 63 ctx->acceleration = MBEDTLS_GCM_ACC_SMALLTABLE; 64 #endif 65 66 #if defined(MBEDTLS_AESNI_HAVE_CODE) 67 /* With CLMUL support, we need only h, not the rest of the table */ 68 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) { 69 ctx->acceleration = MBEDTLS_GCM_ACC_AESNI; 70 } 71 #endif 72 73 #if defined(MBEDTLS_AESCE_HAVE_CODE) 74 if (MBEDTLS_AESCE_HAS_SUPPORT()) { 75 ctx->acceleration = MBEDTLS_GCM_ACC_AESCE; 76 } 77 #endif 78 } 79 80 static inline void gcm_gen_table_rightshift(uint64_t dst[2], const uint64_t src[2]) 81 { 82 uint8_t *u8Dst = (uint8_t *) dst; 83 uint8_t *u8Src = (uint8_t *) src; 84 85 MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[1], 0) >> 1, &dst[1], 0); 86 u8Dst[8] |= (u8Src[7] & 0x01) << 7; 87 MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[0], 0) >> 1, &dst[0], 0); 88 u8Dst[0] ^= (u8Src[15] & 0x01) ? 0xE1 : 0; 89 } 90 91 /* 92 * Precompute small multiples of H, that is set 93 * HH[i] || HL[i] = H times i, 94 * where i is seen as a field element as in [MGV], ie high-order bits 95 * correspond to low powers of P. The result is stored in the same way, that 96 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL 97 * corresponds to P^127. 98 */ 99 static int gcm_gen_table(mbedtls_gcm_context *ctx) 100 { 101 int ret, i, j; 102 uint64_t u64h[2] = { 0 }; 103 uint8_t *h = (uint8_t *) u64h; 104 105 #if defined(MBEDTLS_BLOCK_CIPHER_C) 106 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, h, h); 107 #else 108 size_t olen = 0; 109 ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen); 110 #endif 111 if (ret != 0) { 112 return ret; 113 } 114 115 gcm_set_acceleration(ctx); 116 117 /* MBEDTLS_GCM_HTABLE_SIZE/2 = 1000 corresponds to 1 in GF(2^128) */ 118 ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][0] = u64h[0]; 119 ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][1] = u64h[1]; 120 121 switch (ctx->acceleration) { 122 #if defined(MBEDTLS_AESNI_HAVE_CODE) 123 case MBEDTLS_GCM_ACC_AESNI: 124 return 0; 125 #endif 126 127 #if defined(MBEDTLS_AESCE_HAVE_CODE) 128 case MBEDTLS_GCM_ACC_AESCE: 129 return 0; 130 #endif 131 132 default: 133 /* 0 corresponds to 0 in GF(2^128) */ 134 ctx->H[0][0] = 0; 135 ctx->H[0][1] = 0; 136 137 for (i = MBEDTLS_GCM_HTABLE_SIZE/4; i > 0; i >>= 1) { 138 gcm_gen_table_rightshift(ctx->H[i], ctx->H[i*2]); 139 } 140 141 #if !defined(MBEDTLS_GCM_LARGE_TABLE) 142 /* pack elements of H as 64-bits ints, big-endian */ 143 for (i = MBEDTLS_GCM_HTABLE_SIZE/2; i > 0; i >>= 1) { 144 MBEDTLS_PUT_UINT64_BE(ctx->H[i][0], &ctx->H[i][0], 0); 145 MBEDTLS_PUT_UINT64_BE(ctx->H[i][1], &ctx->H[i][1], 0); 146 } 147 #endif 148 149 for (i = 2; i < MBEDTLS_GCM_HTABLE_SIZE; i <<= 1) { 150 for (j = 1; j < i; j++) { 151 mbedtls_xor_no_simd((unsigned char *) ctx->H[i+j], 152 (unsigned char *) ctx->H[i], 153 (unsigned char *) ctx->H[j], 154 16); 155 } 156 } 157 } 158 159 return 0; 160 } 161 162 int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx, 163 mbedtls_cipher_id_t cipher, 164 const unsigned char *key, 165 unsigned int keybits) 166 { 167 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 168 169 if (keybits != 128 && keybits != 192 && keybits != 256) { 170 return MBEDTLS_ERR_GCM_BAD_INPUT; 171 } 172 173 #if defined(MBEDTLS_BLOCK_CIPHER_C) 174 mbedtls_block_cipher_free(&ctx->block_cipher_ctx); 175 176 if ((ret = mbedtls_block_cipher_setup(&ctx->block_cipher_ctx, cipher)) != 0) { 177 return ret; 178 } 179 180 if ((ret = mbedtls_block_cipher_setkey(&ctx->block_cipher_ctx, key, keybits)) != 0) { 181 return ret; 182 } 183 #else 184 const mbedtls_cipher_info_t *cipher_info; 185 186 cipher_info = mbedtls_cipher_info_from_values(cipher, keybits, 187 MBEDTLS_MODE_ECB); 188 if (cipher_info == NULL) { 189 return MBEDTLS_ERR_GCM_BAD_INPUT; 190 } 191 192 if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) { 193 return MBEDTLS_ERR_GCM_BAD_INPUT; 194 } 195 196 mbedtls_cipher_free(&ctx->cipher_ctx); 197 198 if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) { 199 return ret; 200 } 201 202 if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits, 203 MBEDTLS_ENCRYPT)) != 0) { 204 return ret; 205 } 206 #endif 207 208 if ((ret = gcm_gen_table(ctx)) != 0) { 209 return ret; 210 } 211 212 return 0; 213 } 214 215 #if defined(MBEDTLS_GCM_LARGE_TABLE) 216 static const uint16_t last8[256] = { 217 0x0000, 0xc201, 0x8403, 0x4602, 0x0807, 0xca06, 0x8c04, 0x4e05, 218 0x100e, 0xd20f, 0x940d, 0x560c, 0x1809, 0xda08, 0x9c0a, 0x5e0b, 219 0x201c, 0xe21d, 0xa41f, 0x661e, 0x281b, 0xea1a, 0xac18, 0x6e19, 220 0x3012, 0xf213, 0xb411, 0x7610, 0x3815, 0xfa14, 0xbc16, 0x7e17, 221 0x4038, 0x8239, 0xc43b, 0x063a, 0x483f, 0x8a3e, 0xcc3c, 0x0e3d, 222 0x5036, 0x9237, 0xd435, 0x1634, 0x5831, 0x9a30, 0xdc32, 0x1e33, 223 0x6024, 0xa225, 0xe427, 0x2626, 0x6823, 0xaa22, 0xec20, 0x2e21, 224 0x702a, 0xb22b, 0xf429, 0x3628, 0x782d, 0xba2c, 0xfc2e, 0x3e2f, 225 0x8070, 0x4271, 0x0473, 0xc672, 0x8877, 0x4a76, 0x0c74, 0xce75, 226 0x907e, 0x527f, 0x147d, 0xd67c, 0x9879, 0x5a78, 0x1c7a, 0xde7b, 227 0xa06c, 0x626d, 0x246f, 0xe66e, 0xa86b, 0x6a6a, 0x2c68, 0xee69, 228 0xb062, 0x7263, 0x3461, 0xf660, 0xb865, 0x7a64, 0x3c66, 0xfe67, 229 0xc048, 0x0249, 0x444b, 0x864a, 0xc84f, 0x0a4e, 0x4c4c, 0x8e4d, 230 0xd046, 0x1247, 0x5445, 0x9644, 0xd841, 0x1a40, 0x5c42, 0x9e43, 231 0xe054, 0x2255, 0x6457, 0xa656, 0xe853, 0x2a52, 0x6c50, 0xae51, 232 0xf05a, 0x325b, 0x7459, 0xb658, 0xf85d, 0x3a5c, 0x7c5e, 0xbe5f, 233 0x00e1, 0xc2e0, 0x84e2, 0x46e3, 0x08e6, 0xcae7, 0x8ce5, 0x4ee4, 234 0x10ef, 0xd2ee, 0x94ec, 0x56ed, 0x18e8, 0xdae9, 0x9ceb, 0x5eea, 235 0x20fd, 0xe2fc, 0xa4fe, 0x66ff, 0x28fa, 0xeafb, 0xacf9, 0x6ef8, 236 0x30f3, 0xf2f2, 0xb4f0, 0x76f1, 0x38f4, 0xfaf5, 0xbcf7, 0x7ef6, 237 0x40d9, 0x82d8, 0xc4da, 0x06db, 0x48de, 0x8adf, 0xccdd, 0x0edc, 238 0x50d7, 0x92d6, 0xd4d4, 0x16d5, 0x58d0, 0x9ad1, 0xdcd3, 0x1ed2, 239 0x60c5, 0xa2c4, 0xe4c6, 0x26c7, 0x68c2, 0xaac3, 0xecc1, 0x2ec0, 240 0x70cb, 0xb2ca, 0xf4c8, 0x36c9, 0x78cc, 0xbacd, 0xfccf, 0x3ece, 241 0x8091, 0x4290, 0x0492, 0xc693, 0x8896, 0x4a97, 0x0c95, 0xce94, 242 0x909f, 0x529e, 0x149c, 0xd69d, 0x9898, 0x5a99, 0x1c9b, 0xde9a, 243 0xa08d, 0x628c, 0x248e, 0xe68f, 0xa88a, 0x6a8b, 0x2c89, 0xee88, 244 0xb083, 0x7282, 0x3480, 0xf681, 0xb884, 0x7a85, 0x3c87, 0xfe86, 245 0xc0a9, 0x02a8, 0x44aa, 0x86ab, 0xc8ae, 0x0aaf, 0x4cad, 0x8eac, 246 0xd0a7, 0x12a6, 0x54a4, 0x96a5, 0xd8a0, 0x1aa1, 0x5ca3, 0x9ea2, 247 0xe0b5, 0x22b4, 0x64b6, 0xa6b7, 0xe8b2, 0x2ab3, 0x6cb1, 0xaeb0, 248 0xf0bb, 0x32ba, 0x74b8, 0xb6b9, 0xf8bc, 0x3abd, 0x7cbf, 0xbebe 249 }; 250 251 static void gcm_mult_largetable(uint8_t *output, const uint8_t *x, uint64_t H[256][2]) 252 { 253 int i; 254 uint64_t u64z[2]; 255 uint16_t *u16z = (uint16_t *) u64z; 256 uint8_t *u8z = (uint8_t *) u64z; 257 uint8_t rem; 258 259 u64z[0] = 0; 260 u64z[1] = 0; 261 262 if (MBEDTLS_IS_BIG_ENDIAN) { 263 for (i = 15; i > 0; i--) { 264 mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16); 265 rem = u8z[15]; 266 267 u64z[1] >>= 8; 268 u8z[8] = u8z[7]; 269 u64z[0] >>= 8; 270 271 u16z[0] ^= MBEDTLS_GET_UINT16_LE(&last8[rem], 0); 272 } 273 } else { 274 for (i = 15; i > 0; i--) { 275 mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16); 276 rem = u8z[15]; 277 278 u64z[1] <<= 8; 279 u8z[8] = u8z[7]; 280 u64z[0] <<= 8; 281 282 u16z[0] ^= last8[rem]; 283 } 284 } 285 286 mbedtls_xor_no_simd(output, u8z, (uint8_t *) H[x[0]], 16); 287 } 288 #else 289 /* 290 * Shoup's method for multiplication use this table with 291 * last4[x] = x times P^128 292 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV] 293 */ 294 static const uint16_t last4[16] = 295 { 296 0x0000, 0x1c20, 0x3840, 0x2460, 297 0x7080, 0x6ca0, 0x48c0, 0x54e0, 298 0xe100, 0xfd20, 0xd940, 0xc560, 299 0x9180, 0x8da0, 0xa9c0, 0xb5e0 300 }; 301 302 static void gcm_mult_smalltable(uint8_t *output, const uint8_t *x, uint64_t H[16][2]) 303 { 304 int i = 0; 305 unsigned char lo, hi, rem; 306 uint64_t u64z[2]; 307 const uint64_t *pu64z = NULL; 308 uint8_t *u8z = (uint8_t *) u64z; 309 310 lo = x[15] & 0xf; 311 hi = (x[15] >> 4) & 0xf; 312 313 pu64z = H[lo]; 314 315 rem = (unsigned char) pu64z[1] & 0xf; 316 u64z[1] = (pu64z[0] << 60) | (pu64z[1] >> 4); 317 u64z[0] = (pu64z[0] >> 4); 318 u64z[0] ^= (uint64_t) last4[rem] << 48; 319 mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16); 320 321 for (i = 14; i >= 0; i--) { 322 lo = x[i] & 0xf; 323 hi = (x[i] >> 4) & 0xf; 324 325 rem = (unsigned char) u64z[1] & 0xf; 326 u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4); 327 u64z[0] = (u64z[0] >> 4); 328 u64z[0] ^= (uint64_t) last4[rem] << 48; 329 mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[lo], 16); 330 331 rem = (unsigned char) u64z[1] & 0xf; 332 u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4); 333 u64z[0] = (u64z[0] >> 4); 334 u64z[0] ^= (uint64_t) last4[rem] << 48; 335 mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16); 336 } 337 338 MBEDTLS_PUT_UINT64_BE(u64z[0], output, 0); 339 MBEDTLS_PUT_UINT64_BE(u64z[1], output, 8); 340 } 341 #endif 342 343 /* 344 * Sets output to x times H using the precomputed tables. 345 * x and output are seen as elements of GF(2^128) as in [MGV]. 346 */ 347 static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16], 348 unsigned char output[16]) 349 { 350 switch (ctx->acceleration) { 351 #if defined(MBEDTLS_AESNI_HAVE_CODE) 352 case MBEDTLS_GCM_ACC_AESNI: 353 mbedtls_aesni_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]); 354 break; 355 #endif 356 357 #if defined(MBEDTLS_AESCE_HAVE_CODE) 358 case MBEDTLS_GCM_ACC_AESCE: 359 mbedtls_aesce_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]); 360 break; 361 #endif 362 363 #if defined(MBEDTLS_GCM_LARGE_TABLE) 364 case MBEDTLS_GCM_ACC_LARGETABLE: 365 gcm_mult_largetable(output, x, ctx->H); 366 break; 367 #else 368 case MBEDTLS_GCM_ACC_SMALLTABLE: 369 gcm_mult_smalltable(output, x, ctx->H); 370 break; 371 #endif 372 } 373 374 return; 375 } 376 377 int mbedtls_gcm_starts(mbedtls_gcm_context *ctx, 378 int mode, 379 const unsigned char *iv, size_t iv_len) 380 { 381 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 382 unsigned char work_buf[16]; 383 const unsigned char *p; 384 size_t use_len; 385 uint64_t iv_bits; 386 #if !defined(MBEDTLS_BLOCK_CIPHER_C) 387 size_t olen = 0; 388 #endif 389 390 /* IV is limited to 2^64 bits, so 2^61 bytes */ 391 /* IV is not allowed to be zero length */ 392 if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) { 393 return MBEDTLS_ERR_GCM_BAD_INPUT; 394 } 395 396 memset(ctx->y, 0x00, sizeof(ctx->y)); 397 memset(ctx->buf, 0x00, sizeof(ctx->buf)); 398 399 ctx->mode = mode; 400 ctx->len = 0; 401 ctx->add_len = 0; 402 403 if (iv_len == 12) { 404 memcpy(ctx->y, iv, iv_len); 405 ctx->y[15] = 1; 406 } else { 407 memset(work_buf, 0x00, 16); 408 iv_bits = (uint64_t) iv_len * 8; 409 MBEDTLS_PUT_UINT64_BE(iv_bits, work_buf, 8); 410 411 p = iv; 412 while (iv_len > 0) { 413 use_len = (iv_len < 16) ? iv_len : 16; 414 415 #if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110) 416 #pragma GCC diagnostic push 417 #pragma GCC diagnostic warning "-Wstringop-overflow=0" 418 #endif 419 420 mbedtls_xor(ctx->y, ctx->y, p, use_len); 421 422 #if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110) 423 #pragma GCC diagnostic pop 424 #endif 425 426 gcm_mult(ctx, ctx->y, ctx->y); 427 428 iv_len -= use_len; 429 p += use_len; 430 } 431 432 mbedtls_xor(ctx->y, ctx->y, work_buf, 16); 433 434 gcm_mult(ctx, ctx->y, ctx->y); 435 } 436 437 438 #if defined(MBEDTLS_BLOCK_CIPHER_C) 439 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->base_ectr); 440 #else 441 ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, &olen); 442 #endif 443 if (ret != 0) { 444 return ret; 445 } 446 447 return 0; 448 } 449 450 /** 451 * mbedtls_gcm_context::buf contains the partial state of the computation of 452 * the authentication tag. 453 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate 454 * different stages of the computation: 455 * * len == 0 && add_len == 0: initial state 456 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have 457 * a partial block of AD that has been 458 * xored in but not yet multiplied in. 459 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if 460 * the data ends now. 461 * * len % 16 != 0: the first `len % 16` bytes have 462 * a partial block of ciphertext that has 463 * been xored in but not yet multiplied in. 464 * * len > 0 && len % 16 == 0: the authentication tag is correct if 465 * the data ends now. 466 */ 467 int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx, 468 const unsigned char *add, size_t add_len) 469 { 470 const unsigned char *p; 471 size_t use_len, offset; 472 uint64_t new_add_len; 473 474 /* AD is limited to 2^64 bits, ie 2^61 bytes 475 * Also check for possible overflow */ 476 #if SIZE_MAX > 0xFFFFFFFFFFFFFFFFULL 477 if (add_len > 0xFFFFFFFFFFFFFFFFULL) { 478 return MBEDTLS_ERR_GCM_BAD_INPUT; 479 } 480 #endif 481 new_add_len = ctx->add_len + (uint64_t) add_len; 482 if (new_add_len < ctx->add_len || new_add_len >> 61 != 0) { 483 return MBEDTLS_ERR_GCM_BAD_INPUT; 484 } 485 486 offset = ctx->add_len % 16; 487 p = add; 488 489 if (offset != 0) { 490 use_len = 16 - offset; 491 if (use_len > add_len) { 492 use_len = add_len; 493 } 494 495 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len); 496 497 if (offset + use_len == 16) { 498 gcm_mult(ctx, ctx->buf, ctx->buf); 499 } 500 501 ctx->add_len += use_len; 502 add_len -= use_len; 503 p += use_len; 504 } 505 506 ctx->add_len += add_len; 507 508 while (add_len >= 16) { 509 mbedtls_xor(ctx->buf, ctx->buf, p, 16); 510 511 gcm_mult(ctx, ctx->buf, ctx->buf); 512 513 add_len -= 16; 514 p += 16; 515 } 516 517 if (add_len > 0) { 518 mbedtls_xor(ctx->buf, ctx->buf, p, add_len); 519 } 520 521 return 0; 522 } 523 524 /* Increment the counter. */ 525 static void gcm_incr(unsigned char y[16]) 526 { 527 uint32_t x = MBEDTLS_GET_UINT32_BE(y, 12); 528 x++; 529 MBEDTLS_PUT_UINT32_BE(x, y, 12); 530 } 531 532 /* Calculate and apply the encryption mask. Process use_len bytes of data, 533 * starting at position offset in the mask block. */ 534 static int gcm_mask(mbedtls_gcm_context *ctx, 535 unsigned char ectr[16], 536 size_t offset, size_t use_len, 537 const unsigned char *input, 538 unsigned char *output) 539 { 540 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 541 542 #if defined(MBEDTLS_BLOCK_CIPHER_C) 543 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ectr); 544 #else 545 size_t olen = 0; 546 ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, &olen); 547 #endif 548 if (ret != 0) { 549 mbedtls_platform_zeroize(ectr, 16); 550 return ret; 551 } 552 553 if (ctx->mode == MBEDTLS_GCM_DECRYPT) { 554 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len); 555 } 556 mbedtls_xor(output, ectr + offset, input, use_len); 557 if (ctx->mode == MBEDTLS_GCM_ENCRYPT) { 558 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len); 559 } 560 561 return 0; 562 } 563 564 int mbedtls_gcm_update(mbedtls_gcm_context *ctx, 565 const unsigned char *input, size_t input_length, 566 unsigned char *output, size_t output_size, 567 size_t *output_length) 568 { 569 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 570 const unsigned char *p = input; 571 unsigned char *out_p = output; 572 size_t offset; 573 unsigned char ectr[16] = { 0 }; 574 575 if (output_size < input_length) { 576 return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL; 577 } 578 *output_length = input_length; 579 580 /* Exit early if input_length==0 so that we don't do any pointer arithmetic 581 * on a potentially null pointer. 582 * Returning early also means that the last partial block of AD remains 583 * untouched for mbedtls_gcm_finish */ 584 if (input_length == 0) { 585 return 0; 586 } 587 588 if (output > input && (size_t) (output - input) < input_length) { 589 return MBEDTLS_ERR_GCM_BAD_INPUT; 590 } 591 592 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes 593 * Also check for possible overflow */ 594 if (ctx->len + input_length < ctx->len || 595 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) { 596 return MBEDTLS_ERR_GCM_BAD_INPUT; 597 } 598 599 if (ctx->len == 0 && ctx->add_len % 16 != 0) { 600 gcm_mult(ctx, ctx->buf, ctx->buf); 601 } 602 603 offset = ctx->len % 16; 604 if (offset != 0) { 605 size_t use_len = 16 - offset; 606 if (use_len > input_length) { 607 use_len = input_length; 608 } 609 610 if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) { 611 return ret; 612 } 613 614 if (offset + use_len == 16) { 615 gcm_mult(ctx, ctx->buf, ctx->buf); 616 } 617 618 ctx->len += use_len; 619 input_length -= use_len; 620 p += use_len; 621 out_p += use_len; 622 } 623 624 ctx->len += input_length; 625 626 while (input_length >= 16) { 627 gcm_incr(ctx->y); 628 if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) { 629 return ret; 630 } 631 632 gcm_mult(ctx, ctx->buf, ctx->buf); 633 634 input_length -= 16; 635 p += 16; 636 out_p += 16; 637 } 638 639 if (input_length > 0) { 640 gcm_incr(ctx->y); 641 if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) { 642 return ret; 643 } 644 } 645 646 mbedtls_platform_zeroize(ectr, sizeof(ectr)); 647 return 0; 648 } 649 650 int mbedtls_gcm_finish(mbedtls_gcm_context *ctx, 651 unsigned char *output, size_t output_size, 652 size_t *output_length, 653 unsigned char *tag, size_t tag_len) 654 { 655 unsigned char work_buf[16]; 656 uint64_t orig_len; 657 uint64_t orig_add_len; 658 659 /* We never pass any output in finish(). The output parameter exists only 660 * for the sake of alternative implementations. */ 661 (void) output; 662 (void) output_size; 663 *output_length = 0; 664 665 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes 666 * and AD length is restricted to 2^64 bits, ie 2^61 bytes so neither of 667 * the two multiplications would overflow. */ 668 orig_len = ctx->len * 8; 669 orig_add_len = ctx->add_len * 8; 670 671 if (ctx->len == 0 && ctx->add_len % 16 != 0) { 672 gcm_mult(ctx, ctx->buf, ctx->buf); 673 } 674 675 if (tag_len > 16 || tag_len < 4) { 676 return MBEDTLS_ERR_GCM_BAD_INPUT; 677 } 678 679 if (ctx->len % 16 != 0) { 680 gcm_mult(ctx, ctx->buf, ctx->buf); 681 } 682 683 memcpy(tag, ctx->base_ectr, tag_len); 684 685 if (orig_len || orig_add_len) { 686 memset(work_buf, 0x00, 16); 687 688 MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0); 689 MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4); 690 MBEDTLS_PUT_UINT32_BE((orig_len >> 32), work_buf, 8); 691 MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12); 692 693 mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16); 694 695 gcm_mult(ctx, ctx->buf, ctx->buf); 696 697 mbedtls_xor(tag, tag, ctx->buf, tag_len); 698 } 699 700 return 0; 701 } 702 703 int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx, 704 int mode, 705 size_t length, 706 const unsigned char *iv, 707 size_t iv_len, 708 const unsigned char *add, 709 size_t add_len, 710 const unsigned char *input, 711 unsigned char *output, 712 size_t tag_len, 713 unsigned char *tag) 714 { 715 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 716 size_t olen; 717 718 if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) { 719 return ret; 720 } 721 722 if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) { 723 return ret; 724 } 725 726 if ((ret = mbedtls_gcm_update(ctx, input, length, 727 output, length, &olen)) != 0) { 728 return ret; 729 } 730 731 if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) { 732 return ret; 733 } 734 735 return 0; 736 } 737 738 int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx, 739 size_t length, 740 const unsigned char *iv, 741 size_t iv_len, 742 const unsigned char *add, 743 size_t add_len, 744 const unsigned char *tag, 745 size_t tag_len, 746 const unsigned char *input, 747 unsigned char *output) 748 { 749 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 750 unsigned char check_tag[16]; 751 int diff; 752 753 if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length, 754 iv, iv_len, add, add_len, 755 input, output, tag_len, check_tag)) != 0) { 756 return ret; 757 } 758 759 /* Check tag in "constant-time" */ 760 diff = mbedtls_ct_memcmp(tag, check_tag, tag_len); 761 762 if (diff != 0) { 763 mbedtls_platform_zeroize(output, length); 764 return MBEDTLS_ERR_GCM_AUTH_FAILED; 765 } 766 767 return 0; 768 } 769 770 void mbedtls_gcm_free(mbedtls_gcm_context *ctx) 771 { 772 if (ctx == NULL) { 773 return; 774 } 775 #if defined(MBEDTLS_BLOCK_CIPHER_C) 776 mbedtls_block_cipher_free(&ctx->block_cipher_ctx); 777 #else 778 mbedtls_cipher_free(&ctx->cipher_ctx); 779 #endif 780 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context)); 781 } 782 783 #endif /* !MBEDTLS_GCM_ALT */ 784 785 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_CCM_GCM_CAN_AES) 786 /* 787 * AES-GCM test vectors from: 788 * 789 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip 790 */ 791 #define MAX_TESTS 6 792 793 static const int key_index_test_data[MAX_TESTS] = 794 { 0, 0, 1, 1, 1, 1 }; 795 796 static const unsigned char key_test_data[][32] = 797 { 798 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 799 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 800 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 801 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 802 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 803 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 804 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 805 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, 806 }; 807 808 static const size_t iv_len_test_data[MAX_TESTS] = 809 { 12, 12, 12, 12, 8, 60 }; 810 811 static const int iv_index_test_data[MAX_TESTS] = 812 { 0, 0, 1, 1, 1, 2 }; 813 814 static const unsigned char iv_test_data[][64] = 815 { 816 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 817 0x00, 0x00, 0x00, 0x00 }, 818 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 819 0xde, 0xca, 0xf8, 0x88 }, 820 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 821 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, 822 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 823 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, 824 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, 825 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, 826 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, 827 0xa6, 0x37, 0xb3, 0x9b }, 828 }; 829 830 static const size_t add_len_test_data[MAX_TESTS] = 831 { 0, 0, 0, 20, 20, 20 }; 832 833 static const int add_index_test_data[MAX_TESTS] = 834 { 0, 0, 0, 1, 1, 1 }; 835 836 static const unsigned char additional_test_data[][64] = 837 { 838 { 0x00 }, 839 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 840 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 841 0xab, 0xad, 0xda, 0xd2 }, 842 }; 843 844 static const size_t pt_len_test_data[MAX_TESTS] = 845 { 0, 16, 64, 60, 60, 60 }; 846 847 static const int pt_index_test_data[MAX_TESTS] = 848 { 0, 0, 1, 1, 1, 1 }; 849 850 static const unsigned char pt_test_data[][64] = 851 { 852 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 853 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 854 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 855 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 856 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 857 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 858 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 859 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 860 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 861 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, 862 }; 863 864 static const unsigned char ct_test_data[][64] = 865 { 866 { 0x00 }, 867 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, 868 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, 869 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 870 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 871 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 872 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 873 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 874 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 875 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 876 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, 877 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 878 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 879 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 880 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 881 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 882 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 883 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 884 0x3d, 0x58, 0xe0, 0x91 }, 885 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, 886 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, 887 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, 888 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, 889 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, 890 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, 891 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, 892 0xc2, 0x3f, 0x45, 0x98 }, 893 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, 894 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, 895 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, 896 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, 897 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, 898 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, 899 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, 900 0x4c, 0x34, 0xae, 0xe5 }, 901 #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) 902 { 0x00 }, 903 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, 904 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, 905 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 906 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, 907 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 908 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, 909 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 910 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 911 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, 912 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, 913 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 914 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, 915 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 916 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, 917 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 918 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 919 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, 920 0xcc, 0xda, 0x27, 0x10 }, 921 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, 922 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, 923 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, 924 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, 925 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, 926 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, 927 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, 928 0xa0, 0xf0, 0x62, 0xf7 }, 929 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, 930 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, 931 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, 932 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, 933 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, 934 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, 935 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, 936 0xe9, 0xb7, 0x37, 0x3b }, 937 { 0x00 }, 938 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, 939 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, 940 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 941 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, 942 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 943 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, 944 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 945 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 946 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, 947 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, 948 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 949 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, 950 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 951 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, 952 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 953 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 954 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, 955 0xbc, 0xc9, 0xf6, 0x62 }, 956 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, 957 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, 958 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, 959 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, 960 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, 961 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, 962 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, 963 0xf4, 0x7c, 0x9b, 0x1f }, 964 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, 965 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, 966 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, 967 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, 968 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, 969 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, 970 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, 971 0x44, 0xae, 0x7e, 0x3f }, 972 #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ 973 }; 974 975 static const unsigned char tag_test_data[][16] = 976 { 977 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, 978 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, 979 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, 980 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, 981 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 982 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, 983 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, 984 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, 985 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, 986 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, 987 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, 988 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, 989 #if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) 990 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, 991 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, 992 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, 993 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, 994 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, 995 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, 996 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, 997 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, 998 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, 999 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, 1000 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, 1001 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, 1002 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 1003 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, 1004 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, 1005 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, 1006 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, 1007 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, 1008 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, 1009 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, 1010 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, 1011 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, 1012 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, 1013 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, 1014 #endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ 1015 }; 1016 1017 int mbedtls_gcm_self_test(int verbose) 1018 { 1019 mbedtls_gcm_context ctx; 1020 unsigned char buf[64]; 1021 unsigned char tag_buf[16]; 1022 int i, j, ret; 1023 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; 1024 size_t olen; 1025 1026 if (verbose != 0) { 1027 #if defined(MBEDTLS_GCM_ALT) 1028 mbedtls_printf(" GCM note: alternative implementation.\n"); 1029 #else /* MBEDTLS_GCM_ALT */ 1030 #if defined(MBEDTLS_AESNI_HAVE_CODE) 1031 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) { 1032 mbedtls_printf(" GCM note: using AESNI.\n"); 1033 } else 1034 #endif 1035 1036 #if defined(MBEDTLS_AESCE_HAVE_CODE) 1037 if (MBEDTLS_AESCE_HAS_SUPPORT()) { 1038 mbedtls_printf(" GCM note: using AESCE.\n"); 1039 } else 1040 #endif 1041 1042 mbedtls_printf(" GCM note: built-in implementation.\n"); 1043 #endif /* MBEDTLS_GCM_ALT */ 1044 } 1045 1046 static const int loop_limit = 1047 (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS; 1048 1049 for (j = 0; j < loop_limit; j++) { 1050 int key_len = 128 + 64 * j; 1051 1052 for (i = 0; i < MAX_TESTS; i++) { 1053 if (verbose != 0) { 1054 mbedtls_printf(" AES-GCM-%3d #%d (%s): ", 1055 key_len, i, "enc"); 1056 } 1057 1058 mbedtls_gcm_init(&ctx); 1059 1060 ret = mbedtls_gcm_setkey(&ctx, cipher, 1061 key_test_data[key_index_test_data[i]], 1062 key_len); 1063 /* 1064 * AES-192 is an optional feature that may be unavailable when 1065 * there is an alternative underlying implementation i.e. when 1066 * MBEDTLS_AES_ALT is defined. 1067 */ 1068 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) { 1069 mbedtls_printf("skipped\n"); 1070 break; 1071 } else if (ret != 0) { 1072 goto exit; 1073 } 1074 1075 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, 1076 pt_len_test_data[i], 1077 iv_test_data[iv_index_test_data[i]], 1078 iv_len_test_data[i], 1079 additional_test_data[add_index_test_data[i]], 1080 add_len_test_data[i], 1081 pt_test_data[pt_index_test_data[i]], 1082 buf, 16, tag_buf); 1083 #if defined(MBEDTLS_GCM_ALT) 1084 /* Allow alternative implementations to only support 12-byte nonces. */ 1085 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && 1086 iv_len_test_data[i] != 12) { 1087 mbedtls_printf("skipped\n"); 1088 break; 1089 } 1090 #endif /* defined(MBEDTLS_GCM_ALT) */ 1091 if (ret != 0) { 1092 goto exit; 1093 } 1094 1095 if (memcmp(buf, ct_test_data[j * 6 + i], 1096 pt_len_test_data[i]) != 0 || 1097 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { 1098 ret = 1; 1099 goto exit; 1100 } 1101 1102 mbedtls_gcm_free(&ctx); 1103 1104 if (verbose != 0) { 1105 mbedtls_printf("passed\n"); 1106 } 1107 1108 mbedtls_gcm_init(&ctx); 1109 1110 if (verbose != 0) { 1111 mbedtls_printf(" AES-GCM-%3d #%d (%s): ", 1112 key_len, i, "dec"); 1113 } 1114 1115 ret = mbedtls_gcm_setkey(&ctx, cipher, 1116 key_test_data[key_index_test_data[i]], 1117 key_len); 1118 if (ret != 0) { 1119 goto exit; 1120 } 1121 1122 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT, 1123 pt_len_test_data[i], 1124 iv_test_data[iv_index_test_data[i]], 1125 iv_len_test_data[i], 1126 additional_test_data[add_index_test_data[i]], 1127 add_len_test_data[i], 1128 ct_test_data[j * 6 + i], buf, 16, tag_buf); 1129 1130 if (ret != 0) { 1131 goto exit; 1132 } 1133 1134 if (memcmp(buf, pt_test_data[pt_index_test_data[i]], 1135 pt_len_test_data[i]) != 0 || 1136 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { 1137 ret = 1; 1138 goto exit; 1139 } 1140 1141 mbedtls_gcm_free(&ctx); 1142 1143 if (verbose != 0) { 1144 mbedtls_printf("passed\n"); 1145 } 1146 1147 mbedtls_gcm_init(&ctx); 1148 1149 if (verbose != 0) { 1150 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ", 1151 key_len, i, "enc"); 1152 } 1153 1154 ret = mbedtls_gcm_setkey(&ctx, cipher, 1155 key_test_data[key_index_test_data[i]], 1156 key_len); 1157 if (ret != 0) { 1158 goto exit; 1159 } 1160 1161 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT, 1162 iv_test_data[iv_index_test_data[i]], 1163 iv_len_test_data[i]); 1164 if (ret != 0) { 1165 goto exit; 1166 } 1167 1168 ret = mbedtls_gcm_update_ad(&ctx, 1169 additional_test_data[add_index_test_data[i]], 1170 add_len_test_data[i]); 1171 if (ret != 0) { 1172 goto exit; 1173 } 1174 1175 if (pt_len_test_data[i] > 32) { 1176 size_t rest_len = pt_len_test_data[i] - 32; 1177 ret = mbedtls_gcm_update(&ctx, 1178 pt_test_data[pt_index_test_data[i]], 1179 32, 1180 buf, sizeof(buf), &olen); 1181 if (ret != 0) { 1182 goto exit; 1183 } 1184 if (olen != 32) { 1185 goto exit; 1186 } 1187 1188 ret = mbedtls_gcm_update(&ctx, 1189 pt_test_data[pt_index_test_data[i]] + 32, 1190 rest_len, 1191 buf + 32, sizeof(buf) - 32, &olen); 1192 if (ret != 0) { 1193 goto exit; 1194 } 1195 if (olen != rest_len) { 1196 goto exit; 1197 } 1198 } else { 1199 ret = mbedtls_gcm_update(&ctx, 1200 pt_test_data[pt_index_test_data[i]], 1201 pt_len_test_data[i], 1202 buf, sizeof(buf), &olen); 1203 if (ret != 0) { 1204 goto exit; 1205 } 1206 if (olen != pt_len_test_data[i]) { 1207 goto exit; 1208 } 1209 } 1210 1211 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16); 1212 if (ret != 0) { 1213 goto exit; 1214 } 1215 1216 if (memcmp(buf, ct_test_data[j * 6 + i], 1217 pt_len_test_data[i]) != 0 || 1218 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { 1219 ret = 1; 1220 goto exit; 1221 } 1222 1223 mbedtls_gcm_free(&ctx); 1224 1225 if (verbose != 0) { 1226 mbedtls_printf("passed\n"); 1227 } 1228 1229 mbedtls_gcm_init(&ctx); 1230 1231 if (verbose != 0) { 1232 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ", 1233 key_len, i, "dec"); 1234 } 1235 1236 ret = mbedtls_gcm_setkey(&ctx, cipher, 1237 key_test_data[key_index_test_data[i]], 1238 key_len); 1239 if (ret != 0) { 1240 goto exit; 1241 } 1242 1243 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, 1244 iv_test_data[iv_index_test_data[i]], 1245 iv_len_test_data[i]); 1246 if (ret != 0) { 1247 goto exit; 1248 } 1249 ret = mbedtls_gcm_update_ad(&ctx, 1250 additional_test_data[add_index_test_data[i]], 1251 add_len_test_data[i]); 1252 if (ret != 0) { 1253 goto exit; 1254 } 1255 1256 if (pt_len_test_data[i] > 32) { 1257 size_t rest_len = pt_len_test_data[i] - 32; 1258 ret = mbedtls_gcm_update(&ctx, 1259 ct_test_data[j * 6 + i], 32, 1260 buf, sizeof(buf), &olen); 1261 if (ret != 0) { 1262 goto exit; 1263 } 1264 if (olen != 32) { 1265 goto exit; 1266 } 1267 1268 ret = mbedtls_gcm_update(&ctx, 1269 ct_test_data[j * 6 + i] + 32, 1270 rest_len, 1271 buf + 32, sizeof(buf) - 32, &olen); 1272 if (ret != 0) { 1273 goto exit; 1274 } 1275 if (olen != rest_len) { 1276 goto exit; 1277 } 1278 } else { 1279 ret = mbedtls_gcm_update(&ctx, 1280 ct_test_data[j * 6 + i], 1281 pt_len_test_data[i], 1282 buf, sizeof(buf), &olen); 1283 if (ret != 0) { 1284 goto exit; 1285 } 1286 if (olen != pt_len_test_data[i]) { 1287 goto exit; 1288 } 1289 } 1290 1291 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16); 1292 if (ret != 0) { 1293 goto exit; 1294 } 1295 1296 if (memcmp(buf, pt_test_data[pt_index_test_data[i]], 1297 pt_len_test_data[i]) != 0 || 1298 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { 1299 ret = 1; 1300 goto exit; 1301 } 1302 1303 mbedtls_gcm_free(&ctx); 1304 1305 if (verbose != 0) { 1306 mbedtls_printf("passed\n"); 1307 } 1308 } 1309 } 1310 1311 if (verbose != 0) { 1312 mbedtls_printf("\n"); 1313 } 1314 1315 ret = 0; 1316 1317 exit: 1318 if (ret != 0) { 1319 if (verbose != 0) { 1320 mbedtls_printf("failed\n"); 1321 } 1322 mbedtls_gcm_free(&ctx); 1323 } 1324 1325 return ret; 1326 } 1327 1328 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ 1329 1330 #endif /* MBEDTLS_GCM_C */ 1331