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