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