blob: 33306e554eddd2b01e7d5bb7c834f78d4ecde4b3 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakker89e80c92012-03-20 13:50:09 +00005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker89e80c92012-03-20 13:50:09 +00007 *
Paul Bakker89e80c92012-03-20 13:50:09 +00008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010022
Paul Bakker89e80c92012-03-20 13:50:09 +000023/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010024 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
25 *
26 * See also:
27 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
28 *
29 * We use the algorithm described as Shoup's method with 4-bit tables in
30 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000031 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010032
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020033#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker89e80c92012-03-20 13:50:09 +000034#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020035#else
36#include POLARSSL_CONFIG_FILE
37#endif
Paul Bakker89e80c92012-03-20 13:50:09 +000038
39#if defined(POLARSSL_GCM_C)
40
41#include "polarssl/gcm.h"
42
Rich Evans00ab4702015-02-06 13:43:58 +000043#include <string.h>
44
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010045#if defined(POLARSSL_AESNI_C)
46#include "polarssl/aesni.h"
47#endif
48
Rich Evans00ab4702015-02-06 13:43:58 +000049#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
Paul Bakker7dc4c442014-02-01 22:50:26 +010050#if defined(POLARSSL_PLATFORM_C)
51#include "polarssl/platform.h"
52#else
Rich Evans00ab4702015-02-06 13:43:58 +000053#include <stdio.h>
Paul Bakker7dc4c442014-02-01 22:50:26 +010054#define polarssl_printf printf
Rich Evans00ab4702015-02-06 13:43:58 +000055#endif /* POLARSSL_PLATFORM_C */
56#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010057
Paul Bakker89e80c92012-03-20 13:50:09 +000058/*
59 * 32-bit integer manipulation macros (big endian)
60 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000061#ifndef GET_UINT32_BE
62#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000063{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000064 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
65 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
66 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
67 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000068}
69#endif
70
Paul Bakker5c2364c2012-10-01 14:41:15 +000071#ifndef PUT_UINT32_BE
72#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000073{ \
74 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
75 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
76 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
77 (b)[(i) + 3] = (unsigned char) ( (n) ); \
78}
79#endif
80
Paul Bakker34617722014-06-13 17:20:13 +020081/* Implementation that should never be optimized out by the compiler */
82static void polarssl_zeroize( void *v, size_t n ) {
83 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
84}
85
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010086/*
87 * Precompute small multiples of H, that is set
88 * HH[i] || HL[i] = H times i,
89 * where i is seen as a field element as in [MGV], ie high-order bits
90 * correspond to low powers of P. The result is stored in the same way, that
91 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
92 * corresponds to P^127.
93 */
Paul Bakker43aff2a2013-09-09 00:10:27 +020094static int gcm_gen_table( gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000095{
Paul Bakker43aff2a2013-09-09 00:10:27 +020096 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000097 uint64_t hi, lo;
98 uint64_t vl, vh;
99 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200100 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200101
Paul Bakker89e80c92012-03-20 13:50:09 +0000102 memset( h, 0, 16 );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200103 if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
104 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000105
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100106 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000107 GET_UINT32_BE( hi, h, 0 );
108 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000109 vh = (uint64_t) hi << 32 | lo;
110
Paul Bakker5c2364c2012-10-01 14:41:15 +0000111 GET_UINT32_BE( hi, h, 8 );
112 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000113 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200114
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100115 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000116 ctx->HL[8] = vl;
117 ctx->HH[8] = vh;
118
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100119#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
120 /* With CLMUL support, we need only h, not the rest of the table */
121 if( aesni_supports( POLARSSL_AESNI_CLMUL ) )
122 return( 0 );
123#endif
124
125 /* 0 corresponds to 0 in GF(2^128) */
126 ctx->HH[0] = 0;
127 ctx->HL[0] = 0;
128
Paul Bakker89e80c92012-03-20 13:50:09 +0000129 for( i = 4; i > 0; i >>= 1 )
130 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200131 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000132 vl = ( vh << 63 ) | ( vl >> 1 );
133 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
134
135 ctx->HL[i] = vl;
136 ctx->HH[i] = vh;
137 }
138
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000139 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000140 {
141 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
142 vh = *HiH;
143 vl = *HiL;
144 for( j = 1; j < i; j++ )
145 {
146 HiH[j] = vh ^ ctx->HH[j];
147 HiL[j] = vl ^ ctx->HL[j];
148 }
149 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200150
151 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000152}
153
Paul Bakker43aff2a2013-09-09 00:10:27 +0200154int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
155 unsigned int keysize )
Paul Bakker89e80c92012-03-20 13:50:09 +0000156{
157 int ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200158 const cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000159
160 memset( ctx, 0, sizeof(gcm_context) );
161
Paul Bakker84bbeb52014-07-01 14:53:22 +0200162 cipher_init( &ctx->cipher_ctx );
163
Paul Bakker43aff2a2013-09-09 00:10:27 +0200164 cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
165 if( cipher_info == NULL )
166 return( POLARSSL_ERR_GCM_BAD_INPUT );
167
Paul Bakkera0558e02013-09-10 14:25:51 +0200168 if( cipher_info->block_size != 16 )
169 return( POLARSSL_ERR_GCM_BAD_INPUT );
170
Manuel Pégourié-Gonnard61977612015-05-27 17:38:50 +0200171 cipher_free( &ctx->cipher_ctx );
172
Paul Bakker43aff2a2013-09-09 00:10:27 +0200173 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000174 return( ret );
175
Paul Bakker43aff2a2013-09-09 00:10:27 +0200176 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
177 POLARSSL_ENCRYPT ) ) != 0 )
178 {
179 return( ret );
180 }
181
182 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
183 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000184
185 return( 0 );
186}
187
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100188/*
189 * Shoup's method for multiplication use this table with
190 * last4[x] = x times P^128
191 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
192 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000193static const uint64_t last4[16] =
194{
195 0x0000, 0x1c20, 0x3840, 0x2460,
196 0x7080, 0x6ca0, 0x48c0, 0x54e0,
197 0xe100, 0xfd20, 0xd940, 0xc560,
198 0x9180, 0x8da0, 0xa9c0, 0xb5e0
199};
200
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100201/*
202 * Sets output to x times H using the precomputed tables.
203 * x and output are seen as elements of GF(2^128) as in [MGV].
204 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200205static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
206 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000207{
208 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000209 unsigned char lo, hi, rem;
210 uint64_t zh, zl;
211
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100212#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
213 if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) {
214 unsigned char h[16];
215
216 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
217 PUT_UINT32_BE( ctx->HH[8], h, 4 );
218 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
219 PUT_UINT32_BE( ctx->HL[8], h, 12 );
220
Manuel Pégourié-Gonnardd4588cf2013-12-30 13:54:23 +0100221 aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100222 return;
223 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200224#endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100225
Paul Bakker89e80c92012-03-20 13:50:09 +0000226 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000227
228 zh = ctx->HH[lo];
229 zl = ctx->HL[lo];
230
231 for( i = 15; i >= 0; i-- )
232 {
233 lo = x[i] & 0xf;
234 hi = x[i] >> 4;
235
236 if( i != 15 )
237 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000238 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000239 zl = ( zh << 60 ) | ( zl >> 4 );
240 zh = ( zh >> 4 );
241 zh ^= (uint64_t) last4[rem] << 48;
242 zh ^= ctx->HH[lo];
243 zl ^= ctx->HL[lo];
244
245 }
246
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000247 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000248 zl = ( zh << 60 ) | ( zl >> 4 );
249 zh = ( zh >> 4 );
250 zh ^= (uint64_t) last4[rem] << 48;
251 zh ^= ctx->HH[hi];
252 zl ^= ctx->HL[hi];
253 }
254
Paul Bakker5c2364c2012-10-01 14:41:15 +0000255 PUT_UINT32_BE( zh >> 32, output, 0 );
256 PUT_UINT32_BE( zh, output, 4 );
257 PUT_UINT32_BE( zl >> 32, output, 8 );
258 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000259}
260
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200261int gcm_starts( gcm_context *ctx,
262 int mode,
263 const unsigned char *iv,
264 size_t iv_len,
265 const unsigned char *add,
266 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000267{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200268 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000269 unsigned char work_buf[16];
270 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000271 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200272 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000273
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200274 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
275 if( ( (uint64_t) iv_len ) >> 61 != 0 ||
276 ( (uint64_t) add_len ) >> 61 != 0 )
277 {
278 return( POLARSSL_ERR_GCM_BAD_INPUT );
279 }
280
Paul Bakker52cf16c2013-07-26 13:55:38 +0200281 memset( ctx->y, 0x00, sizeof(ctx->y) );
282 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
283
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200284 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200285 ctx->len = 0;
286 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000287
288 if( iv_len == 12 )
289 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200290 memcpy( ctx->y, iv, iv_len );
291 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000292 }
293 else
294 {
295 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000296 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000297
298 p = iv;
299 while( iv_len > 0 )
300 {
301 use_len = ( iv_len < 16 ) ? iv_len : 16;
302
Paul Bakker67f9d532012-10-23 11:49:05 +0000303 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200304 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200305
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200306 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000307
308 iv_len -= use_len;
309 p += use_len;
310 }
311
Paul Bakker67f9d532012-10-23 11:49:05 +0000312 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200313 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000314
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200315 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000316 }
317
Paul Bakker43aff2a2013-09-09 00:10:27 +0200318 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
319 &olen ) ) != 0 )
320 {
321 return( ret );
322 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000323
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200324 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000325 p = add;
326 while( add_len > 0 )
327 {
328 use_len = ( add_len < 16 ) ? add_len : 16;
329
Paul Bakker67f9d532012-10-23 11:49:05 +0000330 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200331 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200332
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200333 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000334
335 add_len -= use_len;
336 p += use_len;
337 }
338
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200339 return( 0 );
340}
341
342int gcm_update( gcm_context *ctx,
343 size_t length,
344 const unsigned char *input,
345 unsigned char *output )
346{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200347 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200348 unsigned char ectr[16];
349 size_t i;
350 const unsigned char *p;
351 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200352 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200353
354 if( output > input && (size_t) ( output - input ) < length )
355 return( POLARSSL_ERR_GCM_BAD_INPUT );
356
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200357 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
358 * Also check for possible overflow */
359 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnardc0501442015-12-10 14:46:25 +0100360 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200361 {
362 return( POLARSSL_ERR_GCM_BAD_INPUT );
363 }
364
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200365 ctx->len += length;
366
Paul Bakker89e80c92012-03-20 13:50:09 +0000367 p = input;
368 while( length > 0 )
369 {
370 use_len = ( length < 16 ) ? length : 16;
371
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100372 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200373 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000374 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000375
Paul Bakker43aff2a2013-09-09 00:10:27 +0200376 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
377 &olen ) ) != 0 )
378 {
379 return( ret );
380 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000381
Paul Bakker67f9d532012-10-23 11:49:05 +0000382 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000383 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200384 if( ctx->mode == GCM_DECRYPT )
385 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000386 out_p[i] = ectr[i] ^ p[i];
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200387 if( ctx->mode == GCM_ENCRYPT )
388 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000389 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200390
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200391 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200392
Paul Bakker89e80c92012-03-20 13:50:09 +0000393 length -= use_len;
394 p += use_len;
395 out_p += use_len;
396 }
397
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200398 return( 0 );
399}
400
401int gcm_finish( gcm_context *ctx,
402 unsigned char *tag,
403 size_t tag_len )
404{
405 unsigned char work_buf[16];
406 size_t i;
407 uint64_t orig_len = ctx->len * 8;
408 uint64_t orig_add_len = ctx->add_len * 8;
409
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200410 if( tag_len > 16 || tag_len < 4 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200411 return( POLARSSL_ERR_GCM_BAD_INPUT );
412
Andres AG6ad5d942016-09-26 10:09:30 +0100413 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200414
Paul Bakker89e80c92012-03-20 13:50:09 +0000415 if( orig_len || orig_add_len )
416 {
417 memset( work_buf, 0x00, 16 );
418
Paul Bakker0ecdb232013-04-09 11:36:42 +0200419 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
420 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
421 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
422 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000423
Paul Bakker67f9d532012-10-23 11:49:05 +0000424 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200425 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000426
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200427 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000428
Paul Bakker67f9d532012-10-23 11:49:05 +0000429 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200430 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000431 }
432
433 return( 0 );
434}
435
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200436int gcm_crypt_and_tag( gcm_context *ctx,
437 int mode,
438 size_t length,
439 const unsigned char *iv,
440 size_t iv_len,
441 const unsigned char *add,
442 size_t add_len,
443 const unsigned char *input,
444 unsigned char *output,
445 size_t tag_len,
446 unsigned char *tag )
447{
448 int ret;
449
450 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
451 return( ret );
452
453 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
454 return( ret );
455
456 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
457 return( ret );
458
459 return( 0 );
460}
461
Paul Bakker89e80c92012-03-20 13:50:09 +0000462int gcm_auth_decrypt( gcm_context *ctx,
463 size_t length,
464 const unsigned char *iv,
465 size_t iv_len,
466 const unsigned char *add,
467 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200468 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000469 size_t tag_len,
470 const unsigned char *input,
471 unsigned char *output )
472{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100473 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000474 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200475 size_t i;
476 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000477
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100478 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
479 iv, iv_len, add, add_len,
480 input, output, tag_len, check_tag ) ) != 0 )
481 {
482 return( ret );
483 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000484
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200485 /* Check tag in "constant-time" */
486 for( diff = 0, i = 0; i < tag_len; i++ )
487 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000488
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200489 if( diff != 0 )
490 {
Paul Bakker34617722014-06-13 17:20:13 +0200491 polarssl_zeroize( output, length );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200492 return( POLARSSL_ERR_GCM_AUTH_FAILED );
493 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000494
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200495 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000496}
497
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200498void gcm_free( gcm_context *ctx )
499{
Paul Bakker84bbeb52014-07-01 14:53:22 +0200500 cipher_free( &ctx->cipher_ctx );
Paul Bakker34617722014-06-13 17:20:13 +0200501 polarssl_zeroize( ctx, sizeof( gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200502}
503
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200504#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000505/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200506 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000507 *
508 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
509 */
510#define MAX_TESTS 6
511
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000512static const int key_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000513 { 0, 0, 1, 1, 1, 1 };
514
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000515static const unsigned char key[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000516{
517 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
522 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
523 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200524 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000525};
526
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000527static const size_t iv_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000528 { 12, 12, 12, 12, 8, 60 };
529
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000530static const int iv_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000531 { 0, 0, 1, 1, 1, 2 };
532
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000533static const unsigned char iv[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000534{
535 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536 0x00, 0x00, 0x00, 0x00 },
537 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
538 0xde, 0xca, 0xf8, 0x88 },
539 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200540 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000541 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200542 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000543 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200544 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000545 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200546 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000547};
548
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000549static const size_t add_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000550 { 0, 0, 0, 20, 20, 20 };
551
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000552static const int add_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000553 { 0, 0, 0, 1, 1, 1 };
554
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000555static const unsigned char additional[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000556{
557 { 0x00 },
558 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200559 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000560 0xab, 0xad, 0xda, 0xd2 },
561};
562
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000563static const size_t pt_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000564 { 0, 16, 64, 60, 60, 60 };
565
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000566static const int pt_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000567 { 0, 0, 1, 1, 1, 1 };
568
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000569static const unsigned char pt[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000570{
571 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
573 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
574 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
575 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
576 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
577 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
578 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
579 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
580 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
581};
582
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000583static const unsigned char ct[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000584{
585 { 0x00 },
586 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
587 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
588 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200589 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000590 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200591 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000592 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200593 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000594 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
595 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
596 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200597 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000598 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200599 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000600 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200601 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000602 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
603 0x3d, 0x58, 0xe0, 0x91 },
604 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200605 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000606 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200607 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000608 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200609 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000610 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
611 0xc2, 0x3f, 0x45, 0x98 },
612 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200613 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000614 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200615 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000616 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200617 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000618 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
619 0x4c, 0x34, 0xae, 0xe5 },
620 { 0x00 },
621 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200622 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000623 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200624 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200626 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000627 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200628 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000629 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
630 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
631 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200632 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000633 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200634 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
635 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
636 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000637 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200638 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000639 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200640 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000641 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200642 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000643 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200644 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000645 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200646 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000647 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200648 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000649 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200650 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000651 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200652 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000653 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200654 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000655 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200656 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
657 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
658 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
659 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
660 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
661 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
662 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
663 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
664 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
665 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
666 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
667 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
668 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
669 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
670 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
671 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
672 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
673 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000674 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200675 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000676 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200677 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000678 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200679 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000680 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200681 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000682 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200683 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000684 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200685 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000686 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200687 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000688 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200689 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000690};
691
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000692static const unsigned char tag[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000693{
694 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
695 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
696 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
697 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
698 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200699 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000700 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
701 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
702 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
703 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
704 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
705 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
706 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
707 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
708 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200709 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000710 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
711 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
712 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200713 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000714 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200715 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000716 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200717 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000718 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200719 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000720 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200721 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000722 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200723 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000724 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200725 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000726 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200727 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000728 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200729 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000730};
731
732int gcm_self_test( int verbose )
733{
734 gcm_context ctx;
735 unsigned char buf[64];
736 unsigned char tag_buf[16];
737 int i, j, ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200738 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000739
740 for( j = 0; j < 3; j++ )
741 {
742 int key_len = 128 + 64 * j;
743
744 for( i = 0; i < MAX_TESTS; i++ )
745 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200746 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100747 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
748 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200749
Paul Bakker43aff2a2013-09-09 00:10:27 +0200750 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000751
752 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
753 pt_len[i],
754 iv[iv_index[i]], iv_len[i],
755 additional[add_index[i]], add_len[i],
756 pt[pt_index[i]], buf, 16, tag_buf );
757
758 if( ret != 0 ||
759 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
760 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
761 {
762 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100763 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000764
765 return( 1 );
766 }
767
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200768 gcm_free( &ctx );
769
Paul Bakker89e80c92012-03-20 13:50:09 +0000770 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100771 polarssl_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000772
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200773 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100774 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
775 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200776
Paul Bakker43aff2a2013-09-09 00:10:27 +0200777 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000778
779 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
780 pt_len[i],
781 iv[iv_index[i]], iv_len[i],
782 additional[add_index[i]], add_len[i],
783 ct[j * 6 + i], buf, 16, tag_buf );
784
785 if( ret != 0 ||
786 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
787 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
788 {
789 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100790 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000791
792 return( 1 );
793 }
794
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200795 gcm_free( &ctx );
796
Paul Bakker89e80c92012-03-20 13:50:09 +0000797 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100798 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200799
800 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100801 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
802 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200803
Paul Bakker43aff2a2013-09-09 00:10:27 +0200804 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200805
806 ret = gcm_starts( &ctx, GCM_ENCRYPT,
807 iv[iv_index[i]], iv_len[i],
808 additional[add_index[i]], add_len[i] );
809 if( ret != 0 )
810 {
811 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100812 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200813
814 return( 1 );
815 }
816
817 if( pt_len[i] > 32 )
818 {
819 size_t rest_len = pt_len[i] - 32;
820 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
821 if( ret != 0 )
822 {
823 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100824 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200825
826 return( 1 );
827 }
828
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200829 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
830 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200831 if( ret != 0 )
832 {
833 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100834 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200835
836 return( 1 );
837 }
838 }
839 else
840 {
841 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
842 if( ret != 0 )
843 {
844 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100845 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200846
847 return( 1 );
848 }
849 }
850
851 ret = gcm_finish( &ctx, tag_buf, 16 );
852 if( ret != 0 ||
853 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
854 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
855 {
856 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100857 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200858
859 return( 1 );
860 }
861
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200862 gcm_free( &ctx );
863
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200864 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100865 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200866
867 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100868 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
869 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200870
Paul Bakker43aff2a2013-09-09 00:10:27 +0200871 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200872
873 ret = gcm_starts( &ctx, GCM_DECRYPT,
874 iv[iv_index[i]], iv_len[i],
875 additional[add_index[i]], add_len[i] );
876 if( ret != 0 )
877 {
878 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100879 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200880
881 return( 1 );
882 }
883
884 if( pt_len[i] > 32 )
885 {
886 size_t rest_len = pt_len[i] - 32;
887 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
888 if( ret != 0 )
889 {
890 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100891 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200892
893 return( 1 );
894 }
895
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200896 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
897 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200898 if( ret != 0 )
899 {
900 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100901 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200902
903 return( 1 );
904 }
905 }
906 else
907 {
908 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
909 if( ret != 0 )
910 {
911 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100912 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200913
914 return( 1 );
915 }
916 }
917
918 ret = gcm_finish( &ctx, tag_buf, 16 );
919 if( ret != 0 ||
920 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
921 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
922 {
923 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100924 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200925
926 return( 1 );
927 }
928
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200929 gcm_free( &ctx );
930
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200931 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100932 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200933
Paul Bakker89e80c92012-03-20 13:50:09 +0000934 }
935 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200936
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200937 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100938 polarssl_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000939
940 return( 0 );
941}
942
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200943#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000944
Paul Bakker9af723c2014-05-01 13:03:14 +0200945#endif /* POLARSSL_GCM_C */