blob: e9c37fe83bc89f8fe2fef34d4d1e57224be80040 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
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 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000037#ifndef GET_UINT32_BE
38#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000039{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000040 (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] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000044}
45#endif
46
Paul Bakker5c2364c2012-10-01 14:41:15 +000047#ifndef PUT_UINT32_BE
48#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000049{ \
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
Paul Bakker312da332014-06-13 17:20:13 +020057/* Implementation that should never be optimized out by the compiler */
58static void polarssl_zeroize( void *v, size_t n ) {
59 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
60}
61
Paul Bakker89e80c92012-03-20 13:50:09 +000062static 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
Paul Bakker5c2364c2012-10-01 14:41:15 +000075 GET_UINT32_BE( hi, h, 0 );
76 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000077 vh = (uint64_t) hi << 32 | lo;
78
Paul Bakker5c2364c2012-10-01 14:41:15 +000079 GET_UINT32_BE( hi, h, 8 );
80 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000081 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 {
Paul Bakkerf42e5cc2013-04-12 13:21:29 +020088 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +000089 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
110int 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
124static 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
132void gcm_mult( gcm_context *ctx, const unsigned char x[16], unsigned char output[16] )
133{
134 int i = 0;
135 unsigned char z[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000136 unsigned char lo, hi, rem;
137 uint64_t zh, zl;
138
139 memset( z, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000140
141 lo = x[15] & 0xf;
142 hi = x[15] >> 4;
143
144 zh = ctx->HH[lo];
145 zl = ctx->HL[lo];
146
147 for( i = 15; i >= 0; i-- )
148 {
149 lo = x[i] & 0xf;
150 hi = x[i] >> 4;
151
152 if( i != 15 )
153 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000154 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000155 zl = ( zh << 60 ) | ( zl >> 4 );
156 zh = ( zh >> 4 );
157 zh ^= (uint64_t) last4[rem] << 48;
158 zh ^= ctx->HH[lo];
159 zl ^= ctx->HL[lo];
160
161 }
162
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000163 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000164 zl = ( zh << 60 ) | ( zl >> 4 );
165 zh = ( zh >> 4 );
166 zh ^= (uint64_t) last4[rem] << 48;
167 zh ^= ctx->HH[hi];
168 zl ^= ctx->HL[hi];
169 }
170
Paul Bakker5c2364c2012-10-01 14:41:15 +0000171 PUT_UINT32_BE( zh >> 32, output, 0 );
172 PUT_UINT32_BE( zh, output, 4 );
173 PUT_UINT32_BE( zl >> 32, output, 8 );
174 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000175}
176
177int gcm_crypt_and_tag( gcm_context *ctx,
178 int mode,
179 size_t length,
180 const unsigned char *iv,
181 size_t iv_len,
182 const unsigned char *add,
183 size_t add_len,
184 const unsigned char *input,
185 unsigned char *output,
186 size_t tag_len,
187 unsigned char *tag )
188{
Paul Bakker89e80c92012-03-20 13:50:09 +0000189 unsigned char y[16];
190 unsigned char ectr[16];
191 unsigned char buf[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000192 unsigned char work_buf[16];
193 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000194 const unsigned char *p;
195 unsigned char *out_p = output;
196 size_t use_len;
Paul Bakkerf42e5cc2013-04-12 13:21:29 +0200197 uint64_t orig_len = length * 8;
198 uint64_t orig_add_len = add_len * 8;
Paul Bakker89e80c92012-03-20 13:50:09 +0000199
Paul Bakker89e80c92012-03-20 13:50:09 +0000200 memset( y, 0x00, 16 );
201 memset( work_buf, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000202 memset( tag, 0x00, tag_len );
203 memset( buf, 0x00, 16 );
204
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000205 if( ( mode == GCM_DECRYPT && output <= input && ( input - output ) < 8 ) ||
206 ( output > input && (size_t) ( output - input ) < length ) )
207 {
208 return( POLARSSL_ERR_GCM_BAD_INPUT );
209 }
210
Paul Bakker89e80c92012-03-20 13:50:09 +0000211 if( iv_len == 12 )
212 {
213 memcpy( y, iv, iv_len );
214 y[15] = 1;
215 }
216 else
217 {
218 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000219 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000220
221 p = iv;
222 while( iv_len > 0 )
223 {
224 use_len = ( iv_len < 16 ) ? iv_len : 16;
225
Paul Bakker67f9d532012-10-23 11:49:05 +0000226 for( i = 0; i < use_len; i++ )
227 y[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000228
229 gcm_mult( ctx, y, y );
230
231 iv_len -= use_len;
232 p += use_len;
233 }
234
Paul Bakker67f9d532012-10-23 11:49:05 +0000235 for( i = 0; i < 16; i++ )
236 y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000237
238 gcm_mult( ctx, y, y );
239 }
240
241 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
242 memcpy( tag, ectr, tag_len );
243
244 p = add;
245 while( add_len > 0 )
246 {
247 use_len = ( add_len < 16 ) ? add_len : 16;
248
Paul Bakker67f9d532012-10-23 11:49:05 +0000249 for( i = 0; i < use_len; i++ )
250 buf[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000251
252 gcm_mult( ctx, buf, buf );
253
254 add_len -= use_len;
255 p += use_len;
256 }
257
258 p = input;
259 while( length > 0 )
260 {
261 use_len = ( length < 16 ) ? length : 16;
262
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100263 for( i = 16; i > 12; i-- )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000264 if( ++y[i - 1] != 0 )
265 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000266
267 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
268
Paul Bakker67f9d532012-10-23 11:49:05 +0000269 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000270 {
Paul Bakker67f9d532012-10-23 11:49:05 +0000271 out_p[i] = ectr[i] ^ p[i];
Paul Bakkereae09db2013-06-06 12:35:54 +0200272 if( mode == GCM_ENCRYPT )
273 buf[i] ^= out_p[i];
274 else
275 buf[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000276 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000277
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
Paul Bakkerf42e5cc2013-04-12 13:21:29 +0200289 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
290 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
291 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
292 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000293
Paul Bakker67f9d532012-10-23 11:49:05 +0000294 for( i = 0; i < 16; i++ )
295 buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000296
297 gcm_mult( ctx, buf, buf );
298
Paul Bakker67f9d532012-10-23 11:49:05 +0000299 for( i = 0; i < tag_len; i++ )
300 tag[i] ^= buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000301 }
302
303 return( 0 );
304}
305
306int gcm_auth_decrypt( gcm_context *ctx,
307 size_t length,
308 const unsigned char *iv,
309 size_t iv_len,
310 const unsigned char *add,
311 size_t add_len,
312 const unsigned char *tag,
313 size_t tag_len,
314 const unsigned char *input,
315 unsigned char *output )
316{
Manuel Pégourié-Gonnardb55f5782014-01-18 18:49:32 +0100317 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000318 unsigned char check_tag[16];
319
Manuel Pégourié-Gonnardb55f5782014-01-18 18:49:32 +0100320 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
321 iv, iv_len, add, add_len,
322 input, output, tag_len, check_tag ) ) != 0 )
323 {
324 return( ret );
325 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000326
327 if( memcmp( check_tag, tag, tag_len ) == 0 )
328 return( 0 );
329
Paul Bakker312da332014-06-13 17:20:13 +0200330 polarssl_zeroize( output, length );
Paul Bakker89e80c92012-03-20 13:50:09 +0000331
332 return( POLARSSL_ERR_GCM_AUTH_FAILED );
333}
334
335#if defined(POLARSSL_SELF_TEST)
336
337#include <stdio.h>
338
339/*
340 * GCM test vectors from:
341 *
342 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
343 */
344#define MAX_TESTS 6
345
346int key_index[MAX_TESTS] =
347 { 0, 0, 1, 1, 1, 1 };
348
349unsigned char key[MAX_TESTS][32] =
350{
351 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
355 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
356 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
357 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
358 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
359};
360
361size_t iv_len[MAX_TESTS] =
362 { 12, 12, 12, 12, 8, 60 };
363
364int iv_index[MAX_TESTS] =
365 { 0, 0, 1, 1, 1, 2 };
366
367unsigned char iv[MAX_TESTS][64] =
368{
369 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00 },
371 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
372 0xde, 0xca, 0xf8, 0x88 },
373 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
374 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
375 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
376 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
377 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
378 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
379 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
380 0xa6, 0x37, 0xb3, 0x9b },
381};
382
383size_t add_len[MAX_TESTS] =
384 { 0, 0, 0, 20, 20, 20 };
385
386int add_index[MAX_TESTS] =
387 { 0, 0, 0, 1, 1, 1 };
388
389unsigned char additional[MAX_TESTS][64] =
390{
391 { 0x00 },
392 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
393 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
394 0xab, 0xad, 0xda, 0xd2 },
395};
396
397size_t pt_len[MAX_TESTS] =
398 { 0, 16, 64, 60, 60, 60 };
399
400int pt_index[MAX_TESTS] =
401 { 0, 0, 1, 1, 1, 1 };
402
403unsigned char pt[MAX_TESTS][64] =
404{
405 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
407 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
408 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
409 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
410 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
411 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
412 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
413 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
414 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
415};
416
417unsigned char ct[MAX_TESTS * 3][64] =
418{
419 { 0x00 },
420 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
421 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
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, 0x47, 0x3f, 0x59, 0x85 },
430 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
431 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
432 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
433 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
434 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
435 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
436 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
437 0x3d, 0x58, 0xe0, 0x91 },
438 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
439 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
440 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
441 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
442 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
443 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
444 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
445 0xc2, 0x3f, 0x45, 0x98 },
446 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
447 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
448 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
449 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
450 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
451 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
452 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
453 0x4c, 0x34, 0xae, 0xe5 },
454 { 0x00 },
455 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
456 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
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, 0xac, 0xad, 0xe2, 0x56 },
465 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
466 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
467 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
468 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
469 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
470 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
471 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
472 0xcc, 0xda, 0x27, 0x10 },
473 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
474 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
475 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
476 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
477 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
478 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
479 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
480 0xa0, 0xf0, 0x62, 0xf7 },
481 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
482 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
483 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
484 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
485 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
486 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
487 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
488 0xe9, 0xb7, 0x37, 0x3b },
489 { 0x00 },
490 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
491 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
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, 0x89, 0x80, 0x15, 0xad },
500 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
501 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
502 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
503 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
504 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
505 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
506 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
507 0xbc, 0xc9, 0xf6, 0x62 },
508 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
509 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
510 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
511 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
512 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
513 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
514 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
515 0xf4, 0x7c, 0x9b, 0x1f },
516 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
517 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
518 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
519 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
520 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
521 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
522 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
523 0x44, 0xae, 0x7e, 0x3f },
524};
525
526unsigned char tag[MAX_TESTS * 3][16] =
527{
528 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
529 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
530 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
531 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
532 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
533 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
534 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
535 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
536 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
537 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
538 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
539 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
540 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
541 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
542 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
543 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
544 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
545 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
546 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
547 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
548 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
549 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
550 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
551 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
552 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
553 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
554 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
555 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
556 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
557 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
558 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
559 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
560 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
561 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
562 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
563 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
564};
565
566int gcm_self_test( int verbose )
567{
568 gcm_context ctx;
569 unsigned char buf[64];
570 unsigned char tag_buf[16];
571 int i, j, ret;
572
573 for( j = 0; j < 3; j++ )
574 {
575 int key_len = 128 + 64 * j;
576
577 for( i = 0; i < MAX_TESTS; i++ )
578 {
579 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
580 gcm_init( &ctx, key[key_index[i]], key_len );
581
582 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
583 pt_len[i],
584 iv[iv_index[i]], iv_len[i],
585 additional[add_index[i]], add_len[i],
586 pt[pt_index[i]], buf, 16, tag_buf );
587
588 if( ret != 0 ||
589 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
590 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
591 {
592 if( verbose != 0 )
593 printf( "failed\n" );
594
595 return( 1 );
596 }
597
598 if( verbose != 0 )
599 printf( "passed\n" );
600
601 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
602 gcm_init( &ctx, key[key_index[i]], key_len );
603
604 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
605 pt_len[i],
606 iv[iv_index[i]], iv_len[i],
607 additional[add_index[i]], add_len[i],
608 ct[j * 6 + i], buf, 16, tag_buf );
609
610 if( ret != 0 ||
611 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
612 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
613 {
614 if( verbose != 0 )
615 printf( "failed\n" );
616
617 return( 1 );
618 }
619
620 if( verbose != 0 )
621 printf( "passed\n" );
622 }
623 }
624
625 printf( "\n" );
626
627 return( 0 );
628}
629
630#endif
631
632#endif