PolarSSL v1.2.9
gcm.c
Go to the documentation of this file.
1 /*
2  * NIST SP800-38D compliant GCM implementation
3  *
4  * Copyright (C) 2006-2012, 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 void gcm_gen_table( gcm_context *ctx )
58 {
59  int i, j;
60  uint64_t hi, lo;
61  uint64_t vl, vh;
62  unsigned char h[16];
63 
64  memset( h, 0, 16 );
65  aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, h, h );
66 
67  ctx->HH[0] = 0;
68  ctx->HL[0] = 0;
69 
70  GET_UINT32_BE( hi, h, 0 );
71  GET_UINT32_BE( lo, h, 4 );
72  vh = (uint64_t) hi << 32 | lo;
73 
74  GET_UINT32_BE( hi, h, 8 );
75  GET_UINT32_BE( lo, h, 12 );
76  vl = (uint64_t) hi << 32 | lo;
77 
78  ctx->HL[8] = vl;
79  ctx->HH[8] = vh;
80 
81  for( i = 4; i > 0; i >>= 1 )
82  {
83  uint32_t T = ( vl & 1 ) * 0xe1000000U;
84  vl = ( vh << 63 ) | ( vl >> 1 );
85  vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
86 
87  ctx->HL[i] = vl;
88  ctx->HH[i] = vh;
89  }
90 
91  for (i = 2; i < 16; i <<= 1 )
92  {
93  uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
94  vh = *HiH;
95  vl = *HiL;
96  for( j = 1; j < i; j++ )
97  {
98  HiH[j] = vh ^ ctx->HH[j];
99  HiL[j] = vl ^ ctx->HL[j];
100  }
101  }
102 
103 }
104 
105 int gcm_init( gcm_context *ctx, const unsigned char *key, unsigned int keysize )
106 {
107  int ret;
108 
109  memset( ctx, 0, sizeof(gcm_context) );
110 
111  if( ( ret = aes_setkey_enc( &ctx->aes_ctx, key, keysize ) ) != 0 )
112  return( ret );
113 
114  gcm_gen_table( ctx );
115 
116  return( 0 );
117 }
118 
119 static const uint64_t last4[16] =
120 {
121  0x0000, 0x1c20, 0x3840, 0x2460,
122  0x7080, 0x6ca0, 0x48c0, 0x54e0,
123  0xe100, 0xfd20, 0xd940, 0xc560,
124  0x9180, 0x8da0, 0xa9c0, 0xb5e0
125 };
126 
127 void gcm_mult( gcm_context *ctx, const unsigned char x[16], unsigned char output[16] )
128 {
129  int i = 0;
130  unsigned char z[16];
131  unsigned char lo, hi, rem;
132  uint64_t zh, zl;
133 
134  memset( z, 0x00, 16 );
135 
136  lo = x[15] & 0xf;
137  hi = x[15] >> 4;
138 
139  zh = ctx->HH[lo];
140  zl = ctx->HL[lo];
141 
142  for( i = 15; i >= 0; i-- )
143  {
144  lo = x[i] & 0xf;
145  hi = x[i] >> 4;
146 
147  if( i != 15 )
148  {
149  rem = (unsigned char) zl & 0xf;
150  zl = ( zh << 60 ) | ( zl >> 4 );
151  zh = ( zh >> 4 );
152  zh ^= (uint64_t) last4[rem] << 48;
153  zh ^= ctx->HH[lo];
154  zl ^= ctx->HL[lo];
155 
156  }
157 
158  rem = (unsigned char) zl & 0xf;
159  zl = ( zh << 60 ) | ( zl >> 4 );
160  zh = ( zh >> 4 );
161  zh ^= (uint64_t) last4[rem] << 48;
162  zh ^= ctx->HH[hi];
163  zl ^= ctx->HL[hi];
164  }
165 
166  PUT_UINT32_BE( zh >> 32, output, 0 );
167  PUT_UINT32_BE( zh, output, 4 );
168  PUT_UINT32_BE( zl >> 32, output, 8 );
169  PUT_UINT32_BE( zl, output, 12 );
170 }
171 
173  int mode,
174  size_t length,
175  const unsigned char *iv,
176  size_t iv_len,
177  const unsigned char *add,
178  size_t add_len,
179  const unsigned char *input,
180  unsigned char *output,
181  size_t tag_len,
182  unsigned char *tag )
183 {
184  unsigned char y[16];
185  unsigned char ectr[16];
186  unsigned char buf[16];
187  unsigned char work_buf[16];
188  size_t i;
189  const unsigned char *p;
190  unsigned char *out_p = output;
191  size_t use_len;
192  uint64_t orig_len = length * 8;
193  uint64_t orig_add_len = add_len * 8;
194 
195  memset( y, 0x00, 16 );
196  memset( work_buf, 0x00, 16 );
197  memset( tag, 0x00, tag_len );
198  memset( buf, 0x00, 16 );
199 
200  if( ( mode == GCM_DECRYPT && output <= input && ( input - output ) < 8 ) ||
201  ( output > input && (size_t) ( output - input ) < length ) )
202  {
203  return( POLARSSL_ERR_GCM_BAD_INPUT );
204  }
205 
206  if( iv_len == 12 )
207  {
208  memcpy( y, iv, iv_len );
209  y[15] = 1;
210  }
211  else
212  {
213  memset( work_buf, 0x00, 16 );
214  PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
215 
216  p = iv;
217  while( iv_len > 0 )
218  {
219  use_len = ( iv_len < 16 ) ? iv_len : 16;
220 
221  for( i = 0; i < use_len; i++ )
222  y[i] ^= p[i];
223 
224  gcm_mult( ctx, y, y );
225 
226  iv_len -= use_len;
227  p += use_len;
228  }
229 
230  for( i = 0; i < 16; i++ )
231  y[i] ^= work_buf[i];
232 
233  gcm_mult( ctx, y, y );
234  }
235 
236  aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
237  memcpy( tag, ectr, tag_len );
238 
239  p = add;
240  while( add_len > 0 )
241  {
242  use_len = ( add_len < 16 ) ? add_len : 16;
243 
244  for( i = 0; i < use_len; i++ )
245  buf[i] ^= p[i];
246 
247  gcm_mult( ctx, buf, buf );
248 
249  add_len -= use_len;
250  p += use_len;
251  }
252 
253  p = input;
254  while( length > 0 )
255  {
256  use_len = ( length < 16 ) ? length : 16;
257 
258  for( i = 16; i > 12; i-- )
259  if( ++y[i - 1] != 0 )
260  break;
261 
262  aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
263 
264  for( i = 0; i < use_len; i++ )
265  {
266  out_p[i] = ectr[i] ^ p[i];
267  if( mode == GCM_ENCRYPT )
268  buf[i] ^= out_p[i];
269  else
270  buf[i] ^= p[i];
271  }
272 
273  gcm_mult( ctx, buf, buf );
274 
275  length -= use_len;
276  p += use_len;
277  out_p += use_len;
278  }
279 
280  if( orig_len || orig_add_len )
281  {
282  memset( work_buf, 0x00, 16 );
283 
284  PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
285  PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
286  PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
287  PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
288 
289  for( i = 0; i < 16; i++ )
290  buf[i] ^= work_buf[i];
291 
292  gcm_mult( ctx, buf, buf );
293 
294  for( i = 0; i < tag_len; i++ )
295  tag[i] ^= buf[i];
296  }
297 
298  return( 0 );
299 }
300 
301 int gcm_auth_decrypt( gcm_context *ctx,
302  size_t length,
303  const unsigned char *iv,
304  size_t iv_len,
305  const unsigned char *add,
306  size_t add_len,
307  const unsigned char *tag,
308  size_t tag_len,
309  const unsigned char *input,
310  unsigned char *output )
311 {
312  unsigned char check_tag[16];
313 
314  gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
315 
316  if( memcmp( check_tag, tag, tag_len ) == 0 )
317  return( 0 );
318 
319  memset( output, 0, length );
320 
322 }
323 
324 #if defined(POLARSSL_SELF_TEST)
325 
326 #include <stdio.h>
327 
328 /*
329  * GCM test vectors from:
330  *
331  * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
332  */
333 #define MAX_TESTS 6
334 
335 int key_index[MAX_TESTS] =
336  { 0, 0, 1, 1, 1, 1 };
337 
338 unsigned char key[MAX_TESTS][32] =
339 {
340  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
344  { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
345  0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
346  0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
347  0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
348 };
349 
350 size_t iv_len[MAX_TESTS] =
351  { 12, 12, 12, 12, 8, 60 };
352 
353 int iv_index[MAX_TESTS] =
354  { 0, 0, 1, 1, 1, 2 };
355 
356 unsigned char iv[MAX_TESTS][64] =
357 {
358  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359  0x00, 0x00, 0x00, 0x00 },
360  { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
361  0xde, 0xca, 0xf8, 0x88 },
362  { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
363  0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
364  0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
365  0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
366  0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
367  0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
368  0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
369  0xa6, 0x37, 0xb3, 0x9b },
370 };
371 
372 size_t add_len[MAX_TESTS] =
373  { 0, 0, 0, 20, 20, 20 };
374 
375 int add_index[MAX_TESTS] =
376  { 0, 0, 0, 1, 1, 1 };
377 
378 unsigned char additional[MAX_TESTS][64] =
379 {
380  { 0x00 },
381  { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
382  0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
383  0xab, 0xad, 0xda, 0xd2 },
384 };
385 
386 size_t pt_len[MAX_TESTS] =
387  { 0, 16, 64, 60, 60, 60 };
388 
389 int pt_index[MAX_TESTS] =
390  { 0, 0, 1, 1, 1, 1 };
391 
392 unsigned char pt[MAX_TESTS][64] =
393 {
394  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
396  { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
397  0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
398  0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
399  0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
400  0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
401  0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
402  0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
403  0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
404 };
405 
406 unsigned char ct[MAX_TESTS * 3][64] =
407 {
408  { 0x00 },
409  { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
410  0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
411  { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
412  0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
413  0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
414  0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
415  0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
416  0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
417  0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
418  0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
419  { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
420  0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
421  0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
422  0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
423  0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
424  0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
425  0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
426  0x3d, 0x58, 0xe0, 0x91 },
427  { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
428  0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
429  0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
430  0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
431  0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
432  0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
433  0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
434  0xc2, 0x3f, 0x45, 0x98 },
435  { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
436  0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
437  0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
438  0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
439  0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
440  0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
441  0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
442  0x4c, 0x34, 0xae, 0xe5 },
443  { 0x00 },
444  { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
445  0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
446  { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
447  0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
448  0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
449  0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
450  0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
451  0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
452  0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
453  0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
454  { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
455  0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
456  0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
457  0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
458  0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
459  0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
460  0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
461  0xcc, 0xda, 0x27, 0x10 },
462  { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
463  0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
464  0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
465  0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
466  0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
467  0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
468  0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
469  0xa0, 0xf0, 0x62, 0xf7 },
470  { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
471  0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
472  0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
473  0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
474  0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
475  0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
476  0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
477  0xe9, 0xb7, 0x37, 0x3b },
478  { 0x00 },
479  { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
480  0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
481  { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
482  0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
483  0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
484  0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
485  0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
486  0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
487  0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
488  0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
489  { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
490  0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
491  0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
492  0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
493  0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
494  0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
495  0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
496  0xbc, 0xc9, 0xf6, 0x62 },
497  { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
498  0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
499  0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
500  0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
501  0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
502  0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
503  0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
504  0xf4, 0x7c, 0x9b, 0x1f },
505  { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
506  0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
507  0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
508  0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
509  0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
510  0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
511  0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
512  0x44, 0xae, 0x7e, 0x3f },
513 };
514 
515 unsigned char tag[MAX_TESTS * 3][16] =
516 {
517  { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
518  0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
519  { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
520  0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
521  { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
522  0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
523  { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
524  0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
525  { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
526  0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
527  { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
528  0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
529  { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
530  0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
531  { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
532  0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
533  { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
534  0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
535  { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
536  0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
537  { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
538  0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
539  { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
540  0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
541  { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
542  0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
543  { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
544  0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
545  { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
546  0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
547  { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
548  0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
549  { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
550  0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
551  { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
552  0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
553 };
554 
555 int gcm_self_test( int verbose )
556 {
557  gcm_context ctx;
558  unsigned char buf[64];
559  unsigned char tag_buf[16];
560  int i, j, ret;
561 
562  for( j = 0; j < 3; j++ )
563  {
564  int key_len = 128 + 64 * j;
565 
566  for( i = 0; i < MAX_TESTS; i++ )
567  {
568  printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
569  gcm_init( &ctx, key[key_index[i]], key_len );
570 
571  ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
572  pt_len[i],
573  iv[iv_index[i]], iv_len[i],
574  additional[add_index[i]], add_len[i],
575  pt[pt_index[i]], buf, 16, tag_buf );
576 
577  if( ret != 0 ||
578  memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
579  memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
580  {
581  if( verbose != 0 )
582  printf( "failed\n" );
583 
584  return( 1 );
585  }
586 
587  if( verbose != 0 )
588  printf( "passed\n" );
589 
590  printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
591  gcm_init( &ctx, key[key_index[i]], key_len );
592 
593  ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
594  pt_len[i],
595  iv[iv_index[i]], iv_len[i],
596  additional[add_index[i]], add_len[i],
597  ct[j * 6 + i], buf, 16, tag_buf );
598 
599  if( ret != 0 ||
600  memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
601  memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
602  {
603  if( verbose != 0 )
604  printf( "failed\n" );
605 
606  return( 1 );
607  }
608 
609  if( verbose != 0 )
610  printf( "passed\n" );
611  }
612  }
613 
614  printf( "\n" );
615 
616  return( 0 );
617 }
618 
619 #endif
620 
621 #endif
#define GCM_DECRYPT
Definition: gcm.h:40
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 AES.
#define POLARSSL_ERR_GCM_BAD_INPUT
Bad input parameters to function.
Definition: gcm.h:43
int gcm_self_test(int verbose)
Checkup routine.
Configuration options (set of defines)
uint64_t HL[16]
Definition: gcm.h:50
#define GCM_ENCRYPT
Definition: gcm.h:39
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 AES.
uint64_t HH[16]
Definition: gcm.h:51
GCM context structure.
Definition: gcm.h:48
aes_context aes_ctx
Definition: gcm.h:49
int gcm_init(gcm_context *ctx, const unsigned char *key, unsigned int keysize)
GCM initialization (encryption)
#define POLARSSL_ERR_GCM_AUTH_FAILED
Authenticated decryption failed.
Definition: gcm.h:42
#define AES_ENCRYPT
Definition: aes.h:41
Galois/Counter mode for AES.
int aes_setkey_enc(aes_context *ctx, const unsigned char *key, unsigned int keysize)
AES key schedule (encryption)
int aes_crypt_ecb(aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16])
AES-ECB block encryption/decryption.