blob: e041647d353941fa53d3e86508296a2cd09ce43f [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
Paul Bakker43aff2a2013-09-09 00:10:27 +020057static int gcm_gen_table( gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000058{
Paul Bakker43aff2a2013-09-09 00:10:27 +020059 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000060 uint64_t hi, lo;
61 uint64_t vl, vh;
62 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020063 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020064
Paul Bakker89e80c92012-03-20 13:50:09 +000065 memset( h, 0, 16 );
Paul Bakker43aff2a2013-09-09 00:10:27 +020066 if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
67 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000068
69 ctx->HH[0] = 0;
70 ctx->HL[0] = 0;
71
Paul Bakker5c2364c2012-10-01 14:41:15 +000072 GET_UINT32_BE( hi, h, 0 );
73 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000074 vh = (uint64_t) hi << 32 | lo;
75
Paul Bakker5c2364c2012-10-01 14:41:15 +000076 GET_UINT32_BE( hi, h, 8 );
77 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000078 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020079
Paul Bakker89e80c92012-03-20 13:50:09 +000080 ctx->HL[8] = vl;
81 ctx->HH[8] = vh;
82
83 for( i = 4; i > 0; i >>= 1 )
84 {
Paul Bakker0ecdb232013-04-09 11:36:42 +020085 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +000086 vl = ( vh << 63 ) | ( vl >> 1 );
87 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
88
89 ctx->HL[i] = vl;
90 ctx->HH[i] = vh;
91 }
92
93 for (i = 2; i < 16; i <<= 1 )
94 {
95 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
96 vh = *HiH;
97 vl = *HiL;
98 for( j = 1; j < i; j++ )
99 {
100 HiH[j] = vh ^ ctx->HH[j];
101 HiL[j] = vl ^ ctx->HL[j];
102 }
103 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200104
105 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000106}
107
Paul Bakker43aff2a2013-09-09 00:10:27 +0200108int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
109 unsigned int keysize )
Paul Bakker89e80c92012-03-20 13:50:09 +0000110{
111 int ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200112 const cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000113
114 memset( ctx, 0, sizeof(gcm_context) );
115
Paul Bakker43aff2a2013-09-09 00:10:27 +0200116 cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
117 if( cipher_info == NULL )
118 return( POLARSSL_ERR_GCM_BAD_INPUT );
119
120 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000121 return( ret );
122
Paul Bakker43aff2a2013-09-09 00:10:27 +0200123 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
124 POLARSSL_ENCRYPT ) ) != 0 )
125 {
126 return( ret );
127 }
128
129 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
130 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000131
132 return( 0 );
133}
134
135static const uint64_t last4[16] =
136{
137 0x0000, 0x1c20, 0x3840, 0x2460,
138 0x7080, 0x6ca0, 0x48c0, 0x54e0,
139 0xe100, 0xfd20, 0xd940, 0xc560,
140 0x9180, 0x8da0, 0xa9c0, 0xb5e0
141};
142
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200143static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
144 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000145{
146 int i = 0;
147 unsigned char z[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000148 unsigned char lo, hi, rem;
149 uint64_t zh, zl;
150
151 memset( z, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000152
153 lo = x[15] & 0xf;
154 hi = x[15] >> 4;
155
156 zh = ctx->HH[lo];
157 zl = ctx->HL[lo];
158
159 for( i = 15; i >= 0; i-- )
160 {
161 lo = x[i] & 0xf;
162 hi = x[i] >> 4;
163
164 if( i != 15 )
165 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000166 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000167 zl = ( zh << 60 ) | ( zl >> 4 );
168 zh = ( zh >> 4 );
169 zh ^= (uint64_t) last4[rem] << 48;
170 zh ^= ctx->HH[lo];
171 zl ^= ctx->HL[lo];
172
173 }
174
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000175 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000176 zl = ( zh << 60 ) | ( zl >> 4 );
177 zh = ( zh >> 4 );
178 zh ^= (uint64_t) last4[rem] << 48;
179 zh ^= ctx->HH[hi];
180 zl ^= ctx->HL[hi];
181 }
182
Paul Bakker5c2364c2012-10-01 14:41:15 +0000183 PUT_UINT32_BE( zh >> 32, output, 0 );
184 PUT_UINT32_BE( zh, output, 4 );
185 PUT_UINT32_BE( zl >> 32, output, 8 );
186 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000187}
188
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200189int gcm_starts( gcm_context *ctx,
190 int mode,
191 const unsigned char *iv,
192 size_t iv_len,
193 const unsigned char *add,
194 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000195{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200196 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000197 unsigned char work_buf[16];
198 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000199 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200200 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000201
Paul Bakker52cf16c2013-07-26 13:55:38 +0200202 memset( ctx->y, 0x00, sizeof(ctx->y) );
203 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
204
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200205 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200206 ctx->len = 0;
207 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000208
209 if( iv_len == 12 )
210 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200211 memcpy( ctx->y, iv, iv_len );
212 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000213 }
214 else
215 {
216 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000217 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000218
219 p = iv;
220 while( iv_len > 0 )
221 {
222 use_len = ( iv_len < 16 ) ? iv_len : 16;
223
Paul Bakker67f9d532012-10-23 11:49:05 +0000224 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200225 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200226
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200227 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000228
229 iv_len -= use_len;
230 p += use_len;
231 }
232
Paul Bakker67f9d532012-10-23 11:49:05 +0000233 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200234 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000235
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200236 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000237 }
238
Paul Bakker43aff2a2013-09-09 00:10:27 +0200239 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
240 &olen ) ) != 0 )
241 {
242 return( ret );
243 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000244
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200245 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000246 p = add;
247 while( add_len > 0 )
248 {
249 use_len = ( add_len < 16 ) ? add_len : 16;
250
Paul Bakker67f9d532012-10-23 11:49:05 +0000251 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200252 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200253
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200254 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000255
256 add_len -= use_len;
257 p += use_len;
258 }
259
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200260 return( 0 );
261}
262
263int gcm_update( gcm_context *ctx,
264 size_t length,
265 const unsigned char *input,
266 unsigned char *output )
267{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200268 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200269 unsigned char ectr[16];
270 size_t i;
271 const unsigned char *p;
272 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200273 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200274
275 if( output > input && (size_t) ( output - input ) < length )
276 return( POLARSSL_ERR_GCM_BAD_INPUT );
277
278 ctx->len += length;
279
Paul Bakker89e80c92012-03-20 13:50:09 +0000280 p = input;
281 while( length > 0 )
282 {
283 use_len = ( length < 16 ) ? length : 16;
284
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100285 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200286 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000287 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000288
Paul Bakker43aff2a2013-09-09 00:10:27 +0200289 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
290 &olen ) ) != 0 )
291 {
292 return( ret );
293 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000294
Paul Bakker67f9d532012-10-23 11:49:05 +0000295 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000296 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200297 if( ctx->mode == GCM_DECRYPT )
298 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000299 out_p[i] = ectr[i] ^ p[i];
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200300 if( ctx->mode == GCM_ENCRYPT )
301 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000302 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200303
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200304 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200305
Paul Bakker89e80c92012-03-20 13:50:09 +0000306 length -= use_len;
307 p += use_len;
308 out_p += use_len;
309 }
310
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200311 return( 0 );
312}
313
314int gcm_finish( gcm_context *ctx,
315 unsigned char *tag,
316 size_t tag_len )
317{
318 unsigned char work_buf[16];
319 size_t i;
320 uint64_t orig_len = ctx->len * 8;
321 uint64_t orig_add_len = ctx->add_len * 8;
322
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200323 if( tag_len > 16 )
324 return( POLARSSL_ERR_GCM_BAD_INPUT );
325
Manuel Pégourié-Gonnard9241be72013-08-31 17:31:03 +0200326 if( tag_len != 0 )
327 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200328
Paul Bakker89e80c92012-03-20 13:50:09 +0000329 if( orig_len || orig_add_len )
330 {
331 memset( work_buf, 0x00, 16 );
332
Paul Bakker0ecdb232013-04-09 11:36:42 +0200333 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
334 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
335 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
336 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000337
Paul Bakker67f9d532012-10-23 11:49:05 +0000338 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200339 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000340
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200341 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000342
Paul Bakker67f9d532012-10-23 11:49:05 +0000343 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200344 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000345 }
346
347 return( 0 );
348}
349
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200350int gcm_crypt_and_tag( gcm_context *ctx,
351 int mode,
352 size_t length,
353 const unsigned char *iv,
354 size_t iv_len,
355 const unsigned char *add,
356 size_t add_len,
357 const unsigned char *input,
358 unsigned char *output,
359 size_t tag_len,
360 unsigned char *tag )
361{
362 int ret;
363
364 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
365 return( ret );
366
367 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
368 return( ret );
369
370 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
371 return( ret );
372
373 return( 0 );
374}
375
Paul Bakker89e80c92012-03-20 13:50:09 +0000376int gcm_auth_decrypt( gcm_context *ctx,
377 size_t length,
378 const unsigned char *iv,
379 size_t iv_len,
380 const unsigned char *add,
381 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200382 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000383 size_t tag_len,
384 const unsigned char *input,
385 unsigned char *output )
386{
387 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200388 size_t i;
389 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000390
391 gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
392
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200393 /* Check tag in "constant-time" */
394 for( diff = 0, i = 0; i < tag_len; i++ )
395 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000396
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200397 if( diff != 0 )
398 {
399 memset( output, 0, length );
400 return( POLARSSL_ERR_GCM_AUTH_FAILED );
401 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000402
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200403 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000404}
405
406#if defined(POLARSSL_SELF_TEST)
407
408#include <stdio.h>
409
410/*
411 * GCM test vectors from:
412 *
413 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
414 */
415#define MAX_TESTS 6
416
417int key_index[MAX_TESTS] =
418 { 0, 0, 1, 1, 1, 1 };
419
420unsigned char key[MAX_TESTS][32] =
421{
422 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
426 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
427 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
428 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200429 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000430};
431
432size_t iv_len[MAX_TESTS] =
433 { 12, 12, 12, 12, 8, 60 };
434
435int iv_index[MAX_TESTS] =
436 { 0, 0, 1, 1, 1, 2 };
437
438unsigned char iv[MAX_TESTS][64] =
439{
440 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441 0x00, 0x00, 0x00, 0x00 },
442 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
443 0xde, 0xca, 0xf8, 0x88 },
444 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200445 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000446 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200447 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000448 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200449 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000450 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200451 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000452};
453
454size_t add_len[MAX_TESTS] =
455 { 0, 0, 0, 20, 20, 20 };
456
457int add_index[MAX_TESTS] =
458 { 0, 0, 0, 1, 1, 1 };
459
460unsigned char additional[MAX_TESTS][64] =
461{
462 { 0x00 },
463 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200464 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000465 0xab, 0xad, 0xda, 0xd2 },
466};
467
468size_t pt_len[MAX_TESTS] =
469 { 0, 16, 64, 60, 60, 60 };
470
471int pt_index[MAX_TESTS] =
472 { 0, 0, 1, 1, 1, 1 };
473
474unsigned char pt[MAX_TESTS][64] =
475{
476 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
478 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
479 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
480 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
481 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
482 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
483 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
484 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
485 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
486};
487
488unsigned char ct[MAX_TESTS * 3][64] =
489{
490 { 0x00 },
491 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
492 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
493 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200494 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000495 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200496 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000497 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200498 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000499 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
500 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
501 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200502 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000503 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200504 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000505 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200506 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000507 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
508 0x3d, 0x58, 0xe0, 0x91 },
509 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200510 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000511 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200512 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000513 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200514 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000515 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
516 0xc2, 0x3f, 0x45, 0x98 },
517 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200518 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000519 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200520 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000521 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200522 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000523 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
524 0x4c, 0x34, 0xae, 0xe5 },
525 { 0x00 },
526 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200527 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000528 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200529 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000530 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200531 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000532 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200533 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000534 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
535 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
536 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200537 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000538 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200539 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
540 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
541 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000542 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200543 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000544 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200545 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000546 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200547 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000548 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200549 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000550 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200551 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000552 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200553 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000554 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200555 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000556 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200557 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000558 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200559 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000560 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200561 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
562 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
563 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
564 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
565 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
566 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
567 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
568 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
569 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
570 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
571 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
572 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
573 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
574 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
575 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
576 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
577 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
578 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000579 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200580 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000581 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200582 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000583 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200584 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000585 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200586 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000587 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200588 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000589 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200590 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000591 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200592 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000593 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200594 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000595};
596
597unsigned char tag[MAX_TESTS * 3][16] =
598{
599 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
600 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
601 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
602 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
603 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200604 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000605 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
606 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
607 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
608 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
609 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
610 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
611 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
612 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
613 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200614 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
616 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
617 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200618 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000619 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200620 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000621 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200622 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000623 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200624 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200626 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000627 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200628 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000629 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200630 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000631 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200632 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000633 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200634 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000635};
636
637int gcm_self_test( int verbose )
638{
639 gcm_context ctx;
640 unsigned char buf[64];
641 unsigned char tag_buf[16];
642 int i, j, ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200643 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000644
645 for( j = 0; j < 3; j++ )
646 {
647 int key_len = 128 + 64 * j;
648
649 for( i = 0; i < MAX_TESTS; i++ )
650 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200651 if( verbose != 0 )
652 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
653
Paul Bakker43aff2a2013-09-09 00:10:27 +0200654 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000655
656 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
657 pt_len[i],
658 iv[iv_index[i]], iv_len[i],
659 additional[add_index[i]], add_len[i],
660 pt[pt_index[i]], buf, 16, tag_buf );
661
662 if( ret != 0 ||
663 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
664 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
665 {
666 if( verbose != 0 )
667 printf( "failed\n" );
668
669 return( 1 );
670 }
671
672 if( verbose != 0 )
673 printf( "passed\n" );
674
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200675 if( verbose != 0 )
676 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
677
Paul Bakker43aff2a2013-09-09 00:10:27 +0200678 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000679
680 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
681 pt_len[i],
682 iv[iv_index[i]], iv_len[i],
683 additional[add_index[i]], add_len[i],
684 ct[j * 6 + i], buf, 16, tag_buf );
685
686 if( ret != 0 ||
687 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
688 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
689 {
690 if( verbose != 0 )
691 printf( "failed\n" );
692
693 return( 1 );
694 }
695
696 if( verbose != 0 )
697 printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200698
699 if( verbose != 0 )
700 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" );
701
Paul Bakker43aff2a2013-09-09 00:10:27 +0200702 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200703
704 ret = gcm_starts( &ctx, GCM_ENCRYPT,
705 iv[iv_index[i]], iv_len[i],
706 additional[add_index[i]], add_len[i] );
707 if( ret != 0 )
708 {
709 if( verbose != 0 )
710 printf( "failed\n" );
711
712 return( 1 );
713 }
714
715 if( pt_len[i] > 32 )
716 {
717 size_t rest_len = pt_len[i] - 32;
718 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
719 if( ret != 0 )
720 {
721 if( verbose != 0 )
722 printf( "failed\n" );
723
724 return( 1 );
725 }
726
727 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
728 if( ret != 0 )
729 {
730 if( verbose != 0 )
731 printf( "failed\n" );
732
733 return( 1 );
734 }
735 }
736 else
737 {
738 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
739 if( ret != 0 )
740 {
741 if( verbose != 0 )
742 printf( "failed\n" );
743
744 return( 1 );
745 }
746 }
747
748 ret = gcm_finish( &ctx, tag_buf, 16 );
749 if( ret != 0 ||
750 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
751 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
752 {
753 if( verbose != 0 )
754 printf( "failed\n" );
755
756 return( 1 );
757 }
758
759 if( verbose != 0 )
760 printf( "passed\n" );
761
762 if( verbose != 0 )
763 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" );
764
Paul Bakker43aff2a2013-09-09 00:10:27 +0200765 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200766
767 ret = gcm_starts( &ctx, GCM_DECRYPT,
768 iv[iv_index[i]], iv_len[i],
769 additional[add_index[i]], add_len[i] );
770 if( ret != 0 )
771 {
772 if( verbose != 0 )
773 printf( "failed\n" );
774
775 return( 1 );
776 }
777
778 if( pt_len[i] > 32 )
779 {
780 size_t rest_len = pt_len[i] - 32;
781 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
782 if( ret != 0 )
783 {
784 if( verbose != 0 )
785 printf( "failed\n" );
786
787 return( 1 );
788 }
789
790 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
791 if( ret != 0 )
792 {
793 if( verbose != 0 )
794 printf( "failed\n" );
795
796 return( 1 );
797 }
798 }
799 else
800 {
801 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
802 if( ret != 0 )
803 {
804 if( verbose != 0 )
805 printf( "failed\n" );
806
807 return( 1 );
808 }
809 }
810
811 ret = gcm_finish( &ctx, tag_buf, 16 );
812 if( ret != 0 ||
813 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
814 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
815 {
816 if( verbose != 0 )
817 printf( "failed\n" );
818
819 return( 1 );
820 }
821
822 if( verbose != 0 )
823 printf( "passed\n" );
824
Paul Bakker89e80c92012-03-20 13:50:09 +0000825 }
826 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200827
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200828 if( verbose != 0 )
829 printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000830
831 return( 0 );
832}
833
834#endif
835
836#endif