blob: 3e9969d3b0903d4c55b1b9ae50c8775e063c0f5a [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 Bakker52cf16c2013-07-26 13:55:38 +0200184 memset( ctx->y, 0x00, sizeof(ctx->y) );
185 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
186
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200187 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200188 ctx->len = 0;
189 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000190
191 if( iv_len == 12 )
192 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200193 memcpy( ctx->y, iv, iv_len );
194 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000195 }
196 else
197 {
198 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000199 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000200
201 p = iv;
202 while( iv_len > 0 )
203 {
204 use_len = ( iv_len < 16 ) ? iv_len : 16;
205
Paul Bakker67f9d532012-10-23 11:49:05 +0000206 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200207 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200208
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200209 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000210
211 iv_len -= use_len;
212 p += use_len;
213 }
214
Paul Bakker67f9d532012-10-23 11:49:05 +0000215 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200216 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000217
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200218 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000219 }
220
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200221 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->y, ctx->base_ectr );
Paul Bakker89e80c92012-03-20 13:50:09 +0000222
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200223 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000224 p = add;
225 while( add_len > 0 )
226 {
227 use_len = ( add_len < 16 ) ? add_len : 16;
228
Paul Bakker67f9d532012-10-23 11:49:05 +0000229 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200230 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200231
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200232 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000233
234 add_len -= use_len;
235 p += use_len;
236 }
237
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200238 return( 0 );
239}
240
241int gcm_update( gcm_context *ctx,
242 size_t length,
243 const unsigned char *input,
244 unsigned char *output )
245{
246 unsigned char ectr[16];
247 size_t i;
248 const unsigned char *p;
249 unsigned char *out_p = output;
250 size_t use_len;
251
252 if( output > input && (size_t) ( output - input ) < length )
253 return( POLARSSL_ERR_GCM_BAD_INPUT );
254
255 ctx->len += length;
256
Paul Bakker89e80c92012-03-20 13:50:09 +0000257 p = input;
258 while( length > 0 )
259 {
260 use_len = ( length < 16 ) ? length : 16;
261
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100262 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200263 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000264 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000265
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200266 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->y, ectr );
Paul Bakker89e80c92012-03-20 13:50:09 +0000267
Paul Bakker67f9d532012-10-23 11:49:05 +0000268 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000269 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200270 if( ctx->mode == GCM_DECRYPT )
271 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000272 out_p[i] = ectr[i] ^ p[i];
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200273 if( ctx->mode == GCM_ENCRYPT )
274 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000275 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200276
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200277 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200278
Paul Bakker89e80c92012-03-20 13:50:09 +0000279 length -= use_len;
280 p += use_len;
281 out_p += use_len;
282 }
283
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200284 return( 0 );
285}
286
287int gcm_finish( gcm_context *ctx,
288 unsigned char *tag,
289 size_t tag_len )
290{
291 unsigned char work_buf[16];
292 size_t i;
293 uint64_t orig_len = ctx->len * 8;
294 uint64_t orig_add_len = ctx->add_len * 8;
295
296 memcpy( tag, ctx->base_ectr, tag_len );
297
298 if( tag_len > 16 )
299 return( POLARSSL_ERR_GCM_BAD_INPUT );
300
Paul Bakker89e80c92012-03-20 13:50:09 +0000301 if( orig_len || orig_add_len )
302 {
303 memset( work_buf, 0x00, 16 );
304
Paul Bakker0ecdb232013-04-09 11:36:42 +0200305 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
306 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
307 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
308 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000309
Paul Bakker67f9d532012-10-23 11:49:05 +0000310 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200311 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000312
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200313 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000314
Paul Bakker67f9d532012-10-23 11:49:05 +0000315 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200316 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000317 }
318
319 return( 0 );
320}
321
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200322int gcm_crypt_and_tag( gcm_context *ctx,
323 int mode,
324 size_t length,
325 const unsigned char *iv,
326 size_t iv_len,
327 const unsigned char *add,
328 size_t add_len,
329 const unsigned char *input,
330 unsigned char *output,
331 size_t tag_len,
332 unsigned char *tag )
333{
334 int ret;
335
336 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
337 return( ret );
338
339 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
340 return( ret );
341
342 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
343 return( ret );
344
345 return( 0 );
346}
347
Paul Bakker89e80c92012-03-20 13:50:09 +0000348int gcm_auth_decrypt( gcm_context *ctx,
349 size_t length,
350 const unsigned char *iv,
351 size_t iv_len,
352 const unsigned char *add,
353 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200354 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000355 size_t tag_len,
356 const unsigned char *input,
357 unsigned char *output )
358{
359 unsigned char check_tag[16];
360
361 gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
362
363 if( memcmp( check_tag, tag, tag_len ) == 0 )
364 return( 0 );
365
366 memset( output, 0, length );
367
368 return( POLARSSL_ERR_GCM_AUTH_FAILED );
369}
370
371#if defined(POLARSSL_SELF_TEST)
372
373#include <stdio.h>
374
375/*
376 * GCM test vectors from:
377 *
378 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
379 */
380#define MAX_TESTS 6
381
382int key_index[MAX_TESTS] =
383 { 0, 0, 1, 1, 1, 1 };
384
385unsigned char key[MAX_TESTS][32] =
386{
387 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
391 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
392 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
393 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200394 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000395};
396
397size_t iv_len[MAX_TESTS] =
398 { 12, 12, 12, 12, 8, 60 };
399
400int iv_index[MAX_TESTS] =
401 { 0, 0, 1, 1, 1, 2 };
402
403unsigned char iv[MAX_TESTS][64] =
404{
405 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00 },
407 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
408 0xde, 0xca, 0xf8, 0x88 },
409 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200410 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000411 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200412 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000413 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200414 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000415 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200416 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000417};
418
419size_t add_len[MAX_TESTS] =
420 { 0, 0, 0, 20, 20, 20 };
421
422int add_index[MAX_TESTS] =
423 { 0, 0, 0, 1, 1, 1 };
424
425unsigned char additional[MAX_TESTS][64] =
426{
427 { 0x00 },
428 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200429 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000430 0xab, 0xad, 0xda, 0xd2 },
431};
432
433size_t pt_len[MAX_TESTS] =
434 { 0, 16, 64, 60, 60, 60 };
435
436int pt_index[MAX_TESTS] =
437 { 0, 0, 1, 1, 1, 1 };
438
439unsigned char pt[MAX_TESTS][64] =
440{
441 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
443 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
444 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
445 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
446 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
447 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
448 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
449 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
450 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
451};
452
453unsigned char ct[MAX_TESTS * 3][64] =
454{
455 { 0x00 },
456 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
457 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
458 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200459 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000460 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200461 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000462 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200463 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000464 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
465 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
466 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200467 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000468 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200469 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000470 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200471 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000472 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
473 0x3d, 0x58, 0xe0, 0x91 },
474 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200475 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000476 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200477 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000478 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200479 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000480 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
481 0xc2, 0x3f, 0x45, 0x98 },
482 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200483 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000484 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200485 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000486 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200487 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000488 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
489 0x4c, 0x34, 0xae, 0xe5 },
490 { 0x00 },
491 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200492 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000493 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200494 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000495 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200496 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000497 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200498 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000499 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
500 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
501 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200502 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000503 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200504 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
505 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
506 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000507 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200508 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000509 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200510 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000511 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200512 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000513 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200514 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000515 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200516 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000517 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200518 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000519 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200520 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000521 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200522 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000523 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200524 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000525 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200526 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
527 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
528 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
529 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
530 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
531 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
532 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
533 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
534 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
535 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
536 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
537 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
538 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
539 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
540 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
541 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
542 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
543 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000544 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200545 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000546 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200547 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000548 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200549 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000550 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200551 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000552 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200553 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000554 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200555 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000556 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200557 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000558 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200559 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000560};
561
562unsigned char tag[MAX_TESTS * 3][16] =
563{
564 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
565 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
566 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
567 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
568 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200569 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000570 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
571 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
572 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
573 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
574 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
575 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
576 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
577 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
578 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200579 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000580 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
581 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
582 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200583 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000584 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200585 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000586 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200587 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000588 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200589 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000590 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200591 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000592 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200593 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000594 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200595 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000596 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200597 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000598 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200599 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000600};
601
602int gcm_self_test( int verbose )
603{
604 gcm_context ctx;
605 unsigned char buf[64];
606 unsigned char tag_buf[16];
607 int i, j, ret;
608
609 for( j = 0; j < 3; j++ )
610 {
611 int key_len = 128 + 64 * j;
612
613 for( i = 0; i < MAX_TESTS; i++ )
614 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200615 if( verbose != 0 )
616 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
617
Paul Bakker89e80c92012-03-20 13:50:09 +0000618 gcm_init( &ctx, key[key_index[i]], key_len );
619
620 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
621 pt_len[i],
622 iv[iv_index[i]], iv_len[i],
623 additional[add_index[i]], add_len[i],
624 pt[pt_index[i]], buf, 16, tag_buf );
625
626 if( ret != 0 ||
627 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
628 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
629 {
630 if( verbose != 0 )
631 printf( "failed\n" );
632
633 return( 1 );
634 }
635
636 if( verbose != 0 )
637 printf( "passed\n" );
638
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200639 if( verbose != 0 )
640 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
641
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 gcm_init( &ctx, key[key_index[i]], key_len );
643
644 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
645 pt_len[i],
646 iv[iv_index[i]], iv_len[i],
647 additional[add_index[i]], add_len[i],
648 ct[j * 6 + i], buf, 16, tag_buf );
649
650 if( ret != 0 ||
651 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
652 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
653 {
654 if( verbose != 0 )
655 printf( "failed\n" );
656
657 return( 1 );
658 }
659
660 if( verbose != 0 )
661 printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200662
663 if( verbose != 0 )
664 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" );
665
666 gcm_init( &ctx, key[key_index[i]], key_len );
667
668 ret = gcm_starts( &ctx, GCM_ENCRYPT,
669 iv[iv_index[i]], iv_len[i],
670 additional[add_index[i]], add_len[i] );
671 if( ret != 0 )
672 {
673 if( verbose != 0 )
674 printf( "failed\n" );
675
676 return( 1 );
677 }
678
679 if( pt_len[i] > 32 )
680 {
681 size_t rest_len = pt_len[i] - 32;
682 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
683 if( ret != 0 )
684 {
685 if( verbose != 0 )
686 printf( "failed\n" );
687
688 return( 1 );
689 }
690
691 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
692 if( ret != 0 )
693 {
694 if( verbose != 0 )
695 printf( "failed\n" );
696
697 return( 1 );
698 }
699 }
700 else
701 {
702 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
703 if( ret != 0 )
704 {
705 if( verbose != 0 )
706 printf( "failed\n" );
707
708 return( 1 );
709 }
710 }
711
712 ret = gcm_finish( &ctx, tag_buf, 16 );
713 if( ret != 0 ||
714 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
715 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
716 {
717 if( verbose != 0 )
718 printf( "failed\n" );
719
720 return( 1 );
721 }
722
723 if( verbose != 0 )
724 printf( "passed\n" );
725
726 if( verbose != 0 )
727 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" );
728
729 gcm_init( &ctx, key[key_index[i]], key_len );
730
731 ret = gcm_starts( &ctx, GCM_DECRYPT,
732 iv[iv_index[i]], iv_len[i],
733 additional[add_index[i]], add_len[i] );
734 if( ret != 0 )
735 {
736 if( verbose != 0 )
737 printf( "failed\n" );
738
739 return( 1 );
740 }
741
742 if( pt_len[i] > 32 )
743 {
744 size_t rest_len = pt_len[i] - 32;
745 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
746 if( ret != 0 )
747 {
748 if( verbose != 0 )
749 printf( "failed\n" );
750
751 return( 1 );
752 }
753
754 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
755 if( ret != 0 )
756 {
757 if( verbose != 0 )
758 printf( "failed\n" );
759
760 return( 1 );
761 }
762 }
763 else
764 {
765 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
766 if( ret != 0 )
767 {
768 if( verbose != 0 )
769 printf( "failed\n" );
770
771 return( 1 );
772 }
773 }
774
775 ret = gcm_finish( &ctx, tag_buf, 16 );
776 if( ret != 0 ||
777 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
778 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
779 {
780 if( verbose != 0 )
781 printf( "failed\n" );
782
783 return( 1 );
784 }
785
786 if( verbose != 0 )
787 printf( "passed\n" );
788
Paul Bakker89e80c92012-03-20 13:50:09 +0000789 }
790 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200791
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200792 if( verbose != 0 )
793 printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000794
795 return( 0 );
796}
797
798#endif
799
800#endif