blob: 123777de479f030554ff37c256a0a764a2f49ce2 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
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é-Gonnard9d574822013-12-25 15:41:25 +010019
Paul Bakker89e80c92012-03-20 13:50:09 +000020/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010021 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
22 *
23 * See also:
24 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
25 *
26 * We use the algorithm described as Shoup's method with 4-bit tables in
27 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000028 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010029
Gilles Peskinedb09ef62020-06-03 01:43:33 +020030#include "common.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000033
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/gcm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050035#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000036#include "mbedtls/error.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000041#include "aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010042#endif
43
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010045#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030047#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000048#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#define mbedtls_printf printf
50#endif /* MBEDTLS_PLATFORM_C */
51#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Jaeden Amero15263302017-09-21 12:53:48 +010053#if !defined(MBEDTLS_GCM_ALT)
54
k-stachowiak8ffc92a2018-12-12 14:21:59 +010055/* Parameter validation macros */
56#define GCM_VALIDATE_RET( cond ) \
57 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
58#define GCM_VALIDATE( cond ) \
59 MBEDTLS_INTERNAL_VALIDATE( cond )
60
Paul Bakker89e80c92012-03-20 13:50:09 +000061/*
62 * 32-bit integer manipulation macros (big endian)
63 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000064#ifndef GET_UINT32_BE
65#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000066{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000067 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
68 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
69 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
70 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000071}
72#endif
73
Paul Bakker5c2364c2012-10-01 14:41:15 +000074#ifndef PUT_UINT32_BE
75#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000076{ \
77 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
78 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
79 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
80 (b)[(i) + 3] = (unsigned char) ( (n) ); \
81}
82#endif
83
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010084/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020085 * Initialize a context
86 */
87void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
88{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010089 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020090 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
91}
92
93/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010094 * Precompute small multiples of H, that is set
95 * HH[i] || HL[i] = H times i,
96 * where i is seen as a field element as in [MGV], ie high-order bits
97 * correspond to low powers of P. The result is stored in the same way, that
98 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
99 * corresponds to P^127.
100 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200101static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000102{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200103 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000104 uint64_t hi, lo;
105 uint64_t vl, vh;
106 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200107 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200108
Paul Bakker89e80c92012-03-20 13:50:09 +0000109 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200111 return ret ;
Paul Bakker89e80c92012-03-20 13:50:09 +0000112
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100113 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000114 GET_UINT32_BE( hi, h, 0 );
115 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000116 vh = (uint64_t) hi << 32 | lo;
117
Paul Bakker5c2364c2012-10-01 14:41:15 +0000118 GET_UINT32_BE( hi, h, 8 );
119 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000120 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200121
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100122 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000123 ctx->HL[8] = vl;
124 ctx->HH[8] = vh;
125
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200126#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100127 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100128 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200129 return 0 ;
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100130#endif
131
132 /* 0 corresponds to 0 in GF(2^128) */
133 ctx->HH[0] = 0;
134 ctx->HL[0] = 0;
135
Paul Bakker89e80c92012-03-20 13:50:09 +0000136 for( i = 4; i > 0; i >>= 1 )
137 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200138 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000139 vl = ( vh << 63 ) | ( vl >> 1 );
140 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
141
142 ctx->HL[i] = vl;
143 ctx->HH[i] = vh;
144 }
145
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000146 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000147 {
148 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
149 vh = *HiH;
150 vl = *HiL;
151 for( j = 1; j < i; j++ )
152 {
153 HiH[j] = vh ^ ctx->HH[j];
154 HiL[j] = vl ^ ctx->HL[j];
155 }
156 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200157
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200158 return 0 ;
Paul Bakker89e80c92012-03-20 13:50:09 +0000159}
160
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200161int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
162 mbedtls_cipher_id_t cipher,
163 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200164 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000165{
Janos Follath24eed8d2019-11-22 13:21:35 +0000166 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000168
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100169 GCM_VALIDATE_RET( ctx != NULL );
170 GCM_VALIDATE_RET( key != NULL );
171 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
172
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500173 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
174 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200175 if( cipher_info == NULL )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200176 return MBEDTLS_ERR_GCM_BAD_INPUT ;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200177
Paul Bakkera0558e02013-09-10 14:25:51 +0200178 if( cipher_info->block_size != 16 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200179 return MBEDTLS_ERR_GCM_BAD_INPUT ;
Paul Bakkera0558e02013-09-10 14:25:51 +0200180
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200181 mbedtls_cipher_free( &ctx->cipher_ctx );
182
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200183 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200184 return ret ;
Paul Bakker89e80c92012-03-20 13:50:09 +0000185
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200186 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200188 {
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200189 return ret ;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200190 }
191
192 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200193 return ret ;
Paul Bakker89e80c92012-03-20 13:50:09 +0000194
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200195 return 0 ;
Paul Bakker89e80c92012-03-20 13:50:09 +0000196}
197
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100198/*
199 * Shoup's method for multiplication use this table with
200 * last4[x] = x times P^128
201 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
202 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000203static const uint64_t last4[16] =
204{
205 0x0000, 0x1c20, 0x3840, 0x2460,
206 0x7080, 0x6ca0, 0x48c0, 0x54e0,
207 0xe100, 0xfd20, 0xd940, 0xc560,
208 0x9180, 0x8da0, 0xa9c0, 0xb5e0
209};
210
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100211/*
212 * Sets output to x times H using the precomputed tables.
213 * x and output are seen as elements of GF(2^128) as in [MGV].
214 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200216 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000217{
218 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000219 unsigned char lo, hi, rem;
220 uint64_t zh, zl;
221
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200222#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100223 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100224 unsigned char h[16];
225
226 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
227 PUT_UINT32_BE( ctx->HH[8], h, 4 );
228 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
229 PUT_UINT32_BE( ctx->HL[8], h, 12 );
230
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200231 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100232 return;
233 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100235
Paul Bakker89e80c92012-03-20 13:50:09 +0000236 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000237
238 zh = ctx->HH[lo];
239 zl = ctx->HL[lo];
240
241 for( i = 15; i >= 0; i-- )
242 {
243 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200244 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000245
246 if( i != 15 )
247 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000248 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000249 zl = ( zh << 60 ) | ( zl >> 4 );
250 zh = ( zh >> 4 );
251 zh ^= (uint64_t) last4[rem] << 48;
252 zh ^= ctx->HH[lo];
253 zl ^= ctx->HL[lo];
254
255 }
256
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000257 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000258 zl = ( zh << 60 ) | ( zl >> 4 );
259 zh = ( zh >> 4 );
260 zh ^= (uint64_t) last4[rem] << 48;
261 zh ^= ctx->HH[hi];
262 zl ^= ctx->HL[hi];
263 }
264
Paul Bakker5c2364c2012-10-01 14:41:15 +0000265 PUT_UINT32_BE( zh >> 32, output, 0 );
266 PUT_UINT32_BE( zh, output, 4 );
267 PUT_UINT32_BE( zl >> 32, output, 8 );
268 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000269}
270
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200271int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Gilles Peskine295fc132021-04-15 18:32:23 +0200272 int mode,
273 const unsigned char *iv, size_t iv_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000274{
Janos Follath24eed8d2019-11-22 13:21:35 +0000275 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000276 unsigned char work_buf[16];
277 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000278 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200279 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000280
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100281 GCM_VALIDATE_RET( ctx != NULL );
282 GCM_VALIDATE_RET( iv != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100283
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200284 /* IV is limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200285 /* IV is not allowed to be zero length */
Gilles Peskine295fc132021-04-15 18:32:23 +0200286 if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200287 return MBEDTLS_ERR_GCM_BAD_INPUT ;
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200288
Paul Bakker52cf16c2013-07-26 13:55:38 +0200289 memset( ctx->y, 0x00, sizeof(ctx->y) );
290 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
291
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200292 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200293 ctx->len = 0;
294 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000295
296 if( iv_len == 12 )
297 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200298 memcpy( ctx->y, iv, iv_len );
299 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000300 }
301 else
302 {
303 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000304 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000305
306 p = iv;
307 while( iv_len > 0 )
308 {
309 use_len = ( iv_len < 16 ) ? iv_len : 16;
310
Paul Bakker67f9d532012-10-23 11:49:05 +0000311 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200312 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200313
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200314 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000315
316 iv_len -= use_len;
317 p += use_len;
318 }
319
Paul Bakker67f9d532012-10-23 11:49:05 +0000320 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200321 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000322
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200323 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000324 }
325
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500326 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
327 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200328 {
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200329 return ret ;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200330 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000331
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200332 return 0 ;
Gilles Peskine295fc132021-04-15 18:32:23 +0200333}
334
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200335/**
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200336 * mbedtls_gcm_context::buf contains the partial state of the computation of
337 * the authentication tag.
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200338 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
339 * different stages of the computation:
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200340 * * len == 0 && add_len == 0: initial state
341 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
342 * a partial block of AD that has been
343 * xored in but not yet multiplied in.
344 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
345 * the data ends now.
346 * * len % 16 != 0: the first `len % 16` bytes have
347 * a partial block of ciphertext that has
348 * been xored in but not yet multiplied in.
349 * * len > 0 && len % 16 == 0: the authentication tag is correct if
350 * the data ends now.
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200351 */
Gilles Peskine295fc132021-04-15 18:32:23 +0200352int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
353 const unsigned char *add, size_t add_len )
354{
355 const unsigned char *p;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200356 size_t use_len, i, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200357
358 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
359
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200360 /* IV is limited to 2^64 bits, so 2^61 bytes */
Gilles Peskine295fc132021-04-15 18:32:23 +0200361 if( (uint64_t) add_len >> 61 != 0 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200362 return MBEDTLS_ERR_GCM_BAD_INPUT ;
Gilles Peskine295fc132021-04-15 18:32:23 +0200363
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200364 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000365 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200366
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200367 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000368 {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200369 use_len = 16 - offset;
370 if( use_len > add_len )
371 use_len = add_len;
372
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200373 for( i = 0; i < use_len; i++ )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200374 ctx->buf[i+offset] ^= p[i];
375
376 if( offset + use_len == 16 )
377 gcm_mult( ctx, ctx->buf, ctx->buf );
378
379 ctx->add_len += use_len;
380 add_len -= use_len;
381 p += use_len;
382 }
383
384 ctx->add_len += add_len;
385
386 while( add_len >= 16 )
387 {
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200388 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200389 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200390
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200391 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000392
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200393 add_len -= 16;
394 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000395 }
396
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200397 if( add_len > 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200398 {
399 for( i = 0; i < add_len; i++ )
400 ctx->buf[i] ^= p[i];
401 }
402
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200403 return 0 ;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200404}
405
Gilles Peskine58fc2722021-04-13 15:58:27 +0200406/* Increment the counter. */
407static void gcm_incr( unsigned char y[16] )
408{
409 size_t i;
410 for( i = 16; i > 12; i-- )
411 if( ++y[i - 1] != 0 )
412 break;
413}
414
415/* Calculate and apply the encryption mask. Process use_len bytes of data,
416 * starting at position offset in the mask block. */
417static int gcm_mask( mbedtls_gcm_context *ctx,
418 unsigned char ectr[16],
419 size_t offset, size_t use_len,
420 const unsigned char *input,
421 unsigned char *output )
422{
423 size_t i;
424 size_t olen = 0;
425 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
426
427 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
428 &olen ) ) != 0 )
429 {
430 mbedtls_platform_zeroize( ectr, 16 );
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200431 return ret ;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200432 }
433
434 for( i = 0; i < use_len; i++ )
435 {
436 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
437 ctx->buf[offset + i] ^= input[i];
438 output[i] = ectr[offset + i] ^ input[i];
439 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
440 ctx->buf[offset + i] ^= output[i];
441 }
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200442 return 0 ;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200443}
444
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200445int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200446 const unsigned char *input, size_t input_length,
447 unsigned char *output, size_t output_size,
448 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200449{
Janos Follath24eed8d2019-11-22 13:21:35 +0000450 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200451 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200452 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200453 size_t offset;
454 unsigned char ectr[16];
455
Gilles Peskinea56c4482021-04-15 17:22:35 +0200456 if( output_size < input_length )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200457 return MBEDTLS_ERR_GCM_BAD_INPUT ;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200458 GCM_VALIDATE_RET( output_length != NULL );
459 *output_length = input_length;
460
461 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200462 * on a potentially null pointer.
463 * Returning early also means that the last partial block of AD remains
464 * untouched for mbedtls_gcm_finish */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200465 if( input_length == 0 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200466 return 0 ;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200467
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100468 GCM_VALIDATE_RET( ctx != NULL );
Gilles Peskine58fc2722021-04-13 15:58:27 +0200469 GCM_VALIDATE_RET( input != NULL );
470 GCM_VALIDATE_RET( output != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100471
Gilles Peskinea56c4482021-04-15 17:22:35 +0200472 if( output > input && (size_t) ( output - input ) < input_length )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200473 return MBEDTLS_ERR_GCM_BAD_INPUT ;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200474
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200475 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
476 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200477 if( ctx->len + input_length < ctx->len ||
478 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200479 {
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200480 return MBEDTLS_ERR_GCM_BAD_INPUT ;
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200481 }
482
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200483 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200484 {
485 gcm_mult( ctx, ctx->buf, ctx->buf );
486 }
487
Gilles Peskine58fc2722021-04-13 15:58:27 +0200488 offset = ctx->len % 16;
489 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000490 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200491 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200492 if( use_len > input_length )
493 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000494
Gilles Peskine58fc2722021-04-13 15:58:27 +0200495 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200496 return ret ;
Paul Bakker89e80c92012-03-20 13:50:09 +0000497
Gilles Peskine58fc2722021-04-13 15:58:27 +0200498 if( offset + use_len == 16 )
499 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200500
Gilles Peskine58fc2722021-04-13 15:58:27 +0200501 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200502 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000503 p += use_len;
504 out_p += use_len;
505 }
506
Gilles Peskinea56c4482021-04-15 17:22:35 +0200507 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200508
Gilles Peskinea56c4482021-04-15 17:22:35 +0200509 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200510 {
511 gcm_incr( ctx->y );
512 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200513 return ret ;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200514
515 gcm_mult( ctx, ctx->buf, ctx->buf );
516
Gilles Peskinea56c4482021-04-15 17:22:35 +0200517 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200518 p += 16;
519 out_p += 16;
520 }
521
Gilles Peskinea56c4482021-04-15 17:22:35 +0200522 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200523 {
524 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200525 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200526 return ret ;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200527 }
528
529 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200530 return 0 ;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200531}
532
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200533int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200534 unsigned char *output, size_t output_size,
Gilles Peskine5a7be102021-06-23 21:51:32 +0200535 size_t *output_length,
Gilles Peskine9461e452021-04-15 16:48:32 +0200536 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200537{
538 unsigned char work_buf[16];
539 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100540 uint64_t orig_len;
541 uint64_t orig_add_len;
542
543 GCM_VALIDATE_RET( ctx != NULL );
544 GCM_VALIDATE_RET( tag != NULL );
545
Gilles Peskine9461e452021-04-15 16:48:32 +0200546 /* We never pass any output in finish(). The output parameter exists only
547 * for the sake of alternative implementations. */
548 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200549 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200550 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200551
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100552 orig_len = ctx->len * 8;
553 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200554
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200555 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200556 {
557 gcm_mult( ctx, ctx->buf, ctx->buf );
558 }
559
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200560 if( tag_len > 16 || tag_len < 4 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200561 return MBEDTLS_ERR_GCM_BAD_INPUT ;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200562
Gilles Peskine58fc2722021-04-13 15:58:27 +0200563 if( ctx->len % 16 != 0 )
564 gcm_mult( ctx, ctx->buf, ctx->buf );
565
Andres AG821da842016-09-26 10:09:30 +0100566 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200567
Paul Bakker89e80c92012-03-20 13:50:09 +0000568 if( orig_len || orig_add_len )
569 {
570 memset( work_buf, 0x00, 16 );
571
Paul Bakker0ecdb232013-04-09 11:36:42 +0200572 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
573 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
574 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
575 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000576
Paul Bakker67f9d532012-10-23 11:49:05 +0000577 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200578 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000579
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200580 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000581
Paul Bakker67f9d532012-10-23 11:49:05 +0000582 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200583 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000584 }
585
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200586 return 0 ;
Paul Bakker89e80c92012-03-20 13:50:09 +0000587}
588
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200590 int mode,
591 size_t length,
592 const unsigned char *iv,
593 size_t iv_len,
594 const unsigned char *add,
595 size_t add_len,
596 const unsigned char *input,
597 unsigned char *output,
598 size_t tag_len,
599 unsigned char *tag )
600{
Janos Follath24eed8d2019-11-22 13:21:35 +0000601 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200602 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200603
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100604 GCM_VALIDATE_RET( ctx != NULL );
605 GCM_VALIDATE_RET( iv != NULL );
606 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
607 GCM_VALIDATE_RET( length == 0 || input != NULL );
608 GCM_VALIDATE_RET( length == 0 || output != NULL );
609 GCM_VALIDATE_RET( tag != NULL );
610
Gilles Peskine295fc132021-04-15 18:32:23 +0200611 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200612 return ret ;
Gilles Peskine295fc132021-04-15 18:32:23 +0200613
614 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200615 return ret ;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200616
Gilles Peskinea56c4482021-04-15 17:22:35 +0200617 if( ( ret = mbedtls_gcm_update( ctx, input, length,
618 output, length, &olen ) ) != 0 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200619 return ret ;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200620
Gilles Peskine5a7be102021-06-23 21:51:32 +0200621 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200622 return ret ;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200623
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200624 return 0 ;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200625}
626
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000628 size_t length,
629 const unsigned char *iv,
630 size_t iv_len,
631 const unsigned char *add,
632 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200633 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000634 size_t tag_len,
635 const unsigned char *input,
636 unsigned char *output )
637{
Janos Follath24eed8d2019-11-22 13:21:35 +0000638 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000639 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200640 size_t i;
641 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000642
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100643 GCM_VALIDATE_RET( ctx != NULL );
644 GCM_VALIDATE_RET( iv != NULL );
645 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
646 GCM_VALIDATE_RET( tag != NULL );
647 GCM_VALIDATE_RET( length == 0 || input != NULL );
648 GCM_VALIDATE_RET( length == 0 || output != NULL );
649
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100651 iv, iv_len, add, add_len,
652 input, output, tag_len, check_tag ) ) != 0 )
653 {
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200654 return ret ;
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100655 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000656
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200657 /* Check tag in "constant-time" */
658 for( diff = 0, i = 0; i < tag_len; i++ )
659 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000660
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200661 if( diff != 0 )
662 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500663 mbedtls_platform_zeroize( output, length );
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200664 return MBEDTLS_ERR_GCM_AUTH_FAILED ;
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200665 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000666
Mateusz Starzyke36f5b12021-07-22 16:43:35 +0200667 return 0 ;
Paul Bakker89e80c92012-03-20 13:50:09 +0000668}
669
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200670void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200671{
k-stachowiak21298a22018-12-13 17:11:58 +0100672 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100673 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200674 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500675 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200676}
677
Jaeden Amero15263302017-09-21 12:53:48 +0100678#endif /* !MBEDTLS_GCM_ALT */
679
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200680#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000681/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200682 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000683 *
684 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
685 */
686#define MAX_TESTS 6
687
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100688static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000689 { 0, 0, 1, 1, 1, 1 };
690
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100691static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000692{
693 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
695 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
697 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
698 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
699 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000701};
702
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100703static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000704 { 12, 12, 12, 12, 8, 60 };
705
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100706static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000707 { 0, 0, 1, 1, 1, 2 };
708
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100709static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000710{
711 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712 0x00, 0x00, 0x00, 0x00 },
713 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
714 0xde, 0xca, 0xf8, 0x88 },
715 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200716 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000717 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200718 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000719 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200720 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000721 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200722 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000723};
724
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100725static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000726 { 0, 0, 0, 20, 20, 20 };
727
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100728static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000729 { 0, 0, 0, 1, 1, 1 };
730
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100731static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000732{
733 { 0x00 },
734 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200735 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000736 0xab, 0xad, 0xda, 0xd2 },
737};
738
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100739static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000740 { 0, 16, 64, 60, 60, 60 };
741
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100742static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000743 { 0, 0, 1, 1, 1, 1 };
744
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100745static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000746{
747 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
748 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
749 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
750 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
751 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
752 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
753 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
754 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
755 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
756 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
757};
758
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100759static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000760{
761 { 0x00 },
762 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
763 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
764 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200765 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000766 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200767 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000768 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200769 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000770 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
771 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
772 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200773 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000774 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200775 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200777 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000778 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
779 0x3d, 0x58, 0xe0, 0x91 },
780 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200781 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000782 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200783 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000784 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200785 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000786 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
787 0xc2, 0x3f, 0x45, 0x98 },
788 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200789 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000790 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200791 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000792 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200793 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000794 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
795 0x4c, 0x34, 0xae, 0xe5 },
796 { 0x00 },
797 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200798 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000799 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200800 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000801 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200802 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000803 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200804 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000805 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
806 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
807 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200808 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000809 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200810 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
811 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
812 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000813 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200814 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000815 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200816 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000817 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200818 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000819 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200820 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000821 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200822 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000823 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200824 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000825 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200826 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000827 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200828 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000829 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200830 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000831 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200832 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
833 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
834 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
835 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
836 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
837 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
838 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
839 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
840 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
841 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
842 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
843 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
844 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
845 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
846 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
847 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
848 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
849 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000850 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200851 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000852 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200853 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000854 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200855 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000856 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200857 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000858 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200859 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000860 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200861 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000862 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200863 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000864 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200865 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000866};
867
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100868static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000869{
870 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
871 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
872 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
873 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
874 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200875 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000876 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
877 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
878 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
879 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
880 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
881 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
882 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
883 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
884 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200885 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000886 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
887 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
888 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200889 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000890 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200891 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000892 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200893 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000894 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200895 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000896 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200897 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000898 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200899 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000900 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200901 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000902 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200903 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000904 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200905 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000906};
907
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000909{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200910 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000911 unsigned char buf[64];
912 unsigned char tag_buf[16];
913 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200915 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000916
917 for( j = 0; j < 3; j++ )
918 {
919 int key_len = 128 + 64 * j;
920
921 for( i = 0; i < MAX_TESTS; i++ )
922 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100923 mbedtls_gcm_init( &ctx );
924
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200925 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200926 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100927 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200928
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500929 ret = mbedtls_gcm_setkey( &ctx, cipher,
930 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100931 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100932 /*
933 * AES-192 is an optional feature that may be unavailable when
934 * there is an alternative underlying implementation i.e. when
935 * MBEDTLS_AES_ALT is defined.
936 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300937 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100938 {
939 mbedtls_printf( "skipped\n" );
940 break;
941 }
942 else if( ret != 0 )
943 {
944 goto exit;
945 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000946
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500948 pt_len_test_data[i],
949 iv_test_data[iv_index_test_data[i]],
950 iv_len_test_data[i],
951 additional_test_data[add_index_test_data[i]],
952 add_len_test_data[i],
953 pt_test_data[pt_index_test_data[i]],
954 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100955#if defined(MBEDTLS_GCM_ALT)
956 /* Allow alternative implementations to only support 12-byte nonces. */
957 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
958 iv_len_test_data[i] != 12 )
959 {
960 mbedtls_printf( "skipped\n" );
961 break;
962 }
963#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100964 if( ret != 0 )
965 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000966
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500967 if ( memcmp( buf, ct_test_data[j * 6 + i],
968 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100969 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000970 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100971 ret = 1;
972 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000973 }
974
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200975 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200976
Paul Bakker89e80c92012-03-20 13:50:09 +0000977 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200978 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000979
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100980 mbedtls_gcm_init( &ctx );
981
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200982 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100984 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200985
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500986 ret = mbedtls_gcm_setkey( &ctx, cipher,
987 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100988 key_len );
989 if( ret != 0 )
990 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000991
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200992 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500993 pt_len_test_data[i],
994 iv_test_data[iv_index_test_data[i]],
995 iv_len_test_data[i],
996 additional_test_data[add_index_test_data[i]],
997 add_len_test_data[i],
998 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000999
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001000 if( ret != 0 )
1001 goto exit;
1002
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001003 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1004 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001005 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +00001006 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001007 ret = 1;
1008 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +00001009 }
1010
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001011 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001012
Paul Bakker89e80c92012-03-20 13:50:09 +00001013 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001014 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001015
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001016 mbedtls_gcm_init( &ctx );
1017
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001018 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001020 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001021
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001022 ret = mbedtls_gcm_setkey( &ctx, cipher,
1023 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001024 key_len );
1025 if( ret != 0 )
1026 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001029 iv_test_data[iv_index_test_data[i]],
1030 iv_len_test_data[i] );
1031 if( ret != 0 )
1032 goto exit;
1033
1034 ret = mbedtls_gcm_update_ad( &ctx,
1035 additional_test_data[add_index_test_data[i]],
1036 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001037 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001038 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001039
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001040 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001041 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001042 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001043 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001044 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001045 32,
1046 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001047 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001048 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001049 if( olen != 32 )
1050 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001051
Gilles Peskinea56c4482021-04-15 17:22:35 +02001052 ret = mbedtls_gcm_update( &ctx,
1053 pt_test_data[pt_index_test_data[i]] + 32,
1054 rest_len,
1055 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001056 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001057 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001058 if( olen != rest_len )
1059 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001060 }
1061 else
1062 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001063 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001064 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001065 pt_len_test_data[i],
1066 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001067 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001068 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001069 if( olen != pt_len_test_data[i] )
1070 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001071 }
1072
Gilles Peskine5a7be102021-06-23 21:51:32 +02001073 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001074 if( ret != 0 )
1075 goto exit;
1076
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001077 if( memcmp( buf, ct_test_data[j * 6 + i],
1078 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001079 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001080 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001081 ret = 1;
1082 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001083 }
1084
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001086
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001087 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001088 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001089
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001090 mbedtls_gcm_init( &ctx );
1091
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001092 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001094 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001095
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001096 ret = mbedtls_gcm_setkey( &ctx, cipher,
1097 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001098 key_len );
1099 if( ret != 0 )
1100 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001101
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001102 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001103 iv_test_data[iv_index_test_data[i]],
1104 iv_len_test_data[i] );
1105 if( ret != 0 )
1106 goto exit;
1107 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001108 additional_test_data[add_index_test_data[i]],
1109 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001110 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001111 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001112
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001113 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001114 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001115 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001116 ret = mbedtls_gcm_update( &ctx,
1117 ct_test_data[j * 6 + i], 32,
1118 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001119 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001120 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001121 if( olen != 32 )
1122 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001123
Gilles Peskinea56c4482021-04-15 17:22:35 +02001124 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001125 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001126 rest_len,
1127 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001128 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001129 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001130 if( olen != rest_len )
1131 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001132 }
1133 else
1134 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001135 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001136 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001137 pt_len_test_data[i],
1138 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001139 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001140 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001141 if( olen != pt_len_test_data[i] )
1142 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001143 }
1144
Gilles Peskine5a7be102021-06-23 21:51:32 +02001145 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001146 if( ret != 0 )
1147 goto exit;
1148
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001149 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1150 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001151 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001152 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001153 ret = 1;
1154 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001155 }
1156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001157 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001158
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001159 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001160 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001161 }
1162 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001163
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001164 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001165 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001166
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001167 ret = 0;
1168
1169exit:
1170 if( ret != 0 )
1171 {
1172 if( verbose != 0 )
1173 mbedtls_printf( "failed\n" );
1174 mbedtls_gcm_free( &ctx );
1175 }
1176
Mateusz Starzyke36f5b12021-07-22 16:43:35 +02001177 return ret ;
Paul Bakker89e80c92012-03-20 13:50:09 +00001178}
1179
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001180#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001181
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001182#endif /* MBEDTLS_GCM_C */