PolarSSL v1.2.7
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  unsigned char **xor_p;
195 
196  memset( y, 0x00, 16 );
197  memset( work_buf, 0x00, 16 );
198  memset( tag, 0x00, tag_len );
199  memset( buf, 0x00, 16 );
200 
201  if( ( mode == GCM_DECRYPT && output <= input && ( input - output ) < 8 ) ||
202  ( output > input && (size_t) ( output - input ) < length ) )
203  {
204  return( POLARSSL_ERR_GCM_BAD_INPUT );
205  }
206 
207  if( mode == GCM_ENCRYPT )
208  xor_p = (unsigned char **) &out_p;
209  else
210  xor_p = (unsigned char **) &p;
211 
212  if( iv_len == 12 )
213  {
214  memcpy( y, iv, iv_len );
215  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  y[i] ^= p[i];
229 
230  gcm_mult( ctx, y, y );
231 
232  iv_len -= use_len;
233  p += use_len;
234  }
235 
236  for( i = 0; i < 16; i++ )
237  y[i] ^= work_buf[i];
238 
239  gcm_mult( ctx, y, y );
240  }
241 
242  aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
243  memcpy( tag, ectr, tag_len );
244 
245  p = add;
246  while( add_len > 0 )
247  {
248  use_len = ( add_len < 16 ) ? add_len : 16;
249 
250  for( i = 0; i < use_len; i++ )
251  buf[i] ^= p[i];
252 
253  gcm_mult( ctx, buf, buf );
254 
255  add_len -= use_len;
256  p += use_len;
257  }
258 
259  p = input;
260  while( length > 0 )
261  {
262  use_len = ( length < 16 ) ? length : 16;
263 
264  for( i = 16; i > 12; i-- )
265  if( ++y[i - 1] != 0 )
266  break;
267 
268  aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
269 
270  for( i = 0; i < use_len; i++ )
271  {
272  out_p[i] = ectr[i] ^ p[i];
273  buf[i] ^= (*xor_p)[i];
274  }
275 
276  gcm_mult( ctx, buf, buf );
277 
278  length -= use_len;
279  p += use_len;
280  out_p += use_len;
281  }
282 
283  if( orig_len || orig_add_len )
284  {
285  memset( work_buf, 0x00, 16 );
286 
287  PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
288  PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
289  PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
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