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