blob: 7374dca71d3710db671f66bd8b06487b212ed493 [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 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010025
Paul Bakker89e80c92012-03-20 13:50:09 +000026/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010027 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
28 *
29 * See also:
30 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
31 *
32 * We use the algorithm described as Shoup's method with 4-bit tables in
33 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000034 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010035
Paul Bakker89e80c92012-03-20 13:50:09 +000036#include "polarssl/config.h"
37
38#if defined(POLARSSL_GCM_C)
39
40#include "polarssl/gcm.h"
41
42/*
43 * 32-bit integer manipulation macros (big endian)
44 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000045#ifndef GET_UINT32_BE
46#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000047{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000048 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
49 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
50 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
51 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000052}
53#endif
54
Paul Bakker5c2364c2012-10-01 14:41:15 +000055#ifndef PUT_UINT32_BE
56#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000057{ \
58 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
59 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
60 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
61 (b)[(i) + 3] = (unsigned char) ( (n) ); \
62}
63#endif
64
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010065/*
66 * Precompute small multiples of H, that is set
67 * HH[i] || HL[i] = H times i,
68 * where i is seen as a field element as in [MGV], ie high-order bits
69 * correspond to low powers of P. The result is stored in the same way, that
70 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
71 * corresponds to P^127.
72 */
Paul Bakker43aff2a2013-09-09 00:10:27 +020073static int gcm_gen_table( gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000074{
Paul Bakker43aff2a2013-09-09 00:10:27 +020075 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000076 uint64_t hi, lo;
77 uint64_t vl, vh;
78 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020079 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020080
Paul Bakker89e80c92012-03-20 13:50:09 +000081 memset( h, 0, 16 );
Paul Bakker43aff2a2013-09-09 00:10:27 +020082 if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
83 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000084
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010085 /* 0 corresponds to 0 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +000086 ctx->HH[0] = 0;
87 ctx->HL[0] = 0;
88
Paul Bakker5c2364c2012-10-01 14:41:15 +000089 GET_UINT32_BE( hi, h, 0 );
90 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000091 vh = (uint64_t) hi << 32 | lo;
92
Paul Bakker5c2364c2012-10-01 14:41:15 +000093 GET_UINT32_BE( hi, h, 8 );
94 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000095 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020096
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010097 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +000098 ctx->HL[8] = vl;
99 ctx->HH[8] = vh;
100
101 for( i = 4; i > 0; i >>= 1 )
102 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200103 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000104 vl = ( vh << 63 ) | ( vl >> 1 );
105 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
106
107 ctx->HL[i] = vl;
108 ctx->HH[i] = vh;
109 }
110
111 for (i = 2; i < 16; i <<= 1 )
112 {
113 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
114 vh = *HiH;
115 vl = *HiL;
116 for( j = 1; j < i; j++ )
117 {
118 HiH[j] = vh ^ ctx->HH[j];
119 HiL[j] = vl ^ ctx->HL[j];
120 }
121 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200122
123 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000124}
125
Paul Bakker43aff2a2013-09-09 00:10:27 +0200126int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
127 unsigned int keysize )
Paul Bakker89e80c92012-03-20 13:50:09 +0000128{
129 int ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200130 const cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000131
132 memset( ctx, 0, sizeof(gcm_context) );
133
Paul Bakker43aff2a2013-09-09 00:10:27 +0200134 cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
135 if( cipher_info == NULL )
136 return( POLARSSL_ERR_GCM_BAD_INPUT );
137
Paul Bakkera0558e02013-09-10 14:25:51 +0200138 if( cipher_info->block_size != 16 )
139 return( POLARSSL_ERR_GCM_BAD_INPUT );
140
Paul Bakker43aff2a2013-09-09 00:10:27 +0200141 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000142 return( ret );
143
Paul Bakker43aff2a2013-09-09 00:10:27 +0200144 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
145 POLARSSL_ENCRYPT ) ) != 0 )
146 {
147 return( ret );
148 }
149
150 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
151 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000152
153 return( 0 );
154}
155
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100156/*
157 * Shoup's method for multiplication use this table with
158 * last4[x] = x times P^128
159 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
160 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000161static const uint64_t last4[16] =
162{
163 0x0000, 0x1c20, 0x3840, 0x2460,
164 0x7080, 0x6ca0, 0x48c0, 0x54e0,
165 0xe100, 0xfd20, 0xd940, 0xc560,
166 0x9180, 0x8da0, 0xa9c0, 0xb5e0
167};
168
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100169/*
170 * Sets output to x times H using the precomputed tables.
171 * x and output are seen as elements of GF(2^128) as in [MGV].
172 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200173static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
174 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000175{
176 int i = 0;
177 unsigned char z[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000178 unsigned char lo, hi, rem;
179 uint64_t zh, zl;
180
181 memset( z, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000182
183 lo = x[15] & 0xf;
184 hi = x[15] >> 4;
185
186 zh = ctx->HH[lo];
187 zl = ctx->HL[lo];
188
189 for( i = 15; i >= 0; i-- )
190 {
191 lo = x[i] & 0xf;
192 hi = x[i] >> 4;
193
194 if( i != 15 )
195 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000196 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000197 zl = ( zh << 60 ) | ( zl >> 4 );
198 zh = ( zh >> 4 );
199 zh ^= (uint64_t) last4[rem] << 48;
200 zh ^= ctx->HH[lo];
201 zl ^= ctx->HL[lo];
202
203 }
204
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000205 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000206 zl = ( zh << 60 ) | ( zl >> 4 );
207 zh = ( zh >> 4 );
208 zh ^= (uint64_t) last4[rem] << 48;
209 zh ^= ctx->HH[hi];
210 zl ^= ctx->HL[hi];
211 }
212
Paul Bakker5c2364c2012-10-01 14:41:15 +0000213 PUT_UINT32_BE( zh >> 32, output, 0 );
214 PUT_UINT32_BE( zh, output, 4 );
215 PUT_UINT32_BE( zl >> 32, output, 8 );
216 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000217}
218
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200219int gcm_starts( gcm_context *ctx,
220 int mode,
221 const unsigned char *iv,
222 size_t iv_len,
223 const unsigned char *add,
224 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000225{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200226 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000227 unsigned char work_buf[16];
228 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000229 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200230 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000231
Paul Bakker52cf16c2013-07-26 13:55:38 +0200232 memset( ctx->y, 0x00, sizeof(ctx->y) );
233 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
234
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200235 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200236 ctx->len = 0;
237 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000238
239 if( iv_len == 12 )
240 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200241 memcpy( ctx->y, iv, iv_len );
242 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000243 }
244 else
245 {
246 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000247 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000248
249 p = iv;
250 while( iv_len > 0 )
251 {
252 use_len = ( iv_len < 16 ) ? iv_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->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200256
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200257 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000258
259 iv_len -= use_len;
260 p += use_len;
261 }
262
Paul Bakker67f9d532012-10-23 11:49:05 +0000263 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200264 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000265
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200266 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000267 }
268
Paul Bakker43aff2a2013-09-09 00:10:27 +0200269 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
270 &olen ) ) != 0 )
271 {
272 return( ret );
273 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000274
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200275 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000276 p = add;
277 while( add_len > 0 )
278 {
279 use_len = ( add_len < 16 ) ? add_len : 16;
280
Paul Bakker67f9d532012-10-23 11:49:05 +0000281 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200282 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200283
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200284 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000285
286 add_len -= use_len;
287 p += use_len;
288 }
289
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200290 return( 0 );
291}
292
293int gcm_update( gcm_context *ctx,
294 size_t length,
295 const unsigned char *input,
296 unsigned char *output )
297{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200298 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200299 unsigned char ectr[16];
300 size_t i;
301 const unsigned char *p;
302 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200303 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200304
305 if( output > input && (size_t) ( output - input ) < length )
306 return( POLARSSL_ERR_GCM_BAD_INPUT );
307
308 ctx->len += length;
309
Paul Bakker89e80c92012-03-20 13:50:09 +0000310 p = input;
311 while( length > 0 )
312 {
313 use_len = ( length < 16 ) ? length : 16;
314
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100315 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200316 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000317 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000318
Paul Bakker43aff2a2013-09-09 00:10:27 +0200319 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
320 &olen ) ) != 0 )
321 {
322 return( ret );
323 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000324
Paul Bakker67f9d532012-10-23 11:49:05 +0000325 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000326 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200327 if( ctx->mode == GCM_DECRYPT )
328 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000329 out_p[i] = ectr[i] ^ p[i];
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200330 if( ctx->mode == GCM_ENCRYPT )
331 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000332 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200333
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200334 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200335
Paul Bakker89e80c92012-03-20 13:50:09 +0000336 length -= use_len;
337 p += use_len;
338 out_p += use_len;
339 }
340
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200341 return( 0 );
342}
343
344int gcm_finish( gcm_context *ctx,
345 unsigned char *tag,
346 size_t tag_len )
347{
348 unsigned char work_buf[16];
349 size_t i;
350 uint64_t orig_len = ctx->len * 8;
351 uint64_t orig_add_len = ctx->add_len * 8;
352
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200353 if( tag_len > 16 )
354 return( POLARSSL_ERR_GCM_BAD_INPUT );
355
Manuel Pégourié-Gonnard9241be72013-08-31 17:31:03 +0200356 if( tag_len != 0 )
357 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200358
Paul Bakker89e80c92012-03-20 13:50:09 +0000359 if( orig_len || orig_add_len )
360 {
361 memset( work_buf, 0x00, 16 );
362
Paul Bakker0ecdb232013-04-09 11:36:42 +0200363 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
364 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
365 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
366 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000367
Paul Bakker67f9d532012-10-23 11:49:05 +0000368 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200369 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000370
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200371 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000372
Paul Bakker67f9d532012-10-23 11:49:05 +0000373 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200374 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000375 }
376
377 return( 0 );
378}
379
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200380int gcm_crypt_and_tag( gcm_context *ctx,
381 int mode,
382 size_t length,
383 const unsigned char *iv,
384 size_t iv_len,
385 const unsigned char *add,
386 size_t add_len,
387 const unsigned char *input,
388 unsigned char *output,
389 size_t tag_len,
390 unsigned char *tag )
391{
392 int ret;
393
394 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
395 return( ret );
396
397 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
398 return( ret );
399
400 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
401 return( ret );
402
403 return( 0 );
404}
405
Paul Bakker89e80c92012-03-20 13:50:09 +0000406int gcm_auth_decrypt( gcm_context *ctx,
407 size_t length,
408 const unsigned char *iv,
409 size_t iv_len,
410 const unsigned char *add,
411 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200412 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000413 size_t tag_len,
414 const unsigned char *input,
415 unsigned char *output )
416{
417 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200418 size_t i;
419 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000420
421 gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
422
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200423 /* Check tag in "constant-time" */
424 for( diff = 0, i = 0; i < tag_len; i++ )
425 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000426
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200427 if( diff != 0 )
428 {
429 memset( output, 0, length );
430 return( POLARSSL_ERR_GCM_AUTH_FAILED );
431 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000432
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200433 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000434}
435
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200436void gcm_free( gcm_context *ctx )
437{
438 (void) cipher_free_ctx( &ctx->cipher_ctx );
439 memset( ctx, 0, sizeof( gcm_context ) );
440}
441
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200442#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000443
444#include <stdio.h>
445
446/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200447 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000448 *
449 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
450 */
451#define MAX_TESTS 6
452
453int key_index[MAX_TESTS] =
454 { 0, 0, 1, 1, 1, 1 };
455
456unsigned char key[MAX_TESTS][32] =
457{
458 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
462 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
463 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
464 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200465 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000466};
467
468size_t iv_len[MAX_TESTS] =
469 { 12, 12, 12, 12, 8, 60 };
470
471int iv_index[MAX_TESTS] =
472 { 0, 0, 1, 1, 1, 2 };
473
474unsigned char iv[MAX_TESTS][64] =
475{
476 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477 0x00, 0x00, 0x00, 0x00 },
478 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
479 0xde, 0xca, 0xf8, 0x88 },
480 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200481 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000482 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200483 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000484 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200485 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000486 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200487 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000488};
489
490size_t add_len[MAX_TESTS] =
491 { 0, 0, 0, 20, 20, 20 };
492
493int add_index[MAX_TESTS] =
494 { 0, 0, 0, 1, 1, 1 };
495
496unsigned char additional[MAX_TESTS][64] =
497{
498 { 0x00 },
499 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200500 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000501 0xab, 0xad, 0xda, 0xd2 },
502};
503
504size_t pt_len[MAX_TESTS] =
505 { 0, 16, 64, 60, 60, 60 };
506
507int pt_index[MAX_TESTS] =
508 { 0, 0, 1, 1, 1, 1 };
509
510unsigned char pt[MAX_TESTS][64] =
511{
512 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
514 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
515 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
516 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
517 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
518 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
519 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
520 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
521 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
522};
523
524unsigned char ct[MAX_TESTS * 3][64] =
525{
526 { 0x00 },
527 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
528 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
529 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200530 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000531 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200532 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000533 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200534 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000535 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
536 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
537 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200538 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000539 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200540 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000541 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200542 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000543 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
544 0x3d, 0x58, 0xe0, 0x91 },
545 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200546 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000547 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200548 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000549 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200550 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000551 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
552 0xc2, 0x3f, 0x45, 0x98 },
553 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200554 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000555 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200556 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000557 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200558 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000559 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
560 0x4c, 0x34, 0xae, 0xe5 },
561 { 0x00 },
562 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200563 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000564 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200565 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000566 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200567 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000568 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200569 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000570 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
571 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
572 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200573 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000574 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200575 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
576 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
577 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000578 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200579 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000580 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200581 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000582 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200583 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000584 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200585 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000586 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200587 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000588 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200589 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000590 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200591 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000592 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200593 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000594 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200595 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000596 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200597 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
598 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
599 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
600 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
601 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
602 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
603 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
604 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
605 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
606 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
607 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
608 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
609 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
610 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
611 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
612 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
613 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
614 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200616 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000617 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200618 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000619 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200620 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000621 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200622 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000623 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200624 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200626 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000627 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200628 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000629 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200630 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000631};
632
633unsigned char tag[MAX_TESTS * 3][16] =
634{
635 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
636 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
637 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
638 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
639 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200640 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000641 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
642 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
643 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
644 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
645 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
646 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
647 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
648 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
649 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200650 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000651 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
652 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
653 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200654 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000655 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200656 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000657 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200658 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000659 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200660 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000661 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200662 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000663 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200664 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000665 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200666 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000667 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200668 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000669 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200670 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000671};
672
673int gcm_self_test( int verbose )
674{
675 gcm_context ctx;
676 unsigned char buf[64];
677 unsigned char tag_buf[16];
678 int i, j, ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200679 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000680
681 for( j = 0; j < 3; j++ )
682 {
683 int key_len = 128 + 64 * j;
684
685 for( i = 0; i < MAX_TESTS; i++ )
686 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200687 if( verbose != 0 )
688 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
689
Paul Bakker43aff2a2013-09-09 00:10:27 +0200690 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000691
692 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
693 pt_len[i],
694 iv[iv_index[i]], iv_len[i],
695 additional[add_index[i]], add_len[i],
696 pt[pt_index[i]], buf, 16, tag_buf );
697
698 if( ret != 0 ||
699 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
700 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
701 {
702 if( verbose != 0 )
703 printf( "failed\n" );
704
705 return( 1 );
706 }
707
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200708 gcm_free( &ctx );
709
Paul Bakker89e80c92012-03-20 13:50:09 +0000710 if( verbose != 0 )
711 printf( "passed\n" );
712
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200713 if( verbose != 0 )
714 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
715
Paul Bakker43aff2a2013-09-09 00:10:27 +0200716 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000717
718 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
719 pt_len[i],
720 iv[iv_index[i]], iv_len[i],
721 additional[add_index[i]], add_len[i],
722 ct[j * 6 + i], buf, 16, tag_buf );
723
724 if( ret != 0 ||
725 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
726 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
727 {
728 if( verbose != 0 )
729 printf( "failed\n" );
730
731 return( 1 );
732 }
733
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200734 gcm_free( &ctx );
735
Paul Bakker89e80c92012-03-20 13:50:09 +0000736 if( verbose != 0 )
737 printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200738
739 if( verbose != 0 )
740 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" );
741
Paul Bakker43aff2a2013-09-09 00:10:27 +0200742 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200743
744 ret = gcm_starts( &ctx, GCM_ENCRYPT,
745 iv[iv_index[i]], iv_len[i],
746 additional[add_index[i]], add_len[i] );
747 if( ret != 0 )
748 {
749 if( verbose != 0 )
750 printf( "failed\n" );
751
752 return( 1 );
753 }
754
755 if( pt_len[i] > 32 )
756 {
757 size_t rest_len = pt_len[i] - 32;
758 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
759 if( ret != 0 )
760 {
761 if( verbose != 0 )
762 printf( "failed\n" );
763
764 return( 1 );
765 }
766
767 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
768 if( ret != 0 )
769 {
770 if( verbose != 0 )
771 printf( "failed\n" );
772
773 return( 1 );
774 }
775 }
776 else
777 {
778 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
779 if( ret != 0 )
780 {
781 if( verbose != 0 )
782 printf( "failed\n" );
783
784 return( 1 );
785 }
786 }
787
788 ret = gcm_finish( &ctx, tag_buf, 16 );
789 if( ret != 0 ||
790 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
791 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
792 {
793 if( verbose != 0 )
794 printf( "failed\n" );
795
796 return( 1 );
797 }
798
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200799 gcm_free( &ctx );
800
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200801 if( verbose != 0 )
802 printf( "passed\n" );
803
804 if( verbose != 0 )
805 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" );
806
Paul Bakker43aff2a2013-09-09 00:10:27 +0200807 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200808
809 ret = gcm_starts( &ctx, GCM_DECRYPT,
810 iv[iv_index[i]], iv_len[i],
811 additional[add_index[i]], add_len[i] );
812 if( ret != 0 )
813 {
814 if( verbose != 0 )
815 printf( "failed\n" );
816
817 return( 1 );
818 }
819
820 if( pt_len[i] > 32 )
821 {
822 size_t rest_len = pt_len[i] - 32;
823 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
824 if( ret != 0 )
825 {
826 if( verbose != 0 )
827 printf( "failed\n" );
828
829 return( 1 );
830 }
831
832 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
833 if( ret != 0 )
834 {
835 if( verbose != 0 )
836 printf( "failed\n" );
837
838 return( 1 );
839 }
840 }
841 else
842 {
843 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
844 if( ret != 0 )
845 {
846 if( verbose != 0 )
847 printf( "failed\n" );
848
849 return( 1 );
850 }
851 }
852
853 ret = gcm_finish( &ctx, tag_buf, 16 );
854 if( ret != 0 ||
855 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
856 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
857 {
858 if( verbose != 0 )
859 printf( "failed\n" );
860
861 return( 1 );
862 }
863
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200864 gcm_free( &ctx );
865
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200866 if( verbose != 0 )
867 printf( "passed\n" );
868
Paul Bakker89e80c92012-03-20 13:50:09 +0000869 }
870 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200871
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200872 if( verbose != 0 )
873 printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000874
875 return( 0 );
876}
877
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200878
879
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200880#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000881
882#endif