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