blob: f1a43af48aa8c586f53d1c886937a1c8cf6ec3b3 [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
Manuel Pégourié-Gonnard4467fb72014-06-18 11:29:30 +0200200 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
201 if( ( (uint64_t) iv_len ) >> 61 != 0 ||
202 ( (uint64_t) add_len ) >> 61 != 0 ||
203 tag_len > 16 || tag_len < 4 ||
204 length > 0x03FFFFE0llu )
205 {
206 return( POLARSSL_ERR_GCM_BAD_INPUT );
207 }
208
Paul Bakker89e80c92012-03-20 13:50:09 +0000209 memset( y, 0x00, 16 );
210 memset( work_buf, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000211 memset( tag, 0x00, tag_len );
212 memset( buf, 0x00, 16 );
213
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000214 if( ( mode == GCM_DECRYPT && output <= input && ( input - output ) < 8 ) ||
215 ( output > input && (size_t) ( output - input ) < length ) )
216 {
217 return( POLARSSL_ERR_GCM_BAD_INPUT );
218 }
219
Paul Bakker89e80c92012-03-20 13:50:09 +0000220 if( iv_len == 12 )
221 {
222 memcpy( y, iv, iv_len );
223 y[15] = 1;
224 }
225 else
226 {
227 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000228 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000229
230 p = iv;
231 while( iv_len > 0 )
232 {
233 use_len = ( iv_len < 16 ) ? iv_len : 16;
234
Paul Bakker67f9d532012-10-23 11:49:05 +0000235 for( i = 0; i < use_len; i++ )
236 y[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000237
238 gcm_mult( ctx, y, y );
239
240 iv_len -= use_len;
241 p += use_len;
242 }
243
Paul Bakker67f9d532012-10-23 11:49:05 +0000244 for( i = 0; i < 16; i++ )
245 y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000246
247 gcm_mult( ctx, y, y );
248 }
249
250 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
251 memcpy( tag, ectr, tag_len );
252
253 p = add;
254 while( add_len > 0 )
255 {
256 use_len = ( add_len < 16 ) ? add_len : 16;
257
Paul Bakker67f9d532012-10-23 11:49:05 +0000258 for( i = 0; i < use_len; i++ )
259 buf[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000260
261 gcm_mult( ctx, buf, buf );
262
263 add_len -= use_len;
264 p += use_len;
265 }
266
267 p = input;
268 while( length > 0 )
269 {
270 use_len = ( length < 16 ) ? length : 16;
271
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100272 for( i = 16; i > 12; i-- )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000273 if( ++y[i - 1] != 0 )
274 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000275
276 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
277
Paul Bakker67f9d532012-10-23 11:49:05 +0000278 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000279 {
Paul Bakker67f9d532012-10-23 11:49:05 +0000280 out_p[i] = ectr[i] ^ p[i];
Paul Bakkereae09db2013-06-06 12:35:54 +0200281 if( mode == GCM_ENCRYPT )
282 buf[i] ^= out_p[i];
283 else
284 buf[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000285 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000286
287 gcm_mult( ctx, buf, buf );
288
289 length -= use_len;
290 p += use_len;
291 out_p += use_len;
292 }
293
294 if( orig_len || orig_add_len )
295 {
296 memset( work_buf, 0x00, 16 );
297
Paul Bakkerf42e5cc2013-04-12 13:21:29 +0200298 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
299 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
300 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
301 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000302
Paul Bakker67f9d532012-10-23 11:49:05 +0000303 for( i = 0; i < 16; i++ )
304 buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000305
306 gcm_mult( ctx, buf, buf );
307
Paul Bakker67f9d532012-10-23 11:49:05 +0000308 for( i = 0; i < tag_len; i++ )
309 tag[i] ^= buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000310 }
311
312 return( 0 );
313}
314
315int gcm_auth_decrypt( gcm_context *ctx,
316 size_t length,
317 const unsigned char *iv,
318 size_t iv_len,
319 const unsigned char *add,
320 size_t add_len,
321 const unsigned char *tag,
322 size_t tag_len,
323 const unsigned char *input,
324 unsigned char *output )
325{
Manuel Pégourié-Gonnardb55f5782014-01-18 18:49:32 +0100326 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000327 unsigned char check_tag[16];
328
Manuel Pégourié-Gonnardb55f5782014-01-18 18:49:32 +0100329 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
330 iv, iv_len, add, add_len,
331 input, output, tag_len, check_tag ) ) != 0 )
332 {
333 return( ret );
334 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000335
336 if( memcmp( check_tag, tag, tag_len ) == 0 )
337 return( 0 );
338
Paul Bakker312da332014-06-13 17:20:13 +0200339 polarssl_zeroize( output, length );
Paul Bakker89e80c92012-03-20 13:50:09 +0000340
341 return( POLARSSL_ERR_GCM_AUTH_FAILED );
342}
343
344#if defined(POLARSSL_SELF_TEST)
345
346#include <stdio.h>
347
348/*
349 * GCM test vectors from:
350 *
351 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
352 */
353#define MAX_TESTS 6
354
355int key_index[MAX_TESTS] =
356 { 0, 0, 1, 1, 1, 1 };
357
358unsigned char key[MAX_TESTS][32] =
359{
360 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
365 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
366 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
367 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
368};
369
370size_t iv_len[MAX_TESTS] =
371 { 12, 12, 12, 12, 8, 60 };
372
373int iv_index[MAX_TESTS] =
374 { 0, 0, 1, 1, 1, 2 };
375
376unsigned char iv[MAX_TESTS][64] =
377{
378 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00 },
380 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
381 0xde, 0xca, 0xf8, 0x88 },
382 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
383 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
384 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
385 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
386 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
387 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
388 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
389 0xa6, 0x37, 0xb3, 0x9b },
390};
391
392size_t add_len[MAX_TESTS] =
393 { 0, 0, 0, 20, 20, 20 };
394
395int add_index[MAX_TESTS] =
396 { 0, 0, 0, 1, 1, 1 };
397
398unsigned char additional[MAX_TESTS][64] =
399{
400 { 0x00 },
401 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
402 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
403 0xab, 0xad, 0xda, 0xd2 },
404};
405
406size_t pt_len[MAX_TESTS] =
407 { 0, 16, 64, 60, 60, 60 };
408
409int pt_index[MAX_TESTS] =
410 { 0, 0, 1, 1, 1, 1 };
411
412unsigned char pt[MAX_TESTS][64] =
413{
414 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
416 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
417 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
418 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
419 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
420 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
421 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
422 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
423 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
424};
425
426unsigned char ct[MAX_TESTS * 3][64] =
427{
428 { 0x00 },
429 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
430 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
431 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
432 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
433 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
434 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
435 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
436 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
437 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
438 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
439 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
440 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
441 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
442 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
443 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
444 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
445 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
446 0x3d, 0x58, 0xe0, 0x91 },
447 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
448 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
449 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
450 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
451 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
452 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
453 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
454 0xc2, 0x3f, 0x45, 0x98 },
455 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
456 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
457 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
458 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
459 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
460 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
461 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
462 0x4c, 0x34, 0xae, 0xe5 },
463 { 0x00 },
464 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
465 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
466 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
467 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
468 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
469 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
470 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
471 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
472 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
473 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
474 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
475 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
476 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
477 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
478 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
479 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
480 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
481 0xcc, 0xda, 0x27, 0x10 },
482 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
483 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
484 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
485 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
486 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
487 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
488 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
489 0xa0, 0xf0, 0x62, 0xf7 },
490 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
491 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
492 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
493 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
494 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
495 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
496 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
497 0xe9, 0xb7, 0x37, 0x3b },
498 { 0x00 },
499 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
500 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
501 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
502 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
503 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
504 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
505 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
506 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
507 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
508 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
509 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
510 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
511 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
512 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
513 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
514 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
515 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
516 0xbc, 0xc9, 0xf6, 0x62 },
517 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
518 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
519 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
520 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
521 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
522 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
523 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
524 0xf4, 0x7c, 0x9b, 0x1f },
525 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
526 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
527 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
528 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
529 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
530 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
531 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
532 0x44, 0xae, 0x7e, 0x3f },
533};
534
535unsigned char tag[MAX_TESTS * 3][16] =
536{
537 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
538 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
539 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
540 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
541 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
542 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
543 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
544 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
545 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
546 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
547 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
548 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
549 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
550 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
551 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
552 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
553 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
554 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
555 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
556 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
557 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
558 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
559 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
560 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
561 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
562 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
563 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
564 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
565 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
566 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
567 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
568 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
569 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
570 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
571 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
572 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
573};
574
575int gcm_self_test( int verbose )
576{
577 gcm_context ctx;
578 unsigned char buf[64];
579 unsigned char tag_buf[16];
580 int i, j, ret;
581
582 for( j = 0; j < 3; j++ )
583 {
584 int key_len = 128 + 64 * j;
585
586 for( i = 0; i < MAX_TESTS; i++ )
587 {
588 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
589 gcm_init( &ctx, key[key_index[i]], key_len );
590
591 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
592 pt_len[i],
593 iv[iv_index[i]], iv_len[i],
594 additional[add_index[i]], add_len[i],
595 pt[pt_index[i]], buf, 16, tag_buf );
596
597 if( ret != 0 ||
598 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
599 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
600 {
601 if( verbose != 0 )
602 printf( "failed\n" );
603
604 return( 1 );
605 }
606
607 if( verbose != 0 )
608 printf( "passed\n" );
609
610 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
611 gcm_init( &ctx, key[key_index[i]], key_len );
612
613 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
614 pt_len[i],
615 iv[iv_index[i]], iv_len[i],
616 additional[add_index[i]], add_len[i],
617 ct[j * 6 + i], buf, 16, tag_buf );
618
619 if( ret != 0 ||
620 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
621 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
622 {
623 if( verbose != 0 )
624 printf( "failed\n" );
625
626 return( 1 );
627 }
628
629 if( verbose != 0 )
630 printf( "passed\n" );
631 }
632 }
633
634 printf( "\n" );
635
636 return( 0 );
637}
638
639#endif
640
641#endif