blob: 0178b5ba75585489960515432cf4c3bc88ec2c5b [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"
Gilles Peskineed1c7f42022-09-15 20:14:22 +020035#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050036#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000037#include "mbedtls/error.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000042#include "aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010043#endif
44
Jaeden Amero15263302017-09-21 12:53:48 +010045#if !defined(MBEDTLS_GCM_ALT)
46
Paul Bakker89e80c92012-03-20 13:50:09 +000047/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020048 * Initialize a context
49 */
50void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
51{
52 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
53}
54
55/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010056 * Precompute small multiples of H, that is set
57 * HH[i] || HL[i] = H times i,
58 * where i is seen as a field element as in [MGV], ie high-order bits
59 * correspond to low powers of P. The result is stored in the same way, that
60 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
61 * corresponds to P^127.
62 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020063static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000064{
Paul Bakker43aff2a2013-09-09 00:10:27 +020065 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000066 uint64_t hi, lo;
67 uint64_t vl, vh;
68 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020069 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020070
Paul Bakker89e80c92012-03-20 13:50:09 +000071 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +020073 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000074
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010075 /* pack h as two 64-bits ints, big-endian */
Joe Subbiani6a506312021-07-07 16:56:29 +010076 hi = MBEDTLS_GET_UINT32_BE( h, 0 );
77 lo = MBEDTLS_GET_UINT32_BE( h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000078 vh = (uint64_t) hi << 32 | lo;
79
Joe Subbiani6a506312021-07-07 16:56:29 +010080 hi = MBEDTLS_GET_UINT32_BE( h, 8 );
81 lo = MBEDTLS_GET_UINT32_BE( h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000082 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020083
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010084 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +000085 ctx->HL[8] = vl;
86 ctx->HH[8] = vh;
87
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020088#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010089 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +010090 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010091 return( 0 );
92#endif
93
94 /* 0 corresponds to 0 in GF(2^128) */
95 ctx->HH[0] = 0;
96 ctx->HL[0] = 0;
97
Paul Bakker89e80c92012-03-20 13:50:09 +000098 for( i = 4; i > 0; i >>= 1 )
99 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200100 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000101 vl = ( vh << 63 ) | ( vl >> 1 );
102 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
103
104 ctx->HL[i] = vl;
105 ctx->HH[i] = vh;
106 }
107
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000108 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000109 {
110 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
111 vh = *HiH;
112 vl = *HiL;
113 for( j = 1; j < i; j++ )
114 {
115 HiH[j] = vh ^ ctx->HH[j];
116 HiL[j] = vl ^ ctx->HL[j];
117 }
118 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200119
120 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000121}
122
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200123int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
124 mbedtls_cipher_id_t cipher,
125 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200126 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000127{
Janos Follath24eed8d2019-11-22 13:21:35 +0000128 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200129 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000130
Tuvshinzaya Erdenekhuuc6b8a672022-08-05 15:31:57 +0100131 if( keybits != 128 && keybits != 192 && keybits != 256 )
132 return MBEDTLS_ERR_GCM_BAD_INPUT;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100133
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500134 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
135 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200136 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200137 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200138
Paul Bakkera0558e02013-09-10 14:25:51 +0200139 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200141
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200142 mbedtls_cipher_free( &ctx->cipher_ctx );
143
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200144 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000145 return( ret );
146
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200147 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200148 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200149 {
150 return( ret );
151 }
152
153 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
154 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000155
156 return( 0 );
157}
158
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100159/*
160 * Shoup's method for multiplication use this table with
161 * last4[x] = x times P^128
162 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
163 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000164static const uint64_t last4[16] =
165{
166 0x0000, 0x1c20, 0x3840, 0x2460,
167 0x7080, 0x6ca0, 0x48c0, 0x54e0,
168 0xe100, 0xfd20, 0xd940, 0xc560,
169 0x9180, 0x8da0, 0xa9c0, 0xb5e0
170};
171
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100172/*
173 * Sets output to x times H using the precomputed tables.
174 * x and output are seen as elements of GF(2^128) as in [MGV].
175 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200176static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200177 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000178{
179 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000180 unsigned char lo, hi, rem;
181 uint64_t zh, zl;
182
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200183#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100184 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100185 unsigned char h[16];
186
Joe Subbiani5ecac212021-06-24 13:00:03 +0100187 MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
188 MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 );
189 MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
190 MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100191
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100193 return;
194 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100196
Paul Bakker89e80c92012-03-20 13:50:09 +0000197 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000198
199 zh = ctx->HH[lo];
200 zl = ctx->HL[lo];
201
202 for( i = 15; i >= 0; i-- )
203 {
204 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200205 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000206
207 if( i != 15 )
208 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000209 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000210 zl = ( zh << 60 ) | ( zl >> 4 );
211 zh = ( zh >> 4 );
212 zh ^= (uint64_t) last4[rem] << 48;
213 zh ^= ctx->HH[lo];
214 zl ^= ctx->HL[lo];
215
216 }
217
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000218 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000219 zl = ( zh << 60 ) | ( zl >> 4 );
220 zh = ( zh >> 4 );
221 zh ^= (uint64_t) last4[rem] << 48;
222 zh ^= ctx->HH[hi];
223 zl ^= ctx->HL[hi];
224 }
225
Joe Subbiani5ecac212021-06-24 13:00:03 +0100226 MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
227 MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
228 MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
229 MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000230}
231
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200232int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Gilles Peskine295fc132021-04-15 18:32:23 +0200233 int mode,
234 const unsigned char *iv, size_t iv_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000235{
Janos Follath24eed8d2019-11-22 13:21:35 +0000236 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000237 unsigned char work_buf[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000238 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200239 size_t use_len, olen = 0;
openluopworldeab65ac2021-09-22 23:59:42 +0800240 uint64_t iv_bits;
Paul Bakker89e80c92012-03-20 13:50:09 +0000241
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200242 /* IV is limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200243 /* IV is not allowed to be zero length */
Gilles Peskine295fc132021-04-15 18:32:23 +0200244 if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200245 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200246
Paul Bakker52cf16c2013-07-26 13:55:38 +0200247 memset( ctx->y, 0x00, sizeof(ctx->y) );
248 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
249
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200250 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200251 ctx->len = 0;
252 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000253
254 if( iv_len == 12 )
255 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200256 memcpy( ctx->y, iv, iv_len );
257 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000258 }
259 else
260 {
261 memset( work_buf, 0x00, 16 );
openluopworldeab65ac2021-09-22 23:59:42 +0800262 iv_bits = (uint64_t)iv_len * 8;
263 MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000264
265 p = iv;
266 while( iv_len > 0 )
267 {
268 use_len = ( iv_len < 16 ) ? iv_len : 16;
269
Dave Rodgmand22fb732022-11-22 16:53:25 +0000270 mbedtls_xor( ctx->y, ctx->y, p, use_len );
Paul Bakker169b7f42013-06-25 14:58:00 +0200271
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200272 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000273
274 iv_len -= use_len;
275 p += use_len;
276 }
277
Dave Rodgmand22fb732022-11-22 16:53:25 +0000278 mbedtls_xor( ctx->y, ctx->y, work_buf, 16);
Paul Bakker89e80c92012-03-20 13:50:09 +0000279
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200280 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000281 }
282
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500283 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
284 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200285 {
286 return( ret );
287 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000288
Gilles Peskine295fc132021-04-15 18:32:23 +0200289 return( 0 );
290}
291
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200292/**
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200293 * mbedtls_gcm_context::buf contains the partial state of the computation of
294 * the authentication tag.
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200295 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
296 * different stages of the computation:
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200297 * * len == 0 && add_len == 0: initial state
298 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
299 * a partial block of AD that has been
300 * xored in but not yet multiplied in.
301 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
302 * the data ends now.
303 * * len % 16 != 0: the first `len % 16` bytes have
304 * a partial block of ciphertext that has
305 * been xored in but not yet multiplied in.
306 * * len > 0 && len % 16 == 0: the authentication tag is correct if
307 * the data ends now.
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200308 */
Gilles Peskine295fc132021-04-15 18:32:23 +0200309int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
310 const unsigned char *add, size_t add_len )
311{
312 const unsigned char *p;
Dave Rodgmand22fb732022-11-22 16:53:25 +0000313 size_t use_len, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200314
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200315 /* IV is limited to 2^64 bits, so 2^61 bytes */
Gilles Peskine295fc132021-04-15 18:32:23 +0200316 if( (uint64_t) add_len >> 61 != 0 )
317 return( MBEDTLS_ERR_GCM_BAD_INPUT );
318
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200319 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000320 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200321
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200322 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000323 {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200324 use_len = 16 - offset;
325 if( use_len > add_len )
326 use_len = add_len;
327
Dave Rodgmand22fb732022-11-22 16:53:25 +0000328 mbedtls_xor( ctx->buf + offset, ctx->buf + offset, p, use_len );
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200329
330 if( offset + use_len == 16 )
331 gcm_mult( ctx, ctx->buf, ctx->buf );
332
333 ctx->add_len += use_len;
334 add_len -= use_len;
335 p += use_len;
336 }
337
338 ctx->add_len += add_len;
339
340 while( add_len >= 16 )
341 {
Dave Rodgmand22fb732022-11-22 16:53:25 +0000342 mbedtls_xor( ctx->buf, ctx->buf, p, 16 );
Paul Bakker169b7f42013-06-25 14:58:00 +0200343
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200344 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000345
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200346 add_len -= 16;
347 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000348 }
349
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200350 if( add_len > 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200351 {
Dave Rodgmand22fb732022-11-22 16:53:25 +0000352 mbedtls_xor( ctx->buf, ctx->buf, p, add_len );
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200353 }
354
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200355 return( 0 );
356}
357
Gilles Peskine58fc2722021-04-13 15:58:27 +0200358/* Increment the counter. */
359static void gcm_incr( unsigned char y[16] )
360{
361 size_t i;
362 for( i = 16; i > 12; i-- )
363 if( ++y[i - 1] != 0 )
364 break;
365}
366
367/* Calculate and apply the encryption mask. Process use_len bytes of data,
368 * starting at position offset in the mask block. */
369static int gcm_mask( mbedtls_gcm_context *ctx,
370 unsigned char ectr[16],
371 size_t offset, size_t use_len,
372 const unsigned char *input,
373 unsigned char *output )
374{
Gilles Peskine58fc2722021-04-13 15:58:27 +0200375 size_t olen = 0;
376 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
377
378 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
379 &olen ) ) != 0 )
380 {
381 mbedtls_platform_zeroize( ectr, 16 );
382 return( ret );
383 }
384
Dave Rodgmand22fb732022-11-22 16:53:25 +0000385 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
386 mbedtls_xor( ctx->buf + offset, ctx->buf + offset, input, use_len );
387 mbedtls_xor( output, ectr + offset, input, use_len );
388 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
389 mbedtls_xor( ctx->buf + offset, ctx->buf + offset, output, use_len );
390
Gilles Peskine58fc2722021-04-13 15:58:27 +0200391 return( 0 );
392}
393
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200394int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200395 const unsigned char *input, size_t input_length,
396 unsigned char *output, size_t output_size,
397 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200398{
Janos Follath24eed8d2019-11-22 13:21:35 +0000399 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200400 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200401 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200402 size_t offset;
Leonid Rozenboima3008e72022-04-21 17:28:18 -0700403 unsigned char ectr[16] = {0};
Gilles Peskine58fc2722021-04-13 15:58:27 +0200404
Gilles Peskinea56c4482021-04-15 17:22:35 +0200405 if( output_size < input_length )
Mateusz Starzykc48f43b2021-10-04 13:46:38 +0200406 return( MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200407 *output_length = input_length;
408
409 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200410 * on a potentially null pointer.
411 * Returning early also means that the last partial block of AD remains
412 * untouched for mbedtls_gcm_finish */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200413 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200414 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200415
Gilles Peskinea56c4482021-04-15 17:22:35 +0200416 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200418
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200419 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
420 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200421 if( ctx->len + input_length < ctx->len ||
422 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200423 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200425 }
426
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200427 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200428 {
429 gcm_mult( ctx, ctx->buf, ctx->buf );
430 }
431
Gilles Peskine58fc2722021-04-13 15:58:27 +0200432 offset = ctx->len % 16;
433 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000434 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200435 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200436 if( use_len > input_length )
437 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000438
Gilles Peskine58fc2722021-04-13 15:58:27 +0200439 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200440 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000441
Gilles Peskine58fc2722021-04-13 15:58:27 +0200442 if( offset + use_len == 16 )
443 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200444
Gilles Peskine58fc2722021-04-13 15:58:27 +0200445 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200446 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000447 p += use_len;
448 out_p += use_len;
449 }
450
Gilles Peskinea56c4482021-04-15 17:22:35 +0200451 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200452
Gilles Peskinea56c4482021-04-15 17:22:35 +0200453 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200454 {
455 gcm_incr( ctx->y );
456 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
457 return( ret );
458
459 gcm_mult( ctx, ctx->buf, ctx->buf );
460
Gilles Peskinea56c4482021-04-15 17:22:35 +0200461 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200462 p += 16;
463 out_p += 16;
464 }
465
Gilles Peskinea56c4482021-04-15 17:22:35 +0200466 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200467 {
468 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200469 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200470 return( ret );
471 }
472
473 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200474 return( 0 );
475}
476
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200478 unsigned char *output, size_t output_size,
Gilles Peskine5a7be102021-06-23 21:51:32 +0200479 size_t *output_length,
Gilles Peskine9461e452021-04-15 16:48:32 +0200480 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200481{
482 unsigned char work_buf[16];
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100483 uint64_t orig_len;
484 uint64_t orig_add_len;
485
Gilles Peskine9461e452021-04-15 16:48:32 +0200486 /* We never pass any output in finish(). The output parameter exists only
487 * for the sake of alternative implementations. */
488 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200489 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200490 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200491
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100492 orig_len = ctx->len * 8;
493 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200494
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200495 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200496 {
497 gcm_mult( ctx, ctx->buf, ctx->buf );
498 }
499
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200500 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200502
Gilles Peskine58fc2722021-04-13 15:58:27 +0200503 if( ctx->len % 16 != 0 )
504 gcm_mult( ctx, ctx->buf, ctx->buf );
505
Andres AG821da842016-09-26 10:09:30 +0100506 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200507
Paul Bakker89e80c92012-03-20 13:50:09 +0000508 if( orig_len || orig_add_len )
509 {
510 memset( work_buf, 0x00, 16 );
511
Joe Subbiani5ecac212021-06-24 13:00:03 +0100512 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
513 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
514 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
515 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000516
Dave Rodgmand22fb732022-11-22 16:53:25 +0000517 mbedtls_xor( ctx->buf, ctx->buf, work_buf, 16 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000518
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200519 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000520
Dave Rodgmand22fb732022-11-22 16:53:25 +0000521 mbedtls_xor( tag, tag, ctx->buf, tag_len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000522 }
523
524 return( 0 );
525}
526
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200527int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200528 int mode,
529 size_t length,
530 const unsigned char *iv,
531 size_t iv_len,
532 const unsigned char *add,
533 size_t add_len,
534 const unsigned char *input,
535 unsigned char *output,
536 size_t tag_len,
537 unsigned char *tag )
538{
Janos Follath24eed8d2019-11-22 13:21:35 +0000539 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200540 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200541
Gilles Peskine295fc132021-04-15 18:32:23 +0200542 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
543 return( ret );
544
545 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200546 return( ret );
547
Gilles Peskinea56c4482021-04-15 17:22:35 +0200548 if( ( ret = mbedtls_gcm_update( ctx, input, length,
549 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200550 return( ret );
551
Gilles Peskine5a7be102021-06-23 21:51:32 +0200552 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200553 return( ret );
554
555 return( 0 );
556}
557
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000559 size_t length,
560 const unsigned char *iv,
561 size_t iv_len,
562 const unsigned char *add,
563 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200564 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000565 size_t tag_len,
566 const unsigned char *input,
567 unsigned char *output )
568{
Janos Follath24eed8d2019-11-22 13:21:35 +0000569 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000570 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200571 size_t i;
572 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000573
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200574 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100575 iv, iv_len, add, add_len,
576 input, output, tag_len, check_tag ) ) != 0 )
577 {
578 return( ret );
579 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000580
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200581 /* Check tag in "constant-time" */
582 for( diff = 0, i = 0; i < tag_len; i++ )
583 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000584
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200585 if( diff != 0 )
586 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500587 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200588 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200589 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000590
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200591 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000592}
593
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200595{
k-stachowiak21298a22018-12-13 17:11:58 +0100596 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100597 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500599 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200600}
601
Jaeden Amero15263302017-09-21 12:53:48 +0100602#endif /* !MBEDTLS_GCM_ALT */
603
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000605/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200606 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000607 *
608 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
609 */
610#define MAX_TESTS 6
611
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100612static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 { 0, 0, 1, 1, 1, 1 };
614
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100615static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000616{
617 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
621 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
622 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
623 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200624 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000625};
626
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100627static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000628 { 12, 12, 12, 12, 8, 60 };
629
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100630static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000631 { 0, 0, 1, 1, 1, 2 };
632
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100633static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000634{
635 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 0x00, 0x00, 0x00, 0x00 },
637 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
638 0xde, 0xca, 0xf8, 0x88 },
639 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200640 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000641 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200642 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000643 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200644 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000645 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200646 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000647};
648
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100649static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000650 { 0, 0, 0, 20, 20, 20 };
651
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100652static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000653 { 0, 0, 0, 1, 1, 1 };
654
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100655static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000656{
657 { 0x00 },
658 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200659 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 0xab, 0xad, 0xda, 0xd2 },
661};
662
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100663static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000664 { 0, 16, 64, 60, 60, 60 };
665
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100666static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000667 { 0, 0, 1, 1, 1, 1 };
668
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100669static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000670{
671 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
673 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
674 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
675 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
676 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
677 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
678 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
679 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
680 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
681};
682
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100683static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000684{
685 { 0x00 },
686 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
687 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
688 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200689 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000690 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200691 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000692 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200693 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000694 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
695 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
696 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200697 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000698 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200699 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000700 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200701 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000702 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
703 0x3d, 0x58, 0xe0, 0x91 },
704 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200705 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000706 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200707 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000708 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200709 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000710 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
711 0xc2, 0x3f, 0x45, 0x98 },
712 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200713 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000714 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200715 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000716 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200717 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000718 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
719 0x4c, 0x34, 0xae, 0xe5 },
720 { 0x00 },
721 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200722 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000723 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200724 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000725 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200726 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000727 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200728 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000729 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
730 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
731 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200732 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000733 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200734 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
735 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
736 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000737 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200738 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000739 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200740 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000741 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200742 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000743 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200744 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000745 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200746 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000747 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200748 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200750 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000751 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200752 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000753 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200754 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000755 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200756 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
757 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
758 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
759 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
760 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
761 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
762 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
763 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
764 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
765 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
766 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
767 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
768 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
769 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
770 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
771 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
772 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
773 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000774 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200775 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200777 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000778 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200779 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000780 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200781 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000782 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200783 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000784 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200785 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000786 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200787 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000788 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200789 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000790};
791
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100792static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000793{
794 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
795 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
796 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
797 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
798 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200799 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000800 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
801 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
802 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
803 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
804 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
805 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
806 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
807 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
808 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200809 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000810 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
811 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
812 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200813 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000814 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200815 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000816 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200817 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000818 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200819 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000820 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200821 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000822 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200823 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000824 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200825 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000826 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200827 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000828 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200829 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000830};
831
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200832int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000833{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200834 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000835 unsigned char buf[64];
836 unsigned char tag_buf[16];
837 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200838 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200839 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000840
841 for( j = 0; j < 3; j++ )
842 {
843 int key_len = 128 + 64 * j;
844
845 for( i = 0; i < MAX_TESTS; i++ )
846 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100847 mbedtls_gcm_init( &ctx );
848
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200849 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200850 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100851 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200852
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500853 ret = mbedtls_gcm_setkey( &ctx, cipher,
854 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100855 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100856 /*
857 * AES-192 is an optional feature that may be unavailable when
858 * there is an alternative underlying implementation i.e. when
859 * MBEDTLS_AES_ALT is defined.
860 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300861 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100862 {
863 mbedtls_printf( "skipped\n" );
864 break;
865 }
866 else if( ret != 0 )
867 {
868 goto exit;
869 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000870
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200871 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500872 pt_len_test_data[i],
873 iv_test_data[iv_index_test_data[i]],
874 iv_len_test_data[i],
875 additional_test_data[add_index_test_data[i]],
876 add_len_test_data[i],
877 pt_test_data[pt_index_test_data[i]],
878 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100879#if defined(MBEDTLS_GCM_ALT)
880 /* Allow alternative implementations to only support 12-byte nonces. */
881 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
882 iv_len_test_data[i] != 12 )
883 {
884 mbedtls_printf( "skipped\n" );
885 break;
886 }
887#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100888 if( ret != 0 )
889 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000890
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500891 if ( memcmp( buf, ct_test_data[j * 6 + i],
892 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100893 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000894 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100895 ret = 1;
896 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000897 }
898
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200900
Paul Bakker89e80c92012-03-20 13:50:09 +0000901 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200902 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000903
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100904 mbedtls_gcm_init( &ctx );
905
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200906 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200907 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100908 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200909
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500910 ret = mbedtls_gcm_setkey( &ctx, cipher,
911 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100912 key_len );
913 if( ret != 0 )
914 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000915
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500917 pt_len_test_data[i],
918 iv_test_data[iv_index_test_data[i]],
919 iv_len_test_data[i],
920 additional_test_data[add_index_test_data[i]],
921 add_len_test_data[i],
922 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000923
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100924 if( ret != 0 )
925 goto exit;
926
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100927 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
928 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100929 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000930 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100931 ret = 1;
932 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000933 }
934
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200935 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200936
Paul Bakker89e80c92012-03-20 13:50:09 +0000937 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200938 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200939
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100940 mbedtls_gcm_init( &ctx );
941
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200942 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200943 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100944 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200945
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500946 ret = mbedtls_gcm_setkey( &ctx, cipher,
947 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100948 key_len );
949 if( ret != 0 )
950 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200951
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200952 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +0200953 iv_test_data[iv_index_test_data[i]],
954 iv_len_test_data[i] );
955 if( ret != 0 )
956 goto exit;
957
958 ret = mbedtls_gcm_update_ad( &ctx,
959 additional_test_data[add_index_test_data[i]],
960 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200961 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100962 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200963
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100964 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200965 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100966 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200967 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100968 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +0200969 32,
970 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200971 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100972 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200973 if( olen != 32 )
974 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200975
Gilles Peskinea56c4482021-04-15 17:22:35 +0200976 ret = mbedtls_gcm_update( &ctx,
977 pt_test_data[pt_index_test_data[i]] + 32,
978 rest_len,
979 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200980 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100981 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200982 if( olen != rest_len )
983 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200984 }
985 else
986 {
Gilles Peskinea56c4482021-04-15 17:22:35 +0200987 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500988 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +0200989 pt_len_test_data[i],
990 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200991 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100992 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200993 if( olen != pt_len_test_data[i] )
994 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200995 }
996
Gilles Peskine5a7be102021-06-23 21:51:32 +0200997 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100998 if( ret != 0 )
999 goto exit;
1000
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001001 if( memcmp( buf, ct_test_data[j * 6 + i],
1002 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001003 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001004 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001005 ret = 1;
1006 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001007 }
1008
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001009 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001010
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001011 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001012 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001013
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001014 mbedtls_gcm_init( &ctx );
1015
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001016 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001018 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001019
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001020 ret = mbedtls_gcm_setkey( &ctx, cipher,
1021 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001022 key_len );
1023 if( ret != 0 )
1024 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001025
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001026 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001027 iv_test_data[iv_index_test_data[i]],
1028 iv_len_test_data[i] );
1029 if( ret != 0 )
1030 goto exit;
1031 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001032 additional_test_data[add_index_test_data[i]],
1033 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001034 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001035 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001036
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001037 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001038 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001039 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001040 ret = mbedtls_gcm_update( &ctx,
1041 ct_test_data[j * 6 + i], 32,
1042 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001043 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001044 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001045 if( olen != 32 )
1046 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001047
Gilles Peskinea56c4482021-04-15 17:22:35 +02001048 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001049 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001050 rest_len,
1051 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001052 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001053 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001054 if( olen != rest_len )
1055 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001056 }
1057 else
1058 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001059 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001060 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001061 pt_len_test_data[i],
1062 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001063 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001064 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001065 if( olen != pt_len_test_data[i] )
1066 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001067 }
1068
Gilles Peskine5a7be102021-06-23 21:51:32 +02001069 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001070 if( ret != 0 )
1071 goto exit;
1072
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001073 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1074 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001075 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001076 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001077 ret = 1;
1078 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001079 }
1080
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001081 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001082
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001083 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001084 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001085 }
1086 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001087
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001088 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001089 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001090
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001091 ret = 0;
1092
1093exit:
1094 if( ret != 0 )
1095 {
1096 if( verbose != 0 )
1097 mbedtls_printf( "failed\n" );
1098 mbedtls_gcm_free( &ctx );
1099 }
1100
1101 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001102}
1103
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001104#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001105
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001106#endif /* MBEDTLS_GCM_C */