blob: 04e9d5b5611faaf68a445e35df15ddf51e25a2fd [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
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200409void gcm_free( gcm_context *ctx )
410{
411 (void) cipher_free_ctx( &ctx->cipher_ctx );
412 memset( ctx, 0, sizeof( gcm_context ) );
413}
414
Paul Bakker89e80c92012-03-20 13:50:09 +0000415#if defined(POLARSSL_SELF_TEST)
416
417#include <stdio.h>
418
419/*
420 * GCM test vectors from:
421 *
422 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
423 */
424#define MAX_TESTS 6
425
426int key_index[MAX_TESTS] =
427 { 0, 0, 1, 1, 1, 1 };
428
429unsigned char key[MAX_TESTS][32] =
430{
431 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
435 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
436 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
437 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200438 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000439};
440
441size_t iv_len[MAX_TESTS] =
442 { 12, 12, 12, 12, 8, 60 };
443
444int iv_index[MAX_TESTS] =
445 { 0, 0, 1, 1, 1, 2 };
446
447unsigned char iv[MAX_TESTS][64] =
448{
449 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 0x00, 0x00, 0x00, 0x00 },
451 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
452 0xde, 0xca, 0xf8, 0x88 },
453 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200454 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000455 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200456 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000457 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200458 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000459 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200460 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000461};
462
463size_t add_len[MAX_TESTS] =
464 { 0, 0, 0, 20, 20, 20 };
465
466int add_index[MAX_TESTS] =
467 { 0, 0, 0, 1, 1, 1 };
468
469unsigned char additional[MAX_TESTS][64] =
470{
471 { 0x00 },
472 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200473 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000474 0xab, 0xad, 0xda, 0xd2 },
475};
476
477size_t pt_len[MAX_TESTS] =
478 { 0, 16, 64, 60, 60, 60 };
479
480int pt_index[MAX_TESTS] =
481 { 0, 0, 1, 1, 1, 1 };
482
483unsigned char pt[MAX_TESTS][64] =
484{
485 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
486 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
487 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
488 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
489 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
490 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
491 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
492 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
493 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
494 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
495};
496
497unsigned char ct[MAX_TESTS * 3][64] =
498{
499 { 0x00 },
500 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
501 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
502 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200503 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000504 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200505 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000506 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200507 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000508 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
509 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
510 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200511 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000512 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200513 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000514 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200515 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000516 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
517 0x3d, 0x58, 0xe0, 0x91 },
518 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200519 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000520 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200521 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000522 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200523 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000524 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
525 0xc2, 0x3f, 0x45, 0x98 },
526 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200527 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000528 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200529 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000530 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200531 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000532 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
533 0x4c, 0x34, 0xae, 0xe5 },
534 { 0x00 },
535 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200536 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000537 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200538 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000539 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200540 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000541 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200542 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000543 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
544 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
545 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200546 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000547 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200548 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
549 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
550 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000551 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200552 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000553 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200554 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000555 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200556 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000557 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200558 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000559 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200560 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000561 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200562 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000563 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200564 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000565 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200566 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000567 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200568 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000569 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200570 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
571 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
572 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
573 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
574 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
575 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
576 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
577 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
578 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
579 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
580 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
581 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
582 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
583 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
584 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
585 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
586 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
587 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000588 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200589 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000590 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200591 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000592 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200593 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000594 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200595 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000596 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200597 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000598 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200599 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000600 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200601 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000602 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200603 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000604};
605
606unsigned char tag[MAX_TESTS * 3][16] =
607{
608 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
609 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
610 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
611 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
612 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200613 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000614 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
615 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
616 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
617 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
618 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
619 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
620 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
621 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
622 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200623 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000624 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
625 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
626 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200627 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000628 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200629 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000630 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200631 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000632 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200633 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000634 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200635 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000636 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200637 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000638 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200639 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000640 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200641 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200643 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000644};
645
646int gcm_self_test( int verbose )
647{
648 gcm_context ctx;
649 unsigned char buf[64];
650 unsigned char tag_buf[16];
651 int i, j, ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200652 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000653
654 for( j = 0; j < 3; j++ )
655 {
656 int key_len = 128 + 64 * j;
657
658 for( i = 0; i < MAX_TESTS; i++ )
659 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200660 if( verbose != 0 )
661 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
662
Paul Bakker43aff2a2013-09-09 00:10:27 +0200663 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000664
665 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
666 pt_len[i],
667 iv[iv_index[i]], iv_len[i],
668 additional[add_index[i]], add_len[i],
669 pt[pt_index[i]], buf, 16, tag_buf );
670
671 if( ret != 0 ||
672 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
673 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
674 {
675 if( verbose != 0 )
676 printf( "failed\n" );
677
678 return( 1 );
679 }
680
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200681 gcm_free( &ctx );
682
Paul Bakker89e80c92012-03-20 13:50:09 +0000683 if( verbose != 0 )
684 printf( "passed\n" );
685
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200686 if( verbose != 0 )
687 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
688
Paul Bakker43aff2a2013-09-09 00:10:27 +0200689 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000690
691 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
692 pt_len[i],
693 iv[iv_index[i]], iv_len[i],
694 additional[add_index[i]], add_len[i],
695 ct[j * 6 + i], buf, 16, tag_buf );
696
697 if( ret != 0 ||
698 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
699 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
700 {
701 if( verbose != 0 )
702 printf( "failed\n" );
703
704 return( 1 );
705 }
706
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200707 gcm_free( &ctx );
708
Paul Bakker89e80c92012-03-20 13:50:09 +0000709 if( verbose != 0 )
710 printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200711
712 if( verbose != 0 )
713 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" );
714
Paul Bakker43aff2a2013-09-09 00:10:27 +0200715 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200716
717 ret = gcm_starts( &ctx, GCM_ENCRYPT,
718 iv[iv_index[i]], iv_len[i],
719 additional[add_index[i]], add_len[i] );
720 if( ret != 0 )
721 {
722 if( verbose != 0 )
723 printf( "failed\n" );
724
725 return( 1 );
726 }
727
728 if( pt_len[i] > 32 )
729 {
730 size_t rest_len = pt_len[i] - 32;
731 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
732 if( ret != 0 )
733 {
734 if( verbose != 0 )
735 printf( "failed\n" );
736
737 return( 1 );
738 }
739
740 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
741 if( ret != 0 )
742 {
743 if( verbose != 0 )
744 printf( "failed\n" );
745
746 return( 1 );
747 }
748 }
749 else
750 {
751 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
752 if( ret != 0 )
753 {
754 if( verbose != 0 )
755 printf( "failed\n" );
756
757 return( 1 );
758 }
759 }
760
761 ret = gcm_finish( &ctx, tag_buf, 16 );
762 if( ret != 0 ||
763 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
764 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
765 {
766 if( verbose != 0 )
767 printf( "failed\n" );
768
769 return( 1 );
770 }
771
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200772 gcm_free( &ctx );
773
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200774 if( verbose != 0 )
775 printf( "passed\n" );
776
777 if( verbose != 0 )
778 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" );
779
Paul Bakker43aff2a2013-09-09 00:10:27 +0200780 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200781
782 ret = gcm_starts( &ctx, GCM_DECRYPT,
783 iv[iv_index[i]], iv_len[i],
784 additional[add_index[i]], add_len[i] );
785 if( ret != 0 )
786 {
787 if( verbose != 0 )
788 printf( "failed\n" );
789
790 return( 1 );
791 }
792
793 if( pt_len[i] > 32 )
794 {
795 size_t rest_len = pt_len[i] - 32;
796 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
797 if( ret != 0 )
798 {
799 if( verbose != 0 )
800 printf( "failed\n" );
801
802 return( 1 );
803 }
804
805 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
806 if( ret != 0 )
807 {
808 if( verbose != 0 )
809 printf( "failed\n" );
810
811 return( 1 );
812 }
813 }
814 else
815 {
816 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
817 if( ret != 0 )
818 {
819 if( verbose != 0 )
820 printf( "failed\n" );
821
822 return( 1 );
823 }
824 }
825
826 ret = gcm_finish( &ctx, tag_buf, 16 );
827 if( ret != 0 ||
828 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
829 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
830 {
831 if( verbose != 0 )
832 printf( "failed\n" );
833
834 return( 1 );
835 }
836
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200837 gcm_free( &ctx );
838
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200839 if( verbose != 0 )
840 printf( "passed\n" );
841
Paul Bakker89e80c92012-03-20 13:50:09 +0000842 }
843 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200844
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200845 if( verbose != 0 )
846 printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000847
848 return( 0 );
849}
850
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200851
852
Paul Bakker89e80c92012-03-20 13:50:09 +0000853#endif
854
855#endif