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