1 /* 2 * NIST SP800-38D compliant GCM implementation 3 * 4 * Copyright The Mbed TLS Contributors 5 * SPDX-License-Identifier: Apache-2.0 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may 8 * not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 /* 21 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf 22 * 23 * See also: 24 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf 25 * 26 * We use the algorithm described as Shoup's method with 4-bit tables in 27 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. 28 */ 29 30 #include "common.h" 31 32 #if defined(MBEDTLS_GCM_C) 33 34 #include "mbedtls/gcm.h" 35 #include "mbedtls/platform.h" 36 #include "mbedtls/platform_util.h" 37 #include "mbedtls/error.h" 38 39 #include <string.h> 40 41 #if defined(MBEDTLS_AESNI_C) 42 #include "aesni.h" 43 #endif 44 45 #if defined(MBEDTLS_AESCE_C) 46 #include "aesce.h" 47 #endif 48 49 #if !defined(MBEDTLS_GCM_ALT) 50 51 /* 52 * Initialize a context 53 */ 54 void mbedtls_gcm_init(mbedtls_gcm_context *ctx) 55 { 56 memset(ctx, 0, sizeof(mbedtls_gcm_context)); 57 } 58 59 /* 60 * Precompute small multiples of H, that is set 61 * HH[i] || HL[i] = H times i, 62 * where i is seen as a field element as in [MGV], ie high-order bits 63 * correspond to low powers of P. The result is stored in the same way, that 64 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL 65 * corresponds to P^127. 66 */ 67 static int gcm_gen_table(mbedtls_gcm_context *ctx) 68 { 69 int ret, i, j; 70 uint64_t hi, lo; 71 uint64_t vl, vh; 72 unsigned char h[16]; 73 size_t olen = 0; 74 75 memset(h, 0, 16); 76 if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen)) != 0) { 77 return ret; 78 } 79 80 /* pack h as two 64-bits ints, big-endian */ 81 hi = MBEDTLS_GET_UINT32_BE(h, 0); 82 lo = MBEDTLS_GET_UINT32_BE(h, 4); 83 vh = (uint64_t) hi << 32 | lo; 84 85 hi = MBEDTLS_GET_UINT32_BE(h, 8); 86 lo = MBEDTLS_GET_UINT32_BE(h, 12); 87 vl = (uint64_t) hi << 32 | lo; 88 89 /* 8 = 1000 corresponds to 1 in GF(2^128) */ 90 ctx->HL[8] = vl; 91 ctx->HH[8] = vh; 92 93 #if defined(MBEDTLS_AESNI_HAVE_CODE) 94 /* With CLMUL support, we need only h, not the rest of the table */ 95 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) { 96 return 0; 97 } 98 #endif 99 100 #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64) 101 if (mbedtls_aesce_has_support()) { 102 return 0; 103 } 104 #endif 105 106 /* 0 corresponds to 0 in GF(2^128) */ 107 ctx->HH[0] = 0; 108 ctx->HL[0] = 0; 109 110 for (i = 4; i > 0; i >>= 1) { 111 uint32_t T = (vl & 1) * 0xe1000000U; 112 vl = (vh << 63) | (vl >> 1); 113 vh = (vh >> 1) ^ ((uint64_t) T << 32); 114 115 ctx->HL[i] = vl; 116 ctx->HH[i] = vh; 117 } 118 119 for (i = 2; i <= 8; i *= 2) { 120 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i; 121 vh = *HiH; 122 vl = *HiL; 123 for (j = 1; j < i; j++) { 124 HiH[j] = vh ^ ctx->HH[j]; 125 HiL[j] = vl ^ ctx->HL[j]; 126 } 127 } 128 129 return 0; 130 } 131 132 int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx, 133 mbedtls_cipher_id_t cipher, 134 const unsigned char *key, 135 unsigned int keybits) 136 { 137 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 138 const mbedtls_cipher_info_t *cipher_info; 139 140 if (keybits != 128 && keybits != 192 && keybits != 256) { 141 return MBEDTLS_ERR_GCM_BAD_INPUT; 142 } 143 144 cipher_info = mbedtls_cipher_info_from_values(cipher, keybits, 145 MBEDTLS_MODE_ECB); 146 if (cipher_info == NULL) { 147 return MBEDTLS_ERR_GCM_BAD_INPUT; 148 } 149 150 if (cipher_info->block_size != 16) { 151 return MBEDTLS_ERR_GCM_BAD_INPUT; 152 } 153 154 mbedtls_cipher_free(&ctx->cipher_ctx); 155 156 if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) { 157 return ret; 158 } 159 160 if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits, 161 MBEDTLS_ENCRYPT)) != 0) { 162 return ret; 163 } 164 165 if ((ret = gcm_gen_table(ctx)) != 0) { 166 return ret; 167 } 168 169 return 0; 170 } 171 172 /* 173 * Shoup's method for multiplication use this table with 174 * last4[x] = x times P^128 175 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV] 176 */ 177 static const uint64_t last4[16] = 178 { 179 0x0000, 0x1c20, 0x3840, 0x2460, 180 0x7080, 0x6ca0, 0x48c0, 0x54e0, 181 0xe100, 0xfd20, 0xd940, 0xc560, 182 0x9180, 0x8da0, 0xa9c0, 0xb5e0 183 }; 184 185 /* 186 * Sets output to x times H using the precomputed tables. 187 * x and output are seen as elements of GF(2^128) as in [MGV]. 188 */ 189 static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16], 190 unsigned char output[16]) 191 { 192 int i = 0; 193 unsigned char lo, hi, rem; 194 uint64_t zh, zl; 195 196 #if defined(MBEDTLS_AESNI_HAVE_CODE) 197 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) { 198 unsigned char h[16]; 199 200 /* mbedtls_aesni_gcm_mult needs big-endian input */ 201 MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0); 202 MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4); 203 MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8); 204 MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12); 205 206 mbedtls_aesni_gcm_mult(output, x, h); 207 return; 208 } 209 #endif /* MBEDTLS_AESNI_HAVE_CODE */ 210 211 #if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64) 212 if (mbedtls_aesce_has_support()) { 213 unsigned char h[16]; 214 215 /* mbedtls_aesce_gcm_mult needs big-endian input */ 216 MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0); 217 MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4); 218 MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8); 219 MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12); 220 221 mbedtls_aesce_gcm_mult(output, x, h); 222 return; 223 } 224 #endif 225 226 lo = x[15] & 0xf; 227 228 zh = ctx->HH[lo]; 229 zl = ctx->HL[lo]; 230 231 for (i = 15; i >= 0; i--) { 232 lo = x[i] & 0xf; 233 hi = (x[i] >> 4) & 0xf; 234 235 if (i != 15) { 236 rem = (unsigned char) zl & 0xf; 237 zl = (zh << 60) | (zl >> 4); 238 zh = (zh >> 4); 239 zh ^= (uint64_t) last4[rem] << 48; 240 zh ^= ctx->HH[lo]; 241 zl ^= ctx->HL[lo]; 242 243 } 244 245 rem = (unsigned char) zl & 0xf; 246 zl = (zh << 60) | (zl >> 4); 247 zh = (zh >> 4); 248 zh ^= (uint64_t) last4[rem] << 48; 249 zh ^= ctx->HH[hi]; 250 zl ^= ctx->HL[hi]; 251 } 252 253 MBEDTLS_PUT_UINT32_BE(zh >> 32, output, 0); 254 MBEDTLS_PUT_UINT32_BE(zh, output, 4); 255 MBEDTLS_PUT_UINT32_BE(zl >> 32, output, 8); 256 MBEDTLS_PUT_UINT32_BE(zl, output, 12); 257 } 258 259 int mbedtls_gcm_starts(mbedtls_gcm_context *ctx, 260 int mode, 261 const unsigned char *iv, size_t iv_len) 262 { 263 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 264 unsigned char work_buf[16]; 265 const unsigned char *p; 266 size_t use_len, olen = 0; 267 uint64_t iv_bits; 268 269 /* IV is limited to 2^64 bits, so 2^61 bytes */ 270 /* IV is not allowed to be zero length */ 271 if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) { 272 return MBEDTLS_ERR_GCM_BAD_INPUT; 273 } 274 275 memset(ctx->y, 0x00, sizeof(ctx->y)); 276 memset(ctx->buf, 0x00, sizeof(ctx->buf)); 277 278 ctx->mode = mode; 279 ctx->len = 0; 280 ctx->add_len = 0; 281 282 if (iv_len == 12) { 283 memcpy(ctx->y, iv, iv_len); 284 ctx->y[15] = 1; 285 } else { 286 memset(work_buf, 0x00, 16); 287 iv_bits = (uint64_t) iv_len * 8; 288 MBEDTLS_PUT_UINT64_BE(iv_bits, work_buf, 8); 289 290 p = iv; 291 while (iv_len > 0) { 292 use_len = (iv_len < 16) ? iv_len : 16; 293 294 mbedtls_xor(ctx->y, ctx->y, p, use_len); 295 296 gcm_mult(ctx, ctx->y, ctx->y); 297 298 iv_len -= use_len; 299 p += use_len; 300 } 301 302 mbedtls_xor(ctx->y, ctx->y, work_buf, 16); 303 304 gcm_mult(ctx, ctx->y, ctx->y); 305 } 306 307 if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, 308 ctx->base_ectr, &olen)) != 0) { 309 return ret; 310 } 311 312 return 0; 313 } 314 315 /** 316 * mbedtls_gcm_context::buf contains the partial state of the computation of 317 * the authentication tag. 318 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate 319 * different stages of the computation: 320 * * len == 0 && add_len == 0: initial state 321 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have 322 * a partial block of AD that has been 323 * xored in but not yet multiplied in. 324 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if 325 * the data ends now. 326 * * len % 16 != 0: the first `len % 16` bytes have 327 * a partial block of ciphertext that has 328 * been xored in but not yet multiplied in. 329 * * len > 0 && len % 16 == 0: the authentication tag is correct if 330 * the data ends now. 331 */ 332 int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx, 333 const unsigned char *add, size_t add_len) 334 { 335 const unsigned char *p; 336 size_t use_len, offset; 337 338 /* IV is limited to 2^64 bits, so 2^61 bytes */ 339 if ((uint64_t) add_len >> 61 != 0) { 340 return MBEDTLS_ERR_GCM_BAD_INPUT; 341 } 342 343 offset = ctx->add_len % 16; 344 p = add; 345 346 if (offset != 0) { 347 use_len = 16 - offset; 348 if (use_len > add_len) { 349 use_len = add_len; 350 } 351 352 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len); 353 354 if (offset + use_len == 16) { 355 gcm_mult(ctx, ctx->buf, ctx->buf); 356 } 357 358 ctx->add_len += use_len; 359 add_len -= use_len; 360 p += use_len; 361 } 362 363 ctx->add_len += add_len; 364 365 while (add_len >= 16) { 366 mbedtls_xor(ctx->buf, ctx->buf, p, 16); 367 368 gcm_mult(ctx, ctx->buf, ctx->buf); 369 370 add_len -= 16; 371 p += 16; 372 } 373 374 if (add_len > 0) { 375 mbedtls_xor(ctx->buf, ctx->buf, p, add_len); 376 } 377 378 return 0; 379 } 380 381 /* Increment the counter. */ 382 static void gcm_incr(unsigned char y[16]) 383 { 384 size_t i; 385 for (i = 16; i > 12; i--) { 386 if (++y[i - 1] != 0) { 387 break; 388 } 389 } 390 } 391 392 /* Calculate and apply the encryption mask. Process use_len bytes of data, 393 * starting at position offset in the mask block. */ 394 static int gcm_mask(mbedtls_gcm_context *ctx, 395 unsigned char ectr[16], 396 size_t offset, size_t use_len, 397 const unsigned char *input, 398 unsigned char *output) 399 { 400 size_t olen = 0; 401 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 402 403 if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, 404 &olen)) != 0) { 405 mbedtls_platform_zeroize(ectr, 16); 406 return ret; 407 } 408 409 if (ctx->mode == MBEDTLS_GCM_DECRYPT) { 410 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len); 411 } 412 mbedtls_xor(output, ectr + offset, input, use_len); 413 if (ctx->mode == MBEDTLS_GCM_ENCRYPT) { 414 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len); 415 } 416 417 return 0; 418 } 419 420 int mbedtls_gcm_update(mbedtls_gcm_context *ctx, 421 const unsigned char *input, size_t input_length, 422 unsigned char *output, size_t output_size, 423 size_t *output_length) 424 { 425 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 426 const unsigned char *p = input; 427 unsigned char *out_p = output; 428 size_t offset; 429 unsigned char ectr[16] = { 0 }; 430 431 if (output_size < input_length) { 432 return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL; 433 } 434 *output_length = input_length; 435 436 /* Exit early if input_length==0 so that we don't do any pointer arithmetic 437 * on a potentially null pointer. 438 * Returning early also means that the last partial block of AD remains 439 * untouched for mbedtls_gcm_finish */ 440 if (input_length == 0) { 441 return 0; 442 } 443 444 if (output > input && (size_t) (output - input) < input_length) { 445 return MBEDTLS_ERR_GCM_BAD_INPUT; 446 } 447 448 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes 449 * Also check for possible overflow */ 450 if (ctx->len + input_length < ctx->len || 451 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) { 452 return MBEDTLS_ERR_GCM_BAD_INPUT; 453 } 454 455 if (ctx->len == 0 && ctx->add_len % 16 != 0) { 456 gcm_mult(ctx, ctx->buf, ctx->buf); 457 } 458 459 offset = ctx->len % 16; 460 if (offset != 0) { 461 size_t use_len = 16 - offset; 462 if (use_len > input_length) { 463 use_len = input_length; 464 } 465 466 if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) { 467 return ret; 468 } 469 470 if (offset + use_len == 16) { 471 gcm_mult(ctx, ctx->buf, ctx->buf); 472 } 473 474 ctx->len += use_len; 475 input_length -= use_len; 476 p += use_len; 477 out_p += use_len; 478 } 479 480 ctx->len += input_length; 481 482 while (input_length >= 16) { 483 gcm_incr(ctx->y); 484 if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) { 485 return ret; 486 } 487 488 gcm_mult(ctx, ctx->buf, ctx->buf); 489 490 input_length -= 16; 491 p += 16; 492 out_p += 16; 493 } 494 495 if (input_length > 0) { 496 gcm_incr(ctx->y); 497 if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) { 498 return ret; 499 } 500 } 501 502 mbedtls_platform_zeroize(ectr, sizeof(ectr)); 503 return 0; 504 } 505 506 int mbedtls_gcm_finish(mbedtls_gcm_context *ctx, 507 unsigned char *output, size_t output_size, 508 size_t *output_length, 509 unsigned char *tag, size_t tag_len) 510 { 511 unsigned char work_buf[16]; 512 uint64_t orig_len; 513 uint64_t orig_add_len; 514 515 /* We never pass any output in finish(). The output parameter exists only 516 * for the sake of alternative implementations. */ 517 (void) output; 518 (void) output_size; 519 *output_length = 0; 520 521 orig_len = ctx->len * 8; 522 orig_add_len = ctx->add_len * 8; 523 524 if (ctx->len == 0 && ctx->add_len % 16 != 0) { 525 gcm_mult(ctx, ctx->buf, ctx->buf); 526 } 527 528 if (tag_len > 16 || tag_len < 4) { 529 return MBEDTLS_ERR_GCM_BAD_INPUT; 530 } 531 532 if (ctx->len % 16 != 0) { 533 gcm_mult(ctx, ctx->buf, ctx->buf); 534 } 535 536 memcpy(tag, ctx->base_ectr, tag_len); 537 538 if (orig_len || orig_add_len) { 539 memset(work_buf, 0x00, 16); 540 541 MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0); 542 MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4); 543 MBEDTLS_PUT_UINT32_BE((orig_len >> 32), work_buf, 8); 544 MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12); 545 546 mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16); 547 548 gcm_mult(ctx, ctx->buf, ctx->buf); 549 550 mbedtls_xor(tag, tag, ctx->buf, tag_len); 551 } 552 553 return 0; 554 } 555 556 int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx, 557 int mode, 558 size_t length, 559 const unsigned char *iv, 560 size_t iv_len, 561 const unsigned char *add, 562 size_t add_len, 563 const unsigned char *input, 564 unsigned char *output, 565 size_t tag_len, 566 unsigned char *tag) 567 { 568 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 569 size_t olen; 570 571 if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) { 572 return ret; 573 } 574 575 if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) { 576 return ret; 577 } 578 579 if ((ret = mbedtls_gcm_update(ctx, input, length, 580 output, length, &olen)) != 0) { 581 return ret; 582 } 583 584 if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) { 585 return ret; 586 } 587 588 return 0; 589 } 590 591 int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx, 592 size_t length, 593 const unsigned char *iv, 594 size_t iv_len, 595 const unsigned char *add, 596 size_t add_len, 597 const unsigned char *tag, 598 size_t tag_len, 599 const unsigned char *input, 600 unsigned char *output) 601 { 602 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 603 unsigned char check_tag[16]; 604 size_t i; 605 int diff; 606 607 if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length, 608 iv, iv_len, add, add_len, 609 input, output, tag_len, check_tag)) != 0) { 610 return ret; 611 } 612 613 /* Check tag in "constant-time" */ 614 for (diff = 0, i = 0; i < tag_len; i++) { 615 diff |= tag[i] ^ check_tag[i]; 616 } 617 618 if (diff != 0) { 619 mbedtls_platform_zeroize(output, length); 620 return MBEDTLS_ERR_GCM_AUTH_FAILED; 621 } 622 623 return 0; 624 } 625 626 void mbedtls_gcm_free(mbedtls_gcm_context *ctx) 627 { 628 if (ctx == NULL) { 629 return; 630 } 631 mbedtls_cipher_free(&ctx->cipher_ctx); 632 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context)); 633 } 634 635 #endif /* !MBEDTLS_GCM_ALT */ 636 637 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) 638 /* 639 * AES-GCM test vectors from: 640 * 641 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip 642 */ 643 #define MAX_TESTS 6 644 645 static const int key_index_test_data[MAX_TESTS] = 646 { 0, 0, 1, 1, 1, 1 }; 647 648 static const unsigned char key_test_data[MAX_TESTS][32] = 649 { 650 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 654 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 655 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 656 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 657 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, 658 }; 659 660 static const size_t iv_len_test_data[MAX_TESTS] = 661 { 12, 12, 12, 12, 8, 60 }; 662 663 static const int iv_index_test_data[MAX_TESTS] = 664 { 0, 0, 1, 1, 1, 2 }; 665 666 static const unsigned char iv_test_data[MAX_TESTS][64] = 667 { 668 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 669 0x00, 0x00, 0x00, 0x00 }, 670 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 671 0xde, 0xca, 0xf8, 0x88 }, 672 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 673 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, 674 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 675 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, 676 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, 677 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, 678 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, 679 0xa6, 0x37, 0xb3, 0x9b }, 680 }; 681 682 static const size_t add_len_test_data[MAX_TESTS] = 683 { 0, 0, 0, 20, 20, 20 }; 684 685 static const int add_index_test_data[MAX_TESTS] = 686 { 0, 0, 0, 1, 1, 1 }; 687 688 static const unsigned char additional_test_data[MAX_TESTS][64] = 689 { 690 { 0x00 }, 691 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 692 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 693 0xab, 0xad, 0xda, 0xd2 }, 694 }; 695 696 static const size_t pt_len_test_data[MAX_TESTS] = 697 { 0, 16, 64, 60, 60, 60 }; 698 699 static const int pt_index_test_data[MAX_TESTS] = 700 { 0, 0, 1, 1, 1, 1 }; 701 702 static const unsigned char pt_test_data[MAX_TESTS][64] = 703 { 704 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 706 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 707 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 708 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 709 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 710 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 711 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 712 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 713 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, 714 }; 715 716 static const unsigned char ct_test_data[MAX_TESTS * 3][64] = 717 { 718 { 0x00 }, 719 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, 720 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, 721 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 722 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 723 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 724 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 725 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 726 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 727 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 728 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, 729 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 730 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 731 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 732 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 733 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 734 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 735 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 736 0x3d, 0x58, 0xe0, 0x91 }, 737 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, 738 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, 739 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, 740 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, 741 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, 742 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, 743 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, 744 0xc2, 0x3f, 0x45, 0x98 }, 745 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, 746 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, 747 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, 748 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, 749 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, 750 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, 751 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, 752 0x4c, 0x34, 0xae, 0xe5 }, 753 { 0x00 }, 754 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, 755 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, 756 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 757 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, 758 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 759 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, 760 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 761 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 762 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, 763 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, 764 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 765 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, 766 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 767 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, 768 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 769 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 770 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, 771 0xcc, 0xda, 0x27, 0x10 }, 772 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, 773 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, 774 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, 775 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, 776 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, 777 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, 778 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, 779 0xa0, 0xf0, 0x62, 0xf7 }, 780 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, 781 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, 782 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, 783 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, 784 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, 785 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, 786 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, 787 0xe9, 0xb7, 0x37, 0x3b }, 788 { 0x00 }, 789 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, 790 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, 791 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 792 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, 793 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 794 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, 795 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 796 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 797 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, 798 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, 799 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 800 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, 801 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 802 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, 803 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 804 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 805 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, 806 0xbc, 0xc9, 0xf6, 0x62 }, 807 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, 808 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, 809 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, 810 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, 811 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, 812 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, 813 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, 814 0xf4, 0x7c, 0x9b, 0x1f }, 815 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, 816 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, 817 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, 818 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, 819 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, 820 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, 821 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, 822 0x44, 0xae, 0x7e, 0x3f }, 823 }; 824 825 static const unsigned char tag_test_data[MAX_TESTS * 3][16] = 826 { 827 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, 828 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, 829 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, 830 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, 831 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 832 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, 833 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, 834 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, 835 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, 836 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, 837 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, 838 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, 839 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, 840 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, 841 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, 842 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, 843 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, 844 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, 845 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, 846 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, 847 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, 848 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, 849 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, 850 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, 851 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 852 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, 853 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, 854 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, 855 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, 856 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, 857 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, 858 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, 859 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, 860 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, 861 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, 862 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, 863 }; 864 865 int mbedtls_gcm_self_test(int verbose) 866 { 867 mbedtls_gcm_context ctx; 868 unsigned char buf[64]; 869 unsigned char tag_buf[16]; 870 int i, j, ret; 871 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; 872 size_t olen; 873 874 if (verbose != 0) { 875 #if defined(MBEDTLS_GCM_ALT) 876 mbedtls_printf(" GCM note: alternative implementation.\n"); 877 #else /* MBEDTLS_GCM_ALT */ 878 #if defined(MBEDTLS_AESNI_HAVE_CODE) 879 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) { 880 mbedtls_printf(" GCM note: using AESNI.\n"); 881 } else 882 #endif 883 mbedtls_printf(" GCM note: built-in implementation.\n"); 884 #endif /* MBEDTLS_GCM_ALT */ 885 } 886 887 for (j = 0; j < 3; j++) { 888 int key_len = 128 + 64 * j; 889 890 for (i = 0; i < MAX_TESTS; i++) { 891 mbedtls_gcm_init(&ctx); 892 893 if (verbose != 0) { 894 mbedtls_printf(" AES-GCM-%3d #%d (%s): ", 895 key_len, i, "enc"); 896 } 897 898 ret = mbedtls_gcm_setkey(&ctx, cipher, 899 key_test_data[key_index_test_data[i]], 900 key_len); 901 /* 902 * AES-192 is an optional feature that may be unavailable when 903 * there is an alternative underlying implementation i.e. when 904 * MBEDTLS_AES_ALT is defined. 905 */ 906 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) { 907 mbedtls_printf("skipped\n"); 908 break; 909 } else if (ret != 0) { 910 goto exit; 911 } 912 913 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, 914 pt_len_test_data[i], 915 iv_test_data[iv_index_test_data[i]], 916 iv_len_test_data[i], 917 additional_test_data[add_index_test_data[i]], 918 add_len_test_data[i], 919 pt_test_data[pt_index_test_data[i]], 920 buf, 16, tag_buf); 921 #if defined(MBEDTLS_GCM_ALT) 922 /* Allow alternative implementations to only support 12-byte nonces. */ 923 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && 924 iv_len_test_data[i] != 12) { 925 mbedtls_printf("skipped\n"); 926 break; 927 } 928 #endif /* defined(MBEDTLS_GCM_ALT) */ 929 if (ret != 0) { 930 goto exit; 931 } 932 933 if (memcmp(buf, ct_test_data[j * 6 + i], 934 pt_len_test_data[i]) != 0 || 935 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { 936 ret = 1; 937 goto exit; 938 } 939 940 mbedtls_gcm_free(&ctx); 941 942 if (verbose != 0) { 943 mbedtls_printf("passed\n"); 944 } 945 946 mbedtls_gcm_init(&ctx); 947 948 if (verbose != 0) { 949 mbedtls_printf(" AES-GCM-%3d #%d (%s): ", 950 key_len, i, "dec"); 951 } 952 953 ret = mbedtls_gcm_setkey(&ctx, cipher, 954 key_test_data[key_index_test_data[i]], 955 key_len); 956 if (ret != 0) { 957 goto exit; 958 } 959 960 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT, 961 pt_len_test_data[i], 962 iv_test_data[iv_index_test_data[i]], 963 iv_len_test_data[i], 964 additional_test_data[add_index_test_data[i]], 965 add_len_test_data[i], 966 ct_test_data[j * 6 + i], buf, 16, tag_buf); 967 968 if (ret != 0) { 969 goto exit; 970 } 971 972 if (memcmp(buf, pt_test_data[pt_index_test_data[i]], 973 pt_len_test_data[i]) != 0 || 974 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { 975 ret = 1; 976 goto exit; 977 } 978 979 mbedtls_gcm_free(&ctx); 980 981 if (verbose != 0) { 982 mbedtls_printf("passed\n"); 983 } 984 985 mbedtls_gcm_init(&ctx); 986 987 if (verbose != 0) { 988 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ", 989 key_len, i, "enc"); 990 } 991 992 ret = mbedtls_gcm_setkey(&ctx, cipher, 993 key_test_data[key_index_test_data[i]], 994 key_len); 995 if (ret != 0) { 996 goto exit; 997 } 998 999 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT, 1000 iv_test_data[iv_index_test_data[i]], 1001 iv_len_test_data[i]); 1002 if (ret != 0) { 1003 goto exit; 1004 } 1005 1006 ret = mbedtls_gcm_update_ad(&ctx, 1007 additional_test_data[add_index_test_data[i]], 1008 add_len_test_data[i]); 1009 if (ret != 0) { 1010 goto exit; 1011 } 1012 1013 if (pt_len_test_data[i] > 32) { 1014 size_t rest_len = pt_len_test_data[i] - 32; 1015 ret = mbedtls_gcm_update(&ctx, 1016 pt_test_data[pt_index_test_data[i]], 1017 32, 1018 buf, sizeof(buf), &olen); 1019 if (ret != 0) { 1020 goto exit; 1021 } 1022 if (olen != 32) { 1023 goto exit; 1024 } 1025 1026 ret = mbedtls_gcm_update(&ctx, 1027 pt_test_data[pt_index_test_data[i]] + 32, 1028 rest_len, 1029 buf + 32, sizeof(buf) - 32, &olen); 1030 if (ret != 0) { 1031 goto exit; 1032 } 1033 if (olen != rest_len) { 1034 goto exit; 1035 } 1036 } else { 1037 ret = mbedtls_gcm_update(&ctx, 1038 pt_test_data[pt_index_test_data[i]], 1039 pt_len_test_data[i], 1040 buf, sizeof(buf), &olen); 1041 if (ret != 0) { 1042 goto exit; 1043 } 1044 if (olen != pt_len_test_data[i]) { 1045 goto exit; 1046 } 1047 } 1048 1049 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16); 1050 if (ret != 0) { 1051 goto exit; 1052 } 1053 1054 if (memcmp(buf, ct_test_data[j * 6 + i], 1055 pt_len_test_data[i]) != 0 || 1056 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { 1057 ret = 1; 1058 goto exit; 1059 } 1060 1061 mbedtls_gcm_free(&ctx); 1062 1063 if (verbose != 0) { 1064 mbedtls_printf("passed\n"); 1065 } 1066 1067 mbedtls_gcm_init(&ctx); 1068 1069 if (verbose != 0) { 1070 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ", 1071 key_len, i, "dec"); 1072 } 1073 1074 ret = mbedtls_gcm_setkey(&ctx, cipher, 1075 key_test_data[key_index_test_data[i]], 1076 key_len); 1077 if (ret != 0) { 1078 goto exit; 1079 } 1080 1081 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, 1082 iv_test_data[iv_index_test_data[i]], 1083 iv_len_test_data[i]); 1084 if (ret != 0) { 1085 goto exit; 1086 } 1087 ret = mbedtls_gcm_update_ad(&ctx, 1088 additional_test_data[add_index_test_data[i]], 1089 add_len_test_data[i]); 1090 if (ret != 0) { 1091 goto exit; 1092 } 1093 1094 if (pt_len_test_data[i] > 32) { 1095 size_t rest_len = pt_len_test_data[i] - 32; 1096 ret = mbedtls_gcm_update(&ctx, 1097 ct_test_data[j * 6 + i], 32, 1098 buf, sizeof(buf), &olen); 1099 if (ret != 0) { 1100 goto exit; 1101 } 1102 if (olen != 32) { 1103 goto exit; 1104 } 1105 1106 ret = mbedtls_gcm_update(&ctx, 1107 ct_test_data[j * 6 + i] + 32, 1108 rest_len, 1109 buf + 32, sizeof(buf) - 32, &olen); 1110 if (ret != 0) { 1111 goto exit; 1112 } 1113 if (olen != rest_len) { 1114 goto exit; 1115 } 1116 } else { 1117 ret = mbedtls_gcm_update(&ctx, 1118 ct_test_data[j * 6 + i], 1119 pt_len_test_data[i], 1120 buf, sizeof(buf), &olen); 1121 if (ret != 0) { 1122 goto exit; 1123 } 1124 if (olen != pt_len_test_data[i]) { 1125 goto exit; 1126 } 1127 } 1128 1129 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16); 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 } 1148 1149 if (verbose != 0) { 1150 mbedtls_printf("\n"); 1151 } 1152 1153 ret = 0; 1154 1155 exit: 1156 if (ret != 0) { 1157 if (verbose != 0) { 1158 mbedtls_printf("failed\n"); 1159 } 1160 mbedtls_gcm_free(&ctx); 1161 } 1162 1163 return ret; 1164 } 1165 1166 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ 1167 1168 #endif /* MBEDTLS_GCM_C */ 1169