blob: 39cb189a406578894baab207a153faf58a9f298e [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
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
Paul Bakker66d5d072014-06-17 16:39:18 +0200139 for( i = 2; i < 16; i <<= 1 )
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
Paul Bakker43aff2a2013-09-09 00:10:27 +0200171 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000172 return( ret );
173
Paul Bakker43aff2a2013-09-09 00:10:27 +0200174 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
175 POLARSSL_ENCRYPT ) ) != 0 )
176 {
177 return( ret );
178 }
179
180 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
181 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000182
183 return( 0 );
184}
185
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100186/*
187 * Shoup's method for multiplication use this table with
188 * last4[x] = x times P^128
189 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
190 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000191static const uint64_t last4[16] =
192{
193 0x0000, 0x1c20, 0x3840, 0x2460,
194 0x7080, 0x6ca0, 0x48c0, 0x54e0,
195 0xe100, 0xfd20, 0xd940, 0xc560,
196 0x9180, 0x8da0, 0xa9c0, 0xb5e0
197};
198
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100199/*
200 * Sets output to x times H using the precomputed tables.
201 * x and output are seen as elements of GF(2^128) as in [MGV].
202 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200203static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
204 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000205{
206 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000207 unsigned char lo, hi, rem;
208 uint64_t zh, zl;
209
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100210#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
211 if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) {
212 unsigned char h[16];
213
214 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
215 PUT_UINT32_BE( ctx->HH[8], h, 4 );
216 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
217 PUT_UINT32_BE( ctx->HL[8], h, 12 );
218
Manuel Pégourié-Gonnardd4588cf2013-12-30 13:54:23 +0100219 aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100220 return;
221 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200222#endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100223
Paul Bakker89e80c92012-03-20 13:50:09 +0000224 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000225
226 zh = ctx->HH[lo];
227 zl = ctx->HL[lo];
228
229 for( i = 15; i >= 0; i-- )
230 {
231 lo = x[i] & 0xf;
232 hi = x[i] >> 4;
233
234 if( i != 15 )
235 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000236 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000237 zl = ( zh << 60 ) | ( zl >> 4 );
238 zh = ( zh >> 4 );
239 zh ^= (uint64_t) last4[rem] << 48;
240 zh ^= ctx->HH[lo];
241 zl ^= ctx->HL[lo];
242
243 }
244
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000245 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000246 zl = ( zh << 60 ) | ( zl >> 4 );
247 zh = ( zh >> 4 );
248 zh ^= (uint64_t) last4[rem] << 48;
249 zh ^= ctx->HH[hi];
250 zl ^= ctx->HL[hi];
251 }
252
Paul Bakker5c2364c2012-10-01 14:41:15 +0000253 PUT_UINT32_BE( zh >> 32, output, 0 );
254 PUT_UINT32_BE( zh, output, 4 );
255 PUT_UINT32_BE( zl >> 32, output, 8 );
256 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000257}
258
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200259int gcm_starts( gcm_context *ctx,
260 int mode,
261 const unsigned char *iv,
262 size_t iv_len,
263 const unsigned char *add,
264 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000265{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200266 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000267 unsigned char work_buf[16];
268 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000269 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200270 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000271
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200272 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
273 if( ( (uint64_t) iv_len ) >> 61 != 0 ||
274 ( (uint64_t) add_len ) >> 61 != 0 )
275 {
276 return( POLARSSL_ERR_GCM_BAD_INPUT );
277 }
278
Paul Bakker52cf16c2013-07-26 13:55:38 +0200279 memset( ctx->y, 0x00, sizeof(ctx->y) );
280 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
281
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200282 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200283 ctx->len = 0;
284 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000285
286 if( iv_len == 12 )
287 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200288 memcpy( ctx->y, iv, iv_len );
289 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000290 }
291 else
292 {
293 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000294 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000295
296 p = iv;
297 while( iv_len > 0 )
298 {
299 use_len = ( iv_len < 16 ) ? iv_len : 16;
300
Paul Bakker67f9d532012-10-23 11:49:05 +0000301 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200302 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200303
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200304 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000305
306 iv_len -= use_len;
307 p += use_len;
308 }
309
Paul Bakker67f9d532012-10-23 11:49:05 +0000310 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200311 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000312
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200313 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000314 }
315
Paul Bakker43aff2a2013-09-09 00:10:27 +0200316 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
317 &olen ) ) != 0 )
318 {
319 return( ret );
320 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000321
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200322 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000323 p = add;
324 while( add_len > 0 )
325 {
326 use_len = ( add_len < 16 ) ? add_len : 16;
327
Paul Bakker67f9d532012-10-23 11:49:05 +0000328 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200329 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200330
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200331 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000332
333 add_len -= use_len;
334 p += use_len;
335 }
336
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200337 return( 0 );
338}
339
340int gcm_update( gcm_context *ctx,
341 size_t length,
342 const unsigned char *input,
343 unsigned char *output )
344{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200345 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200346 unsigned char ectr[16];
347 size_t i;
348 const unsigned char *p;
349 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200350 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200351
352 if( output > input && (size_t) ( output - input ) < length )
353 return( POLARSSL_ERR_GCM_BAD_INPUT );
354
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200355 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
356 * Also check for possible overflow */
357 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard8d77eee2014-07-21 13:59:12 +0200358 (uint64_t) ctx->len + length > 0x03FFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200359 {
360 return( POLARSSL_ERR_GCM_BAD_INPUT );
361 }
362
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200363 ctx->len += length;
364
Paul Bakker89e80c92012-03-20 13:50:09 +0000365 p = input;
366 while( length > 0 )
367 {
368 use_len = ( length < 16 ) ? length : 16;
369
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100370 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200371 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000372 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000373
Paul Bakker43aff2a2013-09-09 00:10:27 +0200374 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
375 &olen ) ) != 0 )
376 {
377 return( ret );
378 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000379
Paul Bakker67f9d532012-10-23 11:49:05 +0000380 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000381 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200382 if( ctx->mode == GCM_DECRYPT )
383 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000384 out_p[i] = ectr[i] ^ p[i];
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200385 if( ctx->mode == GCM_ENCRYPT )
386 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000387 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200388
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200389 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200390
Paul Bakker89e80c92012-03-20 13:50:09 +0000391 length -= use_len;
392 p += use_len;
393 out_p += use_len;
394 }
395
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200396 return( 0 );
397}
398
399int gcm_finish( gcm_context *ctx,
400 unsigned char *tag,
401 size_t tag_len )
402{
403 unsigned char work_buf[16];
404 size_t i;
405 uint64_t orig_len = ctx->len * 8;
406 uint64_t orig_add_len = ctx->add_len * 8;
407
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200408 if( tag_len > 16 || tag_len < 4 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200409 return( POLARSSL_ERR_GCM_BAD_INPUT );
410
Manuel Pégourié-Gonnard9241be72013-08-31 17:31:03 +0200411 if( tag_len != 0 )
412 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200413
Paul Bakker89e80c92012-03-20 13:50:09 +0000414 if( orig_len || orig_add_len )
415 {
416 memset( work_buf, 0x00, 16 );
417
Paul Bakker0ecdb232013-04-09 11:36:42 +0200418 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
419 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
420 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
421 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000422
Paul Bakker67f9d532012-10-23 11:49:05 +0000423 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200424 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000425
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200426 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000427
Paul Bakker67f9d532012-10-23 11:49:05 +0000428 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200429 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000430 }
431
432 return( 0 );
433}
434
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200435int gcm_crypt_and_tag( gcm_context *ctx,
436 int mode,
437 size_t length,
438 const unsigned char *iv,
439 size_t iv_len,
440 const unsigned char *add,
441 size_t add_len,
442 const unsigned char *input,
443 unsigned char *output,
444 size_t tag_len,
445 unsigned char *tag )
446{
447 int ret;
448
449 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
450 return( ret );
451
452 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
453 return( ret );
454
455 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
456 return( ret );
457
458 return( 0 );
459}
460
Paul Bakker89e80c92012-03-20 13:50:09 +0000461int gcm_auth_decrypt( gcm_context *ctx,
462 size_t length,
463 const unsigned char *iv,
464 size_t iv_len,
465 const unsigned char *add,
466 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200467 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000468 size_t tag_len,
469 const unsigned char *input,
470 unsigned char *output )
471{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100472 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000473 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200474 size_t i;
475 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000476
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100477 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
478 iv, iv_len, add, add_len,
479 input, output, tag_len, check_tag ) ) != 0 )
480 {
481 return( ret );
482 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000483
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200484 /* Check tag in "constant-time" */
485 for( diff = 0, i = 0; i < tag_len; i++ )
486 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000487
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200488 if( diff != 0 )
489 {
Paul Bakker34617722014-06-13 17:20:13 +0200490 polarssl_zeroize( output, length );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200491 return( POLARSSL_ERR_GCM_AUTH_FAILED );
492 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000493
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200494 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000495}
496
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200497void gcm_free( gcm_context *ctx )
498{
Paul Bakker84bbeb52014-07-01 14:53:22 +0200499 cipher_free( &ctx->cipher_ctx );
Paul Bakker34617722014-06-13 17:20:13 +0200500 polarssl_zeroize( ctx, sizeof( gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200501}
502
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200503#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000504/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200505 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000506 *
507 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
508 */
509#define MAX_TESTS 6
510
511int key_index[MAX_TESTS] =
512 { 0, 0, 1, 1, 1, 1 };
513
514unsigned char key[MAX_TESTS][32] =
515{
516 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
521 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
522 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200523 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000524};
525
526size_t iv_len[MAX_TESTS] =
527 { 12, 12, 12, 12, 8, 60 };
528
529int iv_index[MAX_TESTS] =
530 { 0, 0, 1, 1, 1, 2 };
531
532unsigned char iv[MAX_TESTS][64] =
533{
534 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
535 0x00, 0x00, 0x00, 0x00 },
536 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
537 0xde, 0xca, 0xf8, 0x88 },
538 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200539 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000540 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200541 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000542 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200543 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000544 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200545 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000546};
547
548size_t add_len[MAX_TESTS] =
549 { 0, 0, 0, 20, 20, 20 };
550
551int add_index[MAX_TESTS] =
552 { 0, 0, 0, 1, 1, 1 };
553
554unsigned char additional[MAX_TESTS][64] =
555{
556 { 0x00 },
557 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200558 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000559 0xab, 0xad, 0xda, 0xd2 },
560};
561
562size_t pt_len[MAX_TESTS] =
563 { 0, 16, 64, 60, 60, 60 };
564
565int pt_index[MAX_TESTS] =
566 { 0, 0, 1, 1, 1, 1 };
567
568unsigned char pt[MAX_TESTS][64] =
569{
570 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
572 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
573 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
574 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
575 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
576 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
577 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
578 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
579 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
580};
581
582unsigned char ct[MAX_TESTS * 3][64] =
583{
584 { 0x00 },
585 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
586 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
587 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200588 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000589 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200590 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000591 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200592 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000593 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
594 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
595 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200596 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000597 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200598 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000599 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200600 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000601 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
602 0x3d, 0x58, 0xe0, 0x91 },
603 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200604 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000605 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200606 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000607 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200608 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000609 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
610 0xc2, 0x3f, 0x45, 0x98 },
611 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200612 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200614 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200616 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000617 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
618 0x4c, 0x34, 0xae, 0xe5 },
619 { 0x00 },
620 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200621 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000622 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200623 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000624 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200625 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000626 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200627 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000628 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
629 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
630 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200631 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000632 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200633 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
634 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
635 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000636 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200637 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000638 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200639 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000640 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200641 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200643 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000644 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200645 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000646 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200647 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200649 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000650 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200651 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200653 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000654 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
656 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
657 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
658 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
659 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
660 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
661 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
662 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
663 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
664 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
665 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
666 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
667 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
668 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
669 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
670 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
671 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
672 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000673 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200674 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000675 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200676 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000677 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200678 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000679 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200680 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000681 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200682 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000683 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200684 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000685 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200686 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000687 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200688 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000689};
690
691unsigned char tag[MAX_TESTS * 3][16] =
692{
693 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
694 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
695 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
696 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
697 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
700 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
701 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
702 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
703 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
704 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
705 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
706 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
707 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200708 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000709 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
710 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
711 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200712 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000713 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200714 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000715 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200716 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000717 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200718 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000719 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200720 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000721 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200722 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000723 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200724 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000725 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200726 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000727 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200728 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000729};
730
731int gcm_self_test( int verbose )
732{
733 gcm_context ctx;
734 unsigned char buf[64];
735 unsigned char tag_buf[16];
736 int i, j, ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200737 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000738
739 for( j = 0; j < 3; j++ )
740 {
741 int key_len = 128 + 64 * j;
742
743 for( i = 0; i < MAX_TESTS; i++ )
744 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200745 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100746 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
747 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200748
Paul Bakker43aff2a2013-09-09 00:10:27 +0200749 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000750
751 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
752 pt_len[i],
753 iv[iv_index[i]], iv_len[i],
754 additional[add_index[i]], add_len[i],
755 pt[pt_index[i]], buf, 16, tag_buf );
756
757 if( ret != 0 ||
758 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
759 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
760 {
761 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100762 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000763
764 return( 1 );
765 }
766
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200767 gcm_free( &ctx );
768
Paul Bakker89e80c92012-03-20 13:50:09 +0000769 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100770 polarssl_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000771
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200772 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100773 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
774 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200775
Paul Bakker43aff2a2013-09-09 00:10:27 +0200776 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000777
778 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
779 pt_len[i],
780 iv[iv_index[i]], iv_len[i],
781 additional[add_index[i]], add_len[i],
782 ct[j * 6 + i], buf, 16, tag_buf );
783
784 if( ret != 0 ||
785 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
786 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
787 {
788 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100789 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000790
791 return( 1 );
792 }
793
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200794 gcm_free( &ctx );
795
Paul Bakker89e80c92012-03-20 13:50:09 +0000796 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100797 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200798
799 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100800 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
801 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200802
Paul Bakker43aff2a2013-09-09 00:10:27 +0200803 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200804
805 ret = gcm_starts( &ctx, GCM_ENCRYPT,
806 iv[iv_index[i]], iv_len[i],
807 additional[add_index[i]], add_len[i] );
808 if( ret != 0 )
809 {
810 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100811 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200812
813 return( 1 );
814 }
815
816 if( pt_len[i] > 32 )
817 {
818 size_t rest_len = pt_len[i] - 32;
819 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
820 if( ret != 0 )
821 {
822 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100823 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200824
825 return( 1 );
826 }
827
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200828 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
829 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200830 if( ret != 0 )
831 {
832 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100833 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200834
835 return( 1 );
836 }
837 }
838 else
839 {
840 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
841 if( ret != 0 )
842 {
843 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100844 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200845
846 return( 1 );
847 }
848 }
849
850 ret = gcm_finish( &ctx, tag_buf, 16 );
851 if( ret != 0 ||
852 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
853 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
854 {
855 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100856 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200857
858 return( 1 );
859 }
860
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200861 gcm_free( &ctx );
862
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200863 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100864 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200865
866 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100867 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
868 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200869
Paul Bakker43aff2a2013-09-09 00:10:27 +0200870 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200871
872 ret = gcm_starts( &ctx, GCM_DECRYPT,
873 iv[iv_index[i]], iv_len[i],
874 additional[add_index[i]], add_len[i] );
875 if( ret != 0 )
876 {
877 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100878 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200879
880 return( 1 );
881 }
882
883 if( pt_len[i] > 32 )
884 {
885 size_t rest_len = pt_len[i] - 32;
886 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
887 if( ret != 0 )
888 {
889 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100890 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200891
892 return( 1 );
893 }
894
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200895 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
896 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200897 if( ret != 0 )
898 {
899 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100900 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200901
902 return( 1 );
903 }
904 }
905 else
906 {
907 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
908 if( ret != 0 )
909 {
910 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100911 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200912
913 return( 1 );
914 }
915 }
916
917 ret = gcm_finish( &ctx, tag_buf, 16 );
918 if( ret != 0 ||
919 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
920 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
921 {
922 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100923 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200924
925 return( 1 );
926 }
927
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200928 gcm_free( &ctx );
929
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200930 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100931 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200932
Paul Bakker89e80c92012-03-20 13:50:09 +0000933 }
934 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200935
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200936 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100937 polarssl_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000938
939 return( 0 );
940}
941
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200942
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 */