blob: 08435f9bfd18df4a028003eebb6d94411d4d0039 [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
Paul Bakker1d073c52014-07-08 20:15:51 +0200132static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
133 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000134{
135 int i = 0;
136 unsigned char z[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000137 unsigned char lo, hi, rem;
138 uint64_t zh, zl;
139
140 memset( z, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000141
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 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000155 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000156 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
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000164 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000165 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
Paul Bakker5c2364c2012-10-01 14:41:15 +0000172 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 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000176}
177
178int gcm_crypt_and_tag( gcm_context *ctx,
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{
Paul Bakker89e80c92012-03-20 13:50:09 +0000190 unsigned char y[16];
191 unsigned char ectr[16];
192 unsigned char buf[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000193 unsigned char work_buf[16];
194 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000195 const unsigned char *p;
196 unsigned char *out_p = output;
197 size_t use_len;
Paul Bakkerf42e5cc2013-04-12 13:21:29 +0200198 uint64_t orig_len = length * 8;
199 uint64_t orig_add_len = add_len * 8;
Paul Bakker89e80c92012-03-20 13:50:09 +0000200
Manuel Pégourié-Gonnard4467fb72014-06-18 11:29:30 +0200201 /* 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
Paul Bakker89e80c92012-03-20 13:50:09 +0000210 memset( y, 0x00, 16 );
211 memset( work_buf, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000212 memset( tag, 0x00, tag_len );
213 memset( buf, 0x00, 16 );
214
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000215 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
Paul Bakker89e80c92012-03-20 13:50:09 +0000221 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 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000229 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000230
231 p = iv;
232 while( iv_len > 0 )
233 {
234 use_len = ( iv_len < 16 ) ? iv_len : 16;
235
Paul Bakker67f9d532012-10-23 11:49:05 +0000236 for( i = 0; i < use_len; i++ )
237 y[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000238
239 gcm_mult( ctx, y, y );
240
241 iv_len -= use_len;
242 p += use_len;
243 }
244
Paul Bakker67f9d532012-10-23 11:49:05 +0000245 for( i = 0; i < 16; i++ )
246 y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000247
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
Paul Bakker67f9d532012-10-23 11:49:05 +0000259 for( i = 0; i < use_len; i++ )
260 buf[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000261
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
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100273 for( i = 16; i > 12; i-- )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000274 if( ++y[i - 1] != 0 )
275 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000276
277 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
278
Paul Bakker67f9d532012-10-23 11:49:05 +0000279 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000280 {
Paul Bakker67f9d532012-10-23 11:49:05 +0000281 out_p[i] = ectr[i] ^ p[i];
Paul Bakkereae09db2013-06-06 12:35:54 +0200282 if( mode == GCM_ENCRYPT )
283 buf[i] ^= out_p[i];
284 else
285 buf[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000286 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000287
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
Paul Bakkerf42e5cc2013-04-12 13:21:29 +0200299 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 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000303
Paul Bakker67f9d532012-10-23 11:49:05 +0000304 for( i = 0; i < 16; i++ )
305 buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000306
307 gcm_mult( ctx, buf, buf );
308
Paul Bakker67f9d532012-10-23 11:49:05 +0000309 for( i = 0; i < tag_len; i++ )
310 tag[i] ^= buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000311 }
312
313 return( 0 );
314}
315
316int 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{
Manuel Pégourié-Gonnardb55f5782014-01-18 18:49:32 +0100327 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000328 unsigned char check_tag[16];
329
Manuel Pégourié-Gonnardb55f5782014-01-18 18:49:32 +0100330 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 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000336
337 if( memcmp( check_tag, tag, tag_len ) == 0 )
338 return( 0 );
339
Paul Bakker312da332014-06-13 17:20:13 +0200340 polarssl_zeroize( output, length );
Paul Bakker89e80c92012-03-20 13:50:09 +0000341
342 return( POLARSSL_ERR_GCM_AUTH_FAILED );
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
356int key_index[MAX_TESTS] =
357 { 0, 0, 1, 1, 1, 1 };
358
359unsigned 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
371size_t iv_len[MAX_TESTS] =
372 { 12, 12, 12, 12, 8, 60 };
373
374int iv_index[MAX_TESTS] =
375 { 0, 0, 1, 1, 1, 2 };
376
377unsigned 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
393size_t add_len[MAX_TESTS] =
394 { 0, 0, 0, 20, 20, 20 };
395
396int add_index[MAX_TESTS] =
397 { 0, 0, 0, 1, 1, 1 };
398
399unsigned 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
407size_t pt_len[MAX_TESTS] =
408 { 0, 16, 64, 60, 60, 60 };
409
410int pt_index[MAX_TESTS] =
411 { 0, 0, 1, 1, 1, 1 };
412
413unsigned 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
427unsigned 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
536unsigned 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
576int 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