fuck! don't perform ssl handshake for blocked hosts!
[mediator.git] / src / libpolarssl / gcm.c
blobb537b02053da68d4b99021462a7d6ca3cbb18cf3
1 /*
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
26 * See also:
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"
35 #else
36 #include POLARSSL_CONFIG_FILE
37 #endif
39 #if defined(POLARSSL_GCM_C)
41 #include "polarssl/gcm.h"
43 #include <string.h>
45 #if defined(POLARSSL_AESNI_C)
46 #include "polarssl/aesni.h"
47 #endif
49 #if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
50 #if defined(POLARSSL_PLATFORM_C)
51 #include "polarssl/platform.h"
52 #else
53 #include <stdio.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)
61 #ifndef GET_UINT32_BE
62 #define GET_UINT32_BE(n,b,i) \
63 { \
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] ); \
69 #endif
71 #ifndef PUT_UINT32_BE
72 #define PUT_UINT32_BE(n,b,i) \
73 { \
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) ); \
79 #endif
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 )
96 int ret, i, j;
97 uint64_t hi, lo;
98 uint64_t vl, vh;
99 unsigned char h[16];
100 size_t olen = 0;
102 memset( h, 0, 16 );
103 if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
104 return( ret );
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) */
116 ctx->HL[8] = vl;
117 ctx->HH[8] = vh;
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 ) )
122 return( 0 );
123 #endif
125 /* 0 corresponds to 0 in GF(2^128) */
126 ctx->HH[0] = 0;
127 ctx->HL[0] = 0;
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);
135 ctx->HL[i] = vl;
136 ctx->HH[i] = vh;
139 for( i = 2; i <= 8; i *= 2 )
141 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
142 vh = *HiH;
143 vl = *HiL;
144 for( j = 1; j < i; j++ )
146 HiH[j] = vh ^ ctx->HH[j];
147 HiL[j] = vl ^ ctx->HL[j];
151 return( 0 );
154 int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
155 unsigned int keysize )
157 int ret;
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 )
174 return( ret );
176 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
177 POLARSSL_ENCRYPT ) ) != 0 )
179 return( ret );
182 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
183 return( ret );
185 return( 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] )
208 int i = 0;
209 unsigned char lo, hi, rem;
210 uint64_t zh, zl;
212 #if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
213 if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) {
214 unsigned char h[16];
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 );
222 return;
224 #endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
226 lo = x[15] & 0xf;
228 zh = ctx->HH[lo];
229 zl = ctx->HL[lo];
231 for( i = 15; i >= 0; i-- )
233 lo = x[i] & 0xf;
234 hi = x[i] >> 4;
236 if( i != 15 )
238 rem = (unsigned char) zl & 0xf;
239 zl = ( zh << 60 ) | ( zl >> 4 );
240 zh = ( zh >> 4 );
241 zh ^= (uint64_t) last4[rem] << 48;
242 zh ^= ctx->HH[lo];
243 zl ^= ctx->HL[lo];
247 rem = (unsigned char) zl & 0xf;
248 zl = ( zh << 60 ) | ( zl >> 4 );
249 zh = ( zh >> 4 );
250 zh ^= (uint64_t) last4[rem] << 48;
251 zh ^= ctx->HH[hi];
252 zl ^= ctx->HL[hi];
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,
262 int mode,
263 const unsigned char *iv,
264 size_t iv_len,
265 const unsigned char *add,
266 size_t add_len )
268 int ret;
269 unsigned char work_buf[16];
270 size_t i;
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) );
284 ctx->mode = mode;
285 ctx->len = 0;
286 ctx->add_len = 0;
288 if( iv_len == 12 )
290 memcpy( ctx->y, iv, iv_len );
291 ctx->y[15] = 1;
293 else
295 memset( work_buf, 0x00, 16 );
296 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
298 p = iv;
299 while( iv_len > 0 )
301 use_len = ( iv_len < 16 ) ? iv_len : 16;
303 for( i = 0; i < use_len; i++ )
304 ctx->y[i] ^= p[i];
306 gcm_mult( ctx, ctx->y, ctx->y );
308 iv_len -= use_len;
309 p += use_len;
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,
319 &olen ) ) != 0 )
321 return( ret );
324 ctx->add_len = add_len;
325 p = add;
326 while( add_len > 0 )
328 use_len = ( add_len < 16 ) ? add_len : 16;
330 for( i = 0; i < use_len; i++ )
331 ctx->buf[i] ^= p[i];
333 gcm_mult( ctx, ctx->buf, ctx->buf );
335 add_len -= use_len;
336 p += use_len;
339 return( 0 );
342 int gcm_update( gcm_context *ctx,
343 size_t length,
344 const unsigned char *input,
345 unsigned char *output )
347 int ret;
348 unsigned char ectr[16];
349 size_t i;
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 );
365 ctx->len += length;
367 p = input;
368 while( length > 0 )
370 use_len = ( length < 16 ) ? length : 16;
372 for( i = 16; i > 12; i-- )
373 if( ++ctx->y[i - 1] != 0 )
374 break;
376 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
377 &olen ) ) != 0 )
379 return( ret );
382 for( i = 0; i < use_len; i++ )
384 if( ctx->mode == GCM_DECRYPT )
385 ctx->buf[i] ^= p[i];
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 );
393 length -= use_len;
394 p += use_len;
395 out_p += use_len;
398 return( 0 );
401 int gcm_finish( gcm_context *ctx,
402 unsigned char *tag,
403 size_t tag_len )
405 unsigned char work_buf[16];
406 size_t i;
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 );
413 if( tag_len != 0 )
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];
434 return( 0 );
437 int gcm_crypt_and_tag( gcm_context *ctx,
438 int mode,
439 size_t length,
440 const unsigned char *iv,
441 size_t iv_len,
442 const unsigned char *add,
443 size_t add_len,
444 const unsigned char *input,
445 unsigned char *output,
446 size_t tag_len,
447 unsigned char *tag )
449 int ret;
451 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
452 return( ret );
454 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
455 return( ret );
457 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
458 return( ret );
460 return( 0 );
463 int gcm_auth_decrypt( gcm_context *ctx,
464 size_t length,
465 const unsigned char *iv,
466 size_t iv_len,
467 const unsigned char *add,
468 size_t add_len,
469 const unsigned char *tag,
470 size_t tag_len,
471 const unsigned char *input,
472 unsigned char *output )
474 int ret;
475 unsigned char check_tag[16];
476 size_t i;
477 int diff;
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 )
483 return( ret );
486 /* Check tag in "constant-time" */
487 for( diff = 0, i = 0; i < tag_len; i++ )
488 diff |= tag[i] ^ check_tag[i];
490 if( diff != 0 )
492 polarssl_zeroize( output, length );
493 return( POLARSSL_ERR_GCM_AUTH_FAILED );
496 return( 0 );
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
511 #define MAX_TESTS 6
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] =
558 { 0x00 },
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] =
586 { 0x00 },
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 },
621 { 0x00 },
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 },
656 { 0x00 },
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 )
735 gcm_context ctx;
736 unsigned char buf[64];
737 unsigned char tag_buf[16];
738 int i, j, ret;
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++ )
747 if( verbose != 0 )
748 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
749 key_len, i, "enc" );
751 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
753 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
754 pt_len[i],
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 );
759 if( ret != 0 ||
760 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
761 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
763 if( verbose != 0 )
764 polarssl_printf( "failed\n" );
766 return( 1 );
769 gcm_free( &ctx );
771 if( verbose != 0 )
772 polarssl_printf( "passed\n" );
774 if( verbose != 0 )
775 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
776 key_len, i, "dec" );
778 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
780 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
781 pt_len[i],
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 );
786 if( ret != 0 ||
787 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
788 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
790 if( verbose != 0 )
791 polarssl_printf( "failed\n" );
793 return( 1 );
796 gcm_free( &ctx );
798 if( verbose != 0 )
799 polarssl_printf( "passed\n" );
801 if( verbose != 0 )
802 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
803 key_len, i, "enc" );
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] );
810 if( ret != 0 )
812 if( verbose != 0 )
813 polarssl_printf( "failed\n" );
815 return( 1 );
818 if( pt_len[i] > 32 )
820 size_t rest_len = pt_len[i] - 32;
821 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
822 if( ret != 0 )
824 if( verbose != 0 )
825 polarssl_printf( "failed\n" );
827 return( 1 );
830 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
831 buf + 32 );
832 if( ret != 0 )
834 if( verbose != 0 )
835 polarssl_printf( "failed\n" );
837 return( 1 );
840 else
842 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
843 if( ret != 0 )
845 if( verbose != 0 )
846 polarssl_printf( "failed\n" );
848 return( 1 );
852 ret = gcm_finish( &ctx, tag_buf, 16 );
853 if( ret != 0 ||
854 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
855 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
857 if( verbose != 0 )
858 polarssl_printf( "failed\n" );
860 return( 1 );
863 gcm_free( &ctx );
865 if( verbose != 0 )
866 polarssl_printf( "passed\n" );
868 if( verbose != 0 )
869 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
870 key_len, i, "dec" );
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] );
877 if( ret != 0 )
879 if( verbose != 0 )
880 polarssl_printf( "failed\n" );
882 return( 1 );
885 if( pt_len[i] > 32 )
887 size_t rest_len = pt_len[i] - 32;
888 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
889 if( ret != 0 )
891 if( verbose != 0 )
892 polarssl_printf( "failed\n" );
894 return( 1 );
897 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
898 buf + 32 );
899 if( ret != 0 )
901 if( verbose != 0 )
902 polarssl_printf( "failed\n" );
904 return( 1 );
907 else
909 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
910 if( ret != 0 )
912 if( verbose != 0 )
913 polarssl_printf( "failed\n" );
915 return( 1 );
919 ret = gcm_finish( &ctx, tag_buf, 16 );
920 if( ret != 0 ||
921 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
922 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
924 if( verbose != 0 )
925 polarssl_printf( "failed\n" );
927 return( 1 );
930 gcm_free( &ctx );
932 if( verbose != 0 )
933 polarssl_printf( "passed\n" );
938 if( verbose != 0 )
939 polarssl_printf( "\n" );
941 return( 0 );
944 #endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
946 #endif /* POLARSSL_GCM_C */