2 * NIST SP800-38D compliant GCM implementation
4 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
6 * This file is part of mbed TLS (https://tls.mbed.org)
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
27 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
29 * We use the algorithm described as Shoup's method with 4-bit tables in
30 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
33 #if !defined(POLARSSL_CONFIG_FILE)
34 #include "polarssl/config.h"
36 #include POLARSSL_CONFIG_FILE
39 #if defined(POLARSSL_GCM_C)
41 #include "polarssl/gcm.h"
45 #if defined(POLARSSL_AESNI_C)
46 #include "polarssl/aesni.h"
49 #if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
50 #if defined(POLARSSL_PLATFORM_C)
51 #include "polarssl/platform.h"
54 #define polarssl_printf printf
55 #endif /* POLARSSL_PLATFORM_C */
56 #endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
59 * 32-bit integer manipulation macros (big endian)
62 #define GET_UINT32_BE(n,b,i) \
64 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
65 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
66 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
67 | ( (uint32_t) (b)[(i) + 3] ); \
72 #define PUT_UINT32_BE(n,b,i) \
74 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
75 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
76 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
77 (b)[(i) + 3] = (unsigned char) ( (n) ); \
81 /* Implementation that should never be optimized out by the compiler */
82 static void polarssl_zeroize( void *v
, size_t n
) {
83 volatile unsigned char *p
= v
; while( n
-- ) *p
++ = 0;
87 * Precompute small multiples of H, that is set
88 * HH[i] || HL[i] = H times i,
89 * where i is seen as a field element as in [MGV], ie high-order bits
90 * correspond to low powers of P. The result is stored in the same way, that
91 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
92 * corresponds to P^127.
94 static int gcm_gen_table( gcm_context
*ctx
)
103 if( ( ret
= cipher_update( &ctx
->cipher_ctx
, h
, 16, h
, &olen
) ) != 0 )
106 /* pack h as two 64-bits ints, big-endian */
107 GET_UINT32_BE( hi
, h
, 0 );
108 GET_UINT32_BE( lo
, h
, 4 );
109 vh
= (uint64_t) hi
<< 32 | lo
;
111 GET_UINT32_BE( hi
, h
, 8 );
112 GET_UINT32_BE( lo
, h
, 12 );
113 vl
= (uint64_t) hi
<< 32 | lo
;
115 /* 8 = 1000 corresponds to 1 in GF(2^128) */
119 #if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
120 /* With CLMUL support, we need only h, not the rest of the table */
121 if( aesni_supports( POLARSSL_AESNI_CLMUL
) )
125 /* 0 corresponds to 0 in GF(2^128) */
129 for( i
= 4; i
> 0; i
>>= 1 )
131 uint32_t T
= ( vl
& 1 ) * 0xe1000000U
;
132 vl
= ( vh
<< 63 ) | ( vl
>> 1 );
133 vh
= ( vh
>> 1 ) ^ ( (uint64_t) T
<< 32);
139 for( i
= 2; i
<= 8; i
*= 2 )
141 uint64_t *HiL
= ctx
->HL
+ i
, *HiH
= ctx
->HH
+ i
;
144 for( j
= 1; j
< i
; j
++ )
146 HiH
[j
] = vh
^ ctx
->HH
[j
];
147 HiL
[j
] = vl
^ ctx
->HL
[j
];
154 int gcm_init( gcm_context
*ctx
, cipher_id_t cipher
, const unsigned char *key
,
155 unsigned int keysize
)
158 const cipher_info_t
*cipher_info
;
160 memset( ctx
, 0, sizeof(gcm_context
) );
162 cipher_init( &ctx
->cipher_ctx
);
164 cipher_info
= cipher_info_from_values( cipher
, keysize
, POLARSSL_MODE_ECB
);
165 if( cipher_info
== NULL
)
166 return( POLARSSL_ERR_GCM_BAD_INPUT
);
168 if( cipher_info
->block_size
!= 16 )
169 return( POLARSSL_ERR_GCM_BAD_INPUT
);
171 cipher_free( &ctx
->cipher_ctx
);
173 if( ( ret
= cipher_init_ctx( &ctx
->cipher_ctx
, cipher_info
) ) != 0 )
176 if( ( ret
= cipher_setkey( &ctx
->cipher_ctx
, key
, keysize
,
177 POLARSSL_ENCRYPT
) ) != 0 )
182 if( ( ret
= gcm_gen_table( ctx
) ) != 0 )
189 * Shoup's method for multiplication use this table with
190 * last4[x] = x times P^128
191 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
193 static const uint64_t last4
[16] =
195 0x0000, 0x1c20, 0x3840, 0x2460,
196 0x7080, 0x6ca0, 0x48c0, 0x54e0,
197 0xe100, 0xfd20, 0xd940, 0xc560,
198 0x9180, 0x8da0, 0xa9c0, 0xb5e0
202 * Sets output to x times H using the precomputed tables.
203 * x and output are seen as elements of GF(2^128) as in [MGV].
205 static void gcm_mult( gcm_context
*ctx
, const unsigned char x
[16],
206 unsigned char output
[16] )
209 unsigned char lo
, hi
, rem
;
212 #if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
213 if( aesni_supports( POLARSSL_AESNI_CLMUL
) ) {
216 PUT_UINT32_BE( ctx
->HH
[8] >> 32, h
, 0 );
217 PUT_UINT32_BE( ctx
->HH
[8], h
, 4 );
218 PUT_UINT32_BE( ctx
->HL
[8] >> 32, h
, 8 );
219 PUT_UINT32_BE( ctx
->HL
[8], h
, 12 );
221 aesni_gcm_mult( output
, x
, h
);
224 #endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
231 for( i
= 15; i
>= 0; i
-- )
238 rem
= (unsigned char) zl
& 0xf;
239 zl
= ( zh
<< 60 ) | ( zl
>> 4 );
241 zh
^= (uint64_t) last4
[rem
] << 48;
247 rem
= (unsigned char) zl
& 0xf;
248 zl
= ( zh
<< 60 ) | ( zl
>> 4 );
250 zh
^= (uint64_t) last4
[rem
] << 48;
255 PUT_UINT32_BE( zh
>> 32, output
, 0 );
256 PUT_UINT32_BE( zh
, output
, 4 );
257 PUT_UINT32_BE( zl
>> 32, output
, 8 );
258 PUT_UINT32_BE( zl
, output
, 12 );
261 int gcm_starts( gcm_context
*ctx
,
263 const unsigned char *iv
,
265 const unsigned char *add
,
269 unsigned char work_buf
[16];
271 const unsigned char *p
;
272 size_t use_len
, olen
= 0;
274 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
275 if( ( (uint64_t) iv_len
) >> 61 != 0 ||
276 ( (uint64_t) add_len
) >> 61 != 0 )
278 return( POLARSSL_ERR_GCM_BAD_INPUT
);
281 memset( ctx
->y
, 0x00, sizeof(ctx
->y
) );
282 memset( ctx
->buf
, 0x00, sizeof(ctx
->buf
) );
290 memcpy( ctx
->y
, iv
, iv_len
);
295 memset( work_buf
, 0x00, 16 );
296 PUT_UINT32_BE( iv_len
* 8, work_buf
, 12 );
301 use_len
= ( iv_len
< 16 ) ? iv_len
: 16;
303 for( i
= 0; i
< use_len
; i
++ )
306 gcm_mult( ctx
, ctx
->y
, ctx
->y
);
312 for( i
= 0; i
< 16; i
++ )
313 ctx
->y
[i
] ^= work_buf
[i
];
315 gcm_mult( ctx
, ctx
->y
, ctx
->y
);
318 if( ( ret
= cipher_update( &ctx
->cipher_ctx
, ctx
->y
, 16, ctx
->base_ectr
,
324 ctx
->add_len
= add_len
;
328 use_len
= ( add_len
< 16 ) ? add_len
: 16;
330 for( i
= 0; i
< use_len
; i
++ )
333 gcm_mult( ctx
, ctx
->buf
, ctx
->buf
);
342 int gcm_update( gcm_context
*ctx
,
344 const unsigned char *input
,
345 unsigned char *output
)
348 unsigned char ectr
[16];
350 const unsigned char *p
;
351 unsigned char *out_p
= output
;
352 size_t use_len
, olen
= 0;
354 if( output
> input
&& (size_t) ( output
- input
) < length
)
355 return( POLARSSL_ERR_GCM_BAD_INPUT
);
357 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
358 * Also check for possible overflow */
359 if( ctx
->len
+ length
< ctx
->len
||
360 (uint64_t) ctx
->len
+ length
> 0x03FFFFE0ull
)
362 return( POLARSSL_ERR_GCM_BAD_INPUT
);
370 use_len
= ( length
< 16 ) ? length
: 16;
372 for( i
= 16; i
> 12; i
-- )
373 if( ++ctx
->y
[i
- 1] != 0 )
376 if( ( ret
= cipher_update( &ctx
->cipher_ctx
, ctx
->y
, 16, ectr
,
382 for( i
= 0; i
< use_len
; i
++ )
384 if( ctx
->mode
== GCM_DECRYPT
)
386 out_p
[i
] = ectr
[i
] ^ p
[i
];
387 if( ctx
->mode
== GCM_ENCRYPT
)
388 ctx
->buf
[i
] ^= out_p
[i
];
391 gcm_mult( ctx
, ctx
->buf
, ctx
->buf
);
401 int gcm_finish( gcm_context
*ctx
,
405 unsigned char work_buf
[16];
407 uint64_t orig_len
= ctx
->len
* 8;
408 uint64_t orig_add_len
= ctx
->add_len
* 8;
410 if( tag_len
> 16 || tag_len
< 4 )
411 return( POLARSSL_ERR_GCM_BAD_INPUT
);
414 memcpy( tag
, ctx
->base_ectr
, tag_len
);
416 if( orig_len
|| orig_add_len
)
418 memset( work_buf
, 0x00, 16 );
420 PUT_UINT32_BE( ( orig_add_len
>> 32 ), work_buf
, 0 );
421 PUT_UINT32_BE( ( orig_add_len
), work_buf
, 4 );
422 PUT_UINT32_BE( ( orig_len
>> 32 ), work_buf
, 8 );
423 PUT_UINT32_BE( ( orig_len
), work_buf
, 12 );
425 for( i
= 0; i
< 16; i
++ )
426 ctx
->buf
[i
] ^= work_buf
[i
];
428 gcm_mult( ctx
, ctx
->buf
, ctx
->buf
);
430 for( i
= 0; i
< tag_len
; i
++ )
431 tag
[i
] ^= ctx
->buf
[i
];
437 int gcm_crypt_and_tag( gcm_context
*ctx
,
440 const unsigned char *iv
,
442 const unsigned char *add
,
444 const unsigned char *input
,
445 unsigned char *output
,
451 if( ( ret
= gcm_starts( ctx
, mode
, iv
, iv_len
, add
, add_len
) ) != 0 )
454 if( ( ret
= gcm_update( ctx
, length
, input
, output
) ) != 0 )
457 if( ( ret
= gcm_finish( ctx
, tag
, tag_len
) ) != 0 )
463 int gcm_auth_decrypt( gcm_context
*ctx
,
465 const unsigned char *iv
,
467 const unsigned char *add
,
469 const unsigned char *tag
,
471 const unsigned char *input
,
472 unsigned char *output
)
475 unsigned char check_tag
[16];
479 if( ( ret
= gcm_crypt_and_tag( ctx
, GCM_DECRYPT
, length
,
480 iv
, iv_len
, add
, add_len
,
481 input
, output
, tag_len
, check_tag
) ) != 0 )
486 /* Check tag in "constant-time" */
487 for( diff
= 0, i
= 0; i
< tag_len
; i
++ )
488 diff
|= tag
[i
] ^ check_tag
[i
];
492 polarssl_zeroize( output
, length
);
493 return( POLARSSL_ERR_GCM_AUTH_FAILED
);
499 void gcm_free( gcm_context
*ctx
)
501 cipher_free( &ctx
->cipher_ctx
);
502 polarssl_zeroize( ctx
, sizeof( gcm_context
) );
505 #if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
507 * AES-GCM test vectors from:
509 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
513 static const int key_index
[MAX_TESTS
] =
514 { 0, 0, 1, 1, 1, 1 };
516 static const unsigned char key
[MAX_TESTS
][32] =
518 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
522 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
523 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
524 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
525 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
528 static const size_t iv_len
[MAX_TESTS
] =
529 { 12, 12, 12, 12, 8, 60 };
531 static const int iv_index
[MAX_TESTS
] =
532 { 0, 0, 1, 1, 1, 2 };
534 static const unsigned char iv
[MAX_TESTS
][64] =
536 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537 0x00, 0x00, 0x00, 0x00 },
538 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
539 0xde, 0xca, 0xf8, 0x88 },
540 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
541 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
542 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
543 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
544 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
545 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
546 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
547 0xa6, 0x37, 0xb3, 0x9b },
550 static const size_t add_len
[MAX_TESTS
] =
551 { 0, 0, 0, 20, 20, 20 };
553 static const int add_index
[MAX_TESTS
] =
554 { 0, 0, 0, 1, 1, 1 };
556 static const unsigned char additional
[MAX_TESTS
][64] =
559 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
560 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
561 0xab, 0xad, 0xda, 0xd2 },
564 static const size_t pt_len
[MAX_TESTS
] =
565 { 0, 16, 64, 60, 60, 60 };
567 static const int pt_index
[MAX_TESTS
] =
568 { 0, 0, 1, 1, 1, 1 };
570 static const unsigned char pt
[MAX_TESTS
][64] =
572 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
574 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
575 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
576 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
577 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
578 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
579 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
580 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
581 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
584 static const unsigned char ct
[MAX_TESTS
* 3][64] =
587 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
588 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
589 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
590 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
591 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
592 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
593 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
594 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
595 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
596 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
597 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
598 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
599 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
600 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
601 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
602 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
603 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
604 0x3d, 0x58, 0xe0, 0x91 },
605 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
606 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
607 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
608 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
609 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
610 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
611 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
612 0xc2, 0x3f, 0x45, 0x98 },
613 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
614 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
615 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
616 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
617 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
618 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
619 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
620 0x4c, 0x34, 0xae, 0xe5 },
622 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
623 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
624 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
625 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
626 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
627 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
628 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
629 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
630 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
631 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
632 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
633 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
634 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
635 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
636 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
637 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
638 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
639 0xcc, 0xda, 0x27, 0x10 },
640 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
641 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
642 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
643 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
644 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
645 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
646 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
647 0xa0, 0xf0, 0x62, 0xf7 },
648 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
649 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
650 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
651 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
652 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
653 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
654 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
655 0xe9, 0xb7, 0x37, 0x3b },
657 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
658 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
659 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
660 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
661 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
662 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
663 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
664 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
665 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
666 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
667 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
668 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
669 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
670 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
671 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
672 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
673 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
674 0xbc, 0xc9, 0xf6, 0x62 },
675 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
676 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
677 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
678 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
679 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
680 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
681 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
682 0xf4, 0x7c, 0x9b, 0x1f },
683 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
684 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
685 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
686 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
687 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
688 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
689 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
690 0x44, 0xae, 0x7e, 0x3f },
693 static const unsigned char tag
[MAX_TESTS
* 3][16] =
695 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
696 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
697 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
698 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
699 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
700 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
701 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
702 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
703 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
704 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
705 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
706 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
707 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
708 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
709 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
710 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
711 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
712 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
713 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
714 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
715 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
716 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
717 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
718 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
719 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
720 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
721 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
722 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
723 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
724 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
725 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
726 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
727 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
728 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
729 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
730 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
733 int gcm_self_test( int verbose
)
736 unsigned char buf
[64];
737 unsigned char tag_buf
[16];
739 cipher_id_t cipher
= POLARSSL_CIPHER_ID_AES
;
741 for( j
= 0; j
< 3; j
++ )
743 int key_len
= 128 + 64 * j
;
745 for( i
= 0; i
< MAX_TESTS
; i
++ )
748 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
751 gcm_init( &ctx
, cipher
, key
[key_index
[i
]], key_len
);
753 ret
= gcm_crypt_and_tag( &ctx
, GCM_ENCRYPT
,
755 iv
[iv_index
[i
]], iv_len
[i
],
756 additional
[add_index
[i
]], add_len
[i
],
757 pt
[pt_index
[i
]], buf
, 16, tag_buf
);
760 memcmp( buf
, ct
[j
* 6 + i
], pt_len
[i
] ) != 0 ||
761 memcmp( tag_buf
, tag
[j
* 6 + i
], 16 ) != 0 )
764 polarssl_printf( "failed\n" );
772 polarssl_printf( "passed\n" );
775 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
778 gcm_init( &ctx
, cipher
, key
[key_index
[i
]], key_len
);
780 ret
= gcm_crypt_and_tag( &ctx
, GCM_DECRYPT
,
782 iv
[iv_index
[i
]], iv_len
[i
],
783 additional
[add_index
[i
]], add_len
[i
],
784 ct
[j
* 6 + i
], buf
, 16, tag_buf
);
787 memcmp( buf
, pt
[pt_index
[i
]], pt_len
[i
] ) != 0 ||
788 memcmp( tag_buf
, tag
[j
* 6 + i
], 16 ) != 0 )
791 polarssl_printf( "failed\n" );
799 polarssl_printf( "passed\n" );
802 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
805 gcm_init( &ctx
, cipher
, key
[key_index
[i
]], key_len
);
807 ret
= gcm_starts( &ctx
, GCM_ENCRYPT
,
808 iv
[iv_index
[i
]], iv_len
[i
],
809 additional
[add_index
[i
]], add_len
[i
] );
813 polarssl_printf( "failed\n" );
820 size_t rest_len
= pt_len
[i
] - 32;
821 ret
= gcm_update( &ctx
, 32, pt
[pt_index
[i
]], buf
);
825 polarssl_printf( "failed\n" );
830 ret
= gcm_update( &ctx
, rest_len
, pt
[pt_index
[i
]] + 32,
835 polarssl_printf( "failed\n" );
842 ret
= gcm_update( &ctx
, pt_len
[i
], pt
[pt_index
[i
]], buf
);
846 polarssl_printf( "failed\n" );
852 ret
= gcm_finish( &ctx
, tag_buf
, 16 );
854 memcmp( buf
, ct
[j
* 6 + i
], pt_len
[i
] ) != 0 ||
855 memcmp( tag_buf
, tag
[j
* 6 + i
], 16 ) != 0 )
858 polarssl_printf( "failed\n" );
866 polarssl_printf( "passed\n" );
869 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
872 gcm_init( &ctx
, cipher
, key
[key_index
[i
]], key_len
);
874 ret
= gcm_starts( &ctx
, GCM_DECRYPT
,
875 iv
[iv_index
[i
]], iv_len
[i
],
876 additional
[add_index
[i
]], add_len
[i
] );
880 polarssl_printf( "failed\n" );
887 size_t rest_len
= pt_len
[i
] - 32;
888 ret
= gcm_update( &ctx
, 32, ct
[j
* 6 + i
], buf
);
892 polarssl_printf( "failed\n" );
897 ret
= gcm_update( &ctx
, rest_len
, ct
[j
* 6 + i
] + 32,
902 polarssl_printf( "failed\n" );
909 ret
= gcm_update( &ctx
, pt_len
[i
], ct
[j
* 6 + i
], buf
);
913 polarssl_printf( "failed\n" );
919 ret
= gcm_finish( &ctx
, tag_buf
, 16 );
921 memcmp( buf
, pt
[pt_index
[i
]], pt_len
[i
] ) != 0 ||
922 memcmp( tag_buf
, tag
[j
* 6 + i
], 16 ) != 0 )
925 polarssl_printf( "failed\n" );
933 polarssl_printf( "passed\n" );
939 polarssl_printf( "\n" );
944 #endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
946 #endif /* POLARSSL_GCM_C */