blob: 415e53af9794decc19f7b0484a34ee94e56d8f6c [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é-Gonnard860b5162015-01-28 17:12:07 +00006 * This file is part of mbed TLS (https://polarssl.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
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010043#if defined(POLARSSL_AESNI_C)
44#include "polarssl/aesni.h"
45#endif
46
Paul Bakker7dc4c442014-02-01 22:50:26 +010047#if defined(POLARSSL_PLATFORM_C)
48#include "polarssl/platform.h"
49#else
50#define polarssl_printf printf
51#endif
52
Paul Bakker89e80c92012-03-20 13:50:09 +000053/*
54 * 32-bit integer manipulation macros (big endian)
55 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000056#ifndef GET_UINT32_BE
57#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000058{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000059 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
60 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
61 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
62 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000063}
64#endif
65
Paul Bakker5c2364c2012-10-01 14:41:15 +000066#ifndef PUT_UINT32_BE
67#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000068{ \
69 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
70 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
71 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
72 (b)[(i) + 3] = (unsigned char) ( (n) ); \
73}
74#endif
75
Paul Bakker34617722014-06-13 17:20:13 +020076/* Implementation that should never be optimized out by the compiler */
77static void polarssl_zeroize( void *v, size_t n ) {
78 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
79}
80
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010081/*
82 * Precompute small multiples of H, that is set
83 * HH[i] || HL[i] = H times i,
84 * where i is seen as a field element as in [MGV], ie high-order bits
85 * correspond to low powers of P. The result is stored in the same way, that
86 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
87 * corresponds to P^127.
88 */
Paul Bakker43aff2a2013-09-09 00:10:27 +020089static int gcm_gen_table( gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000090{
Paul Bakker43aff2a2013-09-09 00:10:27 +020091 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000092 uint64_t hi, lo;
93 uint64_t vl, vh;
94 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020095 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020096
Paul Bakker89e80c92012-03-20 13:50:09 +000097 memset( h, 0, 16 );
Paul Bakker43aff2a2013-09-09 00:10:27 +020098 if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
99 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000100
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100101 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000102 GET_UINT32_BE( hi, h, 0 );
103 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000104 vh = (uint64_t) hi << 32 | lo;
105
Paul Bakker5c2364c2012-10-01 14:41:15 +0000106 GET_UINT32_BE( hi, h, 8 );
107 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000108 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200109
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100110 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000111 ctx->HL[8] = vl;
112 ctx->HH[8] = vh;
113
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100114#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
115 /* With CLMUL support, we need only h, not the rest of the table */
116 if( aesni_supports( POLARSSL_AESNI_CLMUL ) )
117 return( 0 );
118#endif
119
120 /* 0 corresponds to 0 in GF(2^128) */
121 ctx->HH[0] = 0;
122 ctx->HL[0] = 0;
123
Paul Bakker89e80c92012-03-20 13:50:09 +0000124 for( i = 4; i > 0; i >>= 1 )
125 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200126 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000127 vl = ( vh << 63 ) | ( vl >> 1 );
128 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
129
130 ctx->HL[i] = vl;
131 ctx->HH[i] = vh;
132 }
133
Paul Bakker66d5d072014-06-17 16:39:18 +0200134 for( i = 2; i < 16; i <<= 1 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000135 {
136 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
137 vh = *HiH;
138 vl = *HiL;
139 for( j = 1; j < i; j++ )
140 {
141 HiH[j] = vh ^ ctx->HH[j];
142 HiL[j] = vl ^ ctx->HL[j];
143 }
144 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200145
146 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000147}
148
Paul Bakker43aff2a2013-09-09 00:10:27 +0200149int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
150 unsigned int keysize )
Paul Bakker89e80c92012-03-20 13:50:09 +0000151{
152 int ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200153 const cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000154
155 memset( ctx, 0, sizeof(gcm_context) );
156
Paul Bakker84bbeb52014-07-01 14:53:22 +0200157 cipher_init( &ctx->cipher_ctx );
158
Paul Bakker43aff2a2013-09-09 00:10:27 +0200159 cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
160 if( cipher_info == NULL )
161 return( POLARSSL_ERR_GCM_BAD_INPUT );
162
Paul Bakkera0558e02013-09-10 14:25:51 +0200163 if( cipher_info->block_size != 16 )
164 return( POLARSSL_ERR_GCM_BAD_INPUT );
165
Paul Bakker43aff2a2013-09-09 00:10:27 +0200166 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000167 return( ret );
168
Paul Bakker43aff2a2013-09-09 00:10:27 +0200169 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
170 POLARSSL_ENCRYPT ) ) != 0 )
171 {
172 return( ret );
173 }
174
175 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
176 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000177
178 return( 0 );
179}
180
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100181/*
182 * Shoup's method for multiplication use this table with
183 * last4[x] = x times P^128
184 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
185 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000186static const uint64_t last4[16] =
187{
188 0x0000, 0x1c20, 0x3840, 0x2460,
189 0x7080, 0x6ca0, 0x48c0, 0x54e0,
190 0xe100, 0xfd20, 0xd940, 0xc560,
191 0x9180, 0x8da0, 0xa9c0, 0xb5e0
192};
193
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100194/*
195 * Sets output to x times H using the precomputed tables.
196 * x and output are seen as elements of GF(2^128) as in [MGV].
197 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200198static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
199 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000200{
201 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000202 unsigned char lo, hi, rem;
203 uint64_t zh, zl;
204
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100205#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
206 if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) {
207 unsigned char h[16];
208
209 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
210 PUT_UINT32_BE( ctx->HH[8], h, 4 );
211 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
212 PUT_UINT32_BE( ctx->HL[8], h, 12 );
213
Manuel Pégourié-Gonnardd4588cf2013-12-30 13:54:23 +0100214 aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100215 return;
216 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200217#endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100218
Paul Bakker89e80c92012-03-20 13:50:09 +0000219 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000220
221 zh = ctx->HH[lo];
222 zl = ctx->HL[lo];
223
224 for( i = 15; i >= 0; i-- )
225 {
226 lo = x[i] & 0xf;
227 hi = x[i] >> 4;
228
229 if( i != 15 )
230 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000231 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000232 zl = ( zh << 60 ) | ( zl >> 4 );
233 zh = ( zh >> 4 );
234 zh ^= (uint64_t) last4[rem] << 48;
235 zh ^= ctx->HH[lo];
236 zl ^= ctx->HL[lo];
237
238 }
239
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000240 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000241 zl = ( zh << 60 ) | ( zl >> 4 );
242 zh = ( zh >> 4 );
243 zh ^= (uint64_t) last4[rem] << 48;
244 zh ^= ctx->HH[hi];
245 zl ^= ctx->HL[hi];
246 }
247
Paul Bakker5c2364c2012-10-01 14:41:15 +0000248 PUT_UINT32_BE( zh >> 32, output, 0 );
249 PUT_UINT32_BE( zh, output, 4 );
250 PUT_UINT32_BE( zl >> 32, output, 8 );
251 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000252}
253
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200254int gcm_starts( gcm_context *ctx,
255 int mode,
256 const unsigned char *iv,
257 size_t iv_len,
258 const unsigned char *add,
259 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000260{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200261 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000262 unsigned char work_buf[16];
263 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000264 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200265 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000266
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200267 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
268 if( ( (uint64_t) iv_len ) >> 61 != 0 ||
269 ( (uint64_t) add_len ) >> 61 != 0 )
270 {
271 return( POLARSSL_ERR_GCM_BAD_INPUT );
272 }
273
Paul Bakker52cf16c2013-07-26 13:55:38 +0200274 memset( ctx->y, 0x00, sizeof(ctx->y) );
275 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
276
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200277 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200278 ctx->len = 0;
279 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000280
281 if( iv_len == 12 )
282 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200283 memcpy( ctx->y, iv, iv_len );
284 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000285 }
286 else
287 {
288 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000289 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000290
291 p = iv;
292 while( iv_len > 0 )
293 {
294 use_len = ( iv_len < 16 ) ? iv_len : 16;
295
Paul Bakker67f9d532012-10-23 11:49:05 +0000296 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200297 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200298
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200299 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000300
301 iv_len -= use_len;
302 p += use_len;
303 }
304
Paul Bakker67f9d532012-10-23 11:49:05 +0000305 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200306 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000307
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200308 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000309 }
310
Paul Bakker43aff2a2013-09-09 00:10:27 +0200311 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
312 &olen ) ) != 0 )
313 {
314 return( ret );
315 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000316
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200317 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000318 p = add;
319 while( add_len > 0 )
320 {
321 use_len = ( add_len < 16 ) ? add_len : 16;
322
Paul Bakker67f9d532012-10-23 11:49:05 +0000323 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200324 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200325
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200326 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000327
328 add_len -= use_len;
329 p += use_len;
330 }
331
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200332 return( 0 );
333}
334
335int gcm_update( gcm_context *ctx,
336 size_t length,
337 const unsigned char *input,
338 unsigned char *output )
339{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200340 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200341 unsigned char ectr[16];
342 size_t i;
343 const unsigned char *p;
344 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200345 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200346
347 if( output > input && (size_t) ( output - input ) < length )
348 return( POLARSSL_ERR_GCM_BAD_INPUT );
349
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200350 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
351 * Also check for possible overflow */
352 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard8d77eee2014-07-21 13:59:12 +0200353 (uint64_t) ctx->len + length > 0x03FFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200354 {
355 return( POLARSSL_ERR_GCM_BAD_INPUT );
356 }
357
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200358 ctx->len += length;
359
Paul Bakker89e80c92012-03-20 13:50:09 +0000360 p = input;
361 while( length > 0 )
362 {
363 use_len = ( length < 16 ) ? length : 16;
364
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100365 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200366 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000367 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000368
Paul Bakker43aff2a2013-09-09 00:10:27 +0200369 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
370 &olen ) ) != 0 )
371 {
372 return( ret );
373 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000374
Paul Bakker67f9d532012-10-23 11:49:05 +0000375 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000376 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200377 if( ctx->mode == GCM_DECRYPT )
378 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000379 out_p[i] = ectr[i] ^ p[i];
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200380 if( ctx->mode == GCM_ENCRYPT )
381 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000382 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200383
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200384 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200385
Paul Bakker89e80c92012-03-20 13:50:09 +0000386 length -= use_len;
387 p += use_len;
388 out_p += use_len;
389 }
390
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200391 return( 0 );
392}
393
394int gcm_finish( gcm_context *ctx,
395 unsigned char *tag,
396 size_t tag_len )
397{
398 unsigned char work_buf[16];
399 size_t i;
400 uint64_t orig_len = ctx->len * 8;
401 uint64_t orig_add_len = ctx->add_len * 8;
402
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200403 if( tag_len > 16 || tag_len < 4 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200404 return( POLARSSL_ERR_GCM_BAD_INPUT );
405
Manuel Pégourié-Gonnard9241be72013-08-31 17:31:03 +0200406 if( tag_len != 0 )
407 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200408
Paul Bakker89e80c92012-03-20 13:50:09 +0000409 if( orig_len || orig_add_len )
410 {
411 memset( work_buf, 0x00, 16 );
412
Paul Bakker0ecdb232013-04-09 11:36:42 +0200413 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
414 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
415 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
416 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000417
Paul Bakker67f9d532012-10-23 11:49:05 +0000418 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200419 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000420
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200421 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000422
Paul Bakker67f9d532012-10-23 11:49:05 +0000423 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200424 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000425 }
426
427 return( 0 );
428}
429
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200430int gcm_crypt_and_tag( gcm_context *ctx,
431 int mode,
432 size_t length,
433 const unsigned char *iv,
434 size_t iv_len,
435 const unsigned char *add,
436 size_t add_len,
437 const unsigned char *input,
438 unsigned char *output,
439 size_t tag_len,
440 unsigned char *tag )
441{
442 int ret;
443
444 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
445 return( ret );
446
447 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
448 return( ret );
449
450 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
451 return( ret );
452
453 return( 0 );
454}
455
Paul Bakker89e80c92012-03-20 13:50:09 +0000456int gcm_auth_decrypt( gcm_context *ctx,
457 size_t length,
458 const unsigned char *iv,
459 size_t iv_len,
460 const unsigned char *add,
461 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200462 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000463 size_t tag_len,
464 const unsigned char *input,
465 unsigned char *output )
466{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100467 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000468 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200469 size_t i;
470 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000471
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100472 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
473 iv, iv_len, add, add_len,
474 input, output, tag_len, check_tag ) ) != 0 )
475 {
476 return( ret );
477 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000478
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200479 /* Check tag in "constant-time" */
480 for( diff = 0, i = 0; i < tag_len; i++ )
481 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000482
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200483 if( diff != 0 )
484 {
Paul Bakker34617722014-06-13 17:20:13 +0200485 polarssl_zeroize( output, length );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200486 return( POLARSSL_ERR_GCM_AUTH_FAILED );
487 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000488
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200489 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000490}
491
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200492void gcm_free( gcm_context *ctx )
493{
Paul Bakker84bbeb52014-07-01 14:53:22 +0200494 cipher_free( &ctx->cipher_ctx );
Paul Bakker34617722014-06-13 17:20:13 +0200495 polarssl_zeroize( ctx, sizeof( gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200496}
497
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200498#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000499
500#include <stdio.h>
501
502/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200503 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000504 *
505 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
506 */
507#define MAX_TESTS 6
508
509int key_index[MAX_TESTS] =
510 { 0, 0, 1, 1, 1, 1 };
511
512unsigned char key[MAX_TESTS][32] =
513{
514 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
516 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
518 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
519 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
520 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200521 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000522};
523
524size_t iv_len[MAX_TESTS] =
525 { 12, 12, 12, 12, 8, 60 };
526
527int iv_index[MAX_TESTS] =
528 { 0, 0, 1, 1, 1, 2 };
529
530unsigned char iv[MAX_TESTS][64] =
531{
532 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
533 0x00, 0x00, 0x00, 0x00 },
534 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
535 0xde, 0xca, 0xf8, 0x88 },
536 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200537 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000538 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200539 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000540 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200541 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000542 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200543 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000544};
545
546size_t add_len[MAX_TESTS] =
547 { 0, 0, 0, 20, 20, 20 };
548
549int add_index[MAX_TESTS] =
550 { 0, 0, 0, 1, 1, 1 };
551
552unsigned char additional[MAX_TESTS][64] =
553{
554 { 0x00 },
555 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200556 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000557 0xab, 0xad, 0xda, 0xd2 },
558};
559
560size_t pt_len[MAX_TESTS] =
561 { 0, 16, 64, 60, 60, 60 };
562
563int pt_index[MAX_TESTS] =
564 { 0, 0, 1, 1, 1, 1 };
565
566unsigned char pt[MAX_TESTS][64] =
567{
568 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
570 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
571 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
572 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
573 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
574 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
575 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
576 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
577 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
578};
579
580unsigned char ct[MAX_TESTS * 3][64] =
581{
582 { 0x00 },
583 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
584 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
585 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200586 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000587 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200588 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000589 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200590 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000591 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
592 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
593 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200594 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000595 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200596 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000597 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200598 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000599 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
600 0x3d, 0x58, 0xe0, 0x91 },
601 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200602 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000603 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200604 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000605 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200606 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000607 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
608 0xc2, 0x3f, 0x45, 0x98 },
609 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200610 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000611 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200612 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200614 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
616 0x4c, 0x34, 0xae, 0xe5 },
617 { 0x00 },
618 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200619 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000620 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200621 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000622 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200623 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000624 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200625 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000626 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
627 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
628 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200629 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000630 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200631 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
632 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
633 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000634 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200635 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000636 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200637 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000638 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200639 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000640 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200641 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200643 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000644 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200645 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000646 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200647 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200649 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000650 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200651 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200653 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
654 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
655 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
656 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
657 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
658 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
659 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
660 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
661 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
662 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
663 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
664 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
665 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
666 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
667 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
668 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
669 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
670 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000671 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200672 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000673 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200674 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000675 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200676 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000677 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200678 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000679 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200680 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000681 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200682 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000683 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200684 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000685 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200686 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000687};
688
689unsigned char tag[MAX_TESTS * 3][16] =
690{
691 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
692 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
693 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
694 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
695 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200696 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
698 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
699 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
700 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
701 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
702 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
703 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
704 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
705 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200706 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000707 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
708 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
709 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200710 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000711 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200712 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000713 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200714 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000715 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200716 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000717 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200718 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000719 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200720 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000721 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200722 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000723 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200724 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000725 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200726 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000727};
728
729int gcm_self_test( int verbose )
730{
731 gcm_context ctx;
732 unsigned char buf[64];
733 unsigned char tag_buf[16];
734 int i, j, ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200735 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000736
737 for( j = 0; j < 3; j++ )
738 {
739 int key_len = 128 + 64 * j;
740
741 for( i = 0; i < MAX_TESTS; i++ )
742 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200743 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100744 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
745 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200746
Paul Bakker43aff2a2013-09-09 00:10:27 +0200747 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000748
749 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
750 pt_len[i],
751 iv[iv_index[i]], iv_len[i],
752 additional[add_index[i]], add_len[i],
753 pt[pt_index[i]], buf, 16, tag_buf );
754
755 if( ret != 0 ||
756 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
757 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
758 {
759 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100760 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000761
762 return( 1 );
763 }
764
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200765 gcm_free( &ctx );
766
Paul Bakker89e80c92012-03-20 13:50:09 +0000767 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100768 polarssl_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000769
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200770 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100771 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
772 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200773
Paul Bakker43aff2a2013-09-09 00:10:27 +0200774 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000775
776 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
777 pt_len[i],
778 iv[iv_index[i]], iv_len[i],
779 additional[add_index[i]], add_len[i],
780 ct[j * 6 + i], buf, 16, tag_buf );
781
782 if( ret != 0 ||
783 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
784 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
785 {
786 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100787 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000788
789 return( 1 );
790 }
791
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200792 gcm_free( &ctx );
793
Paul Bakker89e80c92012-03-20 13:50:09 +0000794 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100795 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200796
797 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100798 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
799 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200800
Paul Bakker43aff2a2013-09-09 00:10:27 +0200801 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200802
803 ret = gcm_starts( &ctx, GCM_ENCRYPT,
804 iv[iv_index[i]], iv_len[i],
805 additional[add_index[i]], add_len[i] );
806 if( ret != 0 )
807 {
808 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100809 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200810
811 return( 1 );
812 }
813
814 if( pt_len[i] > 32 )
815 {
816 size_t rest_len = pt_len[i] - 32;
817 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
818 if( ret != 0 )
819 {
820 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100821 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200822
823 return( 1 );
824 }
825
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200826 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
827 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200828 if( ret != 0 )
829 {
830 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100831 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200832
833 return( 1 );
834 }
835 }
836 else
837 {
838 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
839 if( ret != 0 )
840 {
841 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100842 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200843
844 return( 1 );
845 }
846 }
847
848 ret = gcm_finish( &ctx, tag_buf, 16 );
849 if( ret != 0 ||
850 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
851 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
852 {
853 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100854 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200855
856 return( 1 );
857 }
858
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200859 gcm_free( &ctx );
860
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200861 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100862 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200863
864 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100865 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
866 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200867
Paul Bakker43aff2a2013-09-09 00:10:27 +0200868 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200869
870 ret = gcm_starts( &ctx, GCM_DECRYPT,
871 iv[iv_index[i]], iv_len[i],
872 additional[add_index[i]], add_len[i] );
873 if( ret != 0 )
874 {
875 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100876 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200877
878 return( 1 );
879 }
880
881 if( pt_len[i] > 32 )
882 {
883 size_t rest_len = pt_len[i] - 32;
884 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
885 if( ret != 0 )
886 {
887 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100888 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200889
890 return( 1 );
891 }
892
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200893 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
894 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200895 if( ret != 0 )
896 {
897 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100898 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200899
900 return( 1 );
901 }
902 }
903 else
904 {
905 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
906 if( ret != 0 )
907 {
908 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100909 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200910
911 return( 1 );
912 }
913 }
914
915 ret = gcm_finish( &ctx, tag_buf, 16 );
916 if( ret != 0 ||
917 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
918 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
919 {
920 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100921 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200922
923 return( 1 );
924 }
925
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200926 gcm_free( &ctx );
927
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200928 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100929 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200930
Paul Bakker89e80c92012-03-20 13:50:09 +0000931 }
932 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200933
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200934 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100935 polarssl_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000936
937 return( 0 );
938}
939
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200940
941
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200942#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000943
Paul Bakker9af723c2014-05-01 13:03:14 +0200944#endif /* POLARSSL_GCM_C */