blob: 62fe1852b644975821ef8b225f26c7532a2defaf [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Paul Bakker7dc4c442014-02-01 22:50:26 +01004 * Copyright (C) 2006-2014, Brainspark B.V.
Paul Bakker89e80c92012-03-20 13:50:09 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010025
Paul Bakker89e80c92012-03-20 13:50:09 +000026/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010027 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
28 *
29 * See also:
30 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
31 *
32 * We use the algorithm described as Shoup's method with 4-bit tables in
33 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000034 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010035
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020036#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker89e80c92012-03-20 13:50:09 +000037#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020038#else
39#include POLARSSL_CONFIG_FILE
40#endif
Paul Bakker89e80c92012-03-20 13:50:09 +000041
42#if defined(POLARSSL_GCM_C)
43
44#include "polarssl/gcm.h"
45
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010046#if defined(POLARSSL_AESNI_C)
47#include "polarssl/aesni.h"
48#endif
49
Paul Bakker7dc4c442014-02-01 22:50:26 +010050#if defined(POLARSSL_PLATFORM_C)
51#include "polarssl/platform.h"
52#else
53#define polarssl_printf printf
54#endif
55
Paul Bakker89e80c92012-03-20 13:50:09 +000056/*
57 * 32-bit integer manipulation macros (big endian)
58 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000059#ifndef GET_UINT32_BE
60#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000061{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000062 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
63 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
64 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
65 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000066}
67#endif
68
Paul Bakker5c2364c2012-10-01 14:41:15 +000069#ifndef PUT_UINT32_BE
70#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000071{ \
72 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
73 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
74 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
75 (b)[(i) + 3] = (unsigned char) ( (n) ); \
76}
77#endif
78
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010079/*
80 * Precompute small multiples of H, that is set
81 * HH[i] || HL[i] = H times i,
82 * where i is seen as a field element as in [MGV], ie high-order bits
83 * correspond to low powers of P. The result is stored in the same way, that
84 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
85 * corresponds to P^127.
86 */
Paul Bakker43aff2a2013-09-09 00:10:27 +020087static int gcm_gen_table( gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000088{
Paul Bakker43aff2a2013-09-09 00:10:27 +020089 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000090 uint64_t hi, lo;
91 uint64_t vl, vh;
92 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020093 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020094
Paul Bakker89e80c92012-03-20 13:50:09 +000095 memset( h, 0, 16 );
Paul Bakker43aff2a2013-09-09 00:10:27 +020096 if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
97 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000098
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010099 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000100 GET_UINT32_BE( hi, h, 0 );
101 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000102 vh = (uint64_t) hi << 32 | lo;
103
Paul Bakker5c2364c2012-10-01 14:41:15 +0000104 GET_UINT32_BE( hi, h, 8 );
105 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000106 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200107
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100108 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000109 ctx->HL[8] = vl;
110 ctx->HH[8] = vh;
111
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100112#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
113 /* With CLMUL support, we need only h, not the rest of the table */
114 if( aesni_supports( POLARSSL_AESNI_CLMUL ) )
115 return( 0 );
116#endif
117
118 /* 0 corresponds to 0 in GF(2^128) */
119 ctx->HH[0] = 0;
120 ctx->HL[0] = 0;
121
Paul Bakker89e80c92012-03-20 13:50:09 +0000122 for( i = 4; i > 0; i >>= 1 )
123 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200124 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000125 vl = ( vh << 63 ) | ( vl >> 1 );
126 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
127
128 ctx->HL[i] = vl;
129 ctx->HH[i] = vh;
130 }
131
132 for (i = 2; i < 16; i <<= 1 )
133 {
134 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
135 vh = *HiH;
136 vl = *HiL;
137 for( j = 1; j < i; j++ )
138 {
139 HiH[j] = vh ^ ctx->HH[j];
140 HiL[j] = vl ^ ctx->HL[j];
141 }
142 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200143
144 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000145}
146
Paul Bakker43aff2a2013-09-09 00:10:27 +0200147int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
148 unsigned int keysize )
Paul Bakker89e80c92012-03-20 13:50:09 +0000149{
150 int ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200151 const cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000152
153 memset( ctx, 0, sizeof(gcm_context) );
154
Paul Bakker43aff2a2013-09-09 00:10:27 +0200155 cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
156 if( cipher_info == NULL )
157 return( POLARSSL_ERR_GCM_BAD_INPUT );
158
Paul Bakkera0558e02013-09-10 14:25:51 +0200159 if( cipher_info->block_size != 16 )
160 return( POLARSSL_ERR_GCM_BAD_INPUT );
161
Paul Bakker43aff2a2013-09-09 00:10:27 +0200162 if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000163 return( ret );
164
Paul Bakker43aff2a2013-09-09 00:10:27 +0200165 if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
166 POLARSSL_ENCRYPT ) ) != 0 )
167 {
168 return( ret );
169 }
170
171 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
172 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000173
174 return( 0 );
175}
176
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100177/*
178 * Shoup's method for multiplication use this table with
179 * last4[x] = x times P^128
180 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
181 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000182static const uint64_t last4[16] =
183{
184 0x0000, 0x1c20, 0x3840, 0x2460,
185 0x7080, 0x6ca0, 0x48c0, 0x54e0,
186 0xe100, 0xfd20, 0xd940, 0xc560,
187 0x9180, 0x8da0, 0xa9c0, 0xb5e0
188};
189
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100190/*
191 * Sets output to x times H using the precomputed tables.
192 * x and output are seen as elements of GF(2^128) as in [MGV].
193 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200194static void gcm_mult( gcm_context *ctx, const unsigned char x[16],
195 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000196{
197 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000198 unsigned char lo, hi, rem;
199 uint64_t zh, zl;
200
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100201#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
202 if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) {
203 unsigned char h[16];
204
205 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
206 PUT_UINT32_BE( ctx->HH[8], h, 4 );
207 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
208 PUT_UINT32_BE( ctx->HL[8], h, 12 );
209
Manuel Pégourié-Gonnardd4588cf2013-12-30 13:54:23 +0100210 aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100211 return;
212 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200213#endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100214
Paul Bakker89e80c92012-03-20 13:50:09 +0000215 lo = x[15] & 0xf;
216 hi = x[15] >> 4;
217
218 zh = ctx->HH[lo];
219 zl = ctx->HL[lo];
220
221 for( i = 15; i >= 0; i-- )
222 {
223 lo = x[i] & 0xf;
224 hi = x[i] >> 4;
225
226 if( i != 15 )
227 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000228 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000229 zl = ( zh << 60 ) | ( zl >> 4 );
230 zh = ( zh >> 4 );
231 zh ^= (uint64_t) last4[rem] << 48;
232 zh ^= ctx->HH[lo];
233 zl ^= ctx->HL[lo];
234
235 }
236
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000237 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000238 zl = ( zh << 60 ) | ( zl >> 4 );
239 zh = ( zh >> 4 );
240 zh ^= (uint64_t) last4[rem] << 48;
241 zh ^= ctx->HH[hi];
242 zl ^= ctx->HL[hi];
243 }
244
Paul Bakker5c2364c2012-10-01 14:41:15 +0000245 PUT_UINT32_BE( zh >> 32, output, 0 );
246 PUT_UINT32_BE( zh, output, 4 );
247 PUT_UINT32_BE( zl >> 32, output, 8 );
248 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000249}
250
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200251int gcm_starts( gcm_context *ctx,
252 int mode,
253 const unsigned char *iv,
254 size_t iv_len,
255 const unsigned char *add,
256 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000257{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200258 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000259 unsigned char work_buf[16];
260 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000261 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200262 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000263
Paul Bakker52cf16c2013-07-26 13:55:38 +0200264 memset( ctx->y, 0x00, sizeof(ctx->y) );
265 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
266
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200267 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200268 ctx->len = 0;
269 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000270
271 if( iv_len == 12 )
272 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200273 memcpy( ctx->y, iv, iv_len );
274 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000275 }
276 else
277 {
278 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000279 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000280
281 p = iv;
282 while( iv_len > 0 )
283 {
284 use_len = ( iv_len < 16 ) ? iv_len : 16;
285
Paul Bakker67f9d532012-10-23 11:49:05 +0000286 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200287 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200288
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200289 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000290
291 iv_len -= use_len;
292 p += use_len;
293 }
294
Paul Bakker67f9d532012-10-23 11:49:05 +0000295 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200296 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000297
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200298 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000299 }
300
Paul Bakker43aff2a2013-09-09 00:10:27 +0200301 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
302 &olen ) ) != 0 )
303 {
304 return( ret );
305 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000306
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200307 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000308 p = add;
309 while( add_len > 0 )
310 {
311 use_len = ( add_len < 16 ) ? add_len : 16;
312
Paul Bakker67f9d532012-10-23 11:49:05 +0000313 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200314 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200315
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200316 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000317
318 add_len -= use_len;
319 p += use_len;
320 }
321
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200322 return( 0 );
323}
324
325int gcm_update( gcm_context *ctx,
326 size_t length,
327 const unsigned char *input,
328 unsigned char *output )
329{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200330 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200331 unsigned char ectr[16];
332 size_t i;
333 const unsigned char *p;
334 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200335 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200336
337 if( output > input && (size_t) ( output - input ) < length )
338 return( POLARSSL_ERR_GCM_BAD_INPUT );
339
340 ctx->len += length;
341
Paul Bakker89e80c92012-03-20 13:50:09 +0000342 p = input;
343 while( length > 0 )
344 {
345 use_len = ( length < 16 ) ? length : 16;
346
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100347 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200348 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000349 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000350
Paul Bakker43aff2a2013-09-09 00:10:27 +0200351 if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
352 &olen ) ) != 0 )
353 {
354 return( ret );
355 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000356
Paul Bakker67f9d532012-10-23 11:49:05 +0000357 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000358 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200359 if( ctx->mode == GCM_DECRYPT )
360 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000361 out_p[i] = ectr[i] ^ p[i];
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200362 if( ctx->mode == GCM_ENCRYPT )
363 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000364 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200365
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200366 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200367
Paul Bakker89e80c92012-03-20 13:50:09 +0000368 length -= use_len;
369 p += use_len;
370 out_p += use_len;
371 }
372
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200373 return( 0 );
374}
375
376int gcm_finish( gcm_context *ctx,
377 unsigned char *tag,
378 size_t tag_len )
379{
380 unsigned char work_buf[16];
381 size_t i;
382 uint64_t orig_len = ctx->len * 8;
383 uint64_t orig_add_len = ctx->add_len * 8;
384
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200385 if( tag_len > 16 )
386 return( POLARSSL_ERR_GCM_BAD_INPUT );
387
Manuel Pégourié-Gonnard9241be72013-08-31 17:31:03 +0200388 if( tag_len != 0 )
389 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200390
Paul Bakker89e80c92012-03-20 13:50:09 +0000391 if( orig_len || orig_add_len )
392 {
393 memset( work_buf, 0x00, 16 );
394
Paul Bakker0ecdb232013-04-09 11:36:42 +0200395 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
396 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
397 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
398 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000399
Paul Bakker67f9d532012-10-23 11:49:05 +0000400 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200401 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000402
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200403 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000404
Paul Bakker67f9d532012-10-23 11:49:05 +0000405 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200406 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000407 }
408
409 return( 0 );
410}
411
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200412int gcm_crypt_and_tag( gcm_context *ctx,
413 int mode,
414 size_t length,
415 const unsigned char *iv,
416 size_t iv_len,
417 const unsigned char *add,
418 size_t add_len,
419 const unsigned char *input,
420 unsigned char *output,
421 size_t tag_len,
422 unsigned char *tag )
423{
424 int ret;
425
426 if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
427 return( ret );
428
429 if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 )
430 return( ret );
431
432 if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 )
433 return( ret );
434
435 return( 0 );
436}
437
Paul Bakker89e80c92012-03-20 13:50:09 +0000438int gcm_auth_decrypt( gcm_context *ctx,
439 size_t length,
440 const unsigned char *iv,
441 size_t iv_len,
442 const unsigned char *add,
443 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200444 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000445 size_t tag_len,
446 const unsigned char *input,
447 unsigned char *output )
448{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100449 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000450 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200451 size_t i;
452 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000453
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100454 if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
455 iv, iv_len, add, add_len,
456 input, output, tag_len, check_tag ) ) != 0 )
457 {
458 return( ret );
459 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000460
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200461 /* Check tag in "constant-time" */
462 for( diff = 0, i = 0; i < tag_len; i++ )
463 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000464
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200465 if( diff != 0 )
466 {
467 memset( output, 0, length );
468 return( POLARSSL_ERR_GCM_AUTH_FAILED );
469 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000470
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200471 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000472}
473
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200474void gcm_free( gcm_context *ctx )
475{
476 (void) cipher_free_ctx( &ctx->cipher_ctx );
477 memset( ctx, 0, sizeof( gcm_context ) );
478}
479
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200480#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000481
482#include <stdio.h>
483
484/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200485 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000486 *
487 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
488 */
489#define MAX_TESTS 6
490
491int key_index[MAX_TESTS] =
492 { 0, 0, 1, 1, 1, 1 };
493
494unsigned char key[MAX_TESTS][32] =
495{
496 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
500 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
501 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
502 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200503 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000504};
505
506size_t iv_len[MAX_TESTS] =
507 { 12, 12, 12, 12, 8, 60 };
508
509int iv_index[MAX_TESTS] =
510 { 0, 0, 1, 1, 1, 2 };
511
512unsigned char iv[MAX_TESTS][64] =
513{
514 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515 0x00, 0x00, 0x00, 0x00 },
516 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
517 0xde, 0xca, 0xf8, 0x88 },
518 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200519 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000520 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200521 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000522 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200523 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000524 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200525 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000526};
527
528size_t add_len[MAX_TESTS] =
529 { 0, 0, 0, 20, 20, 20 };
530
531int add_index[MAX_TESTS] =
532 { 0, 0, 0, 1, 1, 1 };
533
534unsigned char additional[MAX_TESTS][64] =
535{
536 { 0x00 },
537 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200538 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000539 0xab, 0xad, 0xda, 0xd2 },
540};
541
542size_t pt_len[MAX_TESTS] =
543 { 0, 16, 64, 60, 60, 60 };
544
545int pt_index[MAX_TESTS] =
546 { 0, 0, 1, 1, 1, 1 };
547
548unsigned char pt[MAX_TESTS][64] =
549{
550 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
552 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
553 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
554 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
555 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
556 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
557 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
558 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
559 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
560};
561
562unsigned char ct[MAX_TESTS * 3][64] =
563{
564 { 0x00 },
565 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
566 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
567 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200568 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000569 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200570 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000571 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200572 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000573 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
574 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
575 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200576 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000577 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200578 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000579 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200580 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000581 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
582 0x3d, 0x58, 0xe0, 0x91 },
583 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200584 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000585 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200586 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000587 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200588 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000589 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
590 0xc2, 0x3f, 0x45, 0x98 },
591 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200592 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000593 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200594 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000595 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200596 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000597 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
598 0x4c, 0x34, 0xae, 0xe5 },
599 { 0x00 },
600 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200601 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000602 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200603 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000604 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200605 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000606 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200607 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000608 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
609 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
610 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200611 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000612 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200613 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
614 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
615 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000616 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200617 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000618 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200619 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000620 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200621 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000622 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200623 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000624 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200625 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000626 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200627 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000628 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200629 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000630 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200631 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000632 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200633 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000634 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200635 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
636 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
637 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
638 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
639 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
640 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
641 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
642 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
643 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
644 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
645 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
646 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
647 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
648 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
649 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
650 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
651 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
652 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000653 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200654 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000655 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200656 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000657 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200658 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000659 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200660 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000661 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200662 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000663 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200664 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000665 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200666 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000667 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200668 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000669};
670
671unsigned char tag[MAX_TESTS * 3][16] =
672{
673 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
674 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
675 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
676 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
677 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200678 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000679 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
680 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
681 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
682 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
683 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
684 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
685 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
686 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
687 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200688 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000689 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
690 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
691 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200692 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000693 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200694 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000695 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200696 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200702 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000703 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200704 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000705 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200706 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000707 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200708 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000709};
710
711int gcm_self_test( int verbose )
712{
713 gcm_context ctx;
714 unsigned char buf[64];
715 unsigned char tag_buf[16];
716 int i, j, ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200717 cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000718
719 for( j = 0; j < 3; j++ )
720 {
721 int key_len = 128 + 64 * j;
722
723 for( i = 0; i < MAX_TESTS; i++ )
724 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200725 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100726 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
727 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200728
Paul Bakker43aff2a2013-09-09 00:10:27 +0200729 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000730
731 ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
732 pt_len[i],
733 iv[iv_index[i]], iv_len[i],
734 additional[add_index[i]], add_len[i],
735 pt[pt_index[i]], buf, 16, tag_buf );
736
737 if( ret != 0 ||
738 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
739 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
740 {
741 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100742 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000743
744 return( 1 );
745 }
746
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200747 gcm_free( &ctx );
748
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100750 polarssl_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000751
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200752 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100753 polarssl_printf( " AES-GCM-%3d #%d (%s): ",
754 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200755
Paul Bakker43aff2a2013-09-09 00:10:27 +0200756 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000757
758 ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
759 pt_len[i],
760 iv[iv_index[i]], iv_len[i],
761 additional[add_index[i]], add_len[i],
762 ct[j * 6 + i], buf, 16, tag_buf );
763
764 if( ret != 0 ||
765 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
766 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
767 {
768 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100769 polarssl_printf( "failed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000770
771 return( 1 );
772 }
773
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200774 gcm_free( &ctx );
775
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100777 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200778
779 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100780 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
781 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200782
Paul Bakker43aff2a2013-09-09 00:10:27 +0200783 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200784
785 ret = gcm_starts( &ctx, GCM_ENCRYPT,
786 iv[iv_index[i]], iv_len[i],
787 additional[add_index[i]], add_len[i] );
788 if( ret != 0 )
789 {
790 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100791 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200792
793 return( 1 );
794 }
795
796 if( pt_len[i] > 32 )
797 {
798 size_t rest_len = pt_len[i] - 32;
799 ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf );
800 if( ret != 0 )
801 {
802 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100803 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200804
805 return( 1 );
806 }
807
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200808 ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
809 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200810 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 else
819 {
820 ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
821 if( ret != 0 )
822 {
823 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100824 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200825
826 return( 1 );
827 }
828 }
829
830 ret = gcm_finish( &ctx, tag_buf, 16 );
831 if( ret != 0 ||
832 memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
833 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
834 {
835 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100836 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200837
838 return( 1 );
839 }
840
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200841 gcm_free( &ctx );
842
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200843 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100844 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200845
846 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100847 polarssl_printf( " AES-GCM-%3d #%d split (%s): ",
848 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200849
Paul Bakker43aff2a2013-09-09 00:10:27 +0200850 gcm_init( &ctx, cipher, key[key_index[i]], key_len );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200851
852 ret = gcm_starts( &ctx, GCM_DECRYPT,
853 iv[iv_index[i]], iv_len[i],
854 additional[add_index[i]], add_len[i] );
855 if( ret != 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
863 if( pt_len[i] > 32 )
864 {
865 size_t rest_len = pt_len[i] - 32;
866 ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf );
867 if( ret != 0 )
868 {
869 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100870 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200871
872 return( 1 );
873 }
874
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200875 ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
876 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200877 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 else
886 {
887 ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf );
888 if( ret != 0 )
889 {
890 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100891 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200892
893 return( 1 );
894 }
895 }
896
897 ret = gcm_finish( &ctx, tag_buf, 16 );
898 if( ret != 0 ||
899 memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
900 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
901 {
902 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100903 polarssl_printf( "failed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200904
905 return( 1 );
906 }
907
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200908 gcm_free( &ctx );
909
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200910 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100911 polarssl_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200912
Paul Bakker89e80c92012-03-20 13:50:09 +0000913 }
914 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200915
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200916 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100917 polarssl_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000918
919 return( 0 );
920}
921
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200922
923
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200924#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000925
Paul Bakker9af723c2014-05-01 13:03:14 +0200926#endif /* POLARSSL_GCM_C */