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