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,
180 if( cipher_info == NULL )
181 return( MBEDTLS_ERR_GCM_BAD_INPUT );
183 if( cipher_info->block_size != 16 )
184 return( MBEDTLS_ERR_GCM_BAD_INPUT );
186 mbedtls_cipher_free( &ctx->cipher_ctx );
188 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
191 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
192 MBEDTLS_ENCRYPT ) ) != 0 )
197 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
204 * Shoup's method for multiplication use this table with
205 * last4[x] = x times P^128
206 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
208 static const uint64_t last4[16] =
210 0x0000, 0x1c20, 0x3840, 0x2460,
211 0x7080, 0x6ca0, 0x48c0, 0x54e0,
212 0xe100, 0xfd20, 0xd940, 0xc560,
213 0x9180, 0x8da0, 0xa9c0, 0xb5e0
217 * Sets output to x times H using the precomputed tables.
218 * x and output are seen as elements of GF(2^128) as in [MGV].
220 static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
221 unsigned char output[16] )
224 unsigned char lo, hi, rem;
227 #if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
228 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
231 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
232 PUT_UINT32_BE( ctx->HH[8], h, 4 );
233 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
234 PUT_UINT32_BE( ctx->HL[8], h, 12 );
236 mbedtls_aesni_gcm_mult( output, x, h );
239 #endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
246 for( i = 15; i >= 0; i-- )
253 rem = (unsigned char) zl & 0xf;
254 zl = ( zh << 60 ) | ( zl >> 4 );
256 zh ^= (uint64_t) last4[rem] << 48;
262 rem = (unsigned char) zl & 0xf;
263 zl = ( zh << 60 ) | ( zl >> 4 );
265 zh ^= (uint64_t) last4[rem] << 48;
270 PUT_UINT32_BE( zh >> 32, output, 0 );
271 PUT_UINT32_BE( zh, output, 4 );
272 PUT_UINT32_BE( zl >> 32, output, 8 );
273 PUT_UINT32_BE( zl, output, 12 );
276 int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
278 const unsigned char *iv,
280 const unsigned char *add,
284 unsigned char work_buf[16];
286 const unsigned char *p;
287 size_t use_len, olen = 0;
289 GCM_VALIDATE_RET( ctx != NULL );
290 GCM_VALIDATE_RET( iv != NULL );
291 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
293 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
294 /* IV is not allowed to be zero length */
296 ( (uint64_t) iv_len ) >> 61 != 0 ||
297 ( (uint64_t) add_len ) >> 61 != 0 )
299 return( MBEDTLS_ERR_GCM_BAD_INPUT );
302 memset( ctx->y, 0x00, sizeof(ctx->y) );
303 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
311 memcpy( ctx->y, iv, iv_len );
316 memset( work_buf, 0x00, 16 );
317 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
322 use_len = ( iv_len < 16 ) ? iv_len : 16;
324 for( i = 0; i < use_len; i++ )
327 gcm_mult( ctx, ctx->y, ctx->y );
333 for( i = 0; i < 16; i++ )
334 ctx->y[i] ^= work_buf[i];
336 gcm_mult( ctx, ctx->y, ctx->y );
339 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
340 ctx->base_ectr, &olen ) ) != 0 )
345 ctx->add_len = add_len;
349 use_len = ( add_len < 16 ) ? add_len : 16;
351 for( i = 0; i < use_len; i++ )
354 gcm_mult( ctx, ctx->buf, ctx->buf );
363 int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
365 const unsigned char *input,
366 unsigned char *output )
369 unsigned char ectr[16];
371 const unsigned char *p;
372 unsigned char *out_p = output;
373 size_t use_len, olen = 0;
375 GCM_VALIDATE_RET( ctx != NULL );
376 GCM_VALIDATE_RET( length == 0 || input != NULL );
377 GCM_VALIDATE_RET( length == 0 || output != NULL );
379 if( output > input && (size_t) ( output - input ) < length )
380 return( MBEDTLS_ERR_GCM_BAD_INPUT );
382 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
383 * Also check for possible overflow */
384 if( ctx->len + length < ctx->len ||
385 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
387 return( MBEDTLS_ERR_GCM_BAD_INPUT );
395 use_len = ( length < 16 ) ? length : 16;
397 for( i = 16; i > 12; i-- )
398 if( ++ctx->y[i - 1] != 0 )
401 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
407 for( i = 0; i < use_len; i++ )
409 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
411 out_p[i] = ectr[i] ^ p[i];
412 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
413 ctx->buf[i] ^= out_p[i];
416 gcm_mult( ctx, ctx->buf, ctx->buf );
426 int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
430 unsigned char work_buf[16];
433 uint64_t orig_add_len;
435 GCM_VALIDATE_RET( ctx != NULL );
436 GCM_VALIDATE_RET( tag != NULL );
438 orig_len = ctx->len * 8;
439 orig_add_len = ctx->add_len * 8;
441 if( tag_len > 16 || tag_len < 4 )
442 return( MBEDTLS_ERR_GCM_BAD_INPUT );
444 memcpy( tag, ctx->base_ectr, tag_len );
446 if( orig_len || orig_add_len )
448 memset( work_buf, 0x00, 16 );
450 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
451 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
452 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
453 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
455 for( i = 0; i < 16; i++ )
456 ctx->buf[i] ^= work_buf[i];
458 gcm_mult( ctx, ctx->buf, ctx->buf );
460 for( i = 0; i < tag_len; i++ )
461 tag[i] ^= ctx->buf[i];
467 int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
470 const unsigned char *iv,
472 const unsigned char *add,
474 const unsigned char *input,
475 unsigned char *output,
481 GCM_VALIDATE_RET( ctx != NULL );
482 GCM_VALIDATE_RET( iv != NULL );
483 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
484 GCM_VALIDATE_RET( length == 0 || input != NULL );
485 GCM_VALIDATE_RET( length == 0 || output != NULL );
486 GCM_VALIDATE_RET( tag != NULL );
488 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
491 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
494 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
500 int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
502 const unsigned char *iv,
504 const unsigned char *add,
506 const unsigned char *tag,
508 const unsigned char *input,
509 unsigned char *output )
512 unsigned char check_tag[16];
516 GCM_VALIDATE_RET( ctx != NULL );
517 GCM_VALIDATE_RET( iv != NULL );
518 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
519 GCM_VALIDATE_RET( tag != NULL );
520 GCM_VALIDATE_RET( length == 0 || input != NULL );
521 GCM_VALIDATE_RET( length == 0 || output != NULL );
523 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
524 iv, iv_len, add, add_len,
525 input, output, tag_len, check_tag ) ) != 0 )
530 /* Check tag in "constant-time" */
531 for( diff = 0, i = 0; i < tag_len; i++ )
532 diff |= tag[i] ^ check_tag[i];
536 mbedtls_platform_zeroize( output, length );
537 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
543 void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
547 mbedtls_cipher_free( &ctx->cipher_ctx );
548 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
551 #endif /* !MBEDTLS_GCM_ALT */
553 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
555 * AES-GCM test vectors from:
557 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
561 static const int key_index_test_data[MAX_TESTS] =
562 { 0, 0, 1, 1, 1, 1 };
564 static const unsigned char key_test_data[MAX_TESTS][32] =
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
570 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
571 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
572 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
573 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
576 static const size_t iv_len_test_data[MAX_TESTS] =
577 { 12, 12, 12, 12, 8, 60 };
579 static const int iv_index_test_data[MAX_TESTS] =
580 { 0, 0, 1, 1, 1, 2 };
582 static const unsigned char iv_test_data[MAX_TESTS][64] =
584 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00 },
586 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
587 0xde, 0xca, 0xf8, 0x88 },
588 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
589 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
590 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
591 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
592 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
593 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
594 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
595 0xa6, 0x37, 0xb3, 0x9b },
598 static const size_t add_len_test_data[MAX_TESTS] =
599 { 0, 0, 0, 20, 20, 20 };
601 static const int add_index_test_data[MAX_TESTS] =
602 { 0, 0, 0, 1, 1, 1 };
604 static const unsigned char additional_test_data[MAX_TESTS][64] =
607 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
608 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
609 0xab, 0xad, 0xda, 0xd2 },
612 static const size_t pt_len_test_data[MAX_TESTS] =
613 { 0, 16, 64, 60, 60, 60 };
615 static const int pt_index_test_data[MAX_TESTS] =
616 { 0, 0, 1, 1, 1, 1 };
618 static const unsigned char pt_test_data[MAX_TESTS][64] =
620 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
622 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
623 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
624 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
625 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
626 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
627 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
628 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
629 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
632 static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
635 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
636 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
637 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
638 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
639 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
640 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
641 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
642 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
643 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
644 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
645 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
646 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
647 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
648 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
649 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
650 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
651 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
652 0x3d, 0x58, 0xe0, 0x91 },
653 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
654 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
655 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
656 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
657 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
658 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
659 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
660 0xc2, 0x3f, 0x45, 0x98 },
661 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
662 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
663 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
664 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
665 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
666 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
667 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
668 0x4c, 0x34, 0xae, 0xe5 },
670 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
671 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
672 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
673 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
674 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
675 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
676 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
677 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
678 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
679 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
680 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
681 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
682 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
683 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
684 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
685 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
686 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
687 0xcc, 0xda, 0x27, 0x10 },
688 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
689 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
690 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
691 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
692 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
693 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
694 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
695 0xa0, 0xf0, 0x62, 0xf7 },
696 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
697 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
698 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
699 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
700 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
701 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
702 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
703 0xe9, 0xb7, 0x37, 0x3b },
705 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
706 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
707 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
708 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
709 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
710 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
711 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
712 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
713 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
714 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
715 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
716 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
717 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
718 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
719 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
720 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
721 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
722 0xbc, 0xc9, 0xf6, 0x62 },
723 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
724 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
725 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
726 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
727 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
728 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
729 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
730 0xf4, 0x7c, 0x9b, 0x1f },
731 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
732 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
733 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
734 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
735 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
736 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
737 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
738 0x44, 0xae, 0x7e, 0x3f },
741 static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
743 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
744 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
745 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
746 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
747 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
748 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
749 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
750 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
751 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
752 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
753 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
754 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
755 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
756 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
757 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
758 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
759 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
760 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
761 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
762 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
763 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
764 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
765 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
766 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
767 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
768 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
769 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
770 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
771 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
772 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
773 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
774 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
775 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
776 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
777 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
778 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
781 int mbedtls_gcm_self_test( int verbose )
783 mbedtls_gcm_context ctx;
784 unsigned char buf[64];
785 unsigned char tag_buf[16];
787 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
789 for( j = 0; j < 3; j++ )
791 int key_len = 128 + 64 * j;
793 for( i = 0; i < MAX_TESTS; i++ )
795 mbedtls_gcm_init( &ctx );
798 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
801 ret = mbedtls_gcm_setkey( &ctx, cipher,
802 key_test_data[key_index_test_data[i]],
805 * AES-192 is an optional feature that may be unavailable when
806 * there is an alternative underlying implementation i.e. when
807 * MBEDTLS_AES_ALT is defined.
809 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
811 mbedtls_printf( "skipped\n" );
819 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
821 iv_test_data[iv_index_test_data[i]],
823 additional_test_data[add_index_test_data[i]],
824 add_len_test_data[i],
825 pt_test_data[pt_index_test_data[i]],
830 if ( memcmp( buf, ct_test_data[j * 6 + i],
831 pt_len_test_data[i] ) != 0 ||
832 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
838 mbedtls_gcm_free( &ctx );
841 mbedtls_printf( "passed\n" );
843 mbedtls_gcm_init( &ctx );
846 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
849 ret = mbedtls_gcm_setkey( &ctx, cipher,
850 key_test_data[key_index_test_data[i]],
855 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
857 iv_test_data[iv_index_test_data[i]],
859 additional_test_data[add_index_test_data[i]],
860 add_len_test_data[i],
861 ct_test_data[j * 6 + i], buf, 16, tag_buf );
866 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
867 pt_len_test_data[i] ) != 0 ||
868 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
874 mbedtls_gcm_free( &ctx );
877 mbedtls_printf( "passed\n" );
879 mbedtls_gcm_init( &ctx );
882 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
885 ret = mbedtls_gcm_setkey( &ctx, cipher,
886 key_test_data[key_index_test_data[i]],
891 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
892 iv_test_data[iv_index_test_data[i]],
894 additional_test_data[add_index_test_data[i]],
895 add_len_test_data[i] );
899 if( pt_len_test_data[i] > 32 )
901 size_t rest_len = pt_len_test_data[i] - 32;
902 ret = mbedtls_gcm_update( &ctx, 32,
903 pt_test_data[pt_index_test_data[i]],
908 ret = mbedtls_gcm_update( &ctx, rest_len,
909 pt_test_data[pt_index_test_data[i]] + 32,
916 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
917 pt_test_data[pt_index_test_data[i]],
923 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
927 if( memcmp( buf, ct_test_data[j * 6 + i],
928 pt_len_test_data[i] ) != 0 ||
929 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
935 mbedtls_gcm_free( &ctx );
938 mbedtls_printf( "passed\n" );
940 mbedtls_gcm_init( &ctx );
943 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
946 ret = mbedtls_gcm_setkey( &ctx, cipher,
947 key_test_data[key_index_test_data[i]],
952 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
953 iv_test_data[iv_index_test_data[i]],
955 additional_test_data[add_index_test_data[i]],
956 add_len_test_data[i] );
960 if( pt_len_test_data[i] > 32 )
962 size_t rest_len = pt_len_test_data[i] - 32;
963 ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
968 ret = mbedtls_gcm_update( &ctx, rest_len,
969 ct_test_data[j * 6 + i] + 32,
976 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
977 ct_test_data[j * 6 + i],
983 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
987 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
988 pt_len_test_data[i] ) != 0 ||
989 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
995 mbedtls_gcm_free( &ctx );
998 mbedtls_printf( "passed\n" );
1003 mbedtls_printf( "\n" );
1011 mbedtls_printf( "failed\n" );
1012 mbedtls_gcm_free( &ctx );
1018 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
1020 #endif /* MBEDTLS_GCM_C */