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