PolarSSL v1.3.8
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  hi = x[15] >> 4;
224 
225  zh = ctx->HH[lo];
226  zl = ctx->HL[lo];
227 
228  for( i = 15; i >= 0; i-- )
229  {
230  lo = x[i] & 0xf;
231  hi = x[i] >> 4;
232 
233  if( i != 15 )
234  {
235  rem = (unsigned char) zl & 0xf;
236  zl = ( zh << 60 ) | ( zl >> 4 );
237  zh = ( zh >> 4 );
238  zh ^= (uint64_t) last4[rem] << 48;
239  zh ^= ctx->HH[lo];
240  zl ^= ctx->HL[lo];
241 
242  }
243 
244  rem = (unsigned char) zl & 0xf;
245  zl = ( zh << 60 ) | ( zl >> 4 );
246  zh = ( zh >> 4 );
247  zh ^= (uint64_t) last4[rem] << 48;
248  zh ^= ctx->HH[hi];
249  zl ^= ctx->HL[hi];
250  }
251 
252  PUT_UINT32_BE( zh >> 32, output, 0 );
253  PUT_UINT32_BE( zh, output, 4 );
254  PUT_UINT32_BE( zl >> 32, output, 8 );
255  PUT_UINT32_BE( zl, output, 12 );
256 }
257 
258 int gcm_starts( gcm_context *ctx,
259  int mode,
260  const unsigned char *iv,
261  size_t iv_len,
262  const unsigned char *add,
263  size_t add_len )
264 {
265  int ret;
266  unsigned char work_buf[16];
267  size_t i;
268  const unsigned char *p;
269  size_t use_len, olen = 0;
270 
271  /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
272  if( ( (uint64_t) iv_len ) >> 61 != 0 ||
273  ( (uint64_t) add_len ) >> 61 != 0 )
274  {
275  return( POLARSSL_ERR_GCM_BAD_INPUT );
276  }
277 
278  memset( ctx->y, 0x00, sizeof(ctx->y) );
279  memset( ctx->buf, 0x00, sizeof(ctx->buf) );
280 
281  ctx->mode = mode;
282  ctx->len = 0;
283  ctx->add_len = 0;
284 
285  if( iv_len == 12 )
286  {
287  memcpy( ctx->y, iv, iv_len );
288  ctx->y[15] = 1;
289  }
290  else
291  {
292  memset( work_buf, 0x00, 16 );
293  PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
294 
295  p = iv;
296  while( iv_len > 0 )
297  {
298  use_len = ( iv_len < 16 ) ? iv_len : 16;
299 
300  for( i = 0; i < use_len; i++ )
301  ctx->y[i] ^= p[i];
302 
303  gcm_mult( ctx, ctx->y, ctx->y );
304 
305  iv_len -= use_len;
306  p += use_len;
307  }
308 
309  for( i = 0; i < 16; i++ )
310  ctx->y[i] ^= work_buf[i];
311 
312  gcm_mult( ctx, ctx->y, ctx->y );
313  }
314 
315  if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
316  &olen ) ) != 0 )
317  {
318  return( ret );
319  }
320 
321  ctx->add_len = add_len;
322  p = add;
323  while( add_len > 0 )
324  {
325  use_len = ( add_len < 16 ) ? add_len : 16;
326 
327  for( i = 0; i < use_len; i++ )
328  ctx->buf[i] ^= p[i];
329 
330  gcm_mult( ctx, ctx->buf, ctx->buf );
331 
332  add_len -= use_len;
333  p += use_len;
334  }
335 
336  return( 0 );
337 }
338 
339 int gcm_update( gcm_context *ctx,
340  size_t length,
341  const unsigned char *input,
342  unsigned char *output )
343 {
344  int ret;
345  unsigned char ectr[16];
346  size_t i;
347  const unsigned char *p;
348  unsigned char *out_p = output;
349  size_t use_len, olen = 0;
350 
351  if( output > input && (size_t) ( output - input ) < length )
352  return( POLARSSL_ERR_GCM_BAD_INPUT );
353 
354  /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
355  * Also check for possible overflow */
356  if( ctx->len + length < ctx->len ||
357  (uint64_t) ctx->len + length > 0x03FFFFE0llu )
358  {
359  return( POLARSSL_ERR_GCM_BAD_INPUT );
360  }
361 
362  ctx->len += length;
363 
364  p = input;
365  while( length > 0 )
366  {
367  use_len = ( length < 16 ) ? length : 16;
368 
369  for( i = 16; i > 12; i-- )
370  if( ++ctx->y[i - 1] != 0 )
371  break;
372 
373  if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
374  &olen ) ) != 0 )
375  {
376  return( ret );
377  }
378 
379  for( i = 0; i < use_len; i++ )
380  {
381  if( ctx->mode == GCM_DECRYPT )
382  ctx->buf[i] ^= p[i];
383  out_p[i] = ectr[i] ^ p[i];
384  if( ctx->mode == GCM_ENCRYPT )
385  ctx->buf[i] ^= out_p[i];
386  }
387 
388  gcm_mult( ctx, ctx->buf, ctx->buf );
389 
390  length -= use_len;
391  p += use_len;
392  out_p += use_len;
393  }
394 
395  return( 0 );
396 }
397 
398 int gcm_finish( gcm_context *ctx,
399  unsigned char *tag,
400  size_t tag_len )
401 {
402  unsigned char work_buf[16];
403  size_t i;
404  uint64_t orig_len = ctx->len * 8;
405  uint64_t orig_add_len = ctx->add_len * 8;
406 
407  if( tag_len > 16 || tag_len < 4 )
408  return( POLARSSL_ERR_GCM_BAD_INPUT );
409 
410  if( tag_len != 0 )
411  memcpy( tag, ctx->base_ectr, tag_len );
412 
413  if( orig_len || orig_add_len )
414  {
415  memset( work_buf, 0x00, 16 );
416 
417  PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
418  PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
419  PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
420  PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
421 
422  for( i = 0; i < 16; i++ )
423  ctx->buf[i] ^= work_buf[i];
424 
425  gcm_mult( ctx, ctx->buf, ctx->buf );
426 
427  for( i = 0; i < tag_len; i++ )
428  tag[i] ^= ctx->buf[i];
429  }
430 
431  return( 0 );
432 }
433 
435  int mode,
436  size_t length,
437  const unsigned char *iv,
438  size_t iv_len,
439  const unsigned char *add,
440  size_t add_len,
441  const unsigned char *input,
442  unsigned char *output,
443  size_t tag_len,
444  unsigned char *tag )
445 {
446  int ret;
447 
448  if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
449  return( ret );
450 
451  if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
452  return( ret );
453 
454  if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
455  return( ret );
456 
457  return( 0 );
458 }
459 
460 int gcm_auth_decrypt( gcm_context *ctx,
461  size_t length,
462  const unsigned char *iv,
463  size_t iv_len,
464  const unsigned char *add,
465  size_t add_len,
466  const unsigned char *tag,
467  size_t tag_len,
468  const unsigned char *input,
469  unsigned char *output )
470 {
471  int ret;
472  unsigned char check_tag[16];
473  size_t i;
474  int diff;
475 
476  if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
477  iv, iv_len, add, add_len,
478  input, output, tag_len, check_tag ) ) != 0 )
479  {
480  return( ret );
481  }
482 
483  /* Check tag in "constant-time" */
484  for( diff = 0, i = 0; i < tag_len; i++ )
485  diff |= tag[i] ^ check_tag[i];
486 
487  if( diff != 0 )
488  {
489  polarssl_zeroize( output, length );
491  }
492 
493  return( 0 );
494 }
495 
496 void gcm_free( gcm_context *ctx )
497 {
498  cipher_free( &ctx->cipher_ctx );
499  polarssl_zeroize( ctx, sizeof( gcm_context ) );
500 }
501 
502 #if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
503 
504 #include <stdio.h>
505 
506 /*
507  * AES-GCM test vectors from:
508  *
509  * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
510  */
511 #define MAX_TESTS 6
512 
513 int key_index[MAX_TESTS] =
514  { 0, 0, 1, 1, 1, 1 };
515 
516 unsigned char key[MAX_TESTS][32] =
517 {
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 },
526 };
527 
528 size_t iv_len[MAX_TESTS] =
529  { 12, 12, 12, 12, 8, 60 };
530 
531 int iv_index[MAX_TESTS] =
532  { 0, 0, 1, 1, 1, 2 };
533 
534 unsigned char iv[MAX_TESTS][64] =
535 {
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 },
548 };
549 
550 size_t add_len[MAX_TESTS] =
551  { 0, 0, 0, 20, 20, 20 };
552 
553 int add_index[MAX_TESTS] =
554  { 0, 0, 0, 1, 1, 1 };
555 
556 unsigned char additional[MAX_TESTS][64] =
557 {
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 },
562 };
563 
564 size_t pt_len[MAX_TESTS] =
565  { 0, 16, 64, 60, 60, 60 };
566 
567 int pt_index[MAX_TESTS] =
568  { 0, 0, 1, 1, 1, 1 };
569 
570 unsigned char pt[MAX_TESTS][64] =
571 {
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 },
582 };
583 
584 unsigned char ct[MAX_TESTS * 3][64] =
585 {
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 },
691 };
692 
693 unsigned char tag[MAX_TESTS * 3][16] =
694 {
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 },
731 };
732 
733 int gcm_self_test( int verbose )
734 {
735  gcm_context ctx;
736  unsigned char buf[64];
737  unsigned char tag_buf[16];
738  int i, j, ret;
740 
741  for( j = 0; j < 3; j++ )
742  {
743  int key_len = 128 + 64 * j;
744 
745  for( i = 0; i < MAX_TESTS; i++ )
746  {
747  if( verbose != 0 )
748  polarssl_printf( " AES-GCM-%3d #%d (%s): ",
749  key_len, i, "enc" );
750 
751  gcm_init( &ctx, cipher, key[key_index[i]], key_len );
752 
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 );
758 
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 )
762  {
763  if( verbose != 0 )
764  polarssl_printf( "failed\n" );
765 
766  return( 1 );
767  }
768 
769  gcm_free( &ctx );
770 
771  if( verbose != 0 )
772  polarssl_printf( "passed\n" );
773 
774  if( verbose != 0 )
775  polarssl_printf( " AES-GCM-%3d #%d (%s): ",
776  key_len, i, "dec" );
777 
778  gcm_init( &ctx, cipher, key[key_index[i]], key_len );
779 
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 );
785 
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 )
789  {
790  if( verbose != 0 )
791  polarssl_printf( "failed\n" );
792 
793  return( 1 );
794  }
795 
796  gcm_free( &ctx );
797 
798  if( verbose != 0 )
799  polarssl_printf( "passed\n" );
800 
801  if( verbose != 0 )
802  polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
803  key_len, i, "enc" );
804 
805  gcm_init( &ctx, cipher, key[key_index[i]], key_len );
806 
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 )
811  {
812  if( verbose != 0 )
813  polarssl_printf( "failed\n" );
814 
815  return( 1 );
816  }
817 
818  if( pt_len[i] > 32 )
819  {
820  size_t rest_len = pt_len[i] - 32;
821  ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
822  if( ret != 0 )
823  {
824  if( verbose != 0 )
825  polarssl_printf( "failed\n" );
826 
827  return( 1 );
828  }
829 
830  ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
831  buf + 32 );
832  if( ret != 0 )
833  {
834  if( verbose != 0 )
835  polarssl_printf( "failed\n" );
836 
837  return( 1 );
838  }
839  }
840  else
841  {
842  ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
843  if( ret != 0 )
844  {
845  if( verbose != 0 )
846  polarssl_printf( "failed\n" );
847 
848  return( 1 );
849  }
850  }
851 
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 )
856  {
857  if( verbose != 0 )
858  polarssl_printf( "failed\n" );
859 
860  return( 1 );
861  }
862 
863  gcm_free( &ctx );
864 
865  if( verbose != 0 )
866  polarssl_printf( "passed\n" );
867 
868  if( verbose != 0 )
869  polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
870  key_len, i, "dec" );
871 
872  gcm_init( &ctx, cipher, key[key_index[i]], key_len );
873 
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 )
878  {
879  if( verbose != 0 )
880  polarssl_printf( "failed\n" );
881 
882  return( 1 );
883  }
884 
885  if( pt_len[i] > 32 )
886  {
887  size_t rest_len = pt_len[i] - 32;
888  ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
889  if( ret != 0 )
890  {
891  if( verbose != 0 )
892  polarssl_printf( "failed\n" );
893 
894  return( 1 );
895  }
896 
897  ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
898  buf + 32 );
899  if( ret != 0 )
900  {
901  if( verbose != 0 )
902  polarssl_printf( "failed\n" );
903 
904  return( 1 );
905  }
906  }
907  else
908  {
909  ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
910  if( ret != 0 )
911  {
912  if( verbose != 0 )
913  polarssl_printf( "failed\n" );
914 
915  return( 1 );
916  }
917  }
918 
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 )
923  {
924  if( verbose != 0 )
925  polarssl_printf( "failed\n" );
926 
927  return( 1 );
928  }
929 
930  gcm_free( &ctx );
931 
932  if( verbose != 0 )
933  polarssl_printf( "passed\n" );
934 
935  }
936  }
937 
938  if( verbose != 0 )
939  polarssl_printf( "\n" );
940 
941  return( 0 );
942 }
943 
944 
945 
946 #endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
947 
948 #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
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.
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.
#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: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...