blob: 77b1e0fb68358138dc06474f3d01e66e5c2b2811 [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
Paul Bakker34617722014-06-13 17:20:13 +020079/* Implementation that should never be optimized out by the compiler */
80static void polarssl_zeroize( void *v, size_t n ) {
81 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
82}
83
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010084/*
85 * Precompute small multiples of H, that is set
86 * HH[i] || HL[i] = H times i,
87 * where i is seen as a field element as in [MGV], ie high-order bits
88 * correspond to low powers of P. The result is stored in the same way, that
89 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
90 * corresponds to P^127.
91 */
Paul Bakker43aff2a2013-09-09 00:10:27 +020092static int gcm_gen_table( gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000093{
Paul Bakker43aff2a2013-09-09 00:10:27 +020094 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000095 uint64_t hi, lo;
96 uint64_t vl, vh;
97 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020098 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020099
Paul Bakker89e80c92012-03-20 13:50:09 +0000100 memset( h, 0, 16 );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200101 if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
102 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000103
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100104 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000105 GET_UINT32_BE( hi, h, 0 );
106 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000107 vh = (uint64_t) hi << 32 | lo;
108
Paul Bakker5c2364c2012-10-01 14:41:15 +0000109 GET_UINT32_BE( hi, h, 8 );
110 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000111 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200112
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100113 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000114 ctx->HL[8] = vl;
115 ctx->HH[8] = vh;
116
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100117#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
118 /* With CLMUL support, we need only h, not the rest of the table */
119 if( aesni_supports( POLARSSL_AESNI_CLMUL ) )
120 return( 0 );
121#endif
122
123 /* 0 corresponds to 0 in GF(2^128) */
124 ctx->HH[0] = 0;
125 ctx->HL[0] = 0;
126
Paul Bakker89e80c92012-03-20 13:50:09 +0000127 for( i = 4; i > 0; i >>= 1 )
128 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200129 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000130 vl = ( vh << 63 ) | ( vl >> 1 );
131 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
132
133 ctx->HL[i] = vl;
134 ctx->HH[i] = vh;
135 }
136
Paul Bakker66d5d072014-06-17 16:39:18 +0200137 for( i = 2; i < 16; i <<= 1 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000138 {
139 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
140 vh = *HiH;
141 vl = *HiL;
142 for( j = 1; j < i; j++ )
143 {
144 HiH[j] = vh ^ ctx->HH[j];
145 HiL[j] = vl ^ ctx->HL[j];
146 }
147 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200148
149 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000150}
151
Paul Bakker43aff2a2013-09-09 00:10:27 +0200152int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
153 unsigned int keysize )
Paul Bakker89e80c92012-03-20 13:50:09 +0000154{
155 int ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200156 const cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000157
158 memset( ctx, 0, sizeof(gcm_context) );
159
Paul Bakker84bbeb52014-07-01 14:53:22 +0200160 cipher_init( &ctx->cipher_ctx );
161
Paul Bakker43aff2a2013-09-09 00:10:27 +0200162 cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
163 if( cipher_info == NULL )
164 return( POLARSSL_ERR_GCM_BAD_INPUT );
165
Paul Bakkera0558e02013-09-10 14:25:51 +0200166 if( cipher_info->block_size != 16 )
167 return( POLARSSL_ERR_GCM_BAD_INPUT );
168
Paul Bakker43aff2a2013-09-09 00:10:27 +0200169 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000170 return( ret );
171
Paul Bakker43aff2a2013-09-09 00:10:27 +0200172 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
173 POLARSSL_ENCRYPT ) ) != 0 )
174 {
175 return( ret );
176 }
177
178 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
179 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000180
181 return( 0 );
182}
183
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100184/*
185 * Shoup's method for multiplication use this table with
186 * last4[x] = x times P^128
187 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
188 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000189static const uint64_t last4[16] =
190{
191 0x0000, 0x1c20, 0x3840, 0x2460,
192 0x7080, 0x6ca0, 0x48c0, 0x54e0,
193 0xe100, 0xfd20, 0xd940, 0xc560,
194 0x9180, 0x8da0, 0xa9c0, 0xb5e0
195};
196
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100197/*
198 * Sets output to x times H using the precomputed tables.
199 * x and output are seen as elements of GF(2^128) as in [MGV].
200 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200201static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
202 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000203{
204 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000205 unsigned char lo, hi, rem;
206 uint64_t zh, zl;
207
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100208#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
209 if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) {
210 unsigned char h[16];
211
212 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
213 PUT_UINT32_BE( ctx->HH[8], h, 4 );
214 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
215 PUT_UINT32_BE( ctx->HL[8], h, 12 );
216
Manuel Pégourié-Gonnardd4588cf2013-12-30 13:54:23 +0100217 aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100218 return;
219 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200220#endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100221
Paul Bakker89e80c92012-03-20 13:50:09 +0000222 lo = x[15] & 0xf;
223 hi = x[15] >> 4;
224
225 zh = ctx->HH[lo];
226 zl = ctx->HL[lo];
227
228 for( i = 15; i >= 0; i-- )
229 {
230 lo = x[i] & 0xf;
231 hi = x[i] >> 4;
232
233 if( i != 15 )
234 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000235 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000236 zl = ( zh << 60 ) | ( zl >> 4 );
237 zh = ( zh >> 4 );
238 zh ^= (uint64_t) last4[rem] << 48;
239 zh ^= ctx->HH[lo];
240 zl ^= ctx->HL[lo];
241
242 }
243
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000244 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000245 zl = ( zh << 60 ) | ( zl >> 4 );
246 zh = ( zh >> 4 );
247 zh ^= (uint64_t) last4[rem] << 48;
248 zh ^= ctx->HH[hi];
249 zl ^= ctx->HL[hi];
250 }
251
Paul Bakker5c2364c2012-10-01 14:41:15 +0000252 PUT_UINT32_BE( zh >> 32, output, 0 );
253 PUT_UINT32_BE( zh, output, 4 );
254 PUT_UINT32_BE( zl >> 32, output, 8 );
255 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000256}
257
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200258int gcm_starts( gcm_context *ctx,
259 int mode,
260 const unsigned char *iv,
261 size_t iv_len,
262 const unsigned char *add,
263 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000264{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200265 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000266 unsigned char work_buf[16];
267 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000268 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200269 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000270
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200271 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
272 if( ( (uint64_t) iv_len ) >> 61 != 0 ||
273 ( (uint64_t) add_len ) >> 61 != 0 )
274 {
275 return( POLARSSL_ERR_GCM_BAD_INPUT );
276 }
277
Paul Bakker52cf16c2013-07-26 13:55:38 +0200278 memset( ctx->y, 0x00, sizeof(ctx->y) );
279 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
280
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200281 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200282 ctx->len = 0;
283 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000284
285 if( iv_len == 12 )
286 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200287 memcpy( ctx->y, iv, iv_len );
288 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000289 }
290 else
291 {
292 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000293 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000294
295 p = iv;
296 while( iv_len > 0 )
297 {
298 use_len = ( iv_len < 16 ) ? iv_len : 16;
299
Paul Bakker67f9d532012-10-23 11:49:05 +0000300 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200301 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200302
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200303 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000304
305 iv_len -= use_len;
306 p += use_len;
307 }
308
Paul Bakker67f9d532012-10-23 11:49:05 +0000309 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200310 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000311
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200312 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000313 }
314
Paul Bakker43aff2a2013-09-09 00:10:27 +0200315 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
316 &olen ) ) != 0 )
317 {
318 return( ret );
319 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000320
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200321 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000322 p = add;
323 while( add_len > 0 )
324 {
325 use_len = ( add_len < 16 ) ? add_len : 16;
326
Paul Bakker67f9d532012-10-23 11:49:05 +0000327 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200328 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200329
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200330 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000331
332 add_len -= use_len;
333 p += use_len;
334 }
335
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200336 return( 0 );
337}
338
339int gcm_update( gcm_context *ctx,
340 size_t length,
341 const unsigned char *input,
342 unsigned char *output )
343{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200344 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200345 unsigned char ectr[16];
346 size_t i;
347 const unsigned char *p;
348 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200349 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200350
351 if( output > input && (size_t) ( output - input ) < length )
352 return( POLARSSL_ERR_GCM_BAD_INPUT );
353
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200354 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
355 * Also check for possible overflow */
356 if( ctx->len + length < ctx->len ||
357 (uint64_t) ctx->len + length > 0x03FFFFE0llu )
358 {
359 return( POLARSSL_ERR_GCM_BAD_INPUT );
360 }
361
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200362 ctx->len += length;
363
Paul Bakker89e80c92012-03-20 13:50:09 +0000364 p = input;
365 while( length > 0 )
366 {
367 use_len = ( length < 16 ) ? length : 16;
368
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100369 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200370 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000371 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000372
Paul Bakker43aff2a2013-09-09 00:10:27 +0200373 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
374 &olen ) ) != 0 )
375 {
376 return( ret );
377 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000378
Paul Bakker67f9d532012-10-23 11:49:05 +0000379 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000380 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200381 if( ctx->mode == GCM_DECRYPT )
382 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000383 out_p[i] = ectr[i] ^ p[i];
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200384 if( ctx->mode == GCM_ENCRYPT )
385 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000386 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200387
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200388 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200389
Paul Bakker89e80c92012-03-20 13:50:09 +0000390 length -= use_len;
391 p += use_len;
392 out_p += use_len;
393 }
394
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200395 return( 0 );
396}
397
398int gcm_finish( gcm_context *ctx,
399 unsigned char *tag,
400 size_t tag_len )
401{
402 unsigned char work_buf[16];
403 size_t i;
404 uint64_t orig_len = ctx->len * 8;
405 uint64_t orig_add_len = ctx->add_len * 8;
406
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200407 if( tag_len > 16 || tag_len < 4 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200408 return( POLARSSL_ERR_GCM_BAD_INPUT );
409
Manuel Pégourié-Gonnard9241be72013-08-31 17:31:03 +0200410 if( tag_len != 0 )
411 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200412
Paul Bakker89e80c92012-03-20 13:50:09 +0000413 if( orig_len || orig_add_len )
414 {
415 memset( work_buf, 0x00, 16 );
416
Paul Bakker0ecdb232013-04-09 11:36:42 +0200417 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
418 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
419 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
420 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000421
Paul Bakker67f9d532012-10-23 11:49:05 +0000422 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200423 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000424
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200425 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000426
Paul Bakker67f9d532012-10-23 11:49:05 +0000427 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200428 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000429 }
430
431 return( 0 );
432}
433
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200434int gcm_crypt_and_tag( gcm_context *ctx,
435 int mode,
436 size_t length,
437 const unsigned char *iv,
438 size_t iv_len,
439 const unsigned char *add,
440 size_t add_len,
441 const unsigned char *input,
442 unsigned char *output,
443 size_t tag_len,
444 unsigned char *tag )
445{
446 int ret;
447
448 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
449 return( ret );
450
451 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
452 return( ret );
453
454 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
455 return( ret );
456
457 return( 0 );
458}
459
Paul Bakker89e80c92012-03-20 13:50:09 +0000460int gcm_auth_decrypt( gcm_context *ctx,
461 size_t length,
462 const unsigned char *iv,
463 size_t iv_len,
464 const unsigned char *add,
465 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200466 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000467 size_t tag_len,
468 const unsigned char *input,
469 unsigned char *output )
470{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100471 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000472 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200473 size_t i;
474 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000475
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100476 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
477 iv, iv_len, add, add_len,
478 input, output, tag_len, check_tag ) ) != 0 )
479 {
480 return( ret );
481 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000482
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200483 /* Check tag in "constant-time" */
484 for( diff = 0, i = 0; i < tag_len; i++ )
485 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000486
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200487 if( diff != 0 )
488 {
Paul Bakker34617722014-06-13 17:20:13 +0200489 polarssl_zeroize( output, length );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200490 return( POLARSSL_ERR_GCM_AUTH_FAILED );
491 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000492
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200493 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000494}
495
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200496void gcm_free( gcm_context *ctx )
497{
Paul Bakker84bbeb52014-07-01 14:53:22 +0200498 cipher_free( &ctx->cipher_ctx );
Paul Bakker34617722014-06-13 17:20:13 +0200499 polarssl_zeroize( ctx, sizeof( gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200500}
501
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200502#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000503
504#include <stdio.h>
505
506/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200507 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000508 *
509 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
510 */
511#define MAX_TESTS 6
512
513int key_index[MAX_TESTS] =
514 { 0, 0, 1, 1, 1, 1 };
515
516unsigned char key[MAX_TESTS][32] =
517{
518 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
522 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
523 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
524 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200525 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000526};
527
528size_t iv_len[MAX_TESTS] =
529 { 12, 12, 12, 12, 8, 60 };
530
531int iv_index[MAX_TESTS] =
532 { 0, 0, 1, 1, 1, 2 };
533
534unsigned char iv[MAX_TESTS][64] =
535{
536 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537 0x00, 0x00, 0x00, 0x00 },
538 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
539 0xde, 0xca, 0xf8, 0x88 },
540 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200541 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000542 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200543 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000544 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200545 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000546 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200547 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000548};
549
550size_t add_len[MAX_TESTS] =
551 { 0, 0, 0, 20, 20, 20 };
552
553int add_index[MAX_TESTS] =
554 { 0, 0, 0, 1, 1, 1 };
555
556unsigned char additional[MAX_TESTS][64] =
557{
558 { 0x00 },
559 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200560 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000561 0xab, 0xad, 0xda, 0xd2 },
562};
563
564size_t pt_len[MAX_TESTS] =
565 { 0, 16, 64, 60, 60, 60 };
566
567int pt_index[MAX_TESTS] =
568 { 0, 0, 1, 1, 1, 1 };
569
570unsigned char pt[MAX_TESTS][64] =
571{
572 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
574 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
575 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
576 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
577 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
578 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
579 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
580 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
581 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
582};
583
584unsigned char ct[MAX_TESTS * 3][64] =
585{
586 { 0x00 },
587 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
588 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
589 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200590 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000591 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200592 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000593 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200594 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000595 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
596 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
597 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200598 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000599 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200600 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000601 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200602 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000603 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
604 0x3d, 0x58, 0xe0, 0x91 },
605 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200606 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000607 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200608 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000609 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200610 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000611 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
612 0xc2, 0x3f, 0x45, 0x98 },
613 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200614 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200616 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000617 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200618 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000619 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
620 0x4c, 0x34, 0xae, 0xe5 },
621 { 0x00 },
622 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200623 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000624 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200625 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000626 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200627 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000628 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200629 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000630 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
631 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
632 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200633 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000634 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200635 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
636 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
637 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000638 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200639 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000640 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200641 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200643 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000644 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200645 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000646 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200647 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200649 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000650 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200651 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200653 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000654 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000656 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200657 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
658 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
659 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
660 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
661 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
662 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
663 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
664 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
665 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
666 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
667 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
668 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
669 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
670 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
671 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
672 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
673 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
674 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000675 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200676 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000677 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200678 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000679 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200680 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000681 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200682 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000683 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200684 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000685 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200686 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000687 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200688 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000689 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200690 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000691};
692
693unsigned char tag[MAX_TESTS * 3][16] =
694{
695 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
696 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
697 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
698 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
699 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
702 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
703 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
704 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
705 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
706 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
707 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
708 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
709 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200710 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000711 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
712 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
713 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200714 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000715 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200716 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000717 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200718 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000719 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200720 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000721 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200722 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000723 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200724 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000725 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200726 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000727 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200728 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000729 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200730 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000731};
732
733int gcm_self_test( int verbose )
734{
735 gcm_context ctx;
736 unsigned char buf[64];
737 unsigned char tag_buf[16];
738 int i, j, ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200739 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000740
741 for( j = 0; j < 3; j++ )
742 {
743 int key_len = 128 + 64 * j;
744
745 for( i = 0; i < MAX_TESTS; i++ )
746 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200747 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100748 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
749 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200750
Paul Bakker43aff2a2013-09-09 00:10:27 +0200751 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000752
753 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
754 pt_len[i],
755 iv[iv_index[i]], iv_len[i],
756 additional[add_index[i]], add_len[i],
757 pt[pt_index[i]], buf, 16, tag_buf );
758
759 if( ret != 0 ||
760 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
761 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
762 {
763 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100764 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000765
766 return( 1 );
767 }
768
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200769 gcm_free( &ctx );
770
Paul Bakker89e80c92012-03-20 13:50:09 +0000771 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100772 polarssl_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000773
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200774 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100775 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
776 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200777
Paul Bakker43aff2a2013-09-09 00:10:27 +0200778 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000779
780 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
781 pt_len[i],
782 iv[iv_index[i]], iv_len[i],
783 additional[add_index[i]], add_len[i],
784 ct[j * 6 + i], buf, 16, tag_buf );
785
786 if( ret != 0 ||
787 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
788 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
789 {
790 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100791 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000792
793 return( 1 );
794 }
795
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200796 gcm_free( &ctx );
797
Paul Bakker89e80c92012-03-20 13:50:09 +0000798 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100799 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200800
801 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100802 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
803 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200804
Paul Bakker43aff2a2013-09-09 00:10:27 +0200805 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200806
807 ret = gcm_starts( &ctx, GCM_ENCRYPT,
808 iv[iv_index[i]], iv_len[i],
809 additional[add_index[i]], add_len[i] );
810 if( ret != 0 )
811 {
812 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100813 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200814
815 return( 1 );
816 }
817
818 if( pt_len[i] > 32 )
819 {
820 size_t rest_len = pt_len[i] - 32;
821 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
822 if( ret != 0 )
823 {
824 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100825 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200826
827 return( 1 );
828 }
829
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200830 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
831 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200832 if( ret != 0 )
833 {
834 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100835 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200836
837 return( 1 );
838 }
839 }
840 else
841 {
842 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
843 if( ret != 0 )
844 {
845 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100846 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200847
848 return( 1 );
849 }
850 }
851
852 ret = gcm_finish( &ctx, tag_buf, 16 );
853 if( ret != 0 ||
854 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
855 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
856 {
857 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100858 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200859
860 return( 1 );
861 }
862
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200863 gcm_free( &ctx );
864
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200865 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100866 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200867
868 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100869 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
870 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200871
Paul Bakker43aff2a2013-09-09 00:10:27 +0200872 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200873
874 ret = gcm_starts( &ctx, GCM_DECRYPT,
875 iv[iv_index[i]], iv_len[i],
876 additional[add_index[i]], add_len[i] );
877 if( ret != 0 )
878 {
879 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100880 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200881
882 return( 1 );
883 }
884
885 if( pt_len[i] > 32 )
886 {
887 size_t rest_len = pt_len[i] - 32;
888 ret = gcm_update( &ctx, 32, 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
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200897 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
898 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200899 if( ret != 0 )
900 {
901 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100902 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200903
904 return( 1 );
905 }
906 }
907 else
908 {
909 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
910 if( ret != 0 )
911 {
912 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100913 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200914
915 return( 1 );
916 }
917 }
918
919 ret = gcm_finish( &ctx, tag_buf, 16 );
920 if( ret != 0 ||
921 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
922 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
923 {
924 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100925 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200926
927 return( 1 );
928 }
929
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200930 gcm_free( &ctx );
931
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200932 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100933 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200934
Paul Bakker89e80c92012-03-20 13:50:09 +0000935 }
936 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200937
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200938 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100939 polarssl_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000940
941 return( 0 );
942}
943
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200944
945
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200946#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000947
Paul Bakker9af723c2014-05-01 13:03:14 +0200948#endif /* POLARSSL_GCM_C */