blob: b537b02053da68d4b99021462a7d6ca3cbb18cf3 [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é-Gonnard8d77eee2014-07-21 13:59:12 +0200360 (uint64_t) ctx->len + length > 0x03FFFFE0ull )
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
Manuel Pégourié-Gonnard9241be72013-08-31 17:31:03 +0200413 if( tag_len != 0 )
414 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200415
Paul Bakker89e80c92012-03-20 13:50:09 +0000416 if( orig_len || orig_add_len )
417 {
418 memset( work_buf, 0x00, 16 );
419
Paul Bakker0ecdb232013-04-09 11:36:42 +0200420 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
421 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
422 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
423 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000424
Paul Bakker67f9d532012-10-23 11:49:05 +0000425 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200426 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000427
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200428 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000429
Paul Bakker67f9d532012-10-23 11:49:05 +0000430 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200431 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000432 }
433
434 return( 0 );
435}
436
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200437int gcm_crypt_and_tag( gcm_context *ctx,
438 int mode,
439 size_t length,
440 const unsigned char *iv,
441 size_t iv_len,
442 const unsigned char *add,
443 size_t add_len,
444 const unsigned char *input,
445 unsigned char *output,
446 size_t tag_len,
447 unsigned char *tag )
448{
449 int ret;
450
451 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
452 return( ret );
453
454 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
455 return( ret );
456
457 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
458 return( ret );
459
460 return( 0 );
461}
462
Paul Bakker89e80c92012-03-20 13:50:09 +0000463int gcm_auth_decrypt( gcm_context *ctx,
464 size_t length,
465 const unsigned char *iv,
466 size_t iv_len,
467 const unsigned char *add,
468 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200469 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000470 size_t tag_len,
471 const unsigned char *input,
472 unsigned char *output )
473{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100474 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000475 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200476 size_t i;
477 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000478
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100479 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
480 iv, iv_len, add, add_len,
481 input, output, tag_len, check_tag ) ) != 0 )
482 {
483 return( ret );
484 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000485
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200486 /* Check tag in "constant-time" */
487 for( diff = 0, i = 0; i < tag_len; i++ )
488 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000489
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200490 if( diff != 0 )
491 {
Paul Bakker34617722014-06-13 17:20:13 +0200492 polarssl_zeroize( output, length );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200493 return( POLARSSL_ERR_GCM_AUTH_FAILED );
494 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000495
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200496 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000497}
498
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200499void gcm_free( gcm_context *ctx )
500{
Paul Bakker84bbeb52014-07-01 14:53:22 +0200501 cipher_free( &ctx->cipher_ctx );
Paul Bakker34617722014-06-13 17:20:13 +0200502 polarssl_zeroize( ctx, sizeof( gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200503}
504
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200505#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000506/*
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
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000513static const int key_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000514 { 0, 0, 1, 1, 1, 1 };
515
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000516static const unsigned char key[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000517{
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
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000528static const size_t iv_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000529 { 12, 12, 12, 12, 8, 60 };
530
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000531static const int iv_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000532 { 0, 0, 1, 1, 1, 2 };
533
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000534static const unsigned char iv[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000535{
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
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000550static const size_t add_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000551 { 0, 0, 0, 20, 20, 20 };
552
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000553static const int add_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000554 { 0, 0, 0, 1, 1, 1 };
555
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000556static const unsigned char additional[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000557{
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
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000564static const size_t pt_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000565 { 0, 16, 64, 60, 60, 60 };
566
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000567static const int pt_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000568 { 0, 0, 1, 1, 1, 1 };
569
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000570static const unsigned char pt[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000571{
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
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000584static const unsigned char ct[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000585{
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
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000693static const unsigned char tag[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000694{
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é-Gonnarddae70932013-10-24 15:06:33 +0200944#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000945
Paul Bakker9af723c2014-05-01 13:03:14 +0200946#endif /* POLARSSL_GCM_C */