blob: f004a73c75bfb19ebab57e1d7e53249c34726dd8 [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];
238 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000239 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200240 size_t use_len, olen = 0;
openluopworldeab65ac2021-09-22 23:59:42 +0800241 uint64_t iv_bits;
Paul Bakker89e80c92012-03-20 13:50:09 +0000242
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200243 /* IV is limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200244 /* IV is not allowed to be zero length */
Gilles Peskine295fc132021-04-15 18:32:23 +0200245 if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200247
Paul Bakker52cf16c2013-07-26 13:55:38 +0200248 memset( ctx->y, 0x00, sizeof(ctx->y) );
249 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
250
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200251 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200252 ctx->len = 0;
253 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000254
255 if( iv_len == 12 )
256 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200257 memcpy( ctx->y, iv, iv_len );
258 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000259 }
260 else
261 {
262 memset( work_buf, 0x00, 16 );
openluopworldeab65ac2021-09-22 23:59:42 +0800263 iv_bits = (uint64_t)iv_len * 8;
264 MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000265
266 p = iv;
267 while( iv_len > 0 )
268 {
269 use_len = ( iv_len < 16 ) ? iv_len : 16;
270
Paul Bakker67f9d532012-10-23 11:49:05 +0000271 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200272 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200273
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200274 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000275
276 iv_len -= use_len;
277 p += use_len;
278 }
279
Paul Bakker67f9d532012-10-23 11:49:05 +0000280 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200281 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000282
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200283 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000284 }
285
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500286 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
287 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200288 {
289 return( ret );
290 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000291
Gilles Peskine295fc132021-04-15 18:32:23 +0200292 return( 0 );
293}
294
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200295/**
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200296 * mbedtls_gcm_context::buf contains the partial state of the computation of
297 * the authentication tag.
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200298 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
299 * different stages of the computation:
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200300 * * len == 0 && add_len == 0: initial state
301 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
302 * a partial block of AD that has been
303 * xored in but not yet multiplied in.
304 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
305 * the data ends now.
306 * * len % 16 != 0: the first `len % 16` bytes have
307 * a partial block of ciphertext that has
308 * been xored in but not yet multiplied in.
309 * * len > 0 && len % 16 == 0: the authentication tag is correct if
310 * the data ends now.
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200311 */
Gilles Peskine295fc132021-04-15 18:32:23 +0200312int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
313 const unsigned char *add, size_t add_len )
314{
315 const unsigned char *p;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200316 size_t use_len, i, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200317
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200318 /* IV is limited to 2^64 bits, so 2^61 bytes */
Gilles Peskine295fc132021-04-15 18:32:23 +0200319 if( (uint64_t) add_len >> 61 != 0 )
320 return( MBEDTLS_ERR_GCM_BAD_INPUT );
321
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200322 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000323 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200324
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200325 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000326 {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200327 use_len = 16 - offset;
328 if( use_len > add_len )
329 use_len = add_len;
330
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200331 for( i = 0; i < use_len; i++ )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200332 ctx->buf[i+offset] ^= p[i];
333
334 if( offset + use_len == 16 )
335 gcm_mult( ctx, ctx->buf, ctx->buf );
336
337 ctx->add_len += use_len;
338 add_len -= use_len;
339 p += use_len;
340 }
341
342 ctx->add_len += add_len;
343
344 while( add_len >= 16 )
345 {
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200346 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200347 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200348
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200349 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000350
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200351 add_len -= 16;
352 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000353 }
354
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200355 if( add_len > 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200356 {
357 for( i = 0; i < add_len; i++ )
358 ctx->buf[i] ^= p[i];
359 }
360
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200361 return( 0 );
362}
363
Gilles Peskine58fc2722021-04-13 15:58:27 +0200364/* Increment the counter. */
365static void gcm_incr( unsigned char y[16] )
366{
367 size_t i;
368 for( i = 16; i > 12; i-- )
369 if( ++y[i - 1] != 0 )
370 break;
371}
372
373/* Calculate and apply the encryption mask. Process use_len bytes of data,
374 * starting at position offset in the mask block. */
375static int gcm_mask( mbedtls_gcm_context *ctx,
376 unsigned char ectr[16],
377 size_t offset, size_t use_len,
378 const unsigned char *input,
379 unsigned char *output )
380{
381 size_t i;
382 size_t olen = 0;
383 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
384
385 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
386 &olen ) ) != 0 )
387 {
388 mbedtls_platform_zeroize( ectr, 16 );
389 return( ret );
390 }
391
392 for( i = 0; i < use_len; i++ )
393 {
394 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
395 ctx->buf[offset + i] ^= input[i];
396 output[i] = ectr[offset + i] ^ input[i];
397 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
398 ctx->buf[offset + i] ^= output[i];
399 }
400 return( 0 );
401}
402
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200404 const unsigned char *input, size_t input_length,
405 unsigned char *output, size_t output_size,
406 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200407{
Janos Follath24eed8d2019-11-22 13:21:35 +0000408 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200409 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200410 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200411 size_t offset;
Leonid Rozenboima3008e72022-04-21 17:28:18 -0700412 unsigned char ectr[16] = {0};
Gilles Peskine58fc2722021-04-13 15:58:27 +0200413
Gilles Peskinea56c4482021-04-15 17:22:35 +0200414 if( output_size < input_length )
Mateusz Starzykc48f43b2021-10-04 13:46:38 +0200415 return( MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200416 *output_length = input_length;
417
418 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200419 * on a potentially null pointer.
420 * Returning early also means that the last partial block of AD remains
421 * untouched for mbedtls_gcm_finish */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200422 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200423 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200424
Gilles Peskinea56c4482021-04-15 17:22:35 +0200425 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200427
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200428 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
429 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200430 if( ctx->len + input_length < ctx->len ||
431 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200432 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200434 }
435
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200436 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200437 {
438 gcm_mult( ctx, ctx->buf, ctx->buf );
439 }
440
Gilles Peskine58fc2722021-04-13 15:58:27 +0200441 offset = ctx->len % 16;
442 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000443 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200444 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200445 if( use_len > input_length )
446 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000447
Gilles Peskine58fc2722021-04-13 15:58:27 +0200448 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200449 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000450
Gilles Peskine58fc2722021-04-13 15:58:27 +0200451 if( offset + use_len == 16 )
452 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200453
Gilles Peskine58fc2722021-04-13 15:58:27 +0200454 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200455 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000456 p += use_len;
457 out_p += use_len;
458 }
459
Gilles Peskinea56c4482021-04-15 17:22:35 +0200460 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200461
Gilles Peskinea56c4482021-04-15 17:22:35 +0200462 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200463 {
464 gcm_incr( ctx->y );
465 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
466 return( ret );
467
468 gcm_mult( ctx, ctx->buf, ctx->buf );
469
Gilles Peskinea56c4482021-04-15 17:22:35 +0200470 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200471 p += 16;
472 out_p += 16;
473 }
474
Gilles Peskinea56c4482021-04-15 17:22:35 +0200475 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200476 {
477 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200478 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200479 return( ret );
480 }
481
482 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200483 return( 0 );
484}
485
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200486int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200487 unsigned char *output, size_t output_size,
Gilles Peskine5a7be102021-06-23 21:51:32 +0200488 size_t *output_length,
Gilles Peskine9461e452021-04-15 16:48:32 +0200489 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200490{
491 unsigned char work_buf[16];
492 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100493 uint64_t orig_len;
494 uint64_t orig_add_len;
495
Gilles Peskine9461e452021-04-15 16:48:32 +0200496 /* We never pass any output in finish(). The output parameter exists only
497 * for the sake of alternative implementations. */
498 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200499 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200500 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200501
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100502 orig_len = ctx->len * 8;
503 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200504
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200505 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200506 {
507 gcm_mult( ctx, ctx->buf, ctx->buf );
508 }
509
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200510 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200512
Gilles Peskine58fc2722021-04-13 15:58:27 +0200513 if( ctx->len % 16 != 0 )
514 gcm_mult( ctx, ctx->buf, ctx->buf );
515
Andres AG821da842016-09-26 10:09:30 +0100516 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200517
Paul Bakker89e80c92012-03-20 13:50:09 +0000518 if( orig_len || orig_add_len )
519 {
520 memset( work_buf, 0x00, 16 );
521
Joe Subbiani5ecac212021-06-24 13:00:03 +0100522 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
523 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
524 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
525 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000526
Paul Bakker67f9d532012-10-23 11:49:05 +0000527 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200528 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000529
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200530 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000531
Paul Bakker67f9d532012-10-23 11:49:05 +0000532 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200533 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000534 }
535
536 return( 0 );
537}
538
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200539int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200540 int mode,
541 size_t length,
542 const unsigned char *iv,
543 size_t iv_len,
544 const unsigned char *add,
545 size_t add_len,
546 const unsigned char *input,
547 unsigned char *output,
548 size_t tag_len,
549 unsigned char *tag )
550{
Janos Follath24eed8d2019-11-22 13:21:35 +0000551 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200552 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200553
Gilles Peskine295fc132021-04-15 18:32:23 +0200554 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
555 return( ret );
556
557 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200558 return( ret );
559
Gilles Peskinea56c4482021-04-15 17:22:35 +0200560 if( ( ret = mbedtls_gcm_update( ctx, input, length,
561 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200562 return( ret );
563
Gilles Peskine5a7be102021-06-23 21:51:32 +0200564 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200565 return( ret );
566
567 return( 0 );
568}
569
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200570int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000571 size_t length,
572 const unsigned char *iv,
573 size_t iv_len,
574 const unsigned char *add,
575 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200576 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000577 size_t tag_len,
578 const unsigned char *input,
579 unsigned char *output )
580{
Janos Follath24eed8d2019-11-22 13:21:35 +0000581 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000582 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200583 size_t i;
584 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000585
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200586 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100587 iv, iv_len, add, add_len,
588 input, output, tag_len, check_tag ) ) != 0 )
589 {
590 return( ret );
591 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000592
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200593 /* Check tag in "constant-time" */
594 for( diff = 0, i = 0; i < tag_len; i++ )
595 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000596
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200597 if( diff != 0 )
598 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500599 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200601 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000602
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200603 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000604}
605
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200606void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200607{
k-stachowiak21298a22018-12-13 17:11:58 +0100608 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100609 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200610 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500611 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200612}
613
Jaeden Amero15263302017-09-21 12:53:48 +0100614#endif /* !MBEDTLS_GCM_ALT */
615
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000617/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200618 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000619 *
620 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
621 */
622#define MAX_TESTS 6
623
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100624static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 { 0, 0, 1, 1, 1, 1 };
626
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100627static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000628{
629 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
633 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
634 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
635 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200636 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000637};
638
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100639static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000640 { 12, 12, 12, 12, 8, 60 };
641
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100642static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000643 { 0, 0, 1, 1, 1, 2 };
644
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100645static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000646{
647 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00 },
649 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
650 0xde, 0xca, 0xf8, 0x88 },
651 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200652 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000653 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200654 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000655 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200656 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000657 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200658 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000659};
660
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100661static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000662 { 0, 0, 0, 20, 20, 20 };
663
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100664static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000665 { 0, 0, 0, 1, 1, 1 };
666
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100667static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000668{
669 { 0x00 },
670 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200671 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000672 0xab, 0xad, 0xda, 0xd2 },
673};
674
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100675static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000676 { 0, 16, 64, 60, 60, 60 };
677
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100678static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000679 { 0, 0, 1, 1, 1, 1 };
680
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100681static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000682{
683 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
685 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
686 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
687 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
688 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
689 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
690 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
691 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
692 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
693};
694
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100695static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000696{
697 { 0x00 },
698 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
699 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
700 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200701 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000702 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200703 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000704 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200705 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000706 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
707 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
708 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200709 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000710 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200711 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000712 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200713 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000714 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
715 0x3d, 0x58, 0xe0, 0x91 },
716 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200717 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000718 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200719 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000720 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200721 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000722 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
723 0xc2, 0x3f, 0x45, 0x98 },
724 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200725 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000726 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200727 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000728 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200729 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000730 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
731 0x4c, 0x34, 0xae, 0xe5 },
732 { 0x00 },
733 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200734 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000735 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200736 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000737 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200738 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000739 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200740 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000741 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
742 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
743 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200744 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000745 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200746 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
747 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
748 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200750 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000751 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200752 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000753 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200754 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000755 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200756 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000757 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200758 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000759 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200760 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200762 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000763 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200764 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000765 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200766 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000767 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200768 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
769 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
770 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
771 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
772 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
773 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
774 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
775 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
776 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
777 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
778 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
779 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
780 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
781 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
782 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
783 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
784 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
785 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000786 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200787 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000788 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200789 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000790 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200791 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000792 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200793 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000794 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200795 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000796 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200797 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000798 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200799 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000800 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200801 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000802};
803
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100804static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000805{
806 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
807 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
808 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
809 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
810 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200811 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000812 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
813 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
814 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
815 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
816 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
817 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
818 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
819 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
820 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200821 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000822 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
823 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
824 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200825 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000826 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200827 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000828 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200829 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000830 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200831 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000832 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200833 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000834 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200835 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000836 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200837 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000838 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200839 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000840 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200841 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000842};
843
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200844int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000845{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200846 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000847 unsigned char buf[64];
848 unsigned char tag_buf[16];
849 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200850 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200851 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000852
853 for( j = 0; j < 3; j++ )
854 {
855 int key_len = 128 + 64 * j;
856
857 for( i = 0; i < MAX_TESTS; i++ )
858 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100859 mbedtls_gcm_init( &ctx );
860
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200861 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100863 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200864
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500865 ret = mbedtls_gcm_setkey( &ctx, cipher,
866 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100867 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100868 /*
869 * AES-192 is an optional feature that may be unavailable when
870 * there is an alternative underlying implementation i.e. when
871 * MBEDTLS_AES_ALT is defined.
872 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300873 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100874 {
875 mbedtls_printf( "skipped\n" );
876 break;
877 }
878 else if( ret != 0 )
879 {
880 goto exit;
881 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000882
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500884 pt_len_test_data[i],
885 iv_test_data[iv_index_test_data[i]],
886 iv_len_test_data[i],
887 additional_test_data[add_index_test_data[i]],
888 add_len_test_data[i],
889 pt_test_data[pt_index_test_data[i]],
890 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100891#if defined(MBEDTLS_GCM_ALT)
892 /* Allow alternative implementations to only support 12-byte nonces. */
893 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
894 iv_len_test_data[i] != 12 )
895 {
896 mbedtls_printf( "skipped\n" );
897 break;
898 }
899#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100900 if( ret != 0 )
901 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000902
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500903 if ( memcmp( buf, ct_test_data[j * 6 + i],
904 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100905 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000906 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100907 ret = 1;
908 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000909 }
910
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200911 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200912
Paul Bakker89e80c92012-03-20 13:50:09 +0000913 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000915
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100916 mbedtls_gcm_init( &ctx );
917
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200918 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100920 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200921
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500922 ret = mbedtls_gcm_setkey( &ctx, cipher,
923 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100924 key_len );
925 if( ret != 0 )
926 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000927
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200928 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500929 pt_len_test_data[i],
930 iv_test_data[iv_index_test_data[i]],
931 iv_len_test_data[i],
932 additional_test_data[add_index_test_data[i]],
933 add_len_test_data[i],
934 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000935
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100936 if( ret != 0 )
937 goto exit;
938
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100939 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
940 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100941 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000942 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100943 ret = 1;
944 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000945 }
946
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200948
Paul Bakker89e80c92012-03-20 13:50:09 +0000949 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200951
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100952 mbedtls_gcm_init( &ctx );
953
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200954 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200955 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100956 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200957
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500958 ret = mbedtls_gcm_setkey( &ctx, cipher,
959 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100960 key_len );
961 if( ret != 0 )
962 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200963
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200964 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +0200965 iv_test_data[iv_index_test_data[i]],
966 iv_len_test_data[i] );
967 if( ret != 0 )
968 goto exit;
969
970 ret = mbedtls_gcm_update_ad( &ctx,
971 additional_test_data[add_index_test_data[i]],
972 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200973 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100974 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200975
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100976 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200977 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100978 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200979 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100980 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +0200981 32,
982 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200983 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100984 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200985 if( olen != 32 )
986 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200987
Gilles Peskinea56c4482021-04-15 17:22:35 +0200988 ret = mbedtls_gcm_update( &ctx,
989 pt_test_data[pt_index_test_data[i]] + 32,
990 rest_len,
991 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200992 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100993 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200994 if( olen != rest_len )
995 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200996 }
997 else
998 {
Gilles Peskinea56c4482021-04-15 17:22:35 +0200999 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001000 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001001 pt_len_test_data[i],
1002 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001003 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001004 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001005 if( olen != pt_len_test_data[i] )
1006 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001007 }
1008
Gilles Peskine5a7be102021-06-23 21:51:32 +02001009 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001010 if( ret != 0 )
1011 goto exit;
1012
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001013 if( memcmp( buf, ct_test_data[j * 6 + i],
1014 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001015 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001016 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001017 ret = 1;
1018 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001019 }
1020
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001022
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001023 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001025
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001026 mbedtls_gcm_init( &ctx );
1027
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001028 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001029 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001030 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001031
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001032 ret = mbedtls_gcm_setkey( &ctx, cipher,
1033 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001034 key_len );
1035 if( ret != 0 )
1036 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001039 iv_test_data[iv_index_test_data[i]],
1040 iv_len_test_data[i] );
1041 if( ret != 0 )
1042 goto exit;
1043 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001044 additional_test_data[add_index_test_data[i]],
1045 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001046 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001047 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001048
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001049 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001050 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001051 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001052 ret = mbedtls_gcm_update( &ctx,
1053 ct_test_data[j * 6 + i], 32,
1054 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001055 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001056 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001057 if( olen != 32 )
1058 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001059
Gilles Peskinea56c4482021-04-15 17:22:35 +02001060 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001061 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001062 rest_len,
1063 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001064 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001065 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001066 if( olen != rest_len )
1067 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001068 }
1069 else
1070 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001071 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001072 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001073 pt_len_test_data[i],
1074 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001075 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001076 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001077 if( olen != pt_len_test_data[i] )
1078 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001079 }
1080
Gilles Peskine5a7be102021-06-23 21:51:32 +02001081 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001082 if( ret != 0 )
1083 goto exit;
1084
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001085 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1086 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001087 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001088 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001089 ret = 1;
1090 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001091 }
1092
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001094
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001095 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001096 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001097 }
1098 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001099
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001100 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001101 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001102
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001103 ret = 0;
1104
1105exit:
1106 if( ret != 0 )
1107 {
1108 if( verbose != 0 )
1109 mbedtls_printf( "failed\n" );
1110 mbedtls_gcm_free( &ctx );
1111 }
1112
1113 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001114}
1115
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001116#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001117
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001118#endif /* MBEDTLS_GCM_C */