blob: 68b6611e5be8f86507271507b39f156caf1eef2e [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 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000151 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000152 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
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000160 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000161 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
Paul Bakker67f9d532012-10-23 11:49:05 +0000229 for( i = 0; i < use_len; i++ )
230 y[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000231
232 gcm_mult( ctx, y, y );
233
234 iv_len -= use_len;
235 p += use_len;
236 }
237
Paul Bakker67f9d532012-10-23 11:49:05 +0000238 for( i = 0; i < 16; i++ )
239 y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000240
241 gcm_mult( ctx, y, y );
242 }
243
244 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
245 memcpy( tag, ectr, tag_len );
246
247 p = add;
248 while( add_len > 0 )
249 {
250 use_len = ( add_len < 16 ) ? add_len : 16;
251
Paul Bakker67f9d532012-10-23 11:49:05 +0000252 for( i = 0; i < use_len; i++ )
253 buf[i] ^= p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000254
255 gcm_mult( ctx, buf, buf );
256
257 add_len -= use_len;
258 p += use_len;
259 }
260
261 p = input;
262 while( length > 0 )
263 {
264 use_len = ( length < 16 ) ? length : 16;
265
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100266 for( i = 16; i > 12; i-- )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000267 if( ++y[i - 1] != 0 )
268 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000269
270 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
271
Paul Bakker67f9d532012-10-23 11:49:05 +0000272 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000273 {
Paul Bakker67f9d532012-10-23 11:49:05 +0000274 out_p[i] = ectr[i] ^ p[i];
275 buf[i] ^= (*xor_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 Bakker5c2364c2012-10-01 14:41:15 +0000289 PUT_UINT32_BE( orig_add_len , work_buf, 4 );
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