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