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