blob: d5761d279d2d3206f057d358d8e63f09bb140b31 [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
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020036#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker89e80c92012-03-20 13:50:09 +000037#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020038#else
39#include POLARSSL_CONFIG_FILE
40#endif
Paul Bakker89e80c92012-03-20 13:50:09 +000041
42#if defined(POLARSSL_GCM_C)
43
44#include "polarssl/gcm.h"
45
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010046#if defined(POLARSSL_AESNI_C)
47#include "polarssl/aesni.h"
48#endif
49
Paul Bakker7dc4c442014-02-01 22:50:26 +010050#if defined(POLARSSL_PLATFORM_C)
51#include "polarssl/platform.h"
52#else
53#define polarssl_printf printf
54#endif
55
Paul Bakker89e80c92012-03-20 13:50:09 +000056/*
57 * 32-bit integer manipulation macros (big endian)
58 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000059#ifndef GET_UINT32_BE
60#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000061{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000062 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
63 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
64 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
65 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000066}
67#endif
68
Paul Bakker5c2364c2012-10-01 14:41:15 +000069#ifndef PUT_UINT32_BE
70#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000071{ \
72 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
73 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
74 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
75 (b)[(i) + 3] = (unsigned char) ( (n) ); \
76}
77#endif
78
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010079/*
80 * Precompute small multiples of H, that is set
81 * HH[i] || HL[i] = H times i,
82 * where i is seen as a field element as in [MGV], ie high-order bits
83 * correspond to low powers of P. The result is stored in the same way, that
84 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
85 * corresponds to P^127.
86 */
Paul Bakker43aff2a2013-09-09 00:10:27 +020087static int gcm_gen_table( gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000088{
Paul Bakker43aff2a2013-09-09 00:10:27 +020089 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000090 uint64_t hi, lo;
91 uint64_t vl, vh;
92 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020093 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020094
Paul Bakker89e80c92012-03-20 13:50:09 +000095 memset( h, 0, 16 );
Paul Bakker43aff2a2013-09-09 00:10:27 +020096 if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
97 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000098
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010099 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000100 GET_UINT32_BE( hi, h, 0 );
101 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000102 vh = (uint64_t) hi << 32 | lo;
103
Paul Bakker5c2364c2012-10-01 14:41:15 +0000104 GET_UINT32_BE( hi, h, 8 );
105 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000106 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200107
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100108 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000109 ctx->HL[8] = vl;
110 ctx->HH[8] = vh;
111
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100112#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
113 /* With CLMUL support, we need only h, not the rest of the table */
114 if( aesni_supports( POLARSSL_AESNI_CLMUL ) )
115 return( 0 );
116#endif
117
118 /* 0 corresponds to 0 in GF(2^128) */
119 ctx->HH[0] = 0;
120 ctx->HL[0] = 0;
121
Paul Bakker89e80c92012-03-20 13:50:09 +0000122 for( i = 4; i > 0; i >>= 1 )
123 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200124 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000125 vl = ( vh << 63 ) | ( vl >> 1 );
126 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
127
128 ctx->HL[i] = vl;
129 ctx->HH[i] = vh;
130 }
131
132 for (i = 2; i < 16; i <<= 1 )
133 {
134 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
135 vh = *HiH;
136 vl = *HiL;
137 for( j = 1; j < i; j++ )
138 {
139 HiH[j] = vh ^ ctx->HH[j];
140 HiL[j] = vl ^ ctx->HL[j];
141 }
142 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200143
144 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000145}
146
Paul Bakker43aff2a2013-09-09 00:10:27 +0200147int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
148 unsigned int keysize )
Paul Bakker89e80c92012-03-20 13:50:09 +0000149{
150 int ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200151 const cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000152
153 memset( ctx, 0, sizeof(gcm_context) );
154
Paul Bakker43aff2a2013-09-09 00:10:27 +0200155 cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
156 if( cipher_info == NULL )
157 return( POLARSSL_ERR_GCM_BAD_INPUT );
158
Paul Bakkera0558e02013-09-10 14:25:51 +0200159 if( cipher_info->block_size != 16 )
160 return( POLARSSL_ERR_GCM_BAD_INPUT );
161
Paul Bakker43aff2a2013-09-09 00:10:27 +0200162 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000163 return( ret );
164
Paul Bakker43aff2a2013-09-09 00:10:27 +0200165 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
166 POLARSSL_ENCRYPT ) ) != 0 )
167 {
168 return( ret );
169 }
170
171 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
172 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000173
174 return( 0 );
175}
176
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100177/*
178 * Shoup's method for multiplication use this table with
179 * last4[x] = x times P^128
180 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
181 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000182static const uint64_t last4[16] =
183{
184 0x0000, 0x1c20, 0x3840, 0x2460,
185 0x7080, 0x6ca0, 0x48c0, 0x54e0,
186 0xe100, 0xfd20, 0xd940, 0xc560,
187 0x9180, 0x8da0, 0xa9c0, 0xb5e0
188};
189
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100190/*
191 * Sets output to x times H using the precomputed tables.
192 * x and output are seen as elements of GF(2^128) as in [MGV].
193 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200194static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
195 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000196{
197 int i = 0;
198 unsigned char z[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000199 unsigned char lo, hi, rem;
200 uint64_t zh, zl;
201
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100202#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
203 if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) {
204 unsigned char h[16];
205
206 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
207 PUT_UINT32_BE( ctx->HH[8], h, 4 );
208 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
209 PUT_UINT32_BE( ctx->HL[8], h, 12 );
210
Manuel Pégourié-Gonnardd4588cf2013-12-30 13:54:23 +0100211 aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100212 return;
213 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200214#endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100215
Paul Bakker89e80c92012-03-20 13:50:09 +0000216 memset( z, 0x00, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000217
218 lo = x[15] & 0xf;
219 hi = x[15] >> 4;
220
221 zh = ctx->HH[lo];
222 zl = ctx->HL[lo];
223
224 for( i = 15; i >= 0; i-- )
225 {
226 lo = x[i] & 0xf;
227 hi = x[i] >> 4;
228
229 if( i != 15 )
230 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000231 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000232 zl = ( zh << 60 ) | ( zl >> 4 );
233 zh = ( zh >> 4 );
234 zh ^= (uint64_t) last4[rem] << 48;
235 zh ^= ctx->HH[lo];
236 zl ^= ctx->HL[lo];
237
238 }
239
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000240 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000241 zl = ( zh << 60 ) | ( zl >> 4 );
242 zh = ( zh >> 4 );
243 zh ^= (uint64_t) last4[rem] << 48;
244 zh ^= ctx->HH[hi];
245 zl ^= ctx->HL[hi];
246 }
247
Paul Bakker5c2364c2012-10-01 14:41:15 +0000248 PUT_UINT32_BE( zh >> 32, output, 0 );
249 PUT_UINT32_BE( zh, output, 4 );
250 PUT_UINT32_BE( zl >> 32, output, 8 );
251 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000252}
253
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200254int gcm_starts( gcm_context *ctx,
255 int mode,
256 const unsigned char *iv,
257 size_t iv_len,
258 const unsigned char *add,
259 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000260{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200261 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000262 unsigned char work_buf[16];
263 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000264 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200265 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000266
Paul Bakker52cf16c2013-07-26 13:55:38 +0200267 memset( ctx->y, 0x00, sizeof(ctx->y) );
268 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
269
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200270 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200271 ctx->len = 0;
272 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000273
274 if( iv_len == 12 )
275 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200276 memcpy( ctx->y, iv, iv_len );
277 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000278 }
279 else
280 {
281 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000282 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000283
284 p = iv;
285 while( iv_len > 0 )
286 {
287 use_len = ( iv_len < 16 ) ? iv_len : 16;
288
Paul Bakker67f9d532012-10-23 11:49:05 +0000289 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200290 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200291
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200292 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000293
294 iv_len -= use_len;
295 p += use_len;
296 }
297
Paul Bakker67f9d532012-10-23 11:49:05 +0000298 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200299 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000300
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200301 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000302 }
303
Paul Bakker43aff2a2013-09-09 00:10:27 +0200304 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
305 &olen ) ) != 0 )
306 {
307 return( ret );
308 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000309
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200310 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000311 p = add;
312 while( add_len > 0 )
313 {
314 use_len = ( add_len < 16 ) ? add_len : 16;
315
Paul Bakker67f9d532012-10-23 11:49:05 +0000316 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200317 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200318
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200319 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000320
321 add_len -= use_len;
322 p += use_len;
323 }
324
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200325 return( 0 );
326}
327
328int gcm_update( gcm_context *ctx,
329 size_t length,
330 const unsigned char *input,
331 unsigned char *output )
332{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200333 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200334 unsigned char ectr[16];
335 size_t i;
336 const unsigned char *p;
337 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200338 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200339
340 if( output > input && (size_t) ( output - input ) < length )
341 return( POLARSSL_ERR_GCM_BAD_INPUT );
342
343 ctx->len += length;
344
Paul Bakker89e80c92012-03-20 13:50:09 +0000345 p = input;
346 while( length > 0 )
347 {
348 use_len = ( length < 16 ) ? length : 16;
349
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100350 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200351 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000352 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000353
Paul Bakker43aff2a2013-09-09 00:10:27 +0200354 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
355 &olen ) ) != 0 )
356 {
357 return( ret );
358 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000359
Paul Bakker67f9d532012-10-23 11:49:05 +0000360 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000361 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200362 if( ctx->mode == GCM_DECRYPT )
363 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000364 out_p[i] = ectr[i] ^ p[i];
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200365 if( ctx->mode == GCM_ENCRYPT )
366 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000367 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200368
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200369 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200370
Paul Bakker89e80c92012-03-20 13:50:09 +0000371 length -= use_len;
372 p += use_len;
373 out_p += use_len;
374 }
375
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200376 return( 0 );
377}
378
379int gcm_finish( gcm_context *ctx,
380 unsigned char *tag,
381 size_t tag_len )
382{
383 unsigned char work_buf[16];
384 size_t i;
385 uint64_t orig_len = ctx->len * 8;
386 uint64_t orig_add_len = ctx->add_len * 8;
387
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200388 if( tag_len > 16 )
389 return( POLARSSL_ERR_GCM_BAD_INPUT );
390
Manuel Pégourié-Gonnard9241be72013-08-31 17:31:03 +0200391 if( tag_len != 0 )
392 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200393
Paul Bakker89e80c92012-03-20 13:50:09 +0000394 if( orig_len || orig_add_len )
395 {
396 memset( work_buf, 0x00, 16 );
397
Paul Bakker0ecdb232013-04-09 11:36:42 +0200398 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
399 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
400 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
401 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000402
Paul Bakker67f9d532012-10-23 11:49:05 +0000403 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200404 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000405
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200406 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000407
Paul Bakker67f9d532012-10-23 11:49:05 +0000408 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200409 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000410 }
411
412 return( 0 );
413}
414
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200415int gcm_crypt_and_tag( gcm_context *ctx,
416 int mode,
417 size_t length,
418 const unsigned char *iv,
419 size_t iv_len,
420 const unsigned char *add,
421 size_t add_len,
422 const unsigned char *input,
423 unsigned char *output,
424 size_t tag_len,
425 unsigned char *tag )
426{
427 int ret;
428
429 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
430 return( ret );
431
432 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
433 return( ret );
434
435 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
436 return( ret );
437
438 return( 0 );
439}
440
Paul Bakker89e80c92012-03-20 13:50:09 +0000441int gcm_auth_decrypt( gcm_context *ctx,
442 size_t length,
443 const unsigned char *iv,
444 size_t iv_len,
445 const unsigned char *add,
446 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200447 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000448 size_t tag_len,
449 const unsigned char *input,
450 unsigned char *output )
451{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100452 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000453 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200454 size_t i;
455 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000456
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100457 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
458 iv, iv_len, add, add_len,
459 input, output, tag_len, check_tag ) ) != 0 )
460 {
461 return( ret );
462 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000463
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200464 /* Check tag in "constant-time" */
465 for( diff = 0, i = 0; i < tag_len; i++ )
466 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000467
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200468 if( diff != 0 )
469 {
470 memset( output, 0, length );
471 return( POLARSSL_ERR_GCM_AUTH_FAILED );
472 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000473
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200474 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000475}
476
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200477void gcm_free( gcm_context *ctx )
478{
479 (void) cipher_free_ctx( &ctx->cipher_ctx );
480 memset( ctx, 0, sizeof( gcm_context ) );
481}
482
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200483#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000484
485#include <stdio.h>
486
487/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200488 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000489 *
490 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
491 */
492#define MAX_TESTS 6
493
494int key_index[MAX_TESTS] =
495 { 0, 0, 1, 1, 1, 1 };
496
497unsigned char key[MAX_TESTS][32] =
498{
499 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
503 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
504 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
505 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200506 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000507};
508
509size_t iv_len[MAX_TESTS] =
510 { 12, 12, 12, 12, 8, 60 };
511
512int iv_index[MAX_TESTS] =
513 { 0, 0, 1, 1, 1, 2 };
514
515unsigned char iv[MAX_TESTS][64] =
516{
517 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518 0x00, 0x00, 0x00, 0x00 },
519 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
520 0xde, 0xca, 0xf8, 0x88 },
521 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200522 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000523 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200524 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000525 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200526 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000527 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200528 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000529};
530
531size_t add_len[MAX_TESTS] =
532 { 0, 0, 0, 20, 20, 20 };
533
534int add_index[MAX_TESTS] =
535 { 0, 0, 0, 1, 1, 1 };
536
537unsigned char additional[MAX_TESTS][64] =
538{
539 { 0x00 },
540 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200541 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000542 0xab, 0xad, 0xda, 0xd2 },
543};
544
545size_t pt_len[MAX_TESTS] =
546 { 0, 16, 64, 60, 60, 60 };
547
548int pt_index[MAX_TESTS] =
549 { 0, 0, 1, 1, 1, 1 };
550
551unsigned char pt[MAX_TESTS][64] =
552{
553 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
555 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
556 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
557 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
558 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
559 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
560 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
561 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
562 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
563};
564
565unsigned char ct[MAX_TESTS * 3][64] =
566{
567 { 0x00 },
568 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
569 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
570 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200571 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000572 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200573 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000574 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200575 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000576 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
577 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
578 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200579 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000580 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200581 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000582 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200583 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000584 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
585 0x3d, 0x58, 0xe0, 0x91 },
586 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200587 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000588 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200589 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000590 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200591 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000592 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
593 0xc2, 0x3f, 0x45, 0x98 },
594 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200595 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000596 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200597 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000598 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200599 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000600 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
601 0x4c, 0x34, 0xae, 0xe5 },
602 { 0x00 },
603 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200604 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000605 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200606 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000607 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200608 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000609 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200610 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000611 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
612 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
613 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200614 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200616 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
617 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
618 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000619 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200620 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000621 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200622 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000623 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200624 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200626 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000627 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200628 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000629 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200630 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000631 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200632 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000633 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200634 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000635 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200636 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000637 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200638 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
639 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
640 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
641 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
642 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
643 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
644 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
645 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
646 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
647 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
648 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
649 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
650 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
651 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
652 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
653 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
654 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
655 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000656 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200657 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000658 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200659 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200661 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000662 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200663 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000664 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200665 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000666 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200667 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000668 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200669 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000670 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200671 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000672};
673
674unsigned char tag[MAX_TESTS * 3][16] =
675{
676 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
677 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
678 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
679 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
680 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200681 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000682 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
683 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
684 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
685 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
686 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
687 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
688 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
689 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
690 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200691 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000692 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
693 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
694 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200695 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000696 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200697 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000698 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200699 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000700 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200701 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000702 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200703 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000704 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200705 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000706 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200707 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000708 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200709 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000710 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200711 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000712};
713
714int gcm_self_test( int verbose )
715{
716 gcm_context ctx;
717 unsigned char buf[64];
718 unsigned char tag_buf[16];
719 int i, j, ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200720 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000721
722 for( j = 0; j < 3; j++ )
723 {
724 int key_len = 128 + 64 * j;
725
726 for( i = 0; i < MAX_TESTS; i++ )
727 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200728 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100729 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
730 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200731
Paul Bakker43aff2a2013-09-09 00:10:27 +0200732 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000733
734 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
735 pt_len[i],
736 iv[iv_index[i]], iv_len[i],
737 additional[add_index[i]], add_len[i],
738 pt[pt_index[i]], buf, 16, tag_buf );
739
740 if( ret != 0 ||
741 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
742 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
743 {
744 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100745 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000746
747 return( 1 );
748 }
749
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200750 gcm_free( &ctx );
751
Paul Bakker89e80c92012-03-20 13:50:09 +0000752 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100753 polarssl_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000754
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200755 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100756 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
757 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200758
Paul Bakker43aff2a2013-09-09 00:10:27 +0200759 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000760
761 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
762 pt_len[i],
763 iv[iv_index[i]], iv_len[i],
764 additional[add_index[i]], add_len[i],
765 ct[j * 6 + i], buf, 16, tag_buf );
766
767 if( ret != 0 ||
768 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
769 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
770 {
771 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100772 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000773
774 return( 1 );
775 }
776
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200777 gcm_free( &ctx );
778
Paul Bakker89e80c92012-03-20 13:50:09 +0000779 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100780 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200781
782 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100783 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
784 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200785
Paul Bakker43aff2a2013-09-09 00:10:27 +0200786 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200787
788 ret = gcm_starts( &ctx, GCM_ENCRYPT,
789 iv[iv_index[i]], iv_len[i],
790 additional[add_index[i]], add_len[i] );
791 if( ret != 0 )
792 {
793 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100794 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200795
796 return( 1 );
797 }
798
799 if( pt_len[i] > 32 )
800 {
801 size_t rest_len = pt_len[i] - 32;
802 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
803 if( ret != 0 )
804 {
805 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100806 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200807
808 return( 1 );
809 }
810
811 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, buf + 32 );
812 if( ret != 0 )
813 {
814 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100815 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200816
817 return( 1 );
818 }
819 }
820 else
821 {
822 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
823 if( ret != 0 )
824 {
825 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100826 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200827
828 return( 1 );
829 }
830 }
831
832 ret = gcm_finish( &ctx, tag_buf, 16 );
833 if( ret != 0 ||
834 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
835 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
836 {
837 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100838 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200839
840 return( 1 );
841 }
842
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200843 gcm_free( &ctx );
844
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200845 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100846 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200847
848 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100849 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
850 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200851
Paul Bakker43aff2a2013-09-09 00:10:27 +0200852 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200853
854 ret = gcm_starts( &ctx, GCM_DECRYPT,
855 iv[iv_index[i]], iv_len[i],
856 additional[add_index[i]], add_len[i] );
857 if( ret != 0 )
858 {
859 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100860 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200861
862 return( 1 );
863 }
864
865 if( pt_len[i] > 32 )
866 {
867 size_t rest_len = pt_len[i] - 32;
868 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
869 if( ret != 0 )
870 {
871 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100872 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200873
874 return( 1 );
875 }
876
877 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, buf + 32 );
878 if( ret != 0 )
879 {
880 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100881 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200882
883 return( 1 );
884 }
885 }
886 else
887 {
888 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
889 if( ret != 0 )
890 {
891 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100892 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200893
894 return( 1 );
895 }
896 }
897
898 ret = gcm_finish( &ctx, tag_buf, 16 );
899 if( ret != 0 ||
900 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
901 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
902 {
903 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100904 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200905
906 return( 1 );
907 }
908
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200909 gcm_free( &ctx );
910
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200911 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100912 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200913
Paul Bakker89e80c92012-03-20 13:50:09 +0000914 }
915 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200916
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200917 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100918 polarssl_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000919
920 return( 0 );
921}
922
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200923
924
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200925#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000926
Paul Bakker9af723c2014-05-01 13:03:14 +0200927#endif /* POLARSSL_GCM_C */