PolarSSL v1.3.9
gcm.c
Go to the documentation of this file.
1 /*
2  * NIST SP800-38D compliant GCM implementation
3  *
4  * Copyright (C) 2006-2014, Brainspark B.V.
5  *
6  * This file is part of PolarSSL (http://www.polarssl.org)
7  * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8  *
9  * All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
26 /*
27  * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
28  *
29  * See also:
30  * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
31  *
32  * We use the algorithm described as Shoup's method with 4-bit tables in
33  * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
34  */
35 
36 #if !defined(POLARSSL_CONFIG_FILE)
37 #include "polarssl/config.h"
38 #else
39 #include POLARSSL_CONFIG_FILE
40 #endif
41 
42 #if defined(POLARSSL_GCM_C)
43 
44 #include "polarssl/gcm.h"
45 
46 #if defined(POLARSSL_AESNI_C)
47 #include "polarssl/aesni.h"
48 #endif
49 
50 #if defined(POLARSSL_PLATFORM_C)
51 #include "polarssl/platform.h"
52 #else
53 #define polarssl_printf printf
54 #endif
55 
56 /*
57  * 32-bit integer manipulation macros (big endian)
58  */
59 #ifndef GET_UINT32_BE
60 #define GET_UINT32_BE(n,b,i) \
61 { \
62  (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
63  | ( (uint32_t) (b)[(i) + 1] << 16 ) \
64  | ( (uint32_t) (b)[(i) + 2] << 8 ) \
65  | ( (uint32_t) (b)[(i) + 3] ); \
66 }
67 #endif
68 
69 #ifndef PUT_UINT32_BE
70 #define PUT_UINT32_BE(n,b,i) \
71 { \
72  (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
73  (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
74  (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
75  (b)[(i) + 3] = (unsigned char) ( (n) ); \
76 }
77 #endif
78 
79 /* Implementation that should never be optimized out by the compiler */
80 static void polarssl_zeroize( void *v, size_t n ) {
81  volatile unsigned char *p = v; while( n-- ) *p++ = 0;
82 }
83 
84 /*
85  * Precompute small multiples of H, that is set
86  * HH[i] || HL[i] = H times i,
87  * where i is seen as a field element as in [MGV], ie high-order bits
88  * correspond to low powers of P. The result is stored in the same way, that
89  * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
90  * corresponds to P^127.
91  */
92 static int gcm_gen_table( gcm_context *ctx )
93 {
94  int ret, i, j;
95  uint64_t hi, lo;
96  uint64_t vl, vh;
97  unsigned char h[16];
98  size_t olen = 0;
99 
100  memset( h, 0, 16 );
101  if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
102  return( ret );
103 
104  /* pack h as two 64-bits ints, big-endian */
105  GET_UINT32_BE( hi, h, 0 );
106  GET_UINT32_BE( lo, h, 4 );
107  vh = (uint64_t) hi << 32 | lo;
108 
109  GET_UINT32_BE( hi, h, 8 );
110  GET_UINT32_BE( lo, h, 12 );
111  vl = (uint64_t) hi << 32 | lo;
112 
113  /* 8 = 1000 corresponds to 1 in GF(2^128) */
114  ctx->HL[8] = vl;
115  ctx->HH[8] = vh;
116 
117 #if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
118  /* With CLMUL support, we need only h, not the rest of the table */
119  if( aesni_supports( POLARSSL_AESNI_CLMUL ) )
120  return( 0 );
121 #endif
122 
123  /* 0 corresponds to 0 in GF(2^128) */
124  ctx->HH[0] = 0;
125  ctx->HL[0] = 0;
126 
127  for( i = 4; i > 0; i >>= 1 )
128  {
129  uint32_t T = ( vl & 1 ) * 0xe1000000U;
130  vl = ( vh << 63 ) | ( vl >> 1 );
131  vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
132 
133  ctx->HL[i] = vl;
134  ctx->HH[i] = vh;
135  }
136 
137  for( i = 2; i < 16; i <<= 1 )
138  {
139  uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
140  vh = *HiH;
141  vl = *HiL;
142  for( j = 1; j < i; j++ )
143  {
144  HiH[j] = vh ^ ctx->HH[j];
145  HiL[j] = vl ^ ctx->HL[j];
146  }
147  }
148 
149  return( 0 );
150 }
151 
152 int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
153  unsigned int keysize )
154 {
155  int ret;
156  const cipher_info_t *cipher_info;
157 
158  memset( ctx, 0, sizeof(gcm_context) );
159 
160  cipher_init( &ctx->cipher_ctx );
161 
162  cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
163  if( cipher_info == NULL )
164  return( POLARSSL_ERR_GCM_BAD_INPUT );
165 
166  if( cipher_info->block_size != 16 )
167  return( POLARSSL_ERR_GCM_BAD_INPUT );
168 
169  if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
170  return( ret );
171 
172  if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
173  POLARSSL_ENCRYPT ) ) != 0 )
174  {
175  return( ret );
176  }
177 
178  if( ( ret = gcm_gen_table( ctx ) ) != 0 )
179  return( ret );
180 
181  return( 0 );
182 }
183 
184 /*
185  * Shoup's method for multiplication use this table with
186  * last4[x] = x times P^128
187  * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
188  */
189 static const uint64_t last4[16] =
190 {
191  0x0000, 0x1c20, 0x3840, 0x2460,
192  0x7080, 0x6ca0, 0x48c0, 0x54e0,
193  0xe100, 0xfd20, 0xd940, 0xc560,
194  0x9180, 0x8da0, 0xa9c0, 0xb5e0
195 };
196 
197 /*
198  * Sets output to x times H using the precomputed tables.
199  * x and output are seen as elements of GF(2^128) as in [MGV].
200  */
201 static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
202  unsigned char output[16] )
203 {
204  int i = 0;
205  unsigned char lo, hi, rem;
206  uint64_t zh, zl;
207 
208 #if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
209  if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) {
210  unsigned char h[16];
211 
212  PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
213  PUT_UINT32_BE( ctx->HH[8], h, 4 );
214  PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
215  PUT_UINT32_BE( ctx->HL[8], h, 12 );
216 
217  aesni_gcm_mult( output, x, h );
218  return;
219  }
220 #endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
221 
222  lo = x[15] & 0xf;
223 
224  zh = ctx->HH[lo];
225  zl = ctx->HL[lo];
226 
227  for( i = 15; i >= 0; i-- )
228  {
229  lo = x[i] & 0xf;
230  hi = x[i] >> 4;
231 
232  if( i != 15 )
233  {
234  rem = (unsigned char) zl & 0xf;
235  zl = ( zh << 60 ) | ( zl >> 4 );
236  zh = ( zh >> 4 );
237  zh ^= (uint64_t) last4[rem] << 48;
238  zh ^= ctx->HH[lo];
239  zl ^= ctx->HL[lo];
240 
241  }
242 
243  rem = (unsigned char) zl & 0xf;
244  zl = ( zh << 60 ) | ( zl >> 4 );
245  zh = ( zh >> 4 );
246  zh ^= (uint64_t) last4[rem] << 48;
247  zh ^= ctx->HH[hi];
248  zl ^= ctx->HL[hi];
249  }
250 
251  PUT_UINT32_BE( zh >> 32, output, 0 );
252  PUT_UINT32_BE( zh, output, 4 );
253  PUT_UINT32_BE( zl >> 32, output, 8 );
254  PUT_UINT32_BE( zl, output, 12 );
255 }
256 
257 int gcm_starts( gcm_context *ctx,
258  int mode,
259  const unsigned char *iv,
260  size_t iv_len,
261  const unsigned char *add,
262  size_t add_len )
263 {
264  int ret;
265  unsigned char work_buf[16];
266  size_t i;
267  const unsigned char *p;
268  size_t use_len, olen = 0;
269 
270  /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
271  if( ( (uint64_t) iv_len ) >> 61 != 0 ||
272  ( (uint64_t) add_len ) >> 61 != 0 )
273  {
274  return( POLARSSL_ERR_GCM_BAD_INPUT );
275  }
276 
277  memset( ctx->y, 0x00, sizeof(ctx->y) );
278  memset( ctx->buf, 0x00, sizeof(ctx->buf) );
279 
280  ctx->mode = mode;
281  ctx->len = 0;
282  ctx->add_len = 0;
283 
284  if( iv_len == 12 )
285  {
286  memcpy( ctx->y, iv, iv_len );
287  ctx->y[15] = 1;
288  }
289  else
290  {
291  memset( work_buf, 0x00, 16 );
292  PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
293 
294  p = iv;
295  while( iv_len > 0 )
296  {
297  use_len = ( iv_len < 16 ) ? iv_len : 16;
298 
299  for( i = 0; i < use_len; i++ )
300  ctx->y[i] ^= p[i];
301 
302  gcm_mult( ctx, ctx->y, ctx->y );
303 
304  iv_len -= use_len;
305  p += use_len;
306  }
307 
308  for( i = 0; i < 16; i++ )
309  ctx->y[i] ^= work_buf[i];
310 
311  gcm_mult( ctx, ctx->y, ctx->y );
312  }
313 
314  if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
315  &olen ) ) != 0 )
316  {
317  return( ret );
318  }
319 
320  ctx->add_len = add_len;
321  p = add;
322  while( add_len > 0 )
323  {
324  use_len = ( add_len < 16 ) ? add_len : 16;
325 
326  for( i = 0; i < use_len; i++ )
327  ctx->buf[i] ^= p[i];
328 
329  gcm_mult( ctx, ctx->buf, ctx->buf );
330 
331  add_len -= use_len;
332  p += use_len;
333  }
334 
335  return( 0 );
336 }
337 
338 int gcm_update( gcm_context *ctx,
339  size_t length,
340  const unsigned char *input,
341  unsigned char *output )
342 {
343  int ret;
344  unsigned char ectr[16];
345  size_t i;
346  const unsigned char *p;
347  unsigned char *out_p = output;
348  size_t use_len, olen = 0;
349 
350  if( output > input && (size_t) ( output - input ) < length )
351  return( POLARSSL_ERR_GCM_BAD_INPUT );
352 
353  /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
354  * Also check for possible overflow */
355  if( ctx->len + length < ctx->len ||
356  (uint64_t) ctx->len + length > 0x03FFFFE0ull )
357  {
358  return( POLARSSL_ERR_GCM_BAD_INPUT );
359  }
360 
361  ctx->len += length;
362 
363  p = input;
364  while( length > 0 )
365  {
366  use_len = ( length < 16 ) ? length : 16;
367 
368  for( i = 16; i > 12; i-- )
369  if( ++ctx->y[i - 1] != 0 )
370  break;
371 
372  if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
373  &olen ) ) != 0 )
374  {
375  return( ret );
376  }
377 
378  for( i = 0; i < use_len; i++ )
379  {
380  if( ctx->mode == GCM_DECRYPT )
381  ctx->buf[i] ^= p[i];
382  out_p[i] = ectr[i] ^ p[i];
383  if( ctx->mode == GCM_ENCRYPT )
384  ctx->buf[i] ^= out_p[i];
385  }
386 
387  gcm_mult( ctx, ctx->buf, ctx->buf );
388 
389  length -= use_len;
390  p += use_len;
391  out_p += use_len;
392  }
393 
394  return( 0 );
395 }
396 
397 int gcm_finish( gcm_context *ctx,
398  unsigned char *tag,
399  size_t tag_len )
400 {
401  unsigned char work_buf[16];
402  size_t i;
403  uint64_t orig_len = ctx->len * 8;
404  uint64_t orig_add_len = ctx->add_len * 8;
405 
406  if( tag_len > 16 || tag_len < 4 )
407  return( POLARSSL_ERR_GCM_BAD_INPUT );
408 
409  if( tag_len != 0 )
410  memcpy( tag, ctx->base_ectr, tag_len );
411 
412  if( orig_len || orig_add_len )
413  {
414  memset( work_buf, 0x00, 16 );
415 
416  PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
417  PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
418  PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
419  PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
420 
421  for( i = 0; i < 16; i++ )
422  ctx->buf[i] ^= work_buf[i];
423 
424  gcm_mult( ctx, ctx->buf, ctx->buf );
425 
426  for( i = 0; i < tag_len; i++ )
427  tag[i] ^= ctx->buf[i];
428  }
429 
430  return( 0 );
431 }
432 
434  int mode,
435  size_t length,
436  const unsigned char *iv,
437  size_t iv_len,
438  const unsigned char *add,
439  size_t add_len,
440  const unsigned char *input,
441  unsigned char *output,
442  size_t tag_len,
443  unsigned char *tag )
444 {
445  int ret;
446 
447  if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
448  return( ret );
449 
450  if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
451  return( ret );
452 
453  if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
454  return( ret );
455 
456  return( 0 );
457 }
458 
459 int gcm_auth_decrypt( gcm_context *ctx,
460  size_t length,
461  const unsigned char *iv,
462  size_t iv_len,
463  const unsigned char *add,
464  size_t add_len,
465  const unsigned char *tag,
466  size_t tag_len,
467  const unsigned char *input,
468  unsigned char *output )
469 {
470  int ret;
471  unsigned char check_tag[16];
472  size_t i;
473  int diff;
474 
475  if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
476  iv, iv_len, add, add_len,
477  input, output, tag_len, check_tag ) ) != 0 )
478  {
479  return( ret );
480  }
481 
482  /* Check tag in "constant-time" */
483  for( diff = 0, i = 0; i < tag_len; i++ )
484  diff |= tag[i] ^ check_tag[i];
485 
486  if( diff != 0 )
487  {
488  polarssl_zeroize( output, length );
490  }
491 
492  return( 0 );
493 }
494 
495 void gcm_free( gcm_context *ctx )
496 {
497  cipher_free( &ctx->cipher_ctx );
498  polarssl_zeroize( ctx, sizeof( gcm_context ) );
499 }
500 
501 #if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
502 
503 #include <stdio.h>
504 
505 /*
506  * AES-GCM test vectors from:
507  *
508  * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
509  */
510 #define MAX_TESTS 6
511 
512 int key_index[MAX_TESTS] =
513  { 0, 0, 1, 1, 1, 1 };
514 
515 unsigned char key[MAX_TESTS][32] =
516 {
517  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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  { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
522  0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
523  0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
524  0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
525 };
526 
527 size_t iv_len[MAX_TESTS] =
528  { 12, 12, 12, 12, 8, 60 };
529 
530 int iv_index[MAX_TESTS] =
531  { 0, 0, 1, 1, 1, 2 };
532 
533 unsigned char iv[MAX_TESTS][64] =
534 {
535  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536  0x00, 0x00, 0x00, 0x00 },
537  { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
538  0xde, 0xca, 0xf8, 0x88 },
539  { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
540  0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
541  0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
542  0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
543  0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
544  0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
545  0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
546  0xa6, 0x37, 0xb3, 0x9b },
547 };
548 
549 size_t add_len[MAX_TESTS] =
550  { 0, 0, 0, 20, 20, 20 };
551 
552 int add_index[MAX_TESTS] =
553  { 0, 0, 0, 1, 1, 1 };
554 
555 unsigned char additional[MAX_TESTS][64] =
556 {
557  { 0x00 },
558  { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
559  0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
560  0xab, 0xad, 0xda, 0xd2 },
561 };
562 
563 size_t pt_len[MAX_TESTS] =
564  { 0, 16, 64, 60, 60, 60 };
565 
566 int pt_index[MAX_TESTS] =
567  { 0, 0, 1, 1, 1, 1 };
568 
569 unsigned char pt[MAX_TESTS][64] =
570 {
571  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
573  { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
574  0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
575  0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
576  0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
577  0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
578  0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
579  0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
580  0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
581 };
582 
583 unsigned char ct[MAX_TESTS * 3][64] =
584 {
585  { 0x00 },
586  { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
587  0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
588  { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
589  0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
590  0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
591  0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
592  0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
593  0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
594  0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
595  0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
596  { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
597  0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
598  0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
599  0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
600  0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
601  0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
602  0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
603  0x3d, 0x58, 0xe0, 0x91 },
604  { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
605  0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
606  0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
607  0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
608  0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
609  0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
610  0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
611  0xc2, 0x3f, 0x45, 0x98 },
612  { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
613  0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
614  0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
615  0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
616  0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
617  0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
618  0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
619  0x4c, 0x34, 0xae, 0xe5 },
620  { 0x00 },
621  { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
622  0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
623  { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
624  0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
625  0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
626  0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
627  0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
628  0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
629  0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
630  0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
631  { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
632  0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
633  0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
634  0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
635  0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
636  0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
637  0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
638  0xcc, 0xda, 0x27, 0x10 },
639  { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
640  0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
641  0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
642  0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
643  0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
644  0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
645  0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
646  0xa0, 0xf0, 0x62, 0xf7 },
647  { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
648  0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
649  0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
650  0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
651  0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
652  0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
653  0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
654  0xe9, 0xb7, 0x37, 0x3b },
655  { 0x00 },
656  { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
657  0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
658  { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
659  0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
660  0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
661  0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
662  0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
663  0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
664  0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
665  0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
666  { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
667  0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
668  0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
669  0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
670  0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
671  0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
672  0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
673  0xbc, 0xc9, 0xf6, 0x62 },
674  { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
675  0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
676  0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
677  0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
678  0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
679  0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
680  0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
681  0xf4, 0x7c, 0x9b, 0x1f },
682  { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
683  0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
684  0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
685  0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
686  0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
687  0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
688  0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
689  0x44, 0xae, 0x7e, 0x3f },
690 };
691 
692 unsigned char tag[MAX_TESTS * 3][16] =
693 {
694  { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
695  0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
696  { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
697  0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
698  { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
699  0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
700  { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
701  0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
702  { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
703  0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
704  { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
705  0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
706  { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
707  0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
708  { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
709  0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
710  { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
711  0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
712  { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
713  0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
714  { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
715  0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
716  { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
717  0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
718  { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
719  0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
720  { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
721  0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
722  { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
723  0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
724  { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
725  0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
726  { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
727  0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
728  { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
729  0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
730 };
731 
732 int gcm_self_test( int verbose )
733 {
734  gcm_context ctx;
735  unsigned char buf[64];
736  unsigned char tag_buf[16];
737  int i, j, ret;
739 
740  for( j = 0; j < 3; j++ )
741  {
742  int key_len = 128 + 64 * j;
743 
744  for( i = 0; i < MAX_TESTS; i++ )
745  {
746  if( verbose != 0 )
747  polarssl_printf( " AES-GCM-%3d #%d (%s): ",
748  key_len, i, "enc" );
749 
750  gcm_init( &ctx, cipher, key[key_index[i]], key_len );
751 
752  ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
753  pt_len[i],
754  iv[iv_index[i]], iv_len[i],
755  additional[add_index[i]], add_len[i],
756  pt[pt_index[i]], buf, 16, tag_buf );
757 
758  if( ret != 0 ||
759  memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
760  memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
761  {
762  if( verbose != 0 )
763  polarssl_printf( "failed\n" );
764 
765  return( 1 );
766  }
767 
768  gcm_free( &ctx );
769 
770  if( verbose != 0 )
771  polarssl_printf( "passed\n" );
772 
773  if( verbose != 0 )
774  polarssl_printf( " AES-GCM-%3d #%d (%s): ",
775  key_len, i, "dec" );
776 
777  gcm_init( &ctx, cipher, key[key_index[i]], key_len );
778 
779  ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
780  pt_len[i],
781  iv[iv_index[i]], iv_len[i],
782  additional[add_index[i]], add_len[i],
783  ct[j * 6 + i], buf, 16, tag_buf );
784 
785  if( ret != 0 ||
786  memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
787  memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
788  {
789  if( verbose != 0 )
790  polarssl_printf( "failed\n" );
791 
792  return( 1 );
793  }
794 
795  gcm_free( &ctx );
796 
797  if( verbose != 0 )
798  polarssl_printf( "passed\n" );
799 
800  if( verbose != 0 )
801  polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
802  key_len, i, "enc" );
803 
804  gcm_init( &ctx, cipher, key[key_index[i]], key_len );
805 
806  ret = gcm_starts( &ctx, GCM_ENCRYPT,
807  iv[iv_index[i]], iv_len[i],
808  additional[add_index[i]], add_len[i] );
809  if( ret != 0 )
810  {
811  if( verbose != 0 )
812  polarssl_printf( "failed\n" );
813 
814  return( 1 );
815  }
816 
817  if( pt_len[i] > 32 )
818  {
819  size_t rest_len = pt_len[i] - 32;
820  ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
821  if( ret != 0 )
822  {
823  if( verbose != 0 )
824  polarssl_printf( "failed\n" );
825 
826  return( 1 );
827  }
828 
829  ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
830  buf + 32 );
831  if( ret != 0 )
832  {
833  if( verbose != 0 )
834  polarssl_printf( "failed\n" );
835 
836  return( 1 );
837  }
838  }
839  else
840  {
841  ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
842  if( ret != 0 )
843  {
844  if( verbose != 0 )
845  polarssl_printf( "failed\n" );
846 
847  return( 1 );
848  }
849  }
850 
851  ret = gcm_finish( &ctx, tag_buf, 16 );
852  if( ret != 0 ||
853  memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
854  memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
855  {
856  if( verbose != 0 )
857  polarssl_printf( "failed\n" );
858 
859  return( 1 );
860  }
861 
862  gcm_free( &ctx );
863 
864  if( verbose != 0 )
865  polarssl_printf( "passed\n" );
866 
867  if( verbose != 0 )
868  polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
869  key_len, i, "dec" );
870 
871  gcm_init( &ctx, cipher, key[key_index[i]], key_len );
872 
873  ret = gcm_starts( &ctx, GCM_DECRYPT,
874  iv[iv_index[i]], iv_len[i],
875  additional[add_index[i]], add_len[i] );
876  if( ret != 0 )
877  {
878  if( verbose != 0 )
879  polarssl_printf( "failed\n" );
880 
881  return( 1 );
882  }
883 
884  if( pt_len[i] > 32 )
885  {
886  size_t rest_len = pt_len[i] - 32;
887  ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
888  if( ret != 0 )
889  {
890  if( verbose != 0 )
891  polarssl_printf( "failed\n" );
892 
893  return( 1 );
894  }
895 
896  ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
897  buf + 32 );
898  if( ret != 0 )
899  {
900  if( verbose != 0 )
901  polarssl_printf( "failed\n" );
902 
903  return( 1 );
904  }
905  }
906  else
907  {
908  ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
909  if( ret != 0 )
910  {
911  if( verbose != 0 )
912  polarssl_printf( "failed\n" );
913 
914  return( 1 );
915  }
916  }
917 
918  ret = gcm_finish( &ctx, tag_buf, 16 );
919  if( ret != 0 ||
920  memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
921  memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
922  {
923  if( verbose != 0 )
924  polarssl_printf( "failed\n" );
925 
926  return( 1 );
927  }
928 
929  gcm_free( &ctx );
930 
931  if( verbose != 0 )
932  polarssl_printf( "passed\n" );
933 
934  }
935  }
936 
937  if( verbose != 0 )
938  polarssl_printf( "\n" );
939 
940  return( 0 );
941 }
942 
943 
944 
945 #endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
946 
947 #endif /* POLARSSL_GCM_C */
unsigned char y[16]
Definition: gcm.h:60
#define GCM_DECRYPT
Definition: gcm.h:41
#define polarssl_printf
int gcm_auth_decrypt(gcm_context *ctx, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *tag, size_t tag_len, const unsigned char *input, unsigned char *output)
GCM buffer authenticated decryption using a block cipher.
uint64_t len
Definition: gcm.h:57
void cipher_init(cipher_context_t *ctx)
Initialize a cipher_context (as NONE)
Cipher information.
Definition: cipher.h:226
#define POLARSSL_ERR_GCM_BAD_INPUT
Bad input parameters to function.
Definition: gcm.h:44
int gcm_self_test(int verbose)
Checkup routine.
Configuration options (set of defines)
uint64_t HL[16]
Definition: gcm.h:55
PolarSSL Platform abstraction layer.
#define GCM_ENCRYPT
Definition: gcm.h:40
unsigned char buf[16]
Definition: gcm.h:61
AES-NI for hardware AES acceleration on some Intel processors.
int gcm_crypt_and_tag(gcm_context *ctx, int mode, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *input, unsigned char *output, size_t tag_len, unsigned char *tag)
GCM buffer encryption/decryption using a block cipher.
#define PUT_UINT32_BE(n, b, i)
int mode
Definition: gcm.h:62
uint64_t HH[16]
Definition: gcm.h:56
#define POLARSSL_AESNI_CLMUL
Definition: aesni.h:33
int cipher_update(cipher_context_t *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen)
Generic cipher update function.
GCM context structure.
Definition: gcm.h:53
int gcm_init(gcm_context *ctx, cipher_id_t cipher, const unsigned char *key, unsigned int keysize)
GCM initialization (encryption)
cipher_id_t
Definition: cipher.h:71
void cipher_free(cipher_context_t *ctx)
Free and clear the cipher-specific context of ctx.
#define POLARSSL_ERR_GCM_AUTH_FAILED
Authenticated decryption failed.
Definition: gcm.h:43
int cipher_init_ctx(cipher_context_t *ctx, const cipher_info_t *cipher_info)
Initialises and fills the cipher context structure with the appropriate values.
int cipher_setkey(cipher_context_t *ctx, const unsigned char *key, int key_length, const operation_t operation)
Set the key to use with the given context.
int gcm_update(gcm_context *ctx, size_t length, const unsigned char *input, unsigned char *output)
Generic GCM update function.
void gcm_free(gcm_context *ctx)
Free a GCM context and underlying cipher sub-context.
int gcm_starts(gcm_context *ctx, int mode, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len)
Generic GCM stream start function.
Galois/Counter mode for 128-bit block ciphers.
int gcm_finish(gcm_context *ctx, unsigned char *tag, size_t tag_len)
Generic GCM finalisation function.
#define GET_UINT32_BE(n, b, i)
unsigned int block_size
block size, in bytes
Definition: cipher.h:248
unsigned char base_ectr[16]
Definition: gcm.h:59
cipher_context_t cipher_ctx
Definition: gcm.h:54
uint64_t add_len
Definition: gcm.h:58
const cipher_info_t * cipher_info_from_values(const cipher_id_t cipher_id, int key_length, const cipher_mode_t mode)
Returns the cipher information structure associated with the given cipher id, key size and mode...