blob: c486ef765d24366be32ab734c85974e5327c9771 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker89e80c92012-03-20 13:50:09 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker89e80c92012-03-20 13:50:09 +000020 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010021
Paul Bakker89e80c92012-03-20 13:50:09 +000022/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010023 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
24 *
25 * See also:
26 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
27 *
28 * We use the algorithm described as Shoup's method with 4-bit tables in
29 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000030 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000033#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020034#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020036#endif
Paul Bakker89e80c92012-03-20 13:50:09 +000037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000039
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/gcm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050041#include "mbedtls/platform_util.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000042
Rich Evans00ab4702015-02-06 13:43:58 +000043#include <string.h>
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010047#endif
48
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010050#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000051#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030052#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000053#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#define mbedtls_printf printf
55#endif /* MBEDTLS_PLATFORM_C */
56#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010057
Jaeden Amero15263302017-09-21 12:53:48 +010058#if !defined(MBEDTLS_GCM_ALT)
59
Paul Bakker89e80c92012-03-20 13:50:09 +000060/*
61 * 32-bit integer manipulation macros (big endian)
62 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000063#ifndef GET_UINT32_BE
64#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000065{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000066 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
67 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
68 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
69 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000070}
71#endif
72
Paul Bakker5c2364c2012-10-01 14:41:15 +000073#ifndef PUT_UINT32_BE
74#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000075{ \
76 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
77 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
78 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
79 (b)[(i) + 3] = (unsigned char) ( (n) ); \
80}
81#endif
82
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010083/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020084 * Initialize a context
85 */
86void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
87{
88 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
89}
90
91/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010092 * Precompute small multiples of H, that is set
93 * HH[i] || HL[i] = H times i,
94 * where i is seen as a field element as in [MGV], ie high-order bits
95 * correspond to low powers of P. The result is stored in the same way, that
96 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
97 * corresponds to P^127.
98 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000100{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200101 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000102 uint64_t hi, lo;
103 uint64_t vl, vh;
104 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200105 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200106
Paul Bakker89e80c92012-03-20 13:50:09 +0000107 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200109 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000110
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100111 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000112 GET_UINT32_BE( hi, h, 0 );
113 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000114 vh = (uint64_t) hi << 32 | lo;
115
Paul Bakker5c2364c2012-10-01 14:41:15 +0000116 GET_UINT32_BE( hi, h, 8 );
117 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000118 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200119
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100120 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000121 ctx->HL[8] = vl;
122 ctx->HH[8] = vh;
123
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100125 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100126 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100127 return( 0 );
128#endif
129
130 /* 0 corresponds to 0 in GF(2^128) */
131 ctx->HH[0] = 0;
132 ctx->HL[0] = 0;
133
Paul Bakker89e80c92012-03-20 13:50:09 +0000134 for( i = 4; i > 0; i >>= 1 )
135 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200136 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000137 vl = ( vh << 63 ) | ( vl >> 1 );
138 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
139
140 ctx->HL[i] = vl;
141 ctx->HH[i] = vh;
142 }
143
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000144 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000145 {
146 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
147 vh = *HiH;
148 vl = *HiL;
149 for( j = 1; j < i; j++ )
150 {
151 HiH[j] = vh ^ ctx->HH[j];
152 HiL[j] = vl ^ ctx->HL[j];
153 }
154 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200155
156 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000157}
158
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200159int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
160 mbedtls_cipher_id_t cipher,
161 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200162 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000163{
164 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200165 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000166
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200167 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200168 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200170
Paul Bakkera0558e02013-09-10 14:25:51 +0200171 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200172 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200173
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200174 mbedtls_cipher_free( &ctx->cipher_ctx );
175
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200176 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000177 return( ret );
178
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200179 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200180 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200181 {
182 return( ret );
183 }
184
185 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
186 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000187
188 return( 0 );
189}
190
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100191/*
192 * Shoup's method for multiplication use this table with
193 * last4[x] = x times P^128
194 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
195 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000196static const uint64_t last4[16] =
197{
198 0x0000, 0x1c20, 0x3840, 0x2460,
199 0x7080, 0x6ca0, 0x48c0, 0x54e0,
200 0xe100, 0xfd20, 0xd940, 0xc560,
201 0x9180, 0x8da0, 0xa9c0, 0xb5e0
202};
203
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100204/*
205 * Sets output to x times H using the precomputed tables.
206 * x and output are seen as elements of GF(2^128) as in [MGV].
207 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200209 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000210{
211 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000212 unsigned char lo, hi, rem;
213 uint64_t zh, zl;
214
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100216 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100217 unsigned char h[16];
218
219 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
220 PUT_UINT32_BE( ctx->HH[8], h, 4 );
221 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
222 PUT_UINT32_BE( ctx->HL[8], h, 12 );
223
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200224 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100225 return;
226 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200227#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100228
Paul Bakker89e80c92012-03-20 13:50:09 +0000229 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000230
231 zh = ctx->HH[lo];
232 zl = ctx->HL[lo];
233
234 for( i = 15; i >= 0; i-- )
235 {
236 lo = x[i] & 0xf;
237 hi = x[i] >> 4;
238
239 if( i != 15 )
240 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000241 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000242 zl = ( zh << 60 ) | ( zl >> 4 );
243 zh = ( zh >> 4 );
244 zh ^= (uint64_t) last4[rem] << 48;
245 zh ^= ctx->HH[lo];
246 zl ^= ctx->HL[lo];
247
248 }
249
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000250 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000251 zl = ( zh << 60 ) | ( zl >> 4 );
252 zh = ( zh >> 4 );
253 zh ^= (uint64_t) last4[rem] << 48;
254 zh ^= ctx->HH[hi];
255 zl ^= ctx->HL[hi];
256 }
257
Paul Bakker5c2364c2012-10-01 14:41:15 +0000258 PUT_UINT32_BE( zh >> 32, output, 0 );
259 PUT_UINT32_BE( zh, output, 4 );
260 PUT_UINT32_BE( zl >> 32, output, 8 );
261 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000262}
263
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200265 int mode,
266 const unsigned char *iv,
267 size_t iv_len,
268 const unsigned char *add,
269 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000270{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200271 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000272 unsigned char work_buf[16];
273 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000274 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200275 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000276
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200277 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200278 /* IV is not allowed to be zero length */
279 if( iv_len == 0 ||
280 ( (uint64_t) iv_len ) >> 61 != 0 ||
281 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200282 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200284 }
285
Paul Bakker52cf16c2013-07-26 13:55:38 +0200286 memset( ctx->y, 0x00, sizeof(ctx->y) );
287 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
288
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200289 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200290 ctx->len = 0;
291 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000292
293 if( iv_len == 12 )
294 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200295 memcpy( ctx->y, iv, iv_len );
296 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000297 }
298 else
299 {
300 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000301 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000302
303 p = iv;
304 while( iv_len > 0 )
305 {
306 use_len = ( iv_len < 16 ) ? iv_len : 16;
307
Paul Bakker67f9d532012-10-23 11:49:05 +0000308 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200309 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200310
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200311 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000312
313 iv_len -= use_len;
314 p += use_len;
315 }
316
Paul Bakker67f9d532012-10-23 11:49:05 +0000317 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200318 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000319
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200320 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000321 }
322
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200324 &olen ) ) != 0 )
325 {
326 return( ret );
327 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000328
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200329 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000330 p = add;
331 while( add_len > 0 )
332 {
333 use_len = ( add_len < 16 ) ? add_len : 16;
334
Paul Bakker67f9d532012-10-23 11:49:05 +0000335 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200336 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200337
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200338 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000339
340 add_len -= use_len;
341 p += use_len;
342 }
343
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200344 return( 0 );
345}
346
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200348 size_t length,
349 const unsigned char *input,
350 unsigned char *output )
351{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200352 int ret;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200353 unsigned char ectr[16];
354 size_t i;
355 const unsigned char *p;
356 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200357 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200358
359 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200361
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200362 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
363 * Also check for possible overflow */
364 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100365 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200366 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200367 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200368 }
369
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200370 ctx->len += length;
371
Paul Bakker89e80c92012-03-20 13:50:09 +0000372 p = input;
373 while( length > 0 )
374 {
375 use_len = ( length < 16 ) ? length : 16;
376
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100377 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200378 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000379 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000380
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200382 &olen ) ) != 0 )
383 {
384 return( ret );
385 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000386
Paul Bakker67f9d532012-10-23 11:49:05 +0000387 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000388 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200390 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000391 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200393 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000394 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200395
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200396 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200397
Paul Bakker89e80c92012-03-20 13:50:09 +0000398 length -= use_len;
399 p += use_len;
400 out_p += use_len;
401 }
402
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200403 return( 0 );
404}
405
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200407 unsigned char *tag,
408 size_t tag_len )
409{
410 unsigned char work_buf[16];
411 size_t i;
412 uint64_t orig_len = ctx->len * 8;
413 uint64_t orig_add_len = ctx->add_len * 8;
414
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200415 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200417
Andres AG821da842016-09-26 10:09:30 +0100418 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200419
Paul Bakker89e80c92012-03-20 13:50:09 +0000420 if( orig_len || orig_add_len )
421 {
422 memset( work_buf, 0x00, 16 );
423
Paul Bakker0ecdb232013-04-09 11:36:42 +0200424 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
425 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
426 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
427 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000428
Paul Bakker67f9d532012-10-23 11:49:05 +0000429 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200430 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000431
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200432 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000433
Paul Bakker67f9d532012-10-23 11:49:05 +0000434 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200435 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000436 }
437
438 return( 0 );
439}
440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200442 int mode,
443 size_t length,
444 const unsigned char *iv,
445 size_t iv_len,
446 const unsigned char *add,
447 size_t add_len,
448 const unsigned char *input,
449 unsigned char *output,
450 size_t tag_len,
451 unsigned char *tag )
452{
453 int ret;
454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200456 return( ret );
457
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200459 return( ret );
460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200462 return( ret );
463
464 return( 0 );
465}
466
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000468 size_t length,
469 const unsigned char *iv,
470 size_t iv_len,
471 const unsigned char *add,
472 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200473 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000474 size_t tag_len,
475 const unsigned char *input,
476 unsigned char *output )
477{
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100478 int ret;
Paul Bakker89e80c92012-03-20 13:50:09 +0000479 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200480 size_t i;
481 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100484 iv, iv_len, add, add_len,
485 input, output, tag_len, check_tag ) ) != 0 )
486 {
487 return( ret );
488 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000489
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200490 /* Check tag in "constant-time" */
491 for( diff = 0, i = 0; i < tag_len; i++ )
492 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000493
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200494 if( diff != 0 )
495 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500496 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200498 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000499
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200500 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000501}
502
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200504{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500506 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200507}
508
Jaeden Amero15263302017-09-21 12:53:48 +0100509#endif /* !MBEDTLS_GCM_ALT */
510
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000512/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200513 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000514 *
515 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
516 */
517#define MAX_TESTS 6
518
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000519static const int key_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000520 { 0, 0, 1, 1, 1, 1 };
521
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000522static const unsigned char key[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000523{
524 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
525 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
528 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
529 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
530 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200531 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000532};
533
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000534static const size_t iv_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000535 { 12, 12, 12, 12, 8, 60 };
536
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000537static const int iv_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000538 { 0, 0, 1, 1, 1, 2 };
539
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000540static const unsigned char iv[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000541{
542 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0x00, 0x00, 0x00, 0x00 },
544 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
545 0xde, 0xca, 0xf8, 0x88 },
546 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200547 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000548 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200549 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000550 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200551 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000552 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200553 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000554};
555
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000556static const size_t add_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000557 { 0, 0, 0, 20, 20, 20 };
558
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000559static const int add_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000560 { 0, 0, 0, 1, 1, 1 };
561
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000562static const unsigned char additional[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000563{
564 { 0x00 },
565 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200566 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000567 0xab, 0xad, 0xda, 0xd2 },
568};
569
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000570static const size_t pt_len[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000571 { 0, 16, 64, 60, 60, 60 };
572
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000573static const int pt_index[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000574 { 0, 0, 1, 1, 1, 1 };
575
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000576static const unsigned char pt[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000577{
578 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
580 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
581 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
582 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
583 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
584 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
585 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
586 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
587 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
588};
589
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000590static const unsigned char ct[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000591{
592 { 0x00 },
593 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
594 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
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, 0x47, 0x3f, 0x59, 0x85 },
603 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200604 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000605 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200606 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000607 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200608 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000609 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
610 0x3d, 0x58, 0xe0, 0x91 },
611 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200612 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200614 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200616 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000617 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
618 0xc2, 0x3f, 0x45, 0x98 },
619 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200620 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000621 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200622 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000623 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200624 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
626 0x4c, 0x34, 0xae, 0xe5 },
627 { 0x00 },
628 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200629 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000630 { 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,
Paul Bakker89e80c92012-03-20 13:50:09 +0000634 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200635 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000636 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
637 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
638 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200639 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000640 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200641 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
642 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
643 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000644 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200645 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000646 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200647 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200649 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000650 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200651 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200653 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000654 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000656 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200657 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000658 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200659 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200661 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000662 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200663 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
664 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
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, 0x89, 0x80, 0x15, 0xad },
673 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
674 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
675 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
676 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
677 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
678 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
679 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
680 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000681 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200682 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000683 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200684 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000685 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200686 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000687 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200688 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000689 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200690 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000691 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200692 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000693 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200694 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000695 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200696 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000697};
698
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000699static const unsigned char tag[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000700{
701 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
702 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
703 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
704 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
705 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200706 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000707 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
708 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
709 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
710 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
711 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
712 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
713 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
714 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
715 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200716 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000717 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
718 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
719 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200720 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000721 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200722 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000723 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200724 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000725 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200726 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000727 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200728 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000729 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200730 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000731 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200732 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000733 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200734 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000735 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200736 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000737};
738
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000740{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200741 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000742 unsigned char buf[64];
743 unsigned char tag_buf[16];
744 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200745 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000746
747 for( j = 0; j < 3; j++ )
748 {
749 int key_len = 128 + 64 * j;
750
751 for( i = 0; i < MAX_TESTS; i++ )
752 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100753 mbedtls_gcm_init( &ctx );
754
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200755 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200756 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100757 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200758
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100759 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
760 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100761 /*
762 * AES-192 is an optional feature that may be unavailable when
763 * there is an alternative underlying implementation i.e. when
764 * MBEDTLS_AES_ALT is defined.
765 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300766 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100767 {
768 mbedtls_printf( "skipped\n" );
769 break;
770 }
771 else if( ret != 0 )
772 {
773 goto exit;
774 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000775
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200776 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100777 pt_len[i],
778 iv[iv_index[i]], iv_len[i],
779 additional[add_index[i]], add_len[i],
780 pt[pt_index[i]], buf, 16, tag_buf );
781 if( ret != 0 )
782 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000783
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100784 if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
785 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000786 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100787 ret = 1;
788 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000789 }
790
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200791 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200792
Paul Bakker89e80c92012-03-20 13:50:09 +0000793 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000795
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100796 mbedtls_gcm_init( &ctx );
797
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200798 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200799 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100800 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200801
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100802 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
803 key_len );
804 if( ret != 0 )
805 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000806
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100808 pt_len[i],
809 iv[iv_index[i]], iv_len[i],
810 additional[add_index[i]], add_len[i],
811 ct[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000812
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100813 if( ret != 0 )
814 goto exit;
815
816 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
Paul Bakker89e80c92012-03-20 13:50:09 +0000817 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
818 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100819 ret = 1;
820 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000821 }
822
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200823 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200824
Paul Bakker89e80c92012-03-20 13:50:09 +0000825 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200826 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200827
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100828 mbedtls_gcm_init( &ctx );
829
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200830 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200831 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100832 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200833
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100834 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
835 key_len );
836 if( ret != 0 )
837 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200838
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100840 iv[iv_index[i]], iv_len[i],
841 additional[add_index[i]], add_len[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200842 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100843 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200844
845 if( pt_len[i] > 32 )
846 {
847 size_t rest_len = pt_len[i] - 32;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200848 ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200849 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100850 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200851
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852 ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200853 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200854 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100855 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200856 }
857 else
858 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200859 ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200860 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100861 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200862 }
863
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200864 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100865 if( ret != 0 )
866 goto exit;
867
868 if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200869 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
870 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100871 ret = 1;
872 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200873 }
874
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200876
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200877 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200879
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100880 mbedtls_gcm_init( &ctx );
881
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200882 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100884 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200885
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100886 ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
887 key_len );
888 if( ret != 0 )
889 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200890
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200892 iv[iv_index[i]], iv_len[i],
893 additional[add_index[i]], add_len[i] );
894 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100895 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200896
897 if( pt_len[i] > 32 )
898 {
899 size_t rest_len = pt_len[i] - 32;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900 ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200901 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100902 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200903
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100905 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200906 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100907 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200908 }
909 else
910 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100911 ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
912 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200913 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100914 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200915 }
916
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200917 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100918 if( ret != 0 )
919 goto exit;
920
921 if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200922 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
923 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100924 ret = 1;
925 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200926 }
927
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200928 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200929
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200930 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000932 }
933 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200934
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200935 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000937
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100938 ret = 0;
939
940exit:
941 if( ret != 0 )
942 {
943 if( verbose != 0 )
944 mbedtls_printf( "failed\n" );
945 mbedtls_gcm_free( &ctx );
946 }
947
948 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000949}
950
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200951#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000952
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953#endif /* MBEDTLS_GCM_C */