blob: 104fda3a49c9ebf5564611c9b2a7c093822d1ce3 [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é-Gonnard07f8fa52013-08-30 18:34:08 +0200299 memcpy( tag, ctx->base_ectr, tag_len );
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];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200360 size_t i;
361 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000362
363 gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
364
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200365 /* Check tag in "constant-time" */
366 for( diff = 0, i = 0; i < tag_len; i++ )
367 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000368
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200369 if( diff != 0 )
370 {
371 memset( output, 0, length );
372 return( POLARSSL_ERR_GCM_AUTH_FAILED );
373 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000374
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200375 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000376}
377
378#if defined(POLARSSL_SELF_TEST)
379
380#include <stdio.h>
381
382/*
383 * GCM test vectors from:
384 *
385 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
386 */
387#define MAX_TESTS 6
388
389int key_index[MAX_TESTS] =
390 { 0, 0, 1, 1, 1, 1 };
391
392unsigned char key[MAX_TESTS][32] =
393{
394 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
399 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
400 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200401 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000402};
403
404size_t iv_len[MAX_TESTS] =
405 { 12, 12, 12, 12, 8, 60 };
406
407int iv_index[MAX_TESTS] =
408 { 0, 0, 1, 1, 1, 2 };
409
410unsigned char iv[MAX_TESTS][64] =
411{
412 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0x00 },
414 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
415 0xde, 0xca, 0xf8, 0x88 },
416 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200417 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000418 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200419 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000420 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200421 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000422 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200423 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000424};
425
426size_t add_len[MAX_TESTS] =
427 { 0, 0, 0, 20, 20, 20 };
428
429int add_index[MAX_TESTS] =
430 { 0, 0, 0, 1, 1, 1 };
431
432unsigned char additional[MAX_TESTS][64] =
433{
434 { 0x00 },
435 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200436 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000437 0xab, 0xad, 0xda, 0xd2 },
438};
439
440size_t pt_len[MAX_TESTS] =
441 { 0, 16, 64, 60, 60, 60 };
442
443int pt_index[MAX_TESTS] =
444 { 0, 0, 1, 1, 1, 1 };
445
446unsigned char pt[MAX_TESTS][64] =
447{
448 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
450 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
451 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
452 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
453 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
454 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
455 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
456 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
457 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
458};
459
460unsigned char ct[MAX_TESTS * 3][64] =
461{
462 { 0x00 },
463 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
464 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
465 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200466 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000467 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200468 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000469 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200470 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000471 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
472 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
473 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200474 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000475 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200476 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000477 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200478 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000479 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
480 0x3d, 0x58, 0xe0, 0x91 },
481 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200482 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000483 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200484 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000485 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200486 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000487 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
488 0xc2, 0x3f, 0x45, 0x98 },
489 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200490 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000491 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200492 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000493 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200494 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000495 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
496 0x4c, 0x34, 0xae, 0xe5 },
497 { 0x00 },
498 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200499 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000500 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200501 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000502 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200503 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000504 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200505 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000506 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
507 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
508 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200509 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000510 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200511 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
512 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
513 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000514 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200515 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000516 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200517 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000518 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200519 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000520 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200521 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000522 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200523 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000524 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200525 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000526 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200527 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000528 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200529 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000530 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200531 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000532 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200533 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
534 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
535 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
536 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
537 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
538 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
539 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
540 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
541 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
542 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
543 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
544 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
545 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
546 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
547 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
548 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
549 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
550 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000551 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200552 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000553 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200554 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000555 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200556 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000557 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200558 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000559 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200560 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000561 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200562 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000563 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200564 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000565 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200566 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000567};
568
569unsigned char tag[MAX_TESTS * 3][16] =
570{
571 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
572 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
573 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
574 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
575 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200576 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000577 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
578 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
579 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
580 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
581 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
582 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
583 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
584 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
585 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200586 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000587 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
588 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
589 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200590 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000591 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200592 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000593 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200594 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000595 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200596 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000597 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200598 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000599 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200600 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000601 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200602 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000603 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200604 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000605 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200606 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000607};
608
609int gcm_self_test( int verbose )
610{
611 gcm_context ctx;
612 unsigned char buf[64];
613 unsigned char tag_buf[16];
614 int i, j, ret;
615
616 for( j = 0; j < 3; j++ )
617 {
618 int key_len = 128 + 64 * j;
619
620 for( i = 0; i < MAX_TESTS; i++ )
621 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200622 if( verbose != 0 )
623 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
624
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 gcm_init( &ctx, key[key_index[i]], key_len );
626
627 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
628 pt_len[i],
629 iv[iv_index[i]], iv_len[i],
630 additional[add_index[i]], add_len[i],
631 pt[pt_index[i]], buf, 16, tag_buf );
632
633 if( ret != 0 ||
634 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
635 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
636 {
637 if( verbose != 0 )
638 printf( "failed\n" );
639
640 return( 1 );
641 }
642
643 if( verbose != 0 )
644 printf( "passed\n" );
645
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200646 if( verbose != 0 )
647 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
648
Paul Bakker89e80c92012-03-20 13:50:09 +0000649 gcm_init( &ctx, key[key_index[i]], key_len );
650
651 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
652 pt_len[i],
653 iv[iv_index[i]], iv_len[i],
654 additional[add_index[i]], add_len[i],
655 ct[j * 6 + i], buf, 16, tag_buf );
656
657 if( ret != 0 ||
658 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
659 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
660 {
661 if( verbose != 0 )
662 printf( "failed\n" );
663
664 return( 1 );
665 }
666
667 if( verbose != 0 )
668 printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200669
670 if( verbose != 0 )
671 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" );
672
673 gcm_init( &ctx, key[key_index[i]], key_len );
674
675 ret = gcm_starts( &ctx, GCM_ENCRYPT,
676 iv[iv_index[i]], iv_len[i],
677 additional[add_index[i]], add_len[i] );
678 if( ret != 0 )
679 {
680 if( verbose != 0 )
681 printf( "failed\n" );
682
683 return( 1 );
684 }
685
686 if( pt_len[i] > 32 )
687 {
688 size_t rest_len = pt_len[i] - 32;
689 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
690 if( ret != 0 )
691 {
692 if( verbose != 0 )
693 printf( "failed\n" );
694
695 return( 1 );
696 }
697
698 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
699 if( ret != 0 )
700 {
701 if( verbose != 0 )
702 printf( "failed\n" );
703
704 return( 1 );
705 }
706 }
707 else
708 {
709 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
710 if( ret != 0 )
711 {
712 if( verbose != 0 )
713 printf( "failed\n" );
714
715 return( 1 );
716 }
717 }
718
719 ret = gcm_finish( &ctx, tag_buf, 16 );
720 if( ret != 0 ||
721 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
722 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
723 {
724 if( verbose != 0 )
725 printf( "failed\n" );
726
727 return( 1 );
728 }
729
730 if( verbose != 0 )
731 printf( "passed\n" );
732
733 if( verbose != 0 )
734 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" );
735
736 gcm_init( &ctx, key[key_index[i]], key_len );
737
738 ret = gcm_starts( &ctx, GCM_DECRYPT,
739 iv[iv_index[i]], iv_len[i],
740 additional[add_index[i]], add_len[i] );
741 if( ret != 0 )
742 {
743 if( verbose != 0 )
744 printf( "failed\n" );
745
746 return( 1 );
747 }
748
749 if( pt_len[i] > 32 )
750 {
751 size_t rest_len = pt_len[i] - 32;
752 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
753 if( ret != 0 )
754 {
755 if( verbose != 0 )
756 printf( "failed\n" );
757
758 return( 1 );
759 }
760
761 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
762 if( ret != 0 )
763 {
764 if( verbose != 0 )
765 printf( "failed\n" );
766
767 return( 1 );
768 }
769 }
770 else
771 {
772 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
773 if( ret != 0 )
774 {
775 if( verbose != 0 )
776 printf( "failed\n" );
777
778 return( 1 );
779 }
780 }
781
782 ret = gcm_finish( &ctx, tag_buf, 16 );
783 if( ret != 0 ||
784 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
785 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
786 {
787 if( verbose != 0 )
788 printf( "failed\n" );
789
790 return( 1 );
791 }
792
793 if( verbose != 0 )
794 printf( "passed\n" );
795
Paul Bakker89e80c92012-03-20 13:50:09 +0000796 }
797 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200798
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200799 if( verbose != 0 )
800 printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000801
802 return( 0 );
803}
804
805#endif
806
807#endif