blob: 1dfc1999d296b2169b344d03f43fa4280dcebdf7 [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
Paul Bakkera0558e02013-09-10 14:25:51 +0200120 if( cipher_info->block_size != 16 )
121 return( POLARSSL_ERR_GCM_BAD_INPUT );
122
Paul Bakker43aff2a2013-09-09 00:10:27 +0200123 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000124 return( ret );
125
Paul Bakker43aff2a2013-09-09 00:10:27 +0200126 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
127 POLARSSL_ENCRYPT ) ) != 0 )
128 {
129 return( ret );
130 }
131
132 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
133 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000134
135 return( 0 );
136}
137
138static const uint64_t last4[16] =
139{
140 0x0000, 0x1c20, 0x3840, 0x2460,
141 0x7080, 0x6ca0, 0x48c0, 0x54e0,
142 0xe100, 0xfd20, 0xd940, 0xc560,
143 0x9180, 0x8da0, 0xa9c0, 0xb5e0
144};
145
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200146static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
147 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000148{
149 int i = 0;
150 unsigned char z[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000151 unsigned char lo, hi, rem;
152 uint64_t zh, zl;
153
154 memset( z, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000155
156 lo = x[15] & 0xf;
157 hi = x[15] >> 4;
158
159 zh = ctx->HH[lo];
160 zl = ctx->HL[lo];
161
162 for( i = 15; i >= 0; i-- )
163 {
164 lo = x[i] & 0xf;
165 hi = x[i] >> 4;
166
167 if( i != 15 )
168 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000169 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000170 zl = ( zh << 60 ) | ( zl >> 4 );
171 zh = ( zh >> 4 );
172 zh ^= (uint64_t) last4[rem] << 48;
173 zh ^= ctx->HH[lo];
174 zl ^= ctx->HL[lo];
175
176 }
177
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000178 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000179 zl = ( zh << 60 ) | ( zl >> 4 );
180 zh = ( zh >> 4 );
181 zh ^= (uint64_t) last4[rem] << 48;
182 zh ^= ctx->HH[hi];
183 zl ^= ctx->HL[hi];
184 }
185
Paul Bakker5c2364c2012-10-01 14:41:15 +0000186 PUT_UINT32_BE( zh >> 32, output, 0 );
187 PUT_UINT32_BE( zh, output, 4 );
188 PUT_UINT32_BE( zl >> 32, output, 8 );
189 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000190}
191
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200192int gcm_starts( gcm_context *ctx,
193 int mode,
194 const unsigned char *iv,
195 size_t iv_len,
196 const unsigned char *add,
197 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000198{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200199 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000200 unsigned char work_buf[16];
201 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000202 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200203 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000204
Paul Bakker52cf16c2013-07-26 13:55:38 +0200205 memset( ctx->y, 0x00, sizeof(ctx->y) );
206 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
207
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200208 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200209 ctx->len = 0;
210 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000211
212 if( iv_len == 12 )
213 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200214 memcpy( ctx->y, iv, iv_len );
215 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000216 }
217 else
218 {
219 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000220 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000221
222 p = iv;
223 while( iv_len > 0 )
224 {
225 use_len = ( iv_len < 16 ) ? iv_len : 16;
226
Paul Bakker67f9d532012-10-23 11:49:05 +0000227 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200228 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200229
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200230 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000231
232 iv_len -= use_len;
233 p += use_len;
234 }
235
Paul Bakker67f9d532012-10-23 11:49:05 +0000236 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200237 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000238
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200239 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000240 }
241
Paul Bakker43aff2a2013-09-09 00:10:27 +0200242 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
243 &olen ) ) != 0 )
244 {
245 return( ret );
246 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000247
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200248 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000249 p = add;
250 while( add_len > 0 )
251 {
252 use_len = ( add_len < 16 ) ? add_len : 16;
253
Paul Bakker67f9d532012-10-23 11:49:05 +0000254 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200255 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200256
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200257 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000258
259 add_len -= use_len;
260 p += use_len;
261 }
262
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200263 return( 0 );
264}
265
266int gcm_update( gcm_context *ctx,
267 size_t length,
268 const unsigned char *input,
269 unsigned char *output )
270{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200271 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200272 unsigned char ectr[16];
273 size_t i;
274 const unsigned char *p;
275 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200276 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200277
278 if( output > input && (size_t) ( output - input ) < length )
279 return( POLARSSL_ERR_GCM_BAD_INPUT );
280
281 ctx->len += length;
282
Paul Bakker89e80c92012-03-20 13:50:09 +0000283 p = input;
284 while( length > 0 )
285 {
286 use_len = ( length < 16 ) ? length : 16;
287
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100288 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200289 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000290 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000291
Paul Bakker43aff2a2013-09-09 00:10:27 +0200292 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
293 &olen ) ) != 0 )
294 {
295 return( ret );
296 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000297
Paul Bakker67f9d532012-10-23 11:49:05 +0000298 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000299 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200300 if( ctx->mode == GCM_DECRYPT )
301 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000302 out_p[i] = ectr[i] ^ p[i];
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200303 if( ctx->mode == GCM_ENCRYPT )
304 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000305 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200306
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200307 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200308
Paul Bakker89e80c92012-03-20 13:50:09 +0000309 length -= use_len;
310 p += use_len;
311 out_p += use_len;
312 }
313
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200314 return( 0 );
315}
316
317int gcm_finish( gcm_context *ctx,
318 unsigned char *tag,
319 size_t tag_len )
320{
321 unsigned char work_buf[16];
322 size_t i;
323 uint64_t orig_len = ctx->len * 8;
324 uint64_t orig_add_len = ctx->add_len * 8;
325
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200326 if( tag_len > 16 )
327 return( POLARSSL_ERR_GCM_BAD_INPUT );
328
Manuel Pégourié-Gonnard9241be72013-08-31 17:31:03 +0200329 if( tag_len != 0 )
330 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200331
Paul Bakker89e80c92012-03-20 13:50:09 +0000332 if( orig_len || orig_add_len )
333 {
334 memset( work_buf, 0x00, 16 );
335
Paul Bakker0ecdb232013-04-09 11:36:42 +0200336 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
337 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
338 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
339 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000340
Paul Bakker67f9d532012-10-23 11:49:05 +0000341 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200342 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000343
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200344 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000345
Paul Bakker67f9d532012-10-23 11:49:05 +0000346 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200347 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000348 }
349
350 return( 0 );
351}
352
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200353int gcm_crypt_and_tag( gcm_context *ctx,
354 int mode,
355 size_t length,
356 const unsigned char *iv,
357 size_t iv_len,
358 const unsigned char *add,
359 size_t add_len,
360 const unsigned char *input,
361 unsigned char *output,
362 size_t tag_len,
363 unsigned char *tag )
364{
365 int ret;
366
367 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
368 return( ret );
369
370 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
371 return( ret );
372
373 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
374 return( ret );
375
376 return( 0 );
377}
378
Paul Bakker89e80c92012-03-20 13:50:09 +0000379int gcm_auth_decrypt( gcm_context *ctx,
380 size_t length,
381 const unsigned char *iv,
382 size_t iv_len,
383 const unsigned char *add,
384 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200385 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000386 size_t tag_len,
387 const unsigned char *input,
388 unsigned char *output )
389{
390 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200391 size_t i;
392 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000393
394 gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
395
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200396 /* Check tag in "constant-time" */
397 for( diff = 0, i = 0; i < tag_len; i++ )
398 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000399
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200400 if( diff != 0 )
401 {
402 memset( output, 0, length );
403 return( POLARSSL_ERR_GCM_AUTH_FAILED );
404 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000405
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200406 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000407}
408
409#if defined(POLARSSL_SELF_TEST)
410
411#include <stdio.h>
412
413/*
414 * GCM test vectors from:
415 *
416 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
417 */
418#define MAX_TESTS 6
419
420int key_index[MAX_TESTS] =
421 { 0, 0, 1, 1, 1, 1 };
422
423unsigned char key[MAX_TESTS][32] =
424{
425 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
429 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
430 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
431 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200432 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000433};
434
435size_t iv_len[MAX_TESTS] =
436 { 12, 12, 12, 12, 8, 60 };
437
438int iv_index[MAX_TESTS] =
439 { 0, 0, 1, 1, 1, 2 };
440
441unsigned char iv[MAX_TESTS][64] =
442{
443 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444 0x00, 0x00, 0x00, 0x00 },
445 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
446 0xde, 0xca, 0xf8, 0x88 },
447 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200448 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000449 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200450 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000451 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200452 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000453 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200454 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000455};
456
457size_t add_len[MAX_TESTS] =
458 { 0, 0, 0, 20, 20, 20 };
459
460int add_index[MAX_TESTS] =
461 { 0, 0, 0, 1, 1, 1 };
462
463unsigned char additional[MAX_TESTS][64] =
464{
465 { 0x00 },
466 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200467 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000468 0xab, 0xad, 0xda, 0xd2 },
469};
470
471size_t pt_len[MAX_TESTS] =
472 { 0, 16, 64, 60, 60, 60 };
473
474int pt_index[MAX_TESTS] =
475 { 0, 0, 1, 1, 1, 1 };
476
477unsigned char pt[MAX_TESTS][64] =
478{
479 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
481 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
482 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
483 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
484 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
485 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
486 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
487 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
488 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
489};
490
491unsigned char ct[MAX_TESTS * 3][64] =
492{
493 { 0x00 },
494 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
495 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
496 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200497 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000498 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200499 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000500 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200501 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000502 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
503 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
504 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200505 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000506 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200507 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000508 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200509 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000510 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
511 0x3d, 0x58, 0xe0, 0x91 },
512 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200513 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000514 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200515 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000516 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200517 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000518 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
519 0xc2, 0x3f, 0x45, 0x98 },
520 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200521 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000522 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200523 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000524 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200525 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000526 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
527 0x4c, 0x34, 0xae, 0xe5 },
528 { 0x00 },
529 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200530 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000531 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200532 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000533 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200534 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000535 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200536 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000537 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
538 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
539 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200540 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000541 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200542 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
543 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
544 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000545 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200546 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000547 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200548 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000549 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200550 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000551 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200552 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000553 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200554 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000555 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200556 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000557 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200558 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000559 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200560 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000561 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200562 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000563 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200564 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
565 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
566 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
567 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
568 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
569 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
570 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
571 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
572 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
573 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
574 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
575 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
576 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
577 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
578 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
579 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
580 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
581 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000582 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200583 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000584 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200585 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000586 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200587 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000588 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200589 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000590 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200591 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000592 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200593 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000594 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200595 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000596 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200597 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000598};
599
600unsigned char tag[MAX_TESTS * 3][16] =
601{
602 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
603 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
604 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
605 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
606 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200607 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000608 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
609 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
610 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
611 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
612 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
613 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
614 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
615 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
616 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200617 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000618 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
619 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
620 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200621 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000622 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200623 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000624 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200625 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000626 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200627 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000628 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200629 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000630 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200631 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000632 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200633 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000634 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200635 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000636 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200637 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000638};
639
640int gcm_self_test( int verbose )
641{
642 gcm_context ctx;
643 unsigned char buf[64];
644 unsigned char tag_buf[16];
645 int i, j, ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200646 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000647
648 for( j = 0; j < 3; j++ )
649 {
650 int key_len = 128 + 64 * j;
651
652 for( i = 0; i < MAX_TESTS; i++ )
653 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200654 if( verbose != 0 )
655 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
656
Paul Bakker43aff2a2013-09-09 00:10:27 +0200657 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000658
659 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
660 pt_len[i],
661 iv[iv_index[i]], iv_len[i],
662 additional[add_index[i]], add_len[i],
663 pt[pt_index[i]], buf, 16, tag_buf );
664
665 if( ret != 0 ||
666 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
667 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
668 {
669 if( verbose != 0 )
670 printf( "failed\n" );
671
672 return( 1 );
673 }
674
675 if( verbose != 0 )
676 printf( "passed\n" );
677
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200678 if( verbose != 0 )
679 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
680
Paul Bakker43aff2a2013-09-09 00:10:27 +0200681 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000682
683 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
684 pt_len[i],
685 iv[iv_index[i]], iv_len[i],
686 additional[add_index[i]], add_len[i],
687 ct[j * 6 + i], buf, 16, tag_buf );
688
689 if( ret != 0 ||
690 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
691 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
692 {
693 if( verbose != 0 )
694 printf( "failed\n" );
695
696 return( 1 );
697 }
698
699 if( verbose != 0 )
700 printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200701
702 if( verbose != 0 )
703 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" );
704
Paul Bakker43aff2a2013-09-09 00:10:27 +0200705 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200706
707 ret = gcm_starts( &ctx, GCM_ENCRYPT,
708 iv[iv_index[i]], iv_len[i],
709 additional[add_index[i]], add_len[i] );
710 if( ret != 0 )
711 {
712 if( verbose != 0 )
713 printf( "failed\n" );
714
715 return( 1 );
716 }
717
718 if( pt_len[i] > 32 )
719 {
720 size_t rest_len = pt_len[i] - 32;
721 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
722 if( ret != 0 )
723 {
724 if( verbose != 0 )
725 printf( "failed\n" );
726
727 return( 1 );
728 }
729
730 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
731 if( ret != 0 )
732 {
733 if( verbose != 0 )
734 printf( "failed\n" );
735
736 return( 1 );
737 }
738 }
739 else
740 {
741 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
742 if( ret != 0 )
743 {
744 if( verbose != 0 )
745 printf( "failed\n" );
746
747 return( 1 );
748 }
749 }
750
751 ret = gcm_finish( &ctx, tag_buf, 16 );
752 if( ret != 0 ||
753 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
754 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
755 {
756 if( verbose != 0 )
757 printf( "failed\n" );
758
759 return( 1 );
760 }
761
762 if( verbose != 0 )
763 printf( "passed\n" );
764
765 if( verbose != 0 )
766 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" );
767
Paul Bakker43aff2a2013-09-09 00:10:27 +0200768 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200769
770 ret = gcm_starts( &ctx, GCM_DECRYPT,
771 iv[iv_index[i]], iv_len[i],
772 additional[add_index[i]], add_len[i] );
773 if( ret != 0 )
774 {
775 if( verbose != 0 )
776 printf( "failed\n" );
777
778 return( 1 );
779 }
780
781 if( pt_len[i] > 32 )
782 {
783 size_t rest_len = pt_len[i] - 32;
784 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
785 if( ret != 0 )
786 {
787 if( verbose != 0 )
788 printf( "failed\n" );
789
790 return( 1 );
791 }
792
793 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
794 if( ret != 0 )
795 {
796 if( verbose != 0 )
797 printf( "failed\n" );
798
799 return( 1 );
800 }
801 }
802 else
803 {
804 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
805 if( ret != 0 )
806 {
807 if( verbose != 0 )
808 printf( "failed\n" );
809
810 return( 1 );
811 }
812 }
813
814 ret = gcm_finish( &ctx, tag_buf, 16 );
815 if( ret != 0 ||
816 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
817 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
818 {
819 if( verbose != 0 )
820 printf( "failed\n" );
821
822 return( 1 );
823 }
824
825 if( verbose != 0 )
826 printf( "passed\n" );
827
Paul Bakker89e80c92012-03-20 13:50:09 +0000828 }
829 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200830
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200831 if( verbose != 0 )
832 printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000833
834 return( 0 );
835}
836
837#endif
838
839#endif