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