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