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