1 /* 2 * NIST SP800-38D compliant GCM implementation 3 * 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 5 * SPDX-License-Identifier: GPL-2.0 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * This file is part of mbed TLS (https://tls.mbed.org) 22 */ 23 24 /* 25 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf 26 * 27 * See also: 28 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf 29 * 30 * We use the algorithm described as Shoup's method with 4-bit tables in 31 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. 32 */ 33 34 #if !defined(MBEDTLS_CONFIG_FILE) 35 #include "mbedtls/config.h" 36 #else 37 #include MBEDTLS_CONFIG_FILE 38 #endif 39 40 #if defined(MBEDTLS_GCM_C) 41 42 #include "mbedtls/gcm.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 #if defined(MBEDTLS_PLATFORM_C) 53 #include "mbedtls/platform.h" 54 #else 55 #include <stdio.h> 56 #define mbedtls_printf printf 57 #endif /* MBEDTLS_PLATFORM_C */ 58 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ 59 60 #if !defined(MBEDTLS_GCM_ALT) 61 62 /* 63 * 32-bit integer manipulation macros (big endian) 64 */ 65 #ifndef GET_UINT32_BE 66 #define GET_UINT32_BE(n,b,i) \ 67 { \ 68 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 69 | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 70 | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 71 | ( (uint32_t) (b)[(i) + 3] ); \ 72 } 73 #endif 74 75 #ifndef PUT_UINT32_BE 76 #define PUT_UINT32_BE(n,b,i) \ 77 { \ 78 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 79 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 80 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 81 (b)[(i) + 3] = (unsigned char) ( (n) ); \ 82 } 83 #endif 84 85 /* Implementation that should never be optimized out by the compiler */ 86 static void mbedtls_zeroize( void *v, size_t n ) { 87 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 88 } 89 90 /* 91 * Initialize a context 92 */ 93 void mbedtls_gcm_init( mbedtls_gcm_context *ctx ) 94 { 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 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, 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; 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; 279 unsigned char work_buf[16]; 280 size_t i; 281 const unsigned char *p; 282 size_t use_len, olen = 0; 283 284 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */ 285 /* IV is not allowed to be zero length */ 286 if( iv_len == 0 || 287 ( (uint64_t) iv_len ) >> 61 != 0 || 288 ( (uint64_t) add_len ) >> 61 != 0 ) 289 { 290 return( MBEDTLS_ERR_GCM_BAD_INPUT ); 291 } 292 293 memset( ctx->y, 0x00, sizeof(ctx->y) ); 294 memset( ctx->buf, 0x00, sizeof(ctx->buf) ); 295 296 ctx->mode = mode; 297 ctx->len = 0; 298 ctx->add_len = 0; 299 300 if( iv_len == 12 ) 301 { 302 memcpy( ctx->y, iv, iv_len ); 303 ctx->y[15] = 1; 304 } 305 else 306 { 307 memset( work_buf, 0x00, 16 ); 308 PUT_UINT32_BE( iv_len * 8, work_buf, 12 ); 309 310 p = iv; 311 while( iv_len > 0 ) 312 { 313 use_len = ( iv_len < 16 ) ? iv_len : 16; 314 315 for( i = 0; i < use_len; i++ ) 316 ctx->y[i] ^= p[i]; 317 318 gcm_mult( ctx, ctx->y, ctx->y ); 319 320 iv_len -= use_len; 321 p += use_len; 322 } 323 324 for( i = 0; i < 16; i++ ) 325 ctx->y[i] ^= work_buf[i]; 326 327 gcm_mult( ctx, ctx->y, ctx->y ); 328 } 329 330 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, 331 &olen ) ) != 0 ) 332 { 333 return( ret ); 334 } 335 336 ctx->add_len = add_len; 337 p = add; 338 while( add_len > 0 ) 339 { 340 use_len = ( add_len < 16 ) ? add_len : 16; 341 342 for( i = 0; i < use_len; i++ ) 343 ctx->buf[i] ^= p[i]; 344 345 gcm_mult( ctx, ctx->buf, ctx->buf ); 346 347 add_len -= use_len; 348 p += use_len; 349 } 350 351 return( 0 ); 352 } 353 354 int mbedtls_gcm_update( mbedtls_gcm_context *ctx, 355 size_t length, 356 const unsigned char *input, 357 unsigned char *output ) 358 { 359 int ret; 360 unsigned char ectr[16]; 361 size_t i; 362 const unsigned char *p; 363 unsigned char *out_p = output; 364 size_t use_len, olen = 0; 365 366 if( output > input && (size_t) ( output - input ) < length ) 367 return( MBEDTLS_ERR_GCM_BAD_INPUT ); 368 369 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes 370 * Also check for possible overflow */ 371 if( ctx->len + length < ctx->len || 372 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull ) 373 { 374 return( MBEDTLS_ERR_GCM_BAD_INPUT ); 375 } 376 377 ctx->len += length; 378 379 p = input; 380 while( length > 0 ) 381 { 382 use_len = ( length < 16 ) ? length : 16; 383 384 for( i = 16; i > 12; i-- ) 385 if( ++ctx->y[i - 1] != 0 ) 386 break; 387 388 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr, 389 &olen ) ) != 0 ) 390 { 391 return( ret ); 392 } 393 394 for( i = 0; i < use_len; i++ ) 395 { 396 if( ctx->mode == MBEDTLS_GCM_DECRYPT ) 397 ctx->buf[i] ^= p[i]; 398 out_p[i] = ectr[i] ^ p[i]; 399 if( ctx->mode == MBEDTLS_GCM_ENCRYPT ) 400 ctx->buf[i] ^= out_p[i]; 401 } 402 403 gcm_mult( ctx, ctx->buf, ctx->buf ); 404 405 length -= use_len; 406 p += use_len; 407 out_p += use_len; 408 } 409 410 return( 0 ); 411 } 412 413 int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, 414 unsigned char *tag, 415 size_t tag_len ) 416 { 417 unsigned char work_buf[16]; 418 size_t i; 419 uint64_t orig_len = ctx->len * 8; 420 uint64_t orig_add_len = ctx->add_len * 8; 421 422 if( tag_len > 16 || tag_len < 4 ) 423 return( MBEDTLS_ERR_GCM_BAD_INPUT ); 424 425 memcpy( tag, ctx->base_ectr, tag_len ); 426 427 if( orig_len || orig_add_len ) 428 { 429 memset( work_buf, 0x00, 16 ); 430 431 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 ); 432 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 ); 433 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); 434 PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); 435 436 for( i = 0; i < 16; i++ ) 437 ctx->buf[i] ^= work_buf[i]; 438 439 gcm_mult( ctx, ctx->buf, ctx->buf ); 440 441 for( i = 0; i < tag_len; i++ ) 442 tag[i] ^= ctx->buf[i]; 443 } 444 445 return( 0 ); 446 } 447 448 int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, 449 int mode, 450 size_t length, 451 const unsigned char *iv, 452 size_t iv_len, 453 const unsigned char *add, 454 size_t add_len, 455 const unsigned char *input, 456 unsigned char *output, 457 size_t tag_len, 458 unsigned char *tag ) 459 { 460 int ret; 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; 486 unsigned char check_tag[16]; 487 size_t i; 488 int diff; 489 490 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length, 491 iv, iv_len, add, add_len, 492 input, output, tag_len, check_tag ) ) != 0 ) 493 { 494 return( ret ); 495 } 496 497 /* Check tag in "constant-time" */ 498 for( diff = 0, i = 0; i < tag_len; i++ ) 499 diff |= tag[i] ^ check_tag[i]; 500 501 if( diff != 0 ) 502 { 503 mbedtls_zeroize( output, length ); 504 return( MBEDTLS_ERR_GCM_AUTH_FAILED ); 505 } 506 507 return( 0 ); 508 } 509 510 void mbedtls_gcm_free( mbedtls_gcm_context *ctx ) 511 { 512 mbedtls_cipher_free( &ctx->cipher_ctx ); 513 mbedtls_zeroize( ctx, sizeof( mbedtls_gcm_context ) ); 514 } 515 516 #endif /* !MBEDTLS_GCM_ALT */ 517 518 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) 519 /* 520 * AES-GCM test vectors from: 521 * 522 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip 523 */ 524 #define MAX_TESTS 6 525 526 static const int key_index[MAX_TESTS] = 527 { 0, 0, 1, 1, 1, 1 }; 528 529 static const unsigned char key[MAX_TESTS][32] = 530 { 531 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 534 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 535 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 536 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 537 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 538 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, 539 }; 540 541 static const size_t iv_len[MAX_TESTS] = 542 { 12, 12, 12, 12, 8, 60 }; 543 544 static const int iv_index[MAX_TESTS] = 545 { 0, 0, 1, 1, 1, 2 }; 546 547 static const unsigned char iv[MAX_TESTS][64] = 548 { 549 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 550 0x00, 0x00, 0x00, 0x00 }, 551 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 552 0xde, 0xca, 0xf8, 0x88 }, 553 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 554 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, 555 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 556 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, 557 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, 558 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, 559 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, 560 0xa6, 0x37, 0xb3, 0x9b }, 561 }; 562 563 static const size_t add_len[MAX_TESTS] = 564 { 0, 0, 0, 20, 20, 20 }; 565 566 static const int add_index[MAX_TESTS] = 567 { 0, 0, 0, 1, 1, 1 }; 568 569 static const unsigned char additional[MAX_TESTS][64] = 570 { 571 { 0x00 }, 572 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 573 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 574 0xab, 0xad, 0xda, 0xd2 }, 575 }; 576 577 static const size_t pt_len[MAX_TESTS] = 578 { 0, 16, 64, 60, 60, 60 }; 579 580 static const int pt_index[MAX_TESTS] = 581 { 0, 0, 1, 1, 1, 1 }; 582 583 static const unsigned char pt[MAX_TESTS][64] = 584 { 585 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 587 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 588 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 589 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 590 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 591 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 592 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 593 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 594 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, 595 }; 596 597 static const unsigned char ct[MAX_TESTS * 3][64] = 598 { 599 { 0x00 }, 600 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, 601 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, 602 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 603 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 604 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 605 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 606 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 607 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 608 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 609 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, 610 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 611 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 612 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 613 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 614 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 615 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 616 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 617 0x3d, 0x58, 0xe0, 0x91 }, 618 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, 619 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, 620 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, 621 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, 622 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, 623 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, 624 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, 625 0xc2, 0x3f, 0x45, 0x98 }, 626 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, 627 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, 628 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, 629 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, 630 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, 631 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, 632 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, 633 0x4c, 0x34, 0xae, 0xe5 }, 634 { 0x00 }, 635 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, 636 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, 637 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 638 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, 639 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 640 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, 641 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 642 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 643 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, 644 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, 645 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 646 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, 647 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 648 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, 649 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 650 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 651 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, 652 0xcc, 0xda, 0x27, 0x10 }, 653 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, 654 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, 655 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, 656 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, 657 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, 658 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, 659 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, 660 0xa0, 0xf0, 0x62, 0xf7 }, 661 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, 662 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, 663 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, 664 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, 665 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, 666 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, 667 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, 668 0xe9, 0xb7, 0x37, 0x3b }, 669 { 0x00 }, 670 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, 671 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, 672 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 673 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, 674 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 675 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, 676 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 677 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 678 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, 679 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, 680 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 681 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, 682 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 683 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, 684 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 685 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 686 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, 687 0xbc, 0xc9, 0xf6, 0x62 }, 688 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, 689 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, 690 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, 691 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, 692 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, 693 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, 694 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, 695 0xf4, 0x7c, 0x9b, 0x1f }, 696 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, 697 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, 698 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, 699 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, 700 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, 701 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, 702 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, 703 0x44, 0xae, 0x7e, 0x3f }, 704 }; 705 706 static const unsigned char tag[MAX_TESTS * 3][16] = 707 { 708 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, 709 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, 710 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, 711 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, 712 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 713 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, 714 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, 715 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, 716 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, 717 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, 718 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, 719 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, 720 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, 721 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, 722 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, 723 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, 724 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, 725 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, 726 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, 727 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, 728 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, 729 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, 730 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, 731 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, 732 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 733 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, 734 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, 735 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, 736 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, 737 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, 738 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, 739 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, 740 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, 741 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, 742 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, 743 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, 744 }; 745 746 int mbedtls_gcm_self_test( int verbose ) 747 { 748 mbedtls_gcm_context ctx; 749 unsigned char buf[64]; 750 unsigned char tag_buf[16]; 751 int i, j, ret; 752 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; 753 754 for( j = 0; j < 3; j++ ) 755 { 756 int key_len = 128 + 64 * j; 757 758 for( i = 0; i < MAX_TESTS; i++ ) 759 { 760 mbedtls_gcm_init( &ctx ); 761 762 if( verbose != 0 ) 763 mbedtls_printf( " AES-GCM-%3d #%d (%s): ", 764 key_len, i, "enc" ); 765 766 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], 767 key_len ); 768 /* 769 * AES-192 is an optional feature that may be unavailable when 770 * there is an alternative underlying implementation i.e. when 771 * MBEDTLS_AES_ALT is defined. 772 */ 773 if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && key_len == 192 ) 774 { 775 mbedtls_printf( "skipped\n" ); 776 break; 777 } 778 else if( ret != 0 ) 779 { 780 goto exit; 781 } 782 783 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, 784 pt_len[i], 785 iv[iv_index[i]], iv_len[i], 786 additional[add_index[i]], add_len[i], 787 pt[pt_index[i]], buf, 16, tag_buf ); 788 if( ret != 0 ) 789 goto exit; 790 791 if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || 792 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) 793 { 794 ret = 1; 795 goto exit; 796 } 797 798 mbedtls_gcm_free( &ctx ); 799 800 if( verbose != 0 ) 801 mbedtls_printf( "passed\n" ); 802 803 mbedtls_gcm_init( &ctx ); 804 805 if( verbose != 0 ) 806 mbedtls_printf( " AES-GCM-%3d #%d (%s): ", 807 key_len, i, "dec" ); 808 809 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], 810 key_len ); 811 if( ret != 0 ) 812 goto exit; 813 814 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT, 815 pt_len[i], 816 iv[iv_index[i]], iv_len[i], 817 additional[add_index[i]], add_len[i], 818 ct[j * 6 + i], buf, 16, tag_buf ); 819 820 if( ret != 0 ) 821 goto exit; 822 823 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || 824 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) 825 { 826 ret = 1; 827 goto exit; 828 } 829 830 mbedtls_gcm_free( &ctx ); 831 832 if( verbose != 0 ) 833 mbedtls_printf( "passed\n" ); 834 835 mbedtls_gcm_init( &ctx ); 836 837 if( verbose != 0 ) 838 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", 839 key_len, i, "enc" ); 840 841 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], 842 key_len ); 843 if( ret != 0 ) 844 goto exit; 845 846 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT, 847 iv[iv_index[i]], iv_len[i], 848 additional[add_index[i]], add_len[i] ); 849 if( ret != 0 ) 850 goto exit; 851 852 if( pt_len[i] > 32 ) 853 { 854 size_t rest_len = pt_len[i] - 32; 855 ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf ); 856 if( ret != 0 ) 857 goto exit; 858 859 ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, 860 buf + 32 ); 861 if( ret != 0 ) 862 goto exit; 863 } 864 else 865 { 866 ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf ); 867 if( ret != 0 ) 868 goto exit; 869 } 870 871 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); 872 if( ret != 0 ) 873 goto exit; 874 875 if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || 876 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) 877 { 878 ret = 1; 879 goto exit; 880 } 881 882 mbedtls_gcm_free( &ctx ); 883 884 if( verbose != 0 ) 885 mbedtls_printf( "passed\n" ); 886 887 mbedtls_gcm_init( &ctx ); 888 889 if( verbose != 0 ) 890 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", 891 key_len, i, "dec" ); 892 893 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], 894 key_len ); 895 if( ret != 0 ) 896 goto exit; 897 898 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT, 899 iv[iv_index[i]], iv_len[i], 900 additional[add_index[i]], add_len[i] ); 901 if( ret != 0 ) 902 goto exit; 903 904 if( pt_len[i] > 32 ) 905 { 906 size_t rest_len = pt_len[i] - 32; 907 ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf ); 908 if( ret != 0 ) 909 goto exit; 910 911 ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, 912 buf + 32 ); 913 if( ret != 0 ) 914 goto exit; 915 } 916 else 917 { 918 ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + 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, pt[pt_index[i]], pt_len[i] ) != 0 || 929 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) 930 { 931 ret = 1; 932 goto exit; 933 } 934 935 mbedtls_gcm_free( &ctx ); 936 937 if( verbose != 0 ) 938 mbedtls_printf( "passed\n" ); 939 } 940 } 941 942 if( verbose != 0 ) 943 mbedtls_printf( "\n" ); 944 945 ret = 0; 946 947 exit: 948 if( ret != 0 ) 949 { 950 if( verbose != 0 ) 951 mbedtls_printf( "failed\n" ); 952 mbedtls_gcm_free( &ctx ); 953 } 954 955 return( ret ); 956 } 957 958 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ 959 960 #endif /* MBEDTLS_GCM_C */ 961