PolarSSL v1.3.4
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  int ret;
443  unsigned char check_tag[16];
444  size_t i;
445  int diff;
446 
447  if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
448  iv, iv_len, add, add_len,
449  input, output, tag_len, check_tag ) ) != 0 )
450  {
451  return( ret );
452  }
453 
454  /* Check tag in "constant-time" */
455  for( diff = 0, i = 0; i < tag_len; i++ )
456  diff |= tag[i] ^ check_tag[i];
457 
458  if( diff != 0 )
459  {
460  memset( output, 0, length );
462  }
463 
464  return( 0 );
465 }
466 
467 void gcm_free( gcm_context *ctx )
468 {
469  (void) cipher_free_ctx( &ctx->cipher_ctx );
470  memset( ctx, 0, sizeof( gcm_context ) );
471 }
472 
473 #if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
474 
475 #include <stdio.h>
476 
477 /*
478  * AES-GCM test vectors from:
479  *
480  * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
481  */
482 #define MAX_TESTS 6
483 
484 int key_index[MAX_TESTS] =
485  { 0, 0, 1, 1, 1, 1 };
486 
487 unsigned char key[MAX_TESTS][32] =
488 {
489  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
493  { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
494  0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
495  0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
496  0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
497 };
498 
499 size_t iv_len[MAX_TESTS] =
500  { 12, 12, 12, 12, 8, 60 };
501 
502 int iv_index[MAX_TESTS] =
503  { 0, 0, 1, 1, 1, 2 };
504 
505 unsigned char iv[MAX_TESTS][64] =
506 {
507  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508  0x00, 0x00, 0x00, 0x00 },
509  { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
510  0xde, 0xca, 0xf8, 0x88 },
511  { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
512  0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
513  0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
514  0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
515  0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
516  0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
517  0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
518  0xa6, 0x37, 0xb3, 0x9b },
519 };
520 
521 size_t add_len[MAX_TESTS] =
522  { 0, 0, 0, 20, 20, 20 };
523 
524 int add_index[MAX_TESTS] =
525  { 0, 0, 0, 1, 1, 1 };
526 
527 unsigned char additional[MAX_TESTS][64] =
528 {
529  { 0x00 },
530  { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
531  0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
532  0xab, 0xad, 0xda, 0xd2 },
533 };
534 
535 size_t pt_len[MAX_TESTS] =
536  { 0, 16, 64, 60, 60, 60 };
537 
538 int pt_index[MAX_TESTS] =
539  { 0, 0, 1, 1, 1, 1 };
540 
541 unsigned char pt[MAX_TESTS][64] =
542 {
543  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
545  { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
546  0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
547  0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
548  0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
549  0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
550  0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
551  0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
552  0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
553 };
554 
555 unsigned char ct[MAX_TESTS * 3][64] =
556 {
557  { 0x00 },
558  { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
559  0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
560  { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
561  0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
562  0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
563  0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
564  0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
565  0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
566  0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
567  0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
568  { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
569  0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
570  0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
571  0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
572  0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
573  0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
574  0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
575  0x3d, 0x58, 0xe0, 0x91 },
576  { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
577  0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
578  0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
579  0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
580  0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
581  0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
582  0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
583  0xc2, 0x3f, 0x45, 0x98 },
584  { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
585  0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
586  0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
587  0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
588  0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
589  0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
590  0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
591  0x4c, 0x34, 0xae, 0xe5 },
592  { 0x00 },
593  { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
594  0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
595  { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
596  0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
597  0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
598  0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
599  0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
600  0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
601  0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
602  0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
603  { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
604  0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
605  0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
606  0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
607  0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
608  0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
609  0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
610  0xcc, 0xda, 0x27, 0x10 },
611  { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
612  0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
613  0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
614  0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
615  0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
616  0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
617  0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
618  0xa0, 0xf0, 0x62, 0xf7 },
619  { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
620  0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
621  0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
622  0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
623  0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
624  0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
625  0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
626  0xe9, 0xb7, 0x37, 0x3b },
627  { 0x00 },
628  { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
629  0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
630  { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
631  0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
632  0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
633  0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
634  0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
635  0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
636  0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
637  0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
638  { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
639  0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
640  0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
641  0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
642  0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
643  0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
644  0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
645  0xbc, 0xc9, 0xf6, 0x62 },
646  { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
647  0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
648  0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
649  0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
650  0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
651  0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
652  0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
653  0xf4, 0x7c, 0x9b, 0x1f },
654  { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
655  0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
656  0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
657  0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
658  0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
659  0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
660  0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
661  0x44, 0xae, 0x7e, 0x3f },
662 };
663 
664 unsigned char tag[MAX_TESTS * 3][16] =
665 {
666  { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
667  0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
668  { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
669  0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
670  { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
671  0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
672  { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
673  0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
674  { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
675  0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
676  { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
677  0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
678  { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
679  0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
680  { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
681  0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
682  { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
683  0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
684  { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
685  0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
686  { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
687  0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
688  { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
689  0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
690  { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
691  0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
692  { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
693  0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
694  { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
695  0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
696  { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
697  0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
698  { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
699  0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
700  { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
701  0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
702 };
703 
704 int gcm_self_test( int verbose )
705 {
706  gcm_context ctx;
707  unsigned char buf[64];
708  unsigned char tag_buf[16];
709  int i, j, ret;
711 
712  for( j = 0; j < 3; j++ )
713  {
714  int key_len = 128 + 64 * j;
715 
716  for( i = 0; i < MAX_TESTS; i++ )
717  {
718  if( verbose != 0 )
719  printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
720 
721  gcm_init( &ctx, cipher, key[key_index[i]], key_len );
722 
723  ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
724  pt_len[i],
725  iv[iv_index[i]], iv_len[i],
726  additional[add_index[i]], add_len[i],
727  pt[pt_index[i]], buf, 16, tag_buf );
728 
729  if( ret != 0 ||
730  memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
731  memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
732  {
733  if( verbose != 0 )
734  printf( "failed\n" );
735 
736  return( 1 );
737  }
738 
739  gcm_free( &ctx );
740 
741  if( verbose != 0 )
742  printf( "passed\n" );
743 
744  if( verbose != 0 )
745  printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
746 
747  gcm_init( &ctx, cipher, key[key_index[i]], key_len );
748 
749  ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
750  pt_len[i],
751  iv[iv_index[i]], iv_len[i],
752  additional[add_index[i]], add_len[i],
753  ct[j * 6 + i], buf, 16, tag_buf );
754 
755  if( ret != 0 ||
756  memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
757  memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
758  {
759  if( verbose != 0 )
760  printf( "failed\n" );
761 
762  return( 1 );
763  }
764 
765  gcm_free( &ctx );
766 
767  if( verbose != 0 )
768  printf( "passed\n" );
769 
770  if( verbose != 0 )
771  printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" );
772 
773  gcm_init( &ctx, cipher, key[key_index[i]], key_len );
774 
775  ret = gcm_starts( &ctx, GCM_ENCRYPT,
776  iv[iv_index[i]], iv_len[i],
777  additional[add_index[i]], add_len[i] );
778  if( ret != 0 )
779  {
780  if( verbose != 0 )
781  printf( "failed\n" );
782 
783  return( 1 );
784  }
785 
786  if( pt_len[i] > 32 )
787  {
788  size_t rest_len = pt_len[i] - 32;
789  ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
790  if( ret != 0 )
791  {
792  if( verbose != 0 )
793  printf( "failed\n" );
794 
795  return( 1 );
796  }
797 
798  ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
799  if( ret != 0 )
800  {
801  if( verbose != 0 )
802  printf( "failed\n" );
803 
804  return( 1 );
805  }
806  }
807  else
808  {
809  ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
810  if( ret != 0 )
811  {
812  if( verbose != 0 )
813  printf( "failed\n" );
814 
815  return( 1 );
816  }
817  }
818 
819  ret = gcm_finish( &ctx, tag_buf, 16 );
820  if( ret != 0 ||
821  memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
822  memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
823  {
824  if( verbose != 0 )
825  printf( "failed\n" );
826 
827  return( 1 );
828  }
829 
830  gcm_free( &ctx );
831 
832  if( verbose != 0 )
833  printf( "passed\n" );
834 
835  if( verbose != 0 )
836  printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" );
837 
838  gcm_init( &ctx, cipher, key[key_index[i]], key_len );
839 
840  ret = gcm_starts( &ctx, GCM_DECRYPT,
841  iv[iv_index[i]], iv_len[i],
842  additional[add_index[i]], add_len[i] );
843  if( ret != 0 )
844  {
845  if( verbose != 0 )
846  printf( "failed\n" );
847 
848  return( 1 );
849  }
850 
851  if( pt_len[i] > 32 )
852  {
853  size_t rest_len = pt_len[i] - 32;
854  ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
855  if( ret != 0 )
856  {
857  if( verbose != 0 )
858  printf( "failed\n" );
859 
860  return( 1 );
861  }
862 
863  ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
864  if( ret != 0 )
865  {
866  if( verbose != 0 )
867  printf( "failed\n" );
868 
869  return( 1 );
870  }
871  }
872  else
873  {
874  ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
875  if( ret != 0 )
876  {
877  if( verbose != 0 )
878  printf( "failed\n" );
879 
880  return( 1 );
881  }
882  }
883 
884  ret = gcm_finish( &ctx, tag_buf, 16 );
885  if( ret != 0 ||
886  memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
887  memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
888  {
889  if( verbose != 0 )
890  printf( "failed\n" );
891 
892  return( 1 );
893  }
894 
895  gcm_free( &ctx );
896 
897  if( verbose != 0 )
898  printf( "passed\n" );
899 
900  }
901  }
902 
903  if( verbose != 0 )
904  printf( "\n" );
905 
906  return( 0 );
907 }
908 
909 
910 
911 #endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
912 
913 #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...