blob: 894c5d3eb8f4ef3ab9c72044ac8963d2328a2a10 [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
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010042#if defined(POLARSSL_AESNI_C)
43#include "polarssl/aesni.h"
44#endif
45
Paul Bakker89e80c92012-03-20 13:50:09 +000046/*
47 * 32-bit integer manipulation macros (big endian)
48 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000049#ifndef GET_UINT32_BE
50#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000051{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000052 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
53 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
54 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
55 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000056}
57#endif
58
Paul Bakker5c2364c2012-10-01 14:41:15 +000059#ifndef PUT_UINT32_BE
60#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000061{ \
62 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
63 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
64 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
65 (b)[(i) + 3] = (unsigned char) ( (n) ); \
66}
67#endif
68
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010069/*
70 * Precompute small multiples of H, that is set
71 * HH[i] || HL[i] = H times i,
72 * where i is seen as a field element as in [MGV], ie high-order bits
73 * correspond to low powers of P. The result is stored in the same way, that
74 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
75 * corresponds to P^127.
76 */
Paul Bakker43aff2a2013-09-09 00:10:27 +020077static int gcm_gen_table( gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000078{
Paul Bakker43aff2a2013-09-09 00:10:27 +020079 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000080 uint64_t hi, lo;
81 uint64_t vl, vh;
82 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020083 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020084
Paul Bakker89e80c92012-03-20 13:50:09 +000085 memset( h, 0, 16 );
Paul Bakker43aff2a2013-09-09 00:10:27 +020086 if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
87 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000088
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010089 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +000090 GET_UINT32_BE( hi, h, 0 );
91 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000092 vh = (uint64_t) hi << 32 | lo;
93
Paul Bakker5c2364c2012-10-01 14:41:15 +000094 GET_UINT32_BE( hi, h, 8 );
95 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000096 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020097
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010098 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +000099 ctx->HL[8] = vl;
100 ctx->HH[8] = vh;
101
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100102#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
103 /* With CLMUL support, we need only h, not the rest of the table */
104 if( aesni_supports( POLARSSL_AESNI_CLMUL ) )
105 return( 0 );
106#endif
107
108 /* 0 corresponds to 0 in GF(2^128) */
109 ctx->HH[0] = 0;
110 ctx->HL[0] = 0;
111
Paul Bakker89e80c92012-03-20 13:50:09 +0000112 for( i = 4; i > 0; i >>= 1 )
113 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200114 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000115 vl = ( vh << 63 ) | ( vl >> 1 );
116 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
117
118 ctx->HL[i] = vl;
119 ctx->HH[i] = vh;
120 }
121
122 for (i = 2; i < 16; i <<= 1 )
123 {
124 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
125 vh = *HiH;
126 vl = *HiL;
127 for( j = 1; j < i; j++ )
128 {
129 HiH[j] = vh ^ ctx->HH[j];
130 HiL[j] = vl ^ ctx->HL[j];
131 }
132 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200133
134 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000135}
136
Paul Bakker43aff2a2013-09-09 00:10:27 +0200137int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
138 unsigned int keysize )
Paul Bakker89e80c92012-03-20 13:50:09 +0000139{
140 int ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200141 const cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000142
143 memset( ctx, 0, sizeof(gcm_context) );
144
Paul Bakker43aff2a2013-09-09 00:10:27 +0200145 cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
146 if( cipher_info == NULL )
147 return( POLARSSL_ERR_GCM_BAD_INPUT );
148
Paul Bakkera0558e02013-09-10 14:25:51 +0200149 if( cipher_info->block_size != 16 )
150 return( POLARSSL_ERR_GCM_BAD_INPUT );
151
Paul Bakker43aff2a2013-09-09 00:10:27 +0200152 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000153 return( ret );
154
Paul Bakker43aff2a2013-09-09 00:10:27 +0200155 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
156 POLARSSL_ENCRYPT ) ) != 0 )
157 {
158 return( ret );
159 }
160
161 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
162 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000163
164 return( 0 );
165}
166
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100167/*
168 * Shoup's method for multiplication use this table with
169 * last4[x] = x times P^128
170 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
171 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000172static const uint64_t last4[16] =
173{
174 0x0000, 0x1c20, 0x3840, 0x2460,
175 0x7080, 0x6ca0, 0x48c0, 0x54e0,
176 0xe100, 0xfd20, 0xd940, 0xc560,
177 0x9180, 0x8da0, 0xa9c0, 0xb5e0
178};
179
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100180/*
181 * Sets output to x times H using the precomputed tables.
182 * x and output are seen as elements of GF(2^128) as in [MGV].
183 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200184static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
185 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000186{
187 int i = 0;
188 unsigned char z[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000189 unsigned char lo, hi, rem;
190 uint64_t zh, zl;
191
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100192#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
193 if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) {
194 unsigned char h[16];
195
196 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
197 PUT_UINT32_BE( ctx->HH[8], h, 4 );
198 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
199 PUT_UINT32_BE( ctx->HL[8], h, 12 );
200
201 (void) aesni_gcm_mult( output, x, h );
202 return;
203 }
204#endif
205
Paul Bakker89e80c92012-03-20 13:50:09 +0000206 memset( z, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000207
208 lo = x[15] & 0xf;
209 hi = x[15] >> 4;
210
211 zh = ctx->HH[lo];
212 zl = ctx->HL[lo];
213
214 for( i = 15; i >= 0; i-- )
215 {
216 lo = x[i] & 0xf;
217 hi = x[i] >> 4;
218
219 if( i != 15 )
220 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000221 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000222 zl = ( zh << 60 ) | ( zl >> 4 );
223 zh = ( zh >> 4 );
224 zh ^= (uint64_t) last4[rem] << 48;
225 zh ^= ctx->HH[lo];
226 zl ^= ctx->HL[lo];
227
228 }
229
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000230 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000231 zl = ( zh << 60 ) | ( zl >> 4 );
232 zh = ( zh >> 4 );
233 zh ^= (uint64_t) last4[rem] << 48;
234 zh ^= ctx->HH[hi];
235 zl ^= ctx->HL[hi];
236 }
237
Paul Bakker5c2364c2012-10-01 14:41:15 +0000238 PUT_UINT32_BE( zh >> 32, output, 0 );
239 PUT_UINT32_BE( zh, output, 4 );
240 PUT_UINT32_BE( zl >> 32, output, 8 );
241 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000242}
243
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200244int gcm_starts( gcm_context *ctx,
245 int mode,
246 const unsigned char *iv,
247 size_t iv_len,
248 const unsigned char *add,
249 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000250{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200251 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000252 unsigned char work_buf[16];
253 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000254 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200255 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000256
Paul Bakker52cf16c2013-07-26 13:55:38 +0200257 memset( ctx->y, 0x00, sizeof(ctx->y) );
258 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
259
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200260 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200261 ctx->len = 0;
262 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000263
264 if( iv_len == 12 )
265 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200266 memcpy( ctx->y, iv, iv_len );
267 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000268 }
269 else
270 {
271 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000272 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000273
274 p = iv;
275 while( iv_len > 0 )
276 {
277 use_len = ( iv_len < 16 ) ? iv_len : 16;
278
Paul Bakker67f9d532012-10-23 11:49:05 +0000279 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200280 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200281
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200282 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000283
284 iv_len -= use_len;
285 p += use_len;
286 }
287
Paul Bakker67f9d532012-10-23 11:49:05 +0000288 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200289 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000290
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200291 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000292 }
293
Paul Bakker43aff2a2013-09-09 00:10:27 +0200294 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
295 &olen ) ) != 0 )
296 {
297 return( ret );
298 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000299
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200300 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000301 p = add;
302 while( add_len > 0 )
303 {
304 use_len = ( add_len < 16 ) ? add_len : 16;
305
Paul Bakker67f9d532012-10-23 11:49:05 +0000306 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200307 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200308
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200309 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000310
311 add_len -= use_len;
312 p += use_len;
313 }
314
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200315 return( 0 );
316}
317
318int gcm_update( gcm_context *ctx,
319 size_t length,
320 const unsigned char *input,
321 unsigned char *output )
322{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200323 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200324 unsigned char ectr[16];
325 size_t i;
326 const unsigned char *p;
327 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200328 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200329
330 if( output > input && (size_t) ( output - input ) < length )
331 return( POLARSSL_ERR_GCM_BAD_INPUT );
332
333 ctx->len += length;
334
Paul Bakker89e80c92012-03-20 13:50:09 +0000335 p = input;
336 while( length > 0 )
337 {
338 use_len = ( length < 16 ) ? length : 16;
339
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100340 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200341 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000342 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000343
Paul Bakker43aff2a2013-09-09 00:10:27 +0200344 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
345 &olen ) ) != 0 )
346 {
347 return( ret );
348 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000349
Paul Bakker67f9d532012-10-23 11:49:05 +0000350 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000351 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200352 if( ctx->mode == GCM_DECRYPT )
353 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000354 out_p[i] = ectr[i] ^ p[i];
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200355 if( ctx->mode == GCM_ENCRYPT )
356 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000357 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200358
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200359 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200360
Paul Bakker89e80c92012-03-20 13:50:09 +0000361 length -= use_len;
362 p += use_len;
363 out_p += use_len;
364 }
365
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200366 return( 0 );
367}
368
369int gcm_finish( gcm_context *ctx,
370 unsigned char *tag,
371 size_t tag_len )
372{
373 unsigned char work_buf[16];
374 size_t i;
375 uint64_t orig_len = ctx->len * 8;
376 uint64_t orig_add_len = ctx->add_len * 8;
377
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200378 if( tag_len > 16 )
379 return( POLARSSL_ERR_GCM_BAD_INPUT );
380
Manuel Pégourié-Gonnard9241be72013-08-31 17:31:03 +0200381 if( tag_len != 0 )
382 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200383
Paul Bakker89e80c92012-03-20 13:50:09 +0000384 if( orig_len || orig_add_len )
385 {
386 memset( work_buf, 0x00, 16 );
387
Paul Bakker0ecdb232013-04-09 11:36:42 +0200388 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
389 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
390 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
391 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000392
Paul Bakker67f9d532012-10-23 11:49:05 +0000393 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200394 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000395
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200396 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000397
Paul Bakker67f9d532012-10-23 11:49:05 +0000398 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200399 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000400 }
401
402 return( 0 );
403}
404
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200405int gcm_crypt_and_tag( gcm_context *ctx,
406 int mode,
407 size_t length,
408 const unsigned char *iv,
409 size_t iv_len,
410 const unsigned char *add,
411 size_t add_len,
412 const unsigned char *input,
413 unsigned char *output,
414 size_t tag_len,
415 unsigned char *tag )
416{
417 int ret;
418
419 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
420 return( ret );
421
422 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
423 return( ret );
424
425 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
426 return( ret );
427
428 return( 0 );
429}
430
Paul Bakker89e80c92012-03-20 13:50:09 +0000431int gcm_auth_decrypt( gcm_context *ctx,
432 size_t length,
433 const unsigned char *iv,
434 size_t iv_len,
435 const unsigned char *add,
436 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200437 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000438 size_t tag_len,
439 const unsigned char *input,
440 unsigned char *output )
441{
442 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200443 size_t i;
444 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000445
446 gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
447
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200448 /* Check tag in "constant-time" */
449 for( diff = 0, i = 0; i < tag_len; i++ )
450 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000451
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200452 if( diff != 0 )
453 {
454 memset( output, 0, length );
455 return( POLARSSL_ERR_GCM_AUTH_FAILED );
456 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000457
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200458 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000459}
460
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200461void gcm_free( gcm_context *ctx )
462{
463 (void) cipher_free_ctx( &ctx->cipher_ctx );
464 memset( ctx, 0, sizeof( gcm_context ) );
465}
466
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200467#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000468
469#include <stdio.h>
470
471/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200472 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000473 *
474 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
475 */
476#define MAX_TESTS 6
477
478int key_index[MAX_TESTS] =
479 { 0, 0, 1, 1, 1, 1 };
480
481unsigned char key[MAX_TESTS][32] =
482{
483 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
484 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
485 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
486 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
487 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
488 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
489 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200490 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000491};
492
493size_t iv_len[MAX_TESTS] =
494 { 12, 12, 12, 12, 8, 60 };
495
496int iv_index[MAX_TESTS] =
497 { 0, 0, 1, 1, 1, 2 };
498
499unsigned char iv[MAX_TESTS][64] =
500{
501 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502 0x00, 0x00, 0x00, 0x00 },
503 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
504 0xde, 0xca, 0xf8, 0x88 },
505 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200506 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000507 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200508 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000509 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200510 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000511 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200512 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000513};
514
515size_t add_len[MAX_TESTS] =
516 { 0, 0, 0, 20, 20, 20 };
517
518int add_index[MAX_TESTS] =
519 { 0, 0, 0, 1, 1, 1 };
520
521unsigned char additional[MAX_TESTS][64] =
522{
523 { 0x00 },
524 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200525 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000526 0xab, 0xad, 0xda, 0xd2 },
527};
528
529size_t pt_len[MAX_TESTS] =
530 { 0, 16, 64, 60, 60, 60 };
531
532int pt_index[MAX_TESTS] =
533 { 0, 0, 1, 1, 1, 1 };
534
535unsigned char pt[MAX_TESTS][64] =
536{
537 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
539 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
540 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
541 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
542 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
543 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
544 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
545 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
546 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
547};
548
549unsigned char ct[MAX_TESTS * 3][64] =
550{
551 { 0x00 },
552 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
553 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
554 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200555 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000556 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200557 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000558 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200559 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000560 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
561 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
562 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200563 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000564 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200565 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000566 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200567 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000568 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
569 0x3d, 0x58, 0xe0, 0x91 },
570 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200571 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000572 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200573 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000574 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200575 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000576 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
577 0xc2, 0x3f, 0x45, 0x98 },
578 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200579 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000580 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200581 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000582 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200583 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000584 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
585 0x4c, 0x34, 0xae, 0xe5 },
586 { 0x00 },
587 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200588 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000589 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200590 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000591 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200592 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000593 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200594 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000595 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
596 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
597 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200598 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000599 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200600 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
601 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
602 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000603 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200604 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000605 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200606 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000607 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200608 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000609 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200610 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000611 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200612 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200614 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200616 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000617 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200618 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000619 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200620 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000621 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200622 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
623 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
624 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
625 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
626 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
627 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
628 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
629 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
630 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
631 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
632 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
633 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
634 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
635 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
636 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
637 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
638 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
639 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000640 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200641 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200643 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000644 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200645 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000646 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200647 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200649 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000650 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200651 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200653 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000654 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000656};
657
658unsigned char tag[MAX_TESTS * 3][16] =
659{
660 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
661 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
662 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
663 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
664 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200665 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000666 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
667 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
668 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
669 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
670 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
671 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
672 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
673 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
674 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200675 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000676 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
677 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
678 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200679 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000680 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200681 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000682 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200683 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000684 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200685 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000686 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200687 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000688 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200689 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000690 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200691 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000692 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200693 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000694 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200695 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000696};
697
698int gcm_self_test( int verbose )
699{
700 gcm_context ctx;
701 unsigned char buf[64];
702 unsigned char tag_buf[16];
703 int i, j, ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200704 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000705
706 for( j = 0; j < 3; j++ )
707 {
708 int key_len = 128 + 64 * j;
709
710 for( i = 0; i < MAX_TESTS; i++ )
711 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200712 if( verbose != 0 )
713 printf( " AES-GCM-%3d #%d (%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 Bakker89e80c92012-03-20 13:50:09 +0000716
717 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
718 pt_len[i],
719 iv[iv_index[i]], iv_len[i],
720 additional[add_index[i]], add_len[i],
721 pt[pt_index[i]], buf, 16, tag_buf );
722
723 if( ret != 0 ||
724 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
725 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
726 {
727 if( verbose != 0 )
728 printf( "failed\n" );
729
730 return( 1 );
731 }
732
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200733 gcm_free( &ctx );
734
Paul Bakker89e80c92012-03-20 13:50:09 +0000735 if( verbose != 0 )
736 printf( "passed\n" );
737
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200738 if( verbose != 0 )
739 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
740
Paul Bakker43aff2a2013-09-09 00:10:27 +0200741 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000742
743 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
744 pt_len[i],
745 iv[iv_index[i]], iv_len[i],
746 additional[add_index[i]], add_len[i],
747 ct[j * 6 + i], buf, 16, tag_buf );
748
749 if( ret != 0 ||
750 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
751 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
752 {
753 if( verbose != 0 )
754 printf( "failed\n" );
755
756 return( 1 );
757 }
758
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200759 gcm_free( &ctx );
760
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 if( verbose != 0 )
762 printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200763
764 if( verbose != 0 )
765 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" );
766
Paul Bakker43aff2a2013-09-09 00:10:27 +0200767 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200768
769 ret = gcm_starts( &ctx, GCM_ENCRYPT,
770 iv[iv_index[i]], iv_len[i],
771 additional[add_index[i]], add_len[i] );
772 if( ret != 0 )
773 {
774 if( verbose != 0 )
775 printf( "failed\n" );
776
777 return( 1 );
778 }
779
780 if( pt_len[i] > 32 )
781 {
782 size_t rest_len = pt_len[i] - 32;
783 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
784 if( ret != 0 )
785 {
786 if( verbose != 0 )
787 printf( "failed\n" );
788
789 return( 1 );
790 }
791
792 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
793 if( ret != 0 )
794 {
795 if( verbose != 0 )
796 printf( "failed\n" );
797
798 return( 1 );
799 }
800 }
801 else
802 {
803 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
804 if( ret != 0 )
805 {
806 if( verbose != 0 )
807 printf( "failed\n" );
808
809 return( 1 );
810 }
811 }
812
813 ret = gcm_finish( &ctx, tag_buf, 16 );
814 if( ret != 0 ||
815 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
816 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
817 {
818 if( verbose != 0 )
819 printf( "failed\n" );
820
821 return( 1 );
822 }
823
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200824 gcm_free( &ctx );
825
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200826 if( verbose != 0 )
827 printf( "passed\n" );
828
829 if( verbose != 0 )
830 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" );
831
Paul Bakker43aff2a2013-09-09 00:10:27 +0200832 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200833
834 ret = gcm_starts( &ctx, GCM_DECRYPT,
835 iv[iv_index[i]], iv_len[i],
836 additional[add_index[i]], add_len[i] );
837 if( ret != 0 )
838 {
839 if( verbose != 0 )
840 printf( "failed\n" );
841
842 return( 1 );
843 }
844
845 if( pt_len[i] > 32 )
846 {
847 size_t rest_len = pt_len[i] - 32;
848 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
849 if( ret != 0 )
850 {
851 if( verbose != 0 )
852 printf( "failed\n" );
853
854 return( 1 );
855 }
856
857 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
858 if( ret != 0 )
859 {
860 if( verbose != 0 )
861 printf( "failed\n" );
862
863 return( 1 );
864 }
865 }
866 else
867 {
868 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
869 if( ret != 0 )
870 {
871 if( verbose != 0 )
872 printf( "failed\n" );
873
874 return( 1 );
875 }
876 }
877
878 ret = gcm_finish( &ctx, tag_buf, 16 );
879 if( ret != 0 ||
880 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
881 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
882 {
883 if( verbose != 0 )
884 printf( "failed\n" );
885
886 return( 1 );
887 }
888
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200889 gcm_free( &ctx );
890
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200891 if( verbose != 0 )
892 printf( "passed\n" );
893
Paul Bakker89e80c92012-03-20 13:50:09 +0000894 }
895 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200896
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200897 if( verbose != 0 )
898 printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000899
900 return( 0 );
901}
902
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200903
904
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200905#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000906
907#endif