blob: ed7572dc5e4b9e3a0759ccd1dd150338ace0b3a6 [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
57static 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
Paul Bakker5c2364c2012-10-01 14:41:15 +000070 GET_UINT32_BE( hi, h, 0 );
71 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000072 vh = (uint64_t) hi << 32 | lo;
73
Paul Bakker5c2364c2012-10-01 14:41:15 +000074 GET_UINT32_BE( hi, h, 8 );
75 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000076 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 {
Paul Bakkerf42e5cc2013-04-12 13:21:29 +020083 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +000084 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
105int 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
119static 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
127void gcm_mult( gcm_context *ctx, const unsigned char x[16], unsigned char output[16] )
128{
129 int i = 0;
130 unsigned char z[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000131 unsigned char lo, hi, rem;
132 uint64_t zh, zl;
133
134 memset( z, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000135
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 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000149 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000150 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
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000158 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000159 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
Paul Bakker5c2364c2012-10-01 14:41:15 +0000166 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 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000170}
171
172int gcm_crypt_and_tag( gcm_context *ctx,
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{
Paul Bakker89e80c92012-03-20 13:50:09 +0000184 unsigned char y[16];
185 unsigned char ectr[16];
186 unsigned char buf[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000187 unsigned char work_buf[16];
188 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000189 const unsigned char *p;
190 unsigned char *out_p = output;
191 size_t use_len;
Paul Bakkerf42e5cc2013-04-12 13:21:29 +0200192 uint64_t orig_len = length * 8;
193 uint64_t orig_add_len = add_len * 8;
Paul Bakker89e80c92012-03-20 13:50:09 +0000194 unsigned char **xor_p;
195
Paul Bakker89e80c92012-03-20 13:50:09 +0000196 memset( y, 0x00, 16 );
197 memset( work_buf, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000198 memset( tag, 0x00, tag_len );
199 memset( buf, 0x00, 16 );
200
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000201 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
Paul Bakker89e80c92012-03-20 13:50:09 +0000207 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 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000220 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000221
222 p = iv;
223 while( iv_len > 0 )
224 {
225 use_len = ( iv_len < 16 ) ? iv_len : 16;
226
Paul Bakker67f9d532012-10-23 11:49:05 +0000227 for( i = 0; i < use_len; i++ )
228 y[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000229
230 gcm_mult( ctx, y, y );
231
232 iv_len -= use_len;
233 p += use_len;
234 }
235
Paul Bakker67f9d532012-10-23 11:49:05 +0000236 for( i = 0; i < 16; i++ )
237 y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000238
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
Paul Bakker67f9d532012-10-23 11:49:05 +0000250 for( i = 0; i < use_len; i++ )
251 buf[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000252
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
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100264 for( i = 16; i > 12; i-- )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000265 if( ++y[i - 1] != 0 )
266 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000267
268 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
269
Paul Bakker67f9d532012-10-23 11:49:05 +0000270 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000271 {
Paul Bakker67f9d532012-10-23 11:49:05 +0000272 out_p[i] = ectr[i] ^ p[i];
273 buf[i] ^= (*xor_p)[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000274 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000275
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
Paul Bakkerf42e5cc2013-04-12 13:21:29 +0200287 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 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000291
Paul Bakker67f9d532012-10-23 11:49:05 +0000292 for( i = 0; i < 16; i++ )
293 buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000294
295 gcm_mult( ctx, buf, buf );
296
Paul Bakker67f9d532012-10-23 11:49:05 +0000297 for( i = 0; i < tag_len; i++ )
298 tag[i] ^= buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000299 }
300
301 return( 0 );
302}
303
304int 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
324 return( POLARSSL_ERR_GCM_AUTH_FAILED );
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
338int key_index[MAX_TESTS] =
339 { 0, 0, 1, 1, 1, 1 };
340
341unsigned 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
353size_t iv_len[MAX_TESTS] =
354 { 12, 12, 12, 12, 8, 60 };
355
356int iv_index[MAX_TESTS] =
357 { 0, 0, 1, 1, 1, 2 };
358
359unsigned 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
375size_t add_len[MAX_TESTS] =
376 { 0, 0, 0, 20, 20, 20 };
377
378int add_index[MAX_TESTS] =
379 { 0, 0, 0, 1, 1, 1 };
380
381unsigned 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
389size_t pt_len[MAX_TESTS] =
390 { 0, 16, 64, 60, 60, 60 };
391
392int pt_index[MAX_TESTS] =
393 { 0, 0, 1, 1, 1, 1 };
394
395unsigned 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
409unsigned 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
518unsigned 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
558int 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