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