blob: f0bacc618131b744e80ea05d1b14c5ec1529ba75 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02004 * Copyright (C) 2006-2013, Brainspark B.V.
Paul Bakker89e80c92012-03-20 13:50:09 +00005 *
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];
Paul Bakker169b7f42013-06-25 14:58:00 +020063
Paul Bakker89e80c92012-03-20 13:50:09 +000064 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;
Paul Bakker169b7f42013-06-25 14:58:00 +020077
Paul Bakker89e80c92012-03-20 13:50:09 +000078 ctx->HL[8] = vl;
79 ctx->HH[8] = vh;
80
81 for( i = 4; i > 0; i >>= 1 )
82 {
Paul Bakker0ecdb232013-04-09 11:36:42 +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 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000102}
103
104int gcm_init( gcm_context *ctx, const unsigned char *key, unsigned int keysize )
105{
106 int ret;
107
108 memset( ctx, 0, sizeof(gcm_context) );
109
110 if( ( ret = aes_setkey_enc( &ctx->aes_ctx, key, keysize ) ) != 0 )
111 return( ret );
112
113 gcm_gen_table( ctx );
114
115 return( 0 );
116}
117
118static const uint64_t last4[16] =
119{
120 0x0000, 0x1c20, 0x3840, 0x2460,
121 0x7080, 0x6ca0, 0x48c0, 0x54e0,
122 0xe100, 0xfd20, 0xd940, 0xc560,
123 0x9180, 0x8da0, 0xa9c0, 0xb5e0
124};
125
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200126static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
127 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000128{
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
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200172int gcm_starts( gcm_context *ctx,
173 int mode,
174 const unsigned char *iv,
175 size_t iv_len,
176 const unsigned char *add,
177 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000178{
Paul Bakker89e80c92012-03-20 13:50:09 +0000179 unsigned char work_buf[16];
180 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000181 const unsigned char *p;
Paul Bakker89e80c92012-03-20 13:50:09 +0000182 size_t use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000183
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200184 ctx->mode = mode;
Paul Bakker89e80c92012-03-20 13:50:09 +0000185
186 if( iv_len == 12 )
187 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200188 memcpy( ctx->y, iv, iv_len );
189 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000190 }
191 else
192 {
193 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000194 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000195
196 p = iv;
197 while( iv_len > 0 )
198 {
199 use_len = ( iv_len < 16 ) ? iv_len : 16;
200
Paul Bakker67f9d532012-10-23 11:49:05 +0000201 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200202 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200203
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200204 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000205
206 iv_len -= use_len;
207 p += use_len;
208 }
209
Paul Bakker67f9d532012-10-23 11:49:05 +0000210 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200211 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000212
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200213 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000214 }
215
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200216 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->y, ctx->base_ectr );
Paul Bakker89e80c92012-03-20 13:50:09 +0000217
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200218 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000219 p = add;
220 while( add_len > 0 )
221 {
222 use_len = ( add_len < 16 ) ? add_len : 16;
223
Paul Bakker67f9d532012-10-23 11:49:05 +0000224 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200225 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200226
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200227 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000228
229 add_len -= use_len;
230 p += use_len;
231 }
232
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200233 return( 0 );
234}
235
236int gcm_update( gcm_context *ctx,
237 size_t length,
238 const unsigned char *input,
239 unsigned char *output )
240{
241 unsigned char ectr[16];
242 size_t i;
243 const unsigned char *p;
244 unsigned char *out_p = output;
245 size_t use_len;
246
247 if( output > input && (size_t) ( output - input ) < length )
248 return( POLARSSL_ERR_GCM_BAD_INPUT );
249
250 ctx->len += length;
251
Paul Bakker89e80c92012-03-20 13:50:09 +0000252 p = input;
253 while( length > 0 )
254 {
255 use_len = ( length < 16 ) ? length : 16;
256
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100257 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200258 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000259 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000260
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200261 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->y, ectr );
Paul Bakker89e80c92012-03-20 13:50:09 +0000262
Paul Bakker67f9d532012-10-23 11:49:05 +0000263 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000264 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200265 if( ctx->mode == GCM_DECRYPT )
266 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000267 out_p[i] = ectr[i] ^ p[i];
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200268 if( ctx->mode == GCM_ENCRYPT )
269 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000270 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200271
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200272 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200273
Paul Bakker89e80c92012-03-20 13:50:09 +0000274 length -= use_len;
275 p += use_len;
276 out_p += use_len;
277 }
278
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200279 return( 0 );
280}
281
282int gcm_finish( gcm_context *ctx,
283 unsigned char *tag,
284 size_t tag_len )
285{
286 unsigned char work_buf[16];
287 size_t i;
288 uint64_t orig_len = ctx->len * 8;
289 uint64_t orig_add_len = ctx->add_len * 8;
290
291 memcpy( tag, ctx->base_ectr, tag_len );
292
293 if( tag_len > 16 )
294 return( POLARSSL_ERR_GCM_BAD_INPUT );
295
Paul Bakker89e80c92012-03-20 13:50:09 +0000296 if( orig_len || orig_add_len )
297 {
298 memset( work_buf, 0x00, 16 );
299
Paul Bakker0ecdb232013-04-09 11:36:42 +0200300 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
301 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
302 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
303 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000304
Paul Bakker67f9d532012-10-23 11:49:05 +0000305 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200306 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000307
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200308 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000309
Paul Bakker67f9d532012-10-23 11:49:05 +0000310 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200311 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000312 }
313
314 return( 0 );
315}
316
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200317int gcm_crypt_and_tag( gcm_context *ctx,
318 int mode,
319 size_t length,
320 const unsigned char *iv,
321 size_t iv_len,
322 const unsigned char *add,
323 size_t add_len,
324 const unsigned char *input,
325 unsigned char *output,
326 size_t tag_len,
327 unsigned char *tag )
328{
329 int ret;
330
331 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
332 return( ret );
333
334 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
335 return( ret );
336
337 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
338 return( ret );
339
340 return( 0 );
341}
342
Paul Bakker89e80c92012-03-20 13:50:09 +0000343int gcm_auth_decrypt( gcm_context *ctx,
344 size_t length,
345 const unsigned char *iv,
346 size_t iv_len,
347 const unsigned char *add,
348 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200349 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000350 size_t tag_len,
351 const unsigned char *input,
352 unsigned char *output )
353{
354 unsigned char check_tag[16];
355
356 gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
357
358 if( memcmp( check_tag, tag, tag_len ) == 0 )
359 return( 0 );
360
361 memset( output, 0, length );
362
363 return( POLARSSL_ERR_GCM_AUTH_FAILED );
364}
365
366#if defined(POLARSSL_SELF_TEST)
367
368#include <stdio.h>
369
370/*
371 * GCM test vectors from:
372 *
373 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
374 */
375#define MAX_TESTS 6
376
377int key_index[MAX_TESTS] =
378 { 0, 0, 1, 1, 1, 1 };
379
380unsigned char key[MAX_TESTS][32] =
381{
382 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
386 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
387 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
388 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200389 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000390};
391
392size_t iv_len[MAX_TESTS] =
393 { 12, 12, 12, 12, 8, 60 };
394
395int iv_index[MAX_TESTS] =
396 { 0, 0, 1, 1, 1, 2 };
397
398unsigned char iv[MAX_TESTS][64] =
399{
400 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00 },
402 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
403 0xde, 0xca, 0xf8, 0x88 },
404 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200405 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000406 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200407 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000408 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200409 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000410 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200411 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000412};
413
414size_t add_len[MAX_TESTS] =
415 { 0, 0, 0, 20, 20, 20 };
416
417int add_index[MAX_TESTS] =
418 { 0, 0, 0, 1, 1, 1 };
419
420unsigned char additional[MAX_TESTS][64] =
421{
422 { 0x00 },
423 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200424 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000425 0xab, 0xad, 0xda, 0xd2 },
426};
427
428size_t pt_len[MAX_TESTS] =
429 { 0, 16, 64, 60, 60, 60 };
430
431int pt_index[MAX_TESTS] =
432 { 0, 0, 1, 1, 1, 1 };
433
434unsigned char pt[MAX_TESTS][64] =
435{
436 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
437 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
438 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
439 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
440 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
441 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
442 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
443 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
444 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
445 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
446};
447
448unsigned char ct[MAX_TESTS * 3][64] =
449{
450 { 0x00 },
451 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
452 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
453 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200454 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000455 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200456 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000457 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200458 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000459 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
460 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
461 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200462 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000463 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200464 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000465 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200466 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000467 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
468 0x3d, 0x58, 0xe0, 0x91 },
469 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200470 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000471 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200472 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000473 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200474 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000475 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
476 0xc2, 0x3f, 0x45, 0x98 },
477 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200478 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000479 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200480 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000481 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200482 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000483 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
484 0x4c, 0x34, 0xae, 0xe5 },
485 { 0x00 },
486 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200487 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000488 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200489 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000490 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200491 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000492 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200493 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000494 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
495 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
496 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200497 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000498 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200499 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
500 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
501 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000502 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200503 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000504 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200505 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000506 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200507 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000508 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200509 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000510 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200511 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000512 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200513 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000514 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200515 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000516 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200517 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000518 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200519 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000520 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200521 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
522 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
523 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
524 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
525 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
526 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
527 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
528 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
529 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
530 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
531 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
532 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
533 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
534 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
535 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
536 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
537 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
538 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000539 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200540 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000541 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200542 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000543 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200544 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000545 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200546 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000547 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200548 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000549 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200550 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000551 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200552 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000553 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200554 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000555};
556
557unsigned char tag[MAX_TESTS * 3][16] =
558{
559 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
560 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
561 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
562 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
563 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200564 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000565 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
566 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
567 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
568 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
569 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
570 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
571 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
572 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
573 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200574 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000575 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
576 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
577 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200578 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000579 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200580 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000581 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200582 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000583 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200584 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000585 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200586 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000587 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200588 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000589 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200590 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000591 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200592 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000593 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200594 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000595};
596
597int gcm_self_test( int verbose )
598{
599 gcm_context ctx;
600 unsigned char buf[64];
601 unsigned char tag_buf[16];
602 int i, j, ret;
603
604 for( j = 0; j < 3; j++ )
605 {
606 int key_len = 128 + 64 * j;
607
608 for( i = 0; i < MAX_TESTS; i++ )
609 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200610 if( verbose != 0 )
611 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
612
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 gcm_init( &ctx, key[key_index[i]], key_len );
614
615 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
616 pt_len[i],
617 iv[iv_index[i]], iv_len[i],
618 additional[add_index[i]], add_len[i],
619 pt[pt_index[i]], buf, 16, tag_buf );
620
621 if( ret != 0 ||
622 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
623 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
624 {
625 if( verbose != 0 )
626 printf( "failed\n" );
627
628 return( 1 );
629 }
630
631 if( verbose != 0 )
632 printf( "passed\n" );
633
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200634 if( verbose != 0 )
635 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
636
Paul Bakker89e80c92012-03-20 13:50:09 +0000637 gcm_init( &ctx, key[key_index[i]], key_len );
638
639 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
640 pt_len[i],
641 iv[iv_index[i]], iv_len[i],
642 additional[add_index[i]], add_len[i],
643 ct[j * 6 + i], buf, 16, tag_buf );
644
645 if( ret != 0 ||
646 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
647 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
648 {
649 if( verbose != 0 )
650 printf( "failed\n" );
651
652 return( 1 );
653 }
654
655 if( verbose != 0 )
656 printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200657
658 if( verbose != 0 )
659 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" );
660
661 gcm_init( &ctx, key[key_index[i]], key_len );
662
663 ret = gcm_starts( &ctx, GCM_ENCRYPT,
664 iv[iv_index[i]], iv_len[i],
665 additional[add_index[i]], add_len[i] );
666 if( ret != 0 )
667 {
668 if( verbose != 0 )
669 printf( "failed\n" );
670
671 return( 1 );
672 }
673
674 if( pt_len[i] > 32 )
675 {
676 size_t rest_len = pt_len[i] - 32;
677 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
678 if( ret != 0 )
679 {
680 if( verbose != 0 )
681 printf( "failed\n" );
682
683 return( 1 );
684 }
685
686 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
687 if( ret != 0 )
688 {
689 if( verbose != 0 )
690 printf( "failed\n" );
691
692 return( 1 );
693 }
694 }
695 else
696 {
697 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
698 if( ret != 0 )
699 {
700 if( verbose != 0 )
701 printf( "failed\n" );
702
703 return( 1 );
704 }
705 }
706
707 ret = gcm_finish( &ctx, tag_buf, 16 );
708 if( ret != 0 ||
709 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
710 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
711 {
712 if( verbose != 0 )
713 printf( "failed\n" );
714
715 return( 1 );
716 }
717
718 if( verbose != 0 )
719 printf( "passed\n" );
720
721 if( verbose != 0 )
722 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" );
723
724 gcm_init( &ctx, key[key_index[i]], key_len );
725
726 ret = gcm_starts( &ctx, GCM_DECRYPT,
727 iv[iv_index[i]], iv_len[i],
728 additional[add_index[i]], add_len[i] );
729 if( ret != 0 )
730 {
731 if( verbose != 0 )
732 printf( "failed\n" );
733
734 return( 1 );
735 }
736
737 if( pt_len[i] > 32 )
738 {
739 size_t rest_len = pt_len[i] - 32;
740 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
741 if( ret != 0 )
742 {
743 if( verbose != 0 )
744 printf( "failed\n" );
745
746 return( 1 );
747 }
748
749 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
750 if( ret != 0 )
751 {
752 if( verbose != 0 )
753 printf( "failed\n" );
754
755 return( 1 );
756 }
757 }
758 else
759 {
760 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
761 if( ret != 0 )
762 {
763 if( verbose != 0 )
764 printf( "failed\n" );
765
766 return( 1 );
767 }
768 }
769
770 ret = gcm_finish( &ctx, tag_buf, 16 );
771 if( ret != 0 ||
772 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
773 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
774 {
775 if( verbose != 0 )
776 printf( "failed\n" );
777
778 return( 1 );
779 }
780
781 if( verbose != 0 )
782 printf( "passed\n" );
783
Paul Bakker89e80c92012-03-20 13:50:09 +0000784 }
785 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200786
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200787 if( verbose != 0 )
788 printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000789
790 return( 0 );
791}
792
793#endif
794
795#endif