2 * NIST SP800-38D compliant GCM implementation
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * This file is part of mbed TLS (https://tls.mbed.org)
23 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
26 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
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.
32 #if !defined(MBEDTLS_CONFIG_FILE)
33 #include "mbedtls/config.h"
35 #include MBEDTLS_CONFIG_FILE
38 #if defined(MBEDTLS_GCM_C)
40 #include "mbedtls/gcm.h"
41 #include "mbedtls/platform_util.h"
45 #if defined(MBEDTLS_AESNI_C)
46 #include "mbedtls/aesni.h"
49 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
50 #include "mbedtls/aes.h"
51 #include "mbedtls/platform.h"
52 #if !defined(MBEDTLS_PLATFORM_C)
54 #define mbedtls_printf printf
55 #endif /* MBEDTLS_PLATFORM_C */
56 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
58 #if !defined(MBEDTLS_GCM_ALT)
60 /* Parameter validation macros */
61 #define GCM_VALIDATE_RET( cond ) \
62 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
63 #define GCM_VALIDATE( cond ) \
64 MBEDTLS_INTERNAL_VALIDATE( cond )
67 * 32-bit integer manipulation macros (big endian)
70 #define GET_UINT32_BE(n,b,i) \
72 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
73 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
74 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
75 | ( (uint32_t) (b)[(i) + 3] ); \
80 #define PUT_UINT32_BE(n,b,i) \
82 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
83 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
84 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
85 (b)[(i) + 3] = (unsigned char) ( (n) ); \
90 * Initialize a context
92 void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
94 GCM_VALIDATE( ctx != NULL );
95 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
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.
106 static int gcm_gen_table( mbedtls_gcm_context *ctx )
115 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
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;
123 GET_UINT32_BE( hi, h, 8 );
124 GET_UINT32_BE( lo, h, 12 );
125 vl = (uint64_t) hi << 32 | lo;
127 /* 8 = 1000 corresponds to 1 in GF(2^128) */
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 ) )
137 /* 0 corresponds to 0 in GF(2^128) */
141 for( i = 4; i > 0; i >>= 1 )
143 uint32_t T = ( vl & 1 ) * 0xe1000000U;
144 vl = ( vh << 63 ) | ( vl >> 1 );
145 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
151 for( i = 2; i <= 8; i *= 2 )
153 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
156 for( j = 1; j < i; j++ )
158 HiH[j] = vh ^ ctx->HH[j];
159 HiL[j] = vl ^ ctx->HL[j];
166 int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
167 mbedtls_cipher_id_t cipher,
168 const unsigned char *key,
169 unsigned int keybits )
172 const mbedtls_cipher_info_t *cipher_info;
174 GCM_VALIDATE_RET( ctx != NULL );
175 GCM_VALIDATE_RET( key != NULL );
176 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
178 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
179 if( cipher_info == NULL )
180 return( MBEDTLS_ERR_GCM_BAD_INPUT );
182 if( cipher_info->block_size != 16 )
183 return( MBEDTLS_ERR_GCM_BAD_INPUT );
185 mbedtls_cipher_free( &ctx->cipher_ctx );
187 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
190 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
191 MBEDTLS_ENCRYPT ) ) != 0 )
196 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
203 * Shoup's method for multiplication use this table with
204 * last4[x] = x times P^128
205 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
207 static const uint64_t last4[16] =
209 0x0000, 0x1c20, 0x3840, 0x2460,
210 0x7080, 0x6ca0, 0x48c0, 0x54e0,
211 0xe100, 0xfd20, 0xd940, 0xc560,
212 0x9180, 0x8da0, 0xa9c0, 0xb5e0
216 * Sets output to x times H using the precomputed tables.
217 * x and output are seen as elements of GF(2^128) as in [MGV].
219 static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
220 unsigned char output[16] )
223 unsigned char lo, hi, rem;
226 #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
227 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
230 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
231 PUT_UINT32_BE( ctx->HH[8], h, 4 );
232 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
233 PUT_UINT32_BE( ctx->HL[8], h, 12 );
235 mbedtls_aesni_gcm_mult( output, x, h );
238 #endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
245 for( i = 15; i >= 0; i-- )
252 rem = (unsigned char) zl & 0xf;
253 zl = ( zh << 60 ) | ( zl >> 4 );
255 zh ^= (uint64_t) last4[rem] << 48;
261 rem = (unsigned char) zl & 0xf;
262 zl = ( zh << 60 ) | ( zl >> 4 );
264 zh ^= (uint64_t) last4[rem] << 48;
269 PUT_UINT32_BE( zh >> 32, output, 0 );
270 PUT_UINT32_BE( zh, output, 4 );
271 PUT_UINT32_BE( zl >> 32, output, 8 );
272 PUT_UINT32_BE( zl, output, 12 );
275 int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
277 const unsigned char *iv,
279 const unsigned char *add,
283 unsigned char work_buf[16];
285 const unsigned char *p;
286 size_t use_len, olen = 0;
288 GCM_VALIDATE_RET( ctx != NULL );
289 GCM_VALIDATE_RET( iv != NULL );
290 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
292 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
293 /* IV is not allowed to be zero length */
295 ( (uint64_t) iv_len ) >> 61 != 0 ||
296 ( (uint64_t) add_len ) >> 61 != 0 )
298 return( MBEDTLS_ERR_GCM_BAD_INPUT );
301 memset( ctx->y, 0x00, sizeof(ctx->y) );
302 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
310 memcpy( ctx->y, iv, iv_len );
315 memset( work_buf, 0x00, 16 );
316 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
321 use_len = ( iv_len < 16 ) ? iv_len : 16;
323 for( i = 0; i < use_len; i++ )
326 gcm_mult( ctx, ctx->y, ctx->y );
332 for( i = 0; i < 16; i++ )
333 ctx->y[i] ^= work_buf[i];
335 gcm_mult( ctx, ctx->y, ctx->y );
338 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
344 ctx->add_len = add_len;
348 use_len = ( add_len < 16 ) ? add_len : 16;
350 for( i = 0; i < use_len; i++ )
353 gcm_mult( ctx, ctx->buf, ctx->buf );
362 int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
364 const unsigned char *input,
365 unsigned char *output )
368 unsigned char ectr[16];
370 const unsigned char *p;
371 unsigned char *out_p = output;
372 size_t use_len, olen = 0;
374 GCM_VALIDATE_RET( ctx != NULL );
375 GCM_VALIDATE_RET( length == 0 || input != NULL );
376 GCM_VALIDATE_RET( length == 0 || output != NULL );
378 if( output > input && (size_t) ( output - input ) < length )
379 return( MBEDTLS_ERR_GCM_BAD_INPUT );
381 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
382 * Also check for possible overflow */
383 if( ctx->len + length < ctx->len ||
384 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
386 return( MBEDTLS_ERR_GCM_BAD_INPUT );
394 use_len = ( length < 16 ) ? length : 16;
396 for( i = 16; i > 12; i-- )
397 if( ++ctx->y[i - 1] != 0 )
400 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
406 for( i = 0; i < use_len; i++ )
408 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
410 out_p[i] = ectr[i] ^ p[i];
411 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
412 ctx->buf[i] ^= out_p[i];
415 gcm_mult( ctx, ctx->buf, ctx->buf );
425 int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
429 unsigned char work_buf[16];
432 uint64_t orig_add_len;
434 GCM_VALIDATE_RET( ctx != NULL );
435 GCM_VALIDATE_RET( tag != NULL );
437 orig_len = ctx->len * 8;
438 orig_add_len = ctx->add_len * 8;
440 if( tag_len > 16 || tag_len < 4 )
441 return( MBEDTLS_ERR_GCM_BAD_INPUT );
443 memcpy( tag, ctx->base_ectr, tag_len );
445 if( orig_len || orig_add_len )
447 memset( work_buf, 0x00, 16 );
449 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
450 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
451 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
452 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
454 for( i = 0; i < 16; i++ )
455 ctx->buf[i] ^= work_buf[i];
457 gcm_mult( ctx, ctx->buf, ctx->buf );
459 for( i = 0; i < tag_len; i++ )
460 tag[i] ^= ctx->buf[i];
466 int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
469 const unsigned char *iv,
471 const unsigned char *add,
473 const unsigned char *input,
474 unsigned char *output,
480 GCM_VALIDATE_RET( ctx != NULL );
481 GCM_VALIDATE_RET( iv != NULL );
482 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
483 GCM_VALIDATE_RET( length == 0 || input != NULL );
484 GCM_VALIDATE_RET( length == 0 || output != NULL );
485 GCM_VALIDATE_RET( tag != NULL );
487 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
490 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
493 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
499 int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
501 const unsigned char *iv,
503 const unsigned char *add,
505 const unsigned char *tag,
507 const unsigned char *input,
508 unsigned char *output )
511 unsigned char check_tag[16];
515 GCM_VALIDATE_RET( ctx != NULL );
516 GCM_VALIDATE_RET( iv != NULL );
517 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
518 GCM_VALIDATE_RET( tag != NULL );
519 GCM_VALIDATE_RET( length == 0 || input != NULL );
520 GCM_VALIDATE_RET( length == 0 || output != NULL );
522 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
523 iv, iv_len, add, add_len,
524 input, output, tag_len, check_tag ) ) != 0 )
529 /* Check tag in "constant-time" */
530 for( diff = 0, i = 0; i < tag_len; i++ )
531 diff |= tag[i] ^ check_tag[i];
535 mbedtls_platform_zeroize( output, length );
536 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
542 void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
546 mbedtls_cipher_free( &ctx->cipher_ctx );
547 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
550 #endif /* !MBEDTLS_GCM_ALT */
552 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
554 * AES-GCM test vectors from:
556 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
560 static const int key_index[MAX_TESTS] =
561 { 0, 0, 1, 1, 1, 1 };
563 static const unsigned char key[MAX_TESTS][32] =
565 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
569 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
570 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
571 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
572 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
575 static const size_t iv_len[MAX_TESTS] =
576 { 12, 12, 12, 12, 8, 60 };
578 static const int iv_index[MAX_TESTS] =
579 { 0, 0, 1, 1, 1, 2 };
581 static const unsigned char iv[MAX_TESTS][64] =
583 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00 },
585 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
586 0xde, 0xca, 0xf8, 0x88 },
587 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
588 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
589 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
590 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
591 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
592 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
593 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
594 0xa6, 0x37, 0xb3, 0x9b },
597 static const size_t add_len[MAX_TESTS] =
598 { 0, 0, 0, 20, 20, 20 };
600 static const int add_index[MAX_TESTS] =
601 { 0, 0, 0, 1, 1, 1 };
603 static const unsigned char additional[MAX_TESTS][64] =
606 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
607 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
608 0xab, 0xad, 0xda, 0xd2 },
611 static const size_t pt_len[MAX_TESTS] =
612 { 0, 16, 64, 60, 60, 60 };
614 static const int pt_index[MAX_TESTS] =
615 { 0, 0, 1, 1, 1, 1 };
617 static const unsigned char pt[MAX_TESTS][64] =
619 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
621 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
622 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
623 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
624 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
625 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
626 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
627 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
628 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
631 static const unsigned char ct[MAX_TESTS * 3][64] =
634 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
635 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
636 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
637 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
638 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
639 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
640 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
641 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
642 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
643 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
644 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
645 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
646 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
647 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
648 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
649 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
650 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
651 0x3d, 0x58, 0xe0, 0x91 },
652 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
653 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
654 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
655 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
656 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
657 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
658 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
659 0xc2, 0x3f, 0x45, 0x98 },
660 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
661 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
662 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
663 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
664 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
665 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
666 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
667 0x4c, 0x34, 0xae, 0xe5 },
669 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
670 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
671 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
672 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
673 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
674 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
675 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
676 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
677 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
678 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
679 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
680 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
681 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
682 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
683 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
684 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
685 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
686 0xcc, 0xda, 0x27, 0x10 },
687 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
688 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
689 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
690 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
691 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
692 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
693 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
694 0xa0, 0xf0, 0x62, 0xf7 },
695 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
696 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
697 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
698 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
699 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
700 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
701 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
702 0xe9, 0xb7, 0x37, 0x3b },
704 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
705 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
706 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
707 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
708 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
709 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
710 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
711 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
712 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
713 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
714 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
715 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
716 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
717 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
718 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
719 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
720 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
721 0xbc, 0xc9, 0xf6, 0x62 },
722 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
723 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
724 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
725 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
726 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
727 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
728 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
729 0xf4, 0x7c, 0x9b, 0x1f },
730 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
731 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
732 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
733 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
734 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
735 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
736 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
737 0x44, 0xae, 0x7e, 0x3f },
740 static const unsigned char tag[MAX_TESTS * 3][16] =
742 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
743 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
744 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
745 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
746 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
747 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
748 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
749 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
750 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
751 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
752 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
753 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
754 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
755 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
756 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
757 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
758 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
759 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
760 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
761 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
762 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
763 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
764 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
765 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
766 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
767 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
768 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
769 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
770 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
771 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
772 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
773 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
774 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
775 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
776 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
777 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
780 int mbedtls_gcm_self_test( int verbose )
782 mbedtls_gcm_context ctx;
783 unsigned char buf[64];
784 unsigned char tag_buf[16];
786 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
788 for( j = 0; j < 3; j++ )
790 int key_len = 128 + 64 * j;
792 for( i = 0; i < MAX_TESTS; i++ )
794 mbedtls_gcm_init( &ctx );
797 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
800 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
803 * AES-192 is an optional feature that may be unavailable when
804 * there is an alternative underlying implementation i.e. when
805 * MBEDTLS_AES_ALT is defined.
807 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
809 mbedtls_printf( "skipped\n" );
817 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
819 iv[iv_index[i]], iv_len[i],
820 additional[add_index[i]], add_len[i],
821 pt[pt_index[i]], buf, 16, tag_buf );
825 if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
826 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
832 mbedtls_gcm_free( &ctx );
835 mbedtls_printf( "passed\n" );
837 mbedtls_gcm_init( &ctx );
840 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
843 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
848 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
850 iv[iv_index[i]], iv_len[i],
851 additional[add_index[i]], add_len[i],
852 ct[j * 6 + i], buf, 16, tag_buf );
857 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
858 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
864 mbedtls_gcm_free( &ctx );
867 mbedtls_printf( "passed\n" );
869 mbedtls_gcm_init( &ctx );
872 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
875 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
880 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
881 iv[iv_index[i]], iv_len[i],
882 additional[add_index[i]], add_len[i] );
888 size_t rest_len = pt_len[i] - 32;
889 ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
893 ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
900 ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
905 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
909 if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
910 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
916 mbedtls_gcm_free( &ctx );
919 mbedtls_printf( "passed\n" );
921 mbedtls_gcm_init( &ctx );
924 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
927 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
932 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
933 iv[iv_index[i]], iv_len[i],
934 additional[add_index[i]], add_len[i] );
940 size_t rest_len = pt_len[i] - 32;
941 ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
945 ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
952 ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
958 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
962 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
963 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
969 mbedtls_gcm_free( &ctx );
972 mbedtls_printf( "passed\n" );
977 mbedtls_printf( "\n" );
985 mbedtls_printf( "failed\n" );
986 mbedtls_gcm_free( &ctx );
992 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
994 #endif /* MBEDTLS_GCM_C */