blob: 3e1bc77d603f4f4ae1c481c74e68facf8bdee3d4 [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
Manuel Pégourié-Gonnardd4588cf2013-12-30 13:54:23 +0100201 aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100202 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{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100442 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000443 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200444 size_t i;
445 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000446
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100447 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
448 iv, iv_len, add, add_len,
449 input, output, tag_len, check_tag ) ) != 0 )
450 {
451 return( ret );
452 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000453
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200454 /* Check tag in "constant-time" */
455 for( diff = 0, i = 0; i < tag_len; i++ )
456 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000457
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200458 if( diff != 0 )
459 {
460 memset( output, 0, length );
461 return( POLARSSL_ERR_GCM_AUTH_FAILED );
462 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000463
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200464 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000465}
466
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200467void gcm_free( gcm_context *ctx )
468{
469 (void) cipher_free_ctx( &ctx->cipher_ctx );
470 memset( ctx, 0, sizeof( gcm_context ) );
471}
472
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200473#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000474
475#include <stdio.h>
476
477/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200478 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000479 *
480 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
481 */
482#define MAX_TESTS 6
483
484int key_index[MAX_TESTS] =
485 { 0, 0, 1, 1, 1, 1 };
486
487unsigned char key[MAX_TESTS][32] =
488{
489 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
493 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
494 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
495 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200496 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000497};
498
499size_t iv_len[MAX_TESTS] =
500 { 12, 12, 12, 12, 8, 60 };
501
502int iv_index[MAX_TESTS] =
503 { 0, 0, 1, 1, 1, 2 };
504
505unsigned char iv[MAX_TESTS][64] =
506{
507 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508 0x00, 0x00, 0x00, 0x00 },
509 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
510 0xde, 0xca, 0xf8, 0x88 },
511 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200512 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000513 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200514 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000515 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200516 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000517 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200518 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000519};
520
521size_t add_len[MAX_TESTS] =
522 { 0, 0, 0, 20, 20, 20 };
523
524int add_index[MAX_TESTS] =
525 { 0, 0, 0, 1, 1, 1 };
526
527unsigned char additional[MAX_TESTS][64] =
528{
529 { 0x00 },
530 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200531 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000532 0xab, 0xad, 0xda, 0xd2 },
533};
534
535size_t pt_len[MAX_TESTS] =
536 { 0, 16, 64, 60, 60, 60 };
537
538int pt_index[MAX_TESTS] =
539 { 0, 0, 1, 1, 1, 1 };
540
541unsigned char pt[MAX_TESTS][64] =
542{
543 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
545 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
546 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
547 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
548 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
549 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
550 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
551 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
552 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
553};
554
555unsigned char ct[MAX_TESTS * 3][64] =
556{
557 { 0x00 },
558 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
559 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
560 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200561 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000562 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200563 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000564 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200565 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000566 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
567 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
568 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200569 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000570 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200571 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000572 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200573 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000574 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
575 0x3d, 0x58, 0xe0, 0x91 },
576 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200577 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000578 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200579 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000580 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200581 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000582 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
583 0xc2, 0x3f, 0x45, 0x98 },
584 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200585 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000586 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200587 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000588 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200589 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000590 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
591 0x4c, 0x34, 0xae, 0xe5 },
592 { 0x00 },
593 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200594 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000595 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200596 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000597 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200598 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000599 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200600 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000601 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
602 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
603 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200604 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000605 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200606 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
607 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
608 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000609 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200610 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000611 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200612 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200614 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200616 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000617 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200618 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000619 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200620 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000621 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200622 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000623 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200624 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200626 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000627 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200628 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
629 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
630 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
631 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
632 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
633 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
634 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
635 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
636 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
637 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
638 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
639 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
640 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
641 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
642 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
643 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
644 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
645 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000646 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200647 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200649 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000650 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200651 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200653 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000654 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000656 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200657 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000658 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200659 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200661 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000662};
663
664unsigned char tag[MAX_TESTS * 3][16] =
665{
666 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
667 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
668 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
669 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
670 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200671 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000672 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
673 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
674 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
675 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
676 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
677 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
678 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
679 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
680 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200681 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000682 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
683 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
684 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200685 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000686 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200687 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000688 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200689 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000690 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200691 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000692 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200693 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000694 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200695 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000696 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200697 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000698 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200699 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000700 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200701 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000702};
703
704int gcm_self_test( int verbose )
705{
706 gcm_context ctx;
707 unsigned char buf[64];
708 unsigned char tag_buf[16];
709 int i, j, ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200710 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000711
712 for( j = 0; j < 3; j++ )
713 {
714 int key_len = 128 + 64 * j;
715
716 for( i = 0; i < MAX_TESTS; i++ )
717 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200718 if( verbose != 0 )
719 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
720
Paul Bakker43aff2a2013-09-09 00:10:27 +0200721 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000722
723 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
724 pt_len[i],
725 iv[iv_index[i]], iv_len[i],
726 additional[add_index[i]], add_len[i],
727 pt[pt_index[i]], buf, 16, tag_buf );
728
729 if( ret != 0 ||
730 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
731 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
732 {
733 if( verbose != 0 )
734 printf( "failed\n" );
735
736 return( 1 );
737 }
738
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200739 gcm_free( &ctx );
740
Paul Bakker89e80c92012-03-20 13:50:09 +0000741 if( verbose != 0 )
742 printf( "passed\n" );
743
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200744 if( verbose != 0 )
745 printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
746
Paul Bakker43aff2a2013-09-09 00:10:27 +0200747 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000748
749 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
750 pt_len[i],
751 iv[iv_index[i]], iv_len[i],
752 additional[add_index[i]], add_len[i],
753 ct[j * 6 + i], buf, 16, tag_buf );
754
755 if( ret != 0 ||
756 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
757 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
758 {
759 if( verbose != 0 )
760 printf( "failed\n" );
761
762 return( 1 );
763 }
764
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200765 gcm_free( &ctx );
766
Paul Bakker89e80c92012-03-20 13:50:09 +0000767 if( verbose != 0 )
768 printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200769
770 if( verbose != 0 )
771 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" );
772
Paul Bakker43aff2a2013-09-09 00:10:27 +0200773 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200774
775 ret = gcm_starts( &ctx, GCM_ENCRYPT,
776 iv[iv_index[i]], iv_len[i],
777 additional[add_index[i]], add_len[i] );
778 if( ret != 0 )
779 {
780 if( verbose != 0 )
781 printf( "failed\n" );
782
783 return( 1 );
784 }
785
786 if( pt_len[i] > 32 )
787 {
788 size_t rest_len = pt_len[i] - 32;
789 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
790 if( ret != 0 )
791 {
792 if( verbose != 0 )
793 printf( "failed\n" );
794
795 return( 1 );
796 }
797
798 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
799 if( ret != 0 )
800 {
801 if( verbose != 0 )
802 printf( "failed\n" );
803
804 return( 1 );
805 }
806 }
807 else
808 {
809 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
810 if( ret != 0 )
811 {
812 if( verbose != 0 )
813 printf( "failed\n" );
814
815 return( 1 );
816 }
817 }
818
819 ret = gcm_finish( &ctx, tag_buf, 16 );
820 if( ret != 0 ||
821 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
822 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
823 {
824 if( verbose != 0 )
825 printf( "failed\n" );
826
827 return( 1 );
828 }
829
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200830 gcm_free( &ctx );
831
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200832 if( verbose != 0 )
833 printf( "passed\n" );
834
835 if( verbose != 0 )
836 printf( " AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" );
837
Paul Bakker43aff2a2013-09-09 00:10:27 +0200838 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200839
840 ret = gcm_starts( &ctx, GCM_DECRYPT,
841 iv[iv_index[i]], iv_len[i],
842 additional[add_index[i]], add_len[i] );
843 if( ret != 0 )
844 {
845 if( verbose != 0 )
846 printf( "failed\n" );
847
848 return( 1 );
849 }
850
851 if( pt_len[i] > 32 )
852 {
853 size_t rest_len = pt_len[i] - 32;
854 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
855 if( ret != 0 )
856 {
857 if( verbose != 0 )
858 printf( "failed\n" );
859
860 return( 1 );
861 }
862
863 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
864 if( ret != 0 )
865 {
866 if( verbose != 0 )
867 printf( "failed\n" );
868
869 return( 1 );
870 }
871 }
872 else
873 {
874 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
875 if( ret != 0 )
876 {
877 if( verbose != 0 )
878 printf( "failed\n" );
879
880 return( 1 );
881 }
882 }
883
884 ret = gcm_finish( &ctx, tag_buf, 16 );
885 if( ret != 0 ||
886 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
887 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
888 {
889 if( verbose != 0 )
890 printf( "failed\n" );
891
892 return( 1 );
893 }
894
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200895 gcm_free( &ctx );
896
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200897 if( verbose != 0 )
898 printf( "passed\n" );
899
Paul Bakker89e80c92012-03-20 13:50:09 +0000900 }
901 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200902
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200903 if( verbose != 0 )
904 printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000905
906 return( 0 );
907}
908
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200909
910
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200911#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000912
913#endif