blob: 89068c9195269a8111112447e75f9825e27ba535 [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 {
83 uint32_t T = ( vl & 1 ) ? 0xe1000000U : 0;
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
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];
131 unsigned char v[16];
132 unsigned char lo, hi, rem;
133 uint64_t zh, zl;
134
135 memset( z, 0x00, 16 );
136 memcpy( v, x, 16 );
137
138 lo = x[15] & 0xf;
139 hi = x[15] >> 4;
140
141 zh = ctx->HH[lo];
142 zl = ctx->HL[lo];
143
144 for( i = 15; i >= 0; i-- )
145 {
146 lo = x[i] & 0xf;
147 hi = x[i] >> 4;
148
149 if( i != 15 )
150 {
151 rem = zl & 0xf;
152 zl = ( zh << 60 ) | ( zl >> 4 );
153 zh = ( zh >> 4 );
154 zh ^= (uint64_t) last4[rem] << 48;
155 zh ^= ctx->HH[lo];
156 zl ^= ctx->HL[lo];
157
158 }
159
160 rem = zl & 0xf;
161 zl = ( zh << 60 ) | ( zl >> 4 );
162 zh = ( zh >> 4 );
163 zh ^= (uint64_t) last4[rem] << 48;
164 zh ^= ctx->HH[hi];
165 zl ^= ctx->HL[hi];
166 }
167
Paul Bakker5c2364c2012-10-01 14:41:15 +0000168 PUT_UINT32_BE( zh >> 32, output, 0 );
169 PUT_UINT32_BE( zh, output, 4 );
170 PUT_UINT32_BE( zl >> 32, output, 8 );
171 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000172}
173
174int gcm_crypt_and_tag( gcm_context *ctx,
175 int mode,
176 size_t length,
177 const unsigned char *iv,
178 size_t iv_len,
179 const unsigned char *add,
180 size_t add_len,
181 const unsigned char *input,
182 unsigned char *output,
183 size_t tag_len,
184 unsigned char *tag )
185{
Paul Bakker89e80c92012-03-20 13:50:09 +0000186 unsigned char y[16];
187 unsigned char ectr[16];
188 unsigned char buf[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000189 unsigned char work_buf[16];
190 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000191 const unsigned char *p;
192 unsigned char *out_p = output;
193 size_t use_len;
194 size_t orig_len = length * 8;
195 size_t orig_add_len = add_len * 8;
196 unsigned char **xor_p;
197
Paul Bakker89e80c92012-03-20 13:50:09 +0000198 memset( y, 0x00, 16 );
199 memset( work_buf, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000200 memset( tag, 0x00, tag_len );
201 memset( buf, 0x00, 16 );
202
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000203 if( ( mode == GCM_DECRYPT && output <= input && ( input - output ) < 8 ) ||
204 ( output > input && (size_t) ( output - input ) < length ) )
205 {
206 return( POLARSSL_ERR_GCM_BAD_INPUT );
207 }
208
Paul Bakker89e80c92012-03-20 13:50:09 +0000209 if( mode == GCM_ENCRYPT )
210 xor_p = (unsigned char **) &out_p;
211 else
212 xor_p = (unsigned char **) &p;
213
214 if( iv_len == 12 )
215 {
216 memcpy( y, iv, iv_len );
217 y[15] = 1;
218 }
219 else
220 {
221 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000222 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000223
224 p = iv;
225 while( iv_len > 0 )
226 {
227 use_len = ( iv_len < 16 ) ? iv_len : 16;
228
229 if( use_len == 16 )
230 {
231 ((uint64_t *) y)[0] ^= ((uint64_t *) p)[0];
232 ((uint64_t *) y)[1] ^= ((uint64_t *) p)[1];
233 }
234 else
235 for( i = 0; i < use_len; i++ )
236 y[i] ^= p[i];
237
238 gcm_mult( ctx, y, y );
239
240 iv_len -= use_len;
241 p += use_len;
242 }
243
244 ((uint64_t *) y)[0] ^= ((uint64_t *) work_buf)[0];
245 ((uint64_t *) y)[1] ^= ((uint64_t *) work_buf)[1];
246
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
258 if( use_len == 16 )
259 {
260 ((uint64_t *) buf)[0] ^= ((uint64_t *) p)[0];
261 ((uint64_t *) buf)[1] ^= ((uint64_t *) p)[1];
262 }
263 else
264 for( i = 0; i < use_len; i++ )
265 buf[i] ^= p[i];
266
267 gcm_mult( ctx, buf, buf );
268
269 add_len -= use_len;
270 p += use_len;
271 }
272
273 p = input;
274 while( length > 0 )
275 {
276 use_len = ( length < 16 ) ? length : 16;
277
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000278 for( i = 16; i > 0; i-- )
279 if( ++y[i - 1] != 0 )
280 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000281
282 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
283
284 if( use_len == 16 )
285 {
286 ((uint64_t *) out_p)[0] = ((uint64_t *) ectr)[0] ^
287 ((uint64_t *) p)[0];
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000288 ((uint64_t *) buf)[0] ^= ((uint64_t *) (*xor_p))[0];
289
Paul Bakker89e80c92012-03-20 13:50:09 +0000290 ((uint64_t *) out_p)[1] = ((uint64_t *) ectr)[1] ^
291 ((uint64_t *) p)[1];
Paul Bakker89e80c92012-03-20 13:50:09 +0000292 ((uint64_t *) buf)[1] ^= ((uint64_t *) (*xor_p))[1];
293 }
294 else
295 for( i = 0; i < use_len; i++ )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000296 {
297 out_p[i] = ectr[i] ^ p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000298 buf[i] ^= (*xor_p)[i];
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000299 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000300
301 gcm_mult( ctx, buf, buf );
302
303 length -= use_len;
304 p += use_len;
305 out_p += use_len;
306 }
307
308 if( orig_len || orig_add_len )
309 {
310 memset( work_buf, 0x00, 16 );
311
Paul Bakker5c2364c2012-10-01 14:41:15 +0000312 PUT_UINT32_BE( orig_add_len , work_buf, 4 );
313 PUT_UINT32_BE( orig_len , work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000314
315 ((uint64_t *) buf)[0] ^= ((uint64_t *) work_buf)[0];
316 ((uint64_t *) buf)[1] ^= ((uint64_t *) work_buf)[1];
317
318 gcm_mult( ctx, buf, buf );
319
320 if( tag_len == 16 )
321 {
322 ((uint64_t *) tag)[0] ^= ((uint64_t *) buf)[0];
323 ((uint64_t *) tag)[1] ^= ((uint64_t *) buf)[1];
324 }
325 else
326 for( i = 0; i < tag_len; i++ )
327 tag[i] ^= buf[i];
328 }
329
330 return( 0 );
331}
332
333int gcm_auth_decrypt( gcm_context *ctx,
334 size_t length,
335 const unsigned char *iv,
336 size_t iv_len,
337 const unsigned char *add,
338 size_t add_len,
339 const unsigned char *tag,
340 size_t tag_len,
341 const unsigned char *input,
342 unsigned char *output )
343{
344 unsigned char check_tag[16];
345
346 gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
347
348 if( memcmp( check_tag, tag, tag_len ) == 0 )
349 return( 0 );
350
351 memset( output, 0, length );
352
353 return( POLARSSL_ERR_GCM_AUTH_FAILED );
354}
355
356#if defined(POLARSSL_SELF_TEST)
357
358#include <stdio.h>
359
360/*
361 * GCM test vectors from:
362 *
363 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
364 */
365#define MAX_TESTS 6
366
367int key_index[MAX_TESTS] =
368 { 0, 0, 1, 1, 1, 1 };
369
370unsigned char key[MAX_TESTS][32] =
371{
372 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
376 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
377 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
378 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
379 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
380};
381
382size_t iv_len[MAX_TESTS] =
383 { 12, 12, 12, 12, 8, 60 };
384
385int iv_index[MAX_TESTS] =
386 { 0, 0, 1, 1, 1, 2 };
387
388unsigned char iv[MAX_TESTS][64] =
389{
390 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00 },
392 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
393 0xde, 0xca, 0xf8, 0x88 },
394 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
395 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
396 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
397 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
398 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
399 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
400 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
401 0xa6, 0x37, 0xb3, 0x9b },
402};
403
404size_t add_len[MAX_TESTS] =
405 { 0, 0, 0, 20, 20, 20 };
406
407int add_index[MAX_TESTS] =
408 { 0, 0, 0, 1, 1, 1 };
409
410unsigned char additional[MAX_TESTS][64] =
411{
412 { 0x00 },
413 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
414 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
415 0xab, 0xad, 0xda, 0xd2 },
416};
417
418size_t pt_len[MAX_TESTS] =
419 { 0, 16, 64, 60, 60, 60 };
420
421int pt_index[MAX_TESTS] =
422 { 0, 0, 1, 1, 1, 1 };
423
424unsigned char pt[MAX_TESTS][64] =
425{
426 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
428 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
429 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
430 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
431 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
432 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
433 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
434 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
435 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
436};
437
438unsigned char ct[MAX_TESTS * 3][64] =
439{
440 { 0x00 },
441 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
442 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
443 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
444 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
445 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
446 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
447 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
448 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
449 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
450 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
451 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
452 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
453 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
454 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
455 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
456 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
457 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
458 0x3d, 0x58, 0xe0, 0x91 },
459 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
460 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
461 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
462 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
463 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
464 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
465 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
466 0xc2, 0x3f, 0x45, 0x98 },
467 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
468 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
469 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
470 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
471 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
472 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
473 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
474 0x4c, 0x34, 0xae, 0xe5 },
475 { 0x00 },
476 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
477 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
478 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
479 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
480 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
481 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
482 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
483 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
484 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
485 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
486 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
487 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
488 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
489 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
490 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
491 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
492 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
493 0xcc, 0xda, 0x27, 0x10 },
494 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
495 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
496 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
497 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
498 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
499 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
500 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
501 0xa0, 0xf0, 0x62, 0xf7 },
502 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
503 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
504 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
505 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
506 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
507 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
508 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
509 0xe9, 0xb7, 0x37, 0x3b },
510 { 0x00 },
511 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
512 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
513 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
514 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
515 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
516 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
517 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
518 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
519 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
520 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
521 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
522 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
523 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
524 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
525 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
526 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
527 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
528 0xbc, 0xc9, 0xf6, 0x62 },
529 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
530 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
531 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
532 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
533 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
534 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
535 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
536 0xf4, 0x7c, 0x9b, 0x1f },
537 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
538 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
539 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
540 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
541 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
542 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
543 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
544 0x44, 0xae, 0x7e, 0x3f },
545};
546
547unsigned char tag[MAX_TESTS * 3][16] =
548{
549 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
550 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
551 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
552 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
553 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
554 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
555 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
556 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
557 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
558 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
559 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
560 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
561 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
562 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
563 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
564 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
565 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
566 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
567 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
568 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
569 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
570 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
571 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
572 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
573 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
574 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
575 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
576 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
577 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
578 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
579 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
580 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
581 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
582 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
583 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
584 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
585};
586
587int gcm_self_test( int verbose )
588{
589 gcm_context ctx;
590 unsigned char buf[64];
591 unsigned char tag_buf[16];
592 int i, j, ret;
593
594 for( j = 0; j < 3; j++ )
595 {
596 int key_len = 128 + 64 * j;
597
598 for( i = 0; i < MAX_TESTS; i++ )
599 {
600 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
601 gcm_init( &ctx, key[key_index[i]], key_len );
602
603 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
604 pt_len[i],
605 iv[iv_index[i]], iv_len[i],
606 additional[add_index[i]], add_len[i],
607 pt[pt_index[i]], buf, 16, tag_buf );
608
609 if( ret != 0 ||
610 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
611 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
612 {
613 if( verbose != 0 )
614 printf( "failed\n" );
615
616 return( 1 );
617 }
618
619 if( verbose != 0 )
620 printf( "passed\n" );
621
622 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
623 gcm_init( &ctx, key[key_index[i]], key_len );
624
625 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
626 pt_len[i],
627 iv[iv_index[i]], iv_len[i],
628 additional[add_index[i]], add_len[i],
629 ct[j * 6 + i], buf, 16, tag_buf );
630
631 if( ret != 0 ||
632 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
633 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
634 {
635 if( verbose != 0 )
636 printf( "failed\n" );
637
638 return( 1 );
639 }
640
641 if( verbose != 0 )
642 printf( "passed\n" );
643 }
644 }
645
646 printf( "\n" );
647
648 return( 0 );
649}
650
651#endif
652
653#endif