blob: 1c6cf9f93b93c72d8f376e04003f4f9f57ee32bb [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Paul Bakker7dc4c442014-02-01 22:50:26 +01004 * Copyright (C) 2006-2014, 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
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010042#if defined(POLARSSL_AESNI_C)
43#include "polarssl/aesni.h"
44#endif
45
Paul Bakker7dc4c442014-02-01 22:50:26 +010046#if defined(POLARSSL_PLATFORM_C)
47#include "polarssl/platform.h"
48#else
49#define polarssl_printf printf
50#endif
51
Paul Bakker89e80c92012-03-20 13:50:09 +000052/*
53 * 32-bit integer manipulation macros (big endian)
54 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000055#ifndef GET_UINT32_BE
56#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000057{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000058 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
59 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
60 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
61 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000062}
63#endif
64
Paul Bakker5c2364c2012-10-01 14:41:15 +000065#ifndef PUT_UINT32_BE
66#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000067{ \
68 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
69 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
70 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
71 (b)[(i) + 3] = (unsigned char) ( (n) ); \
72}
73#endif
74
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010075/*
76 * Precompute small multiples of H, that is set
77 * HH[i] || HL[i] = H times i,
78 * where i is seen as a field element as in [MGV], ie high-order bits
79 * correspond to low powers of P. The result is stored in the same way, that
80 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
81 * corresponds to P^127.
82 */
Paul Bakker43aff2a2013-09-09 00:10:27 +020083static int gcm_gen_table( gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000084{
Paul Bakker43aff2a2013-09-09 00:10:27 +020085 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000086 uint64_t hi, lo;
87 uint64_t vl, vh;
88 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020089 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020090
Paul Bakker89e80c92012-03-20 13:50:09 +000091 memset( h, 0, 16 );
Paul Bakker43aff2a2013-09-09 00:10:27 +020092 if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
93 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000094
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010095 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +000096 GET_UINT32_BE( hi, h, 0 );
97 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000098 vh = (uint64_t) hi << 32 | lo;
99
Paul Bakker5c2364c2012-10-01 14:41:15 +0000100 GET_UINT32_BE( hi, h, 8 );
101 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000102 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200103
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100104 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000105 ctx->HL[8] = vl;
106 ctx->HH[8] = vh;
107
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100108#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
109 /* With CLMUL support, we need only h, not the rest of the table */
110 if( aesni_supports( POLARSSL_AESNI_CLMUL ) )
111 return( 0 );
112#endif
113
114 /* 0 corresponds to 0 in GF(2^128) */
115 ctx->HH[0] = 0;
116 ctx->HL[0] = 0;
117
Paul Bakker89e80c92012-03-20 13:50:09 +0000118 for( i = 4; i > 0; i >>= 1 )
119 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200120 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000121 vl = ( vh << 63 ) | ( vl >> 1 );
122 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
123
124 ctx->HL[i] = vl;
125 ctx->HH[i] = vh;
126 }
127
128 for (i = 2; i < 16; i <<= 1 )
129 {
130 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
131 vh = *HiH;
132 vl = *HiL;
133 for( j = 1; j < i; j++ )
134 {
135 HiH[j] = vh ^ ctx->HH[j];
136 HiL[j] = vl ^ ctx->HL[j];
137 }
138 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200139
140 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000141}
142
Paul Bakker43aff2a2013-09-09 00:10:27 +0200143int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
144 unsigned int keysize )
Paul Bakker89e80c92012-03-20 13:50:09 +0000145{
146 int ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200147 const cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000148
149 memset( ctx, 0, sizeof(gcm_context) );
150
Paul Bakker43aff2a2013-09-09 00:10:27 +0200151 cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
152 if( cipher_info == NULL )
153 return( POLARSSL_ERR_GCM_BAD_INPUT );
154
Paul Bakkera0558e02013-09-10 14:25:51 +0200155 if( cipher_info->block_size != 16 )
156 return( POLARSSL_ERR_GCM_BAD_INPUT );
157
Paul Bakker43aff2a2013-09-09 00:10:27 +0200158 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000159 return( ret );
160
Paul Bakker43aff2a2013-09-09 00:10:27 +0200161 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
162 POLARSSL_ENCRYPT ) ) != 0 )
163 {
164 return( ret );
165 }
166
167 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
168 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000169
170 return( 0 );
171}
172
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100173/*
174 * Shoup's method for multiplication use this table with
175 * last4[x] = x times P^128
176 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
177 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000178static const uint64_t last4[16] =
179{
180 0x0000, 0x1c20, 0x3840, 0x2460,
181 0x7080, 0x6ca0, 0x48c0, 0x54e0,
182 0xe100, 0xfd20, 0xd940, 0xc560,
183 0x9180, 0x8da0, 0xa9c0, 0xb5e0
184};
185
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100186/*
187 * Sets output to x times H using the precomputed tables.
188 * x and output are seen as elements of GF(2^128) as in [MGV].
189 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200190static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
191 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000192{
193 int i = 0;
194 unsigned char z[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000195 unsigned char lo, hi, rem;
196 uint64_t zh, zl;
197
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100198#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
199 if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) {
200 unsigned char h[16];
201
202 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
203 PUT_UINT32_BE( ctx->HH[8], h, 4 );
204 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
205 PUT_UINT32_BE( ctx->HL[8], h, 12 );
206
Manuel Pégourié-Gonnardd4588cf2013-12-30 13:54:23 +0100207 aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100208 return;
209 }
210#endif
211
Paul Bakker89e80c92012-03-20 13:50:09 +0000212 memset( z, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000213
214 lo = x[15] & 0xf;
215 hi = x[15] >> 4;
216
217 zh = ctx->HH[lo];
218 zl = ctx->HL[lo];
219
220 for( i = 15; i >= 0; i-- )
221 {
222 lo = x[i] & 0xf;
223 hi = x[i] >> 4;
224
225 if( i != 15 )
226 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000227 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000228 zl = ( zh << 60 ) | ( zl >> 4 );
229 zh = ( zh >> 4 );
230 zh ^= (uint64_t) last4[rem] << 48;
231 zh ^= ctx->HH[lo];
232 zl ^= ctx->HL[lo];
233
234 }
235
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000236 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000237 zl = ( zh << 60 ) | ( zl >> 4 );
238 zh = ( zh >> 4 );
239 zh ^= (uint64_t) last4[rem] << 48;
240 zh ^= ctx->HH[hi];
241 zl ^= ctx->HL[hi];
242 }
243
Paul Bakker5c2364c2012-10-01 14:41:15 +0000244 PUT_UINT32_BE( zh >> 32, output, 0 );
245 PUT_UINT32_BE( zh, output, 4 );
246 PUT_UINT32_BE( zl >> 32, output, 8 );
247 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000248}
249
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200250int gcm_starts( gcm_context *ctx,
251 int mode,
252 const unsigned char *iv,
253 size_t iv_len,
254 const unsigned char *add,
255 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000256{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200257 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000258 unsigned char work_buf[16];
259 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000260 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200261 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000262
Paul Bakker52cf16c2013-07-26 13:55:38 +0200263 memset( ctx->y, 0x00, sizeof(ctx->y) );
264 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
265
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200266 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200267 ctx->len = 0;
268 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000269
270 if( iv_len == 12 )
271 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200272 memcpy( ctx->y, iv, iv_len );
273 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000274 }
275 else
276 {
277 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000278 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000279
280 p = iv;
281 while( iv_len > 0 )
282 {
283 use_len = ( iv_len < 16 ) ? iv_len : 16;
284
Paul Bakker67f9d532012-10-23 11:49:05 +0000285 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200286 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200287
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200288 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000289
290 iv_len -= use_len;
291 p += use_len;
292 }
293
Paul Bakker67f9d532012-10-23 11:49:05 +0000294 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200295 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000296
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200297 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000298 }
299
Paul Bakker43aff2a2013-09-09 00:10:27 +0200300 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
301 &olen ) ) != 0 )
302 {
303 return( ret );
304 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000305
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200306 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000307 p = add;
308 while( add_len > 0 )
309 {
310 use_len = ( add_len < 16 ) ? add_len : 16;
311
Paul Bakker67f9d532012-10-23 11:49:05 +0000312 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200313 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200314
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200315 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000316
317 add_len -= use_len;
318 p += use_len;
319 }
320
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200321 return( 0 );
322}
323
324int gcm_update( gcm_context *ctx,
325 size_t length,
326 const unsigned char *input,
327 unsigned char *output )
328{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200329 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200330 unsigned char ectr[16];
331 size_t i;
332 const unsigned char *p;
333 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200334 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200335
336 if( output > input && (size_t) ( output - input ) < length )
337 return( POLARSSL_ERR_GCM_BAD_INPUT );
338
339 ctx->len += length;
340
Paul Bakker89e80c92012-03-20 13:50:09 +0000341 p = input;
342 while( length > 0 )
343 {
344 use_len = ( length < 16 ) ? length : 16;
345
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100346 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200347 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000348 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000349
Paul Bakker43aff2a2013-09-09 00:10:27 +0200350 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
351 &olen ) ) != 0 )
352 {
353 return( ret );
354 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000355
Paul Bakker67f9d532012-10-23 11:49:05 +0000356 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000357 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200358 if( ctx->mode == GCM_DECRYPT )
359 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000360 out_p[i] = ectr[i] ^ p[i];
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200361 if( ctx->mode == GCM_ENCRYPT )
362 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000363 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200364
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200365 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200366
Paul Bakker89e80c92012-03-20 13:50:09 +0000367 length -= use_len;
368 p += use_len;
369 out_p += use_len;
370 }
371
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200372 return( 0 );
373}
374
375int gcm_finish( gcm_context *ctx,
376 unsigned char *tag,
377 size_t tag_len )
378{
379 unsigned char work_buf[16];
380 size_t i;
381 uint64_t orig_len = ctx->len * 8;
382 uint64_t orig_add_len = ctx->add_len * 8;
383
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200384 if( tag_len > 16 )
385 return( POLARSSL_ERR_GCM_BAD_INPUT );
386
Manuel Pégourié-Gonnard9241be72013-08-31 17:31:03 +0200387 if( tag_len != 0 )
388 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200389
Paul Bakker89e80c92012-03-20 13:50:09 +0000390 if( orig_len || orig_add_len )
391 {
392 memset( work_buf, 0x00, 16 );
393
Paul Bakker0ecdb232013-04-09 11:36:42 +0200394 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
395 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
396 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
397 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000398
Paul Bakker67f9d532012-10-23 11:49:05 +0000399 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200400 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000401
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200402 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000403
Paul Bakker67f9d532012-10-23 11:49:05 +0000404 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200405 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000406 }
407
408 return( 0 );
409}
410
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200411int gcm_crypt_and_tag( gcm_context *ctx,
412 int mode,
413 size_t length,
414 const unsigned char *iv,
415 size_t iv_len,
416 const unsigned char *add,
417 size_t add_len,
418 const unsigned char *input,
419 unsigned char *output,
420 size_t tag_len,
421 unsigned char *tag )
422{
423 int ret;
424
425 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
426 return( ret );
427
428 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
429 return( ret );
430
431 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
432 return( ret );
433
434 return( 0 );
435}
436
Paul Bakker89e80c92012-03-20 13:50:09 +0000437int gcm_auth_decrypt( gcm_context *ctx,
438 size_t length,
439 const unsigned char *iv,
440 size_t iv_len,
441 const unsigned char *add,
442 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200443 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000444 size_t tag_len,
445 const unsigned char *input,
446 unsigned char *output )
447{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100448 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000449 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200450 size_t i;
451 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000452
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100453 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
454 iv, iv_len, add, add_len,
455 input, output, tag_len, check_tag ) ) != 0 )
456 {
457 return( ret );
458 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000459
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200460 /* Check tag in "constant-time" */
461 for( diff = 0, i = 0; i < tag_len; i++ )
462 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000463
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200464 if( diff != 0 )
465 {
466 memset( output, 0, length );
467 return( POLARSSL_ERR_GCM_AUTH_FAILED );
468 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000469
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200470 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000471}
472
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200473void gcm_free( gcm_context *ctx )
474{
475 (void) cipher_free_ctx( &ctx->cipher_ctx );
476 memset( ctx, 0, sizeof( gcm_context ) );
477}
478
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200479#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000480
481#include <stdio.h>
482
483/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200484 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000485 *
486 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
487 */
488#define MAX_TESTS 6
489
490int key_index[MAX_TESTS] =
491 { 0, 0, 1, 1, 1, 1 };
492
493unsigned char key[MAX_TESTS][32] =
494{
495 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
499 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
500 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
501 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200502 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000503};
504
505size_t iv_len[MAX_TESTS] =
506 { 12, 12, 12, 12, 8, 60 };
507
508int iv_index[MAX_TESTS] =
509 { 0, 0, 1, 1, 1, 2 };
510
511unsigned char iv[MAX_TESTS][64] =
512{
513 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
514 0x00, 0x00, 0x00, 0x00 },
515 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
516 0xde, 0xca, 0xf8, 0x88 },
517 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200518 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000519 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200520 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000521 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200522 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000523 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200524 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000525};
526
527size_t add_len[MAX_TESTS] =
528 { 0, 0, 0, 20, 20, 20 };
529
530int add_index[MAX_TESTS] =
531 { 0, 0, 0, 1, 1, 1 };
532
533unsigned char additional[MAX_TESTS][64] =
534{
535 { 0x00 },
536 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200537 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000538 0xab, 0xad, 0xda, 0xd2 },
539};
540
541size_t pt_len[MAX_TESTS] =
542 { 0, 16, 64, 60, 60, 60 };
543
544int pt_index[MAX_TESTS] =
545 { 0, 0, 1, 1, 1, 1 };
546
547unsigned char pt[MAX_TESTS][64] =
548{
549 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
551 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
552 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
553 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
554 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
555 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
556 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
557 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
558 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
559};
560
561unsigned char ct[MAX_TESTS * 3][64] =
562{
563 { 0x00 },
564 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
565 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
566 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200567 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000568 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200569 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000570 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200571 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000572 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
573 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
574 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200575 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000576 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200577 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000578 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200579 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000580 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
581 0x3d, 0x58, 0xe0, 0x91 },
582 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200583 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000584 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200585 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000586 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200587 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000588 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
589 0xc2, 0x3f, 0x45, 0x98 },
590 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200591 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000592 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200593 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000594 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200595 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000596 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
597 0x4c, 0x34, 0xae, 0xe5 },
598 { 0x00 },
599 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200600 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000601 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200602 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000603 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200604 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000605 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200606 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000607 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
608 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
609 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200610 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000611 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200612 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
613 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
614 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200616 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000617 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200618 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000619 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200620 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000621 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200622 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000623 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200624 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200626 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000627 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200628 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000629 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200630 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000631 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200632 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000633 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200634 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
635 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
636 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
637 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
638 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
639 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
640 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
641 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
642 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
643 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
644 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
645 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
646 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
647 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
648 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
649 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
650 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
651 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200653 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000654 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000656 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200657 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000658 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200659 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200661 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000662 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200663 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000664 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200665 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000666 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200667 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000668};
669
670unsigned char tag[MAX_TESTS * 3][16] =
671{
672 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
673 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
674 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
675 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
676 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200677 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000678 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
679 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
680 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
681 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
682 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
683 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
684 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
685 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
686 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200687 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000688 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
689 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
690 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200691 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000692 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200693 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000694 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200695 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000696 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200697 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000698 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200699 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000700 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200701 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000702 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200703 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000704 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200705 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000706 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200707 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000708};
709
710int gcm_self_test( int verbose )
711{
712 gcm_context ctx;
713 unsigned char buf[64];
714 unsigned char tag_buf[16];
715 int i, j, ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200716 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000717
718 for( j = 0; j < 3; j++ )
719 {
720 int key_len = 128 + 64 * j;
721
722 for( i = 0; i < MAX_TESTS; i++ )
723 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200724 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100725 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
726 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200727
Paul Bakker43aff2a2013-09-09 00:10:27 +0200728 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000729
730 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
731 pt_len[i],
732 iv[iv_index[i]], iv_len[i],
733 additional[add_index[i]], add_len[i],
734 pt[pt_index[i]], buf, 16, tag_buf );
735
736 if( ret != 0 ||
737 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
738 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
739 {
740 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100741 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000742
743 return( 1 );
744 }
745
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200746 gcm_free( &ctx );
747
Paul Bakker89e80c92012-03-20 13:50:09 +0000748 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100749 polarssl_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000750
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200751 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100752 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
753 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200754
Paul Bakker43aff2a2013-09-09 00:10:27 +0200755 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000756
757 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
758 pt_len[i],
759 iv[iv_index[i]], iv_len[i],
760 additional[add_index[i]], add_len[i],
761 ct[j * 6 + i], buf, 16, tag_buf );
762
763 if( ret != 0 ||
764 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
765 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
766 {
767 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100768 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000769
770 return( 1 );
771 }
772
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200773 gcm_free( &ctx );
774
Paul Bakker89e80c92012-03-20 13:50:09 +0000775 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100776 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200777
778 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100779 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
780 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200781
Paul Bakker43aff2a2013-09-09 00:10:27 +0200782 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200783
784 ret = gcm_starts( &ctx, GCM_ENCRYPT,
785 iv[iv_index[i]], iv_len[i],
786 additional[add_index[i]], add_len[i] );
787 if( ret != 0 )
788 {
789 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100790 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200791
792 return( 1 );
793 }
794
795 if( pt_len[i] > 32 )
796 {
797 size_t rest_len = pt_len[i] - 32;
798 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
799 if( ret != 0 )
800 {
801 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100802 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200803
804 return( 1 );
805 }
806
807 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
808 if( ret != 0 )
809 {
810 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100811 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200812
813 return( 1 );
814 }
815 }
816 else
817 {
818 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
819 if( ret != 0 )
820 {
821 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100822 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200823
824 return( 1 );
825 }
826 }
827
828 ret = gcm_finish( &ctx, tag_buf, 16 );
829 if( ret != 0 ||
830 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
831 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
832 {
833 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100834 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200835
836 return( 1 );
837 }
838
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200839 gcm_free( &ctx );
840
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200841 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100842 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200843
844 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100845 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
846 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200847
Paul Bakker43aff2a2013-09-09 00:10:27 +0200848 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200849
850 ret = gcm_starts( &ctx, GCM_DECRYPT,
851 iv[iv_index[i]], iv_len[i],
852 additional[add_index[i]], add_len[i] );
853 if( ret != 0 )
854 {
855 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100856 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200857
858 return( 1 );
859 }
860
861 if( pt_len[i] > 32 )
862 {
863 size_t rest_len = pt_len[i] - 32;
864 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
865 if( ret != 0 )
866 {
867 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100868 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200869
870 return( 1 );
871 }
872
873 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
874 if( ret != 0 )
875 {
876 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100877 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200878
879 return( 1 );
880 }
881 }
882 else
883 {
884 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
885 if( ret != 0 )
886 {
887 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100888 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200889
890 return( 1 );
891 }
892 }
893
894 ret = gcm_finish( &ctx, tag_buf, 16 );
895 if( ret != 0 ||
896 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
897 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
898 {
899 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100900 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200901
902 return( 1 );
903 }
904
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200905 gcm_free( &ctx );
906
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200907 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100908 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200909
Paul Bakker89e80c92012-03-20 13:50:09 +0000910 }
911 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200912
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200913 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100914 polarssl_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000915
916 return( 0 );
917}
918
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200919
920
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200921#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000922
923#endif