blob: 99036a05c70f739da5741f7b733300b3ff76d783 [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
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200296 if( tag_len > 16 )
297 return( POLARSSL_ERR_GCM_BAD_INPUT );
298
Manuel Pégourié-Gonnard9241be72013-08-31 17:31:03 +0200299 if( tag_len != 0 )
300 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200301
Paul Bakker89e80c92012-03-20 13:50:09 +0000302 if( orig_len || orig_add_len )
303 {
304 memset( work_buf, 0x00, 16 );
305
Paul Bakker0ecdb232013-04-09 11:36:42 +0200306 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
307 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
308 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
309 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000310
Paul Bakker67f9d532012-10-23 11:49:05 +0000311 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200312 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000313
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200314 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000315
Paul Bakker67f9d532012-10-23 11:49:05 +0000316 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200317 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000318 }
319
320 return( 0 );
321}
322
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200323int gcm_crypt_and_tag( gcm_context *ctx,
324 int mode,
325 size_t length,
326 const unsigned char *iv,
327 size_t iv_len,
328 const unsigned char *add,
329 size_t add_len,
330 const unsigned char *input,
331 unsigned char *output,
332 size_t tag_len,
333 unsigned char *tag )
334{
335 int ret;
336
337 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
338 return( ret );
339
340 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
341 return( ret );
342
343 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
344 return( ret );
345
346 return( 0 );
347}
348
Paul Bakker89e80c92012-03-20 13:50:09 +0000349int gcm_auth_decrypt( gcm_context *ctx,
350 size_t length,
351 const unsigned char *iv,
352 size_t iv_len,
353 const unsigned char *add,
354 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200355 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000356 size_t tag_len,
357 const unsigned char *input,
358 unsigned char *output )
359{
360 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200361 size_t i;
362 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000363
364 gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
365
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200366 /* Check tag in "constant-time" */
367 for( diff = 0, i = 0; i < tag_len; i++ )
368 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000369
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200370 if( diff != 0 )
371 {
372 memset( output, 0, length );
373 return( POLARSSL_ERR_GCM_AUTH_FAILED );
374 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000375
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200376 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000377}
378
379#if defined(POLARSSL_SELF_TEST)
380
381#include <stdio.h>
382
383/*
384 * GCM test vectors from:
385 *
386 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
387 */
388#define MAX_TESTS 6
389
390int key_index[MAX_TESTS] =
391 { 0, 0, 1, 1, 1, 1 };
392
393unsigned char key[MAX_TESTS][32] =
394{
395 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
399 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
400 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
401 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200402 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000403};
404
405size_t iv_len[MAX_TESTS] =
406 { 12, 12, 12, 12, 8, 60 };
407
408int iv_index[MAX_TESTS] =
409 { 0, 0, 1, 1, 1, 2 };
410
411unsigned char iv[MAX_TESTS][64] =
412{
413 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 0x00, 0x00, 0x00, 0x00 },
415 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
416 0xde, 0xca, 0xf8, 0x88 },
417 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200418 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000419 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200420 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000421 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200422 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000423 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200424 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000425};
426
427size_t add_len[MAX_TESTS] =
428 { 0, 0, 0, 20, 20, 20 };
429
430int add_index[MAX_TESTS] =
431 { 0, 0, 0, 1, 1, 1 };
432
433unsigned char additional[MAX_TESTS][64] =
434{
435 { 0x00 },
436 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200437 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000438 0xab, 0xad, 0xda, 0xd2 },
439};
440
441size_t pt_len[MAX_TESTS] =
442 { 0, 16, 64, 60, 60, 60 };
443
444int pt_index[MAX_TESTS] =
445 { 0, 0, 1, 1, 1, 1 };
446
447unsigned char pt[MAX_TESTS][64] =
448{
449 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
451 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
452 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
453 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
454 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
455 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
456 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
457 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
458 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
459};
460
461unsigned char ct[MAX_TESTS * 3][64] =
462{
463 { 0x00 },
464 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
465 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
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, 0x47, 0x3f, 0x59, 0x85 },
474 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200475 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000476 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200477 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000478 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200479 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000480 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
481 0x3d, 0x58, 0xe0, 0x91 },
482 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200483 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000484 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200485 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000486 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200487 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000488 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
489 0xc2, 0x3f, 0x45, 0x98 },
490 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200491 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000492 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200493 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000494 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200495 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000496 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
497 0x4c, 0x34, 0xae, 0xe5 },
498 { 0x00 },
499 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200500 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000501 { 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,
Paul Bakker89e80c92012-03-20 13:50:09 +0000505 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200506 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000507 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
508 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
509 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200510 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000511 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200512 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
513 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
514 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000515 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200516 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000517 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200518 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000519 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200520 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000521 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200522 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000523 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200524 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000525 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200526 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000527 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200528 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000529 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200530 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000531 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200532 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000533 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200534 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
535 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
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, 0x89, 0x80, 0x15, 0xad },
544 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
545 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
546 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
547 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
548 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
549 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
550 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
551 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000552 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200553 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000554 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200555 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000556 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200557 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000558 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200559 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000560 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200561 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000562 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200563 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000564 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200565 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000566 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200567 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000568};
569
570unsigned char tag[MAX_TESTS * 3][16] =
571{
572 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
573 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
574 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
575 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
576 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200577 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000578 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
579 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
580 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
581 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
582 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
583 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
584 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
585 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
586 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200587 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000588 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
589 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
590 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200591 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000592 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200593 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000594 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200595 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000596 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200597 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000598 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200599 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000600 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200601 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000602 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200603 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000604 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200605 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000606 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200607 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000608};
609
610int gcm_self_test( int verbose )
611{
612 gcm_context ctx;
613 unsigned char buf[64];
614 unsigned char tag_buf[16];
615 int i, j, ret;
616
617 for( j = 0; j < 3; j++ )
618 {
619 int key_len = 128 + 64 * j;
620
621 for( i = 0; i < MAX_TESTS; i++ )
622 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200623 if( verbose != 0 )
624 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
625
Paul Bakker89e80c92012-03-20 13:50:09 +0000626 gcm_init( &ctx, key[key_index[i]], key_len );
627
628 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
629 pt_len[i],
630 iv[iv_index[i]], iv_len[i],
631 additional[add_index[i]], add_len[i],
632 pt[pt_index[i]], buf, 16, tag_buf );
633
634 if( ret != 0 ||
635 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
636 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
637 {
638 if( verbose != 0 )
639 printf( "failed\n" );
640
641 return( 1 );
642 }
643
644 if( verbose != 0 )
645 printf( "passed\n" );
646
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200647 if( verbose != 0 )
648 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
649
Paul Bakker89e80c92012-03-20 13:50:09 +0000650 gcm_init( &ctx, key[key_index[i]], key_len );
651
652 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
653 pt_len[i],
654 iv[iv_index[i]], iv_len[i],
655 additional[add_index[i]], add_len[i],
656 ct[j * 6 + i], buf, 16, tag_buf );
657
658 if( ret != 0 ||
659 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
660 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
661 {
662 if( verbose != 0 )
663 printf( "failed\n" );
664
665 return( 1 );
666 }
667
668 if( verbose != 0 )
669 printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200670
671 if( verbose != 0 )
672 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" );
673
674 gcm_init( &ctx, key[key_index[i]], key_len );
675
676 ret = gcm_starts( &ctx, GCM_ENCRYPT,
677 iv[iv_index[i]], iv_len[i],
678 additional[add_index[i]], add_len[i] );
679 if( ret != 0 )
680 {
681 if( verbose != 0 )
682 printf( "failed\n" );
683
684 return( 1 );
685 }
686
687 if( pt_len[i] > 32 )
688 {
689 size_t rest_len = pt_len[i] - 32;
690 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
691 if( ret != 0 )
692 {
693 if( verbose != 0 )
694 printf( "failed\n" );
695
696 return( 1 );
697 }
698
699 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
700 if( ret != 0 )
701 {
702 if( verbose != 0 )
703 printf( "failed\n" );
704
705 return( 1 );
706 }
707 }
708 else
709 {
710 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
711 if( ret != 0 )
712 {
713 if( verbose != 0 )
714 printf( "failed\n" );
715
716 return( 1 );
717 }
718 }
719
720 ret = gcm_finish( &ctx, tag_buf, 16 );
721 if( ret != 0 ||
722 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
723 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
724 {
725 if( verbose != 0 )
726 printf( "failed\n" );
727
728 return( 1 );
729 }
730
731 if( verbose != 0 )
732 printf( "passed\n" );
733
734 if( verbose != 0 )
735 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" );
736
737 gcm_init( &ctx, key[key_index[i]], key_len );
738
739 ret = gcm_starts( &ctx, GCM_DECRYPT,
740 iv[iv_index[i]], iv_len[i],
741 additional[add_index[i]], add_len[i] );
742 if( ret != 0 )
743 {
744 if( verbose != 0 )
745 printf( "failed\n" );
746
747 return( 1 );
748 }
749
750 if( pt_len[i] > 32 )
751 {
752 size_t rest_len = pt_len[i] - 32;
753 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
754 if( ret != 0 )
755 {
756 if( verbose != 0 )
757 printf( "failed\n" );
758
759 return( 1 );
760 }
761
762 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
763 if( ret != 0 )
764 {
765 if( verbose != 0 )
766 printf( "failed\n" );
767
768 return( 1 );
769 }
770 }
771 else
772 {
773 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
774 if( ret != 0 )
775 {
776 if( verbose != 0 )
777 printf( "failed\n" );
778
779 return( 1 );
780 }
781 }
782
783 ret = gcm_finish( &ctx, tag_buf, 16 );
784 if( ret != 0 ||
785 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
786 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
787 {
788 if( verbose != 0 )
789 printf( "failed\n" );
790
791 return( 1 );
792 }
793
794 if( verbose != 0 )
795 printf( "passed\n" );
796
Paul Bakker89e80c92012-03-20 13:50:09 +0000797 }
798 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200799
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200800 if( verbose != 0 )
801 printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000802
803 return( 0 );
804}
805
806#endif
807
808#endif