blob: ac329e3b6ce0a1607e05ba925386a6d94efc2fc2 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker89e80c92012-03-20 13:50:09 +000018 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010019
Paul Bakker89e80c92012-03-20 13:50:09 +000020/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010021 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
22 *
23 * See also:
24 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
25 *
26 * We use the algorithm described as Shoup's method with 4-bit tables in
27 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000028 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010029
Gilles Peskinedb09ef62020-06-03 01:43:33 +020030#include "common.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000033
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/gcm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050035#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000036#include "mbedtls/error.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000041#include "aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010042#endif
43
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010045#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030047#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000048#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#define mbedtls_printf printf
50#endif /* MBEDTLS_PLATFORM_C */
51#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Jaeden Amero15263302017-09-21 12:53:48 +010053#if !defined(MBEDTLS_GCM_ALT)
54
Paul Bakker89e80c92012-03-20 13:50:09 +000055/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020056 * Initialize a context
57 */
58void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
59{
60 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
61}
62
63/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010064 * Precompute small multiples of H, that is set
65 * HH[i] || HL[i] = H times i,
66 * where i is seen as a field element as in [MGV], ie high-order bits
67 * correspond to low powers of P. The result is stored in the same way, that
68 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
69 * corresponds to P^127.
70 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020071static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000072{
Paul Bakker43aff2a2013-09-09 00:10:27 +020073 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000074 uint64_t hi, lo;
75 uint64_t vl, vh;
76 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020077 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020078
Paul Bakker89e80c92012-03-20 13:50:09 +000079 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +020081 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000082
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010083 /* pack h as two 64-bits ints, big-endian */
Joe Subbiani6a506312021-07-07 16:56:29 +010084 hi = MBEDTLS_GET_UINT32_BE( h, 0 );
85 lo = MBEDTLS_GET_UINT32_BE( h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000086 vh = (uint64_t) hi << 32 | lo;
87
Joe Subbiani6a506312021-07-07 16:56:29 +010088 hi = MBEDTLS_GET_UINT32_BE( h, 8 );
89 lo = MBEDTLS_GET_UINT32_BE( h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000090 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020091
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010092 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +000093 ctx->HL[8] = vl;
94 ctx->HH[8] = vh;
95
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020096#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010097 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +010098 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010099 return( 0 );
100#endif
101
102 /* 0 corresponds to 0 in GF(2^128) */
103 ctx->HH[0] = 0;
104 ctx->HL[0] = 0;
105
Paul Bakker89e80c92012-03-20 13:50:09 +0000106 for( i = 4; i > 0; i >>= 1 )
107 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200108 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000109 vl = ( vh << 63 ) | ( vl >> 1 );
110 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
111
112 ctx->HL[i] = vl;
113 ctx->HH[i] = vh;
114 }
115
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000116 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000117 {
118 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
119 vh = *HiH;
120 vl = *HiL;
121 for( j = 1; j < i; j++ )
122 {
123 HiH[j] = vh ^ ctx->HH[j];
124 HiL[j] = vl ^ ctx->HL[j];
125 }
126 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200127
128 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000129}
130
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200131int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
132 mbedtls_cipher_id_t cipher,
133 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200134 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000135{
Janos Follath24eed8d2019-11-22 13:21:35 +0000136 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200137 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000138
Tuvshinzaya Erdenekhuuc6b8a672022-08-05 15:31:57 +0100139 if( keybits != 128 && keybits != 192 && keybits != 256 )
140 return MBEDTLS_ERR_GCM_BAD_INPUT;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100141
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500142 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
143 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200144 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200145 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200146
Paul Bakkera0558e02013-09-10 14:25:51 +0200147 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200148 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200149
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200150 mbedtls_cipher_free( &ctx->cipher_ctx );
151
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200152 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000153 return( ret );
154
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200155 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200157 {
158 return( ret );
159 }
160
161 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
162 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000163
164 return( 0 );
165}
166
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100167/*
168 * Shoup's method for multiplication use this table with
169 * last4[x] = x times P^128
170 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
171 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000172static const uint64_t last4[16] =
173{
174 0x0000, 0x1c20, 0x3840, 0x2460,
175 0x7080, 0x6ca0, 0x48c0, 0x54e0,
176 0xe100, 0xfd20, 0xd940, 0xc560,
177 0x9180, 0x8da0, 0xa9c0, 0xb5e0
178};
179
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100180/*
181 * Sets output to x times H using the precomputed tables.
182 * x and output are seen as elements of GF(2^128) as in [MGV].
183 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200184static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200185 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000186{
187 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000188 unsigned char lo, hi, rem;
189 uint64_t zh, zl;
190
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200191#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100192 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100193 unsigned char h[16];
194
Joe Subbiani5ecac212021-06-24 13:00:03 +0100195 MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
196 MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 );
197 MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
198 MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100199
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100201 return;
202 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100204
Paul Bakker89e80c92012-03-20 13:50:09 +0000205 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000206
207 zh = ctx->HH[lo];
208 zl = ctx->HL[lo];
209
210 for( i = 15; i >= 0; i-- )
211 {
212 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200213 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000214
215 if( i != 15 )
216 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000217 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000218 zl = ( zh << 60 ) | ( zl >> 4 );
219 zh = ( zh >> 4 );
220 zh ^= (uint64_t) last4[rem] << 48;
221 zh ^= ctx->HH[lo];
222 zl ^= ctx->HL[lo];
223
224 }
225
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000226 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000227 zl = ( zh << 60 ) | ( zl >> 4 );
228 zh = ( zh >> 4 );
229 zh ^= (uint64_t) last4[rem] << 48;
230 zh ^= ctx->HH[hi];
231 zl ^= ctx->HL[hi];
232 }
233
Joe Subbiani5ecac212021-06-24 13:00:03 +0100234 MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
235 MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
236 MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
237 MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000238}
239
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200240int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Gilles Peskine295fc132021-04-15 18:32:23 +0200241 int mode,
242 const unsigned char *iv, size_t iv_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000243{
Janos Follath24eed8d2019-11-22 13:21:35 +0000244 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000245 unsigned char work_buf[16];
246 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000247 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200248 size_t use_len, olen = 0;
openluopworldeab65ac2021-09-22 23:59:42 +0800249 uint64_t iv_bits;
Paul Bakker89e80c92012-03-20 13:50:09 +0000250
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200251 /* IV is limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200252 /* IV is not allowed to be zero length */
Gilles Peskine295fc132021-04-15 18:32:23 +0200253 if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200254 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200255
Paul Bakker52cf16c2013-07-26 13:55:38 +0200256 memset( ctx->y, 0x00, sizeof(ctx->y) );
257 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
258
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200259 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200260 ctx->len = 0;
261 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000262
263 if( iv_len == 12 )
264 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200265 memcpy( ctx->y, iv, iv_len );
266 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000267 }
268 else
269 {
270 memset( work_buf, 0x00, 16 );
openluopworldeab65ac2021-09-22 23:59:42 +0800271 iv_bits = (uint64_t)iv_len * 8;
272 MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000273
274 p = iv;
275 while( iv_len > 0 )
276 {
277 use_len = ( iv_len < 16 ) ? iv_len : 16;
278
Paul Bakker67f9d532012-10-23 11:49:05 +0000279 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200280 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200281
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200282 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000283
284 iv_len -= use_len;
285 p += use_len;
286 }
287
Paul Bakker67f9d532012-10-23 11:49:05 +0000288 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200289 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000290
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200291 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000292 }
293
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500294 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
295 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200296 {
297 return( ret );
298 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000299
Gilles Peskine295fc132021-04-15 18:32:23 +0200300 return( 0 );
301}
302
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200303/**
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200304 * mbedtls_gcm_context::buf contains the partial state of the computation of
305 * the authentication tag.
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200306 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
307 * different stages of the computation:
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200308 * * len == 0 && add_len == 0: initial state
309 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
310 * a partial block of AD that has been
311 * xored in but not yet multiplied in.
312 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
313 * the data ends now.
314 * * len % 16 != 0: the first `len % 16` bytes have
315 * a partial block of ciphertext that has
316 * been xored in but not yet multiplied in.
317 * * len > 0 && len % 16 == 0: the authentication tag is correct if
318 * the data ends now.
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200319 */
Gilles Peskine295fc132021-04-15 18:32:23 +0200320int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
321 const unsigned char *add, size_t add_len )
322{
323 const unsigned char *p;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200324 size_t use_len, i, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200325
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200326 /* IV is limited to 2^64 bits, so 2^61 bytes */
Gilles Peskine295fc132021-04-15 18:32:23 +0200327 if( (uint64_t) add_len >> 61 != 0 )
328 return( MBEDTLS_ERR_GCM_BAD_INPUT );
329
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200330 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000331 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200332
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200333 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000334 {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200335 use_len = 16 - offset;
336 if( use_len > add_len )
337 use_len = add_len;
338
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200339 for( i = 0; i < use_len; i++ )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200340 ctx->buf[i+offset] ^= p[i];
341
342 if( offset + use_len == 16 )
343 gcm_mult( ctx, ctx->buf, ctx->buf );
344
345 ctx->add_len += use_len;
346 add_len -= use_len;
347 p += use_len;
348 }
349
350 ctx->add_len += add_len;
351
352 while( add_len >= 16 )
353 {
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200354 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200355 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200356
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200357 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000358
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200359 add_len -= 16;
360 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000361 }
362
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200363 if( add_len > 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200364 {
365 for( i = 0; i < add_len; i++ )
366 ctx->buf[i] ^= p[i];
367 }
368
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200369 return( 0 );
370}
371
Gilles Peskine58fc2722021-04-13 15:58:27 +0200372/* Increment the counter. */
373static void gcm_incr( unsigned char y[16] )
374{
375 size_t i;
376 for( i = 16; i > 12; i-- )
377 if( ++y[i - 1] != 0 )
378 break;
379}
380
381/* Calculate and apply the encryption mask. Process use_len bytes of data,
382 * starting at position offset in the mask block. */
383static int gcm_mask( mbedtls_gcm_context *ctx,
384 unsigned char ectr[16],
385 size_t offset, size_t use_len,
386 const unsigned char *input,
387 unsigned char *output )
388{
389 size_t i;
390 size_t olen = 0;
391 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
392
393 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
394 &olen ) ) != 0 )
395 {
396 mbedtls_platform_zeroize( ectr, 16 );
397 return( ret );
398 }
399
400 for( i = 0; i < use_len; i++ )
401 {
402 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
403 ctx->buf[offset + i] ^= input[i];
404 output[i] = ectr[offset + i] ^ input[i];
405 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
406 ctx->buf[offset + i] ^= output[i];
407 }
408 return( 0 );
409}
410
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200412 const unsigned char *input, size_t input_length,
413 unsigned char *output, size_t output_size,
414 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200415{
Janos Follath24eed8d2019-11-22 13:21:35 +0000416 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200417 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200418 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200419 size_t offset;
Leonid Rozenboima3008e72022-04-21 17:28:18 -0700420 unsigned char ectr[16] = {0};
Gilles Peskine58fc2722021-04-13 15:58:27 +0200421
Gilles Peskinea56c4482021-04-15 17:22:35 +0200422 if( output_size < input_length )
Mateusz Starzykc48f43b2021-10-04 13:46:38 +0200423 return( MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200424 *output_length = input_length;
425
426 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200427 * on a potentially null pointer.
428 * Returning early also means that the last partial block of AD remains
429 * untouched for mbedtls_gcm_finish */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200430 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200431 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200432
Gilles Peskinea56c4482021-04-15 17:22:35 +0200433 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200435
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200436 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
437 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200438 if( ctx->len + input_length < ctx->len ||
439 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200440 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200442 }
443
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200444 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200445 {
446 gcm_mult( ctx, ctx->buf, ctx->buf );
447 }
448
Gilles Peskine58fc2722021-04-13 15:58:27 +0200449 offset = ctx->len % 16;
450 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000451 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200452 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200453 if( use_len > input_length )
454 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000455
Gilles Peskine58fc2722021-04-13 15:58:27 +0200456 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200457 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000458
Gilles Peskine58fc2722021-04-13 15:58:27 +0200459 if( offset + use_len == 16 )
460 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200461
Gilles Peskine58fc2722021-04-13 15:58:27 +0200462 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200463 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000464 p += use_len;
465 out_p += use_len;
466 }
467
Gilles Peskinea56c4482021-04-15 17:22:35 +0200468 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200469
Gilles Peskinea56c4482021-04-15 17:22:35 +0200470 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200471 {
472 gcm_incr( ctx->y );
473 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
474 return( ret );
475
476 gcm_mult( ctx, ctx->buf, ctx->buf );
477
Gilles Peskinea56c4482021-04-15 17:22:35 +0200478 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200479 p += 16;
480 out_p += 16;
481 }
482
Gilles Peskinea56c4482021-04-15 17:22:35 +0200483 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200484 {
485 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200486 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200487 return( ret );
488 }
489
490 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200491 return( 0 );
492}
493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200495 unsigned char *output, size_t output_size,
Gilles Peskine5a7be102021-06-23 21:51:32 +0200496 size_t *output_length,
Gilles Peskine9461e452021-04-15 16:48:32 +0200497 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200498{
499 unsigned char work_buf[16];
500 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100501 uint64_t orig_len;
502 uint64_t orig_add_len;
503
Gilles Peskine9461e452021-04-15 16:48:32 +0200504 /* We never pass any output in finish(). The output parameter exists only
505 * for the sake of alternative implementations. */
506 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200507 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200508 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200509
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100510 orig_len = ctx->len * 8;
511 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200512
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200513 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200514 {
515 gcm_mult( ctx, ctx->buf, ctx->buf );
516 }
517
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200518 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200520
Gilles Peskine58fc2722021-04-13 15:58:27 +0200521 if( ctx->len % 16 != 0 )
522 gcm_mult( ctx, ctx->buf, ctx->buf );
523
Andres AG821da842016-09-26 10:09:30 +0100524 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200525
Paul Bakker89e80c92012-03-20 13:50:09 +0000526 if( orig_len || orig_add_len )
527 {
528 memset( work_buf, 0x00, 16 );
529
Joe Subbiani5ecac212021-06-24 13:00:03 +0100530 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
531 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
532 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
533 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000534
Paul Bakker67f9d532012-10-23 11:49:05 +0000535 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200536 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000537
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200538 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000539
Paul Bakker67f9d532012-10-23 11:49:05 +0000540 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200541 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000542 }
543
544 return( 0 );
545}
546
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200548 int mode,
549 size_t length,
550 const unsigned char *iv,
551 size_t iv_len,
552 const unsigned char *add,
553 size_t add_len,
554 const unsigned char *input,
555 unsigned char *output,
556 size_t tag_len,
557 unsigned char *tag )
558{
Janos Follath24eed8d2019-11-22 13:21:35 +0000559 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200560 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200561
Gilles Peskine295fc132021-04-15 18:32:23 +0200562 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
563 return( ret );
564
565 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200566 return( ret );
567
Gilles Peskinea56c4482021-04-15 17:22:35 +0200568 if( ( ret = mbedtls_gcm_update( ctx, input, length,
569 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200570 return( ret );
571
Gilles Peskine5a7be102021-06-23 21:51:32 +0200572 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200573 return( ret );
574
575 return( 0 );
576}
577
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000579 size_t length,
580 const unsigned char *iv,
581 size_t iv_len,
582 const unsigned char *add,
583 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200584 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000585 size_t tag_len,
586 const unsigned char *input,
587 unsigned char *output )
588{
Janos Follath24eed8d2019-11-22 13:21:35 +0000589 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000590 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200591 size_t i;
592 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000593
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100595 iv, iv_len, add, add_len,
596 input, output, tag_len, check_tag ) ) != 0 )
597 {
598 return( ret );
599 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000600
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200601 /* Check tag in "constant-time" */
602 for( diff = 0, i = 0; i < tag_len; i++ )
603 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000604
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200605 if( diff != 0 )
606 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500607 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200609 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000610
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200611 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000612}
613
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200615{
k-stachowiak21298a22018-12-13 17:11:58 +0100616 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100617 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500619 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200620}
621
Jaeden Amero15263302017-09-21 12:53:48 +0100622#endif /* !MBEDTLS_GCM_ALT */
623
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200624#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000625/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200626 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000627 *
628 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
629 */
630#define MAX_TESTS 6
631
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100632static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000633 { 0, 0, 1, 1, 1, 1 };
634
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100635static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000636{
637 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
641 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
642 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
643 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200644 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000645};
646
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100647static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 { 12, 12, 12, 12, 8, 60 };
649
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100650static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000651 { 0, 0, 1, 1, 1, 2 };
652
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100653static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000654{
655 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656 0x00, 0x00, 0x00, 0x00 },
657 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
658 0xde, 0xca, 0xf8, 0x88 },
659 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200660 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000661 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200662 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000663 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200664 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000665 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200666 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000667};
668
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100669static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000670 { 0, 0, 0, 20, 20, 20 };
671
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100672static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000673 { 0, 0, 0, 1, 1, 1 };
674
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100675static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000676{
677 { 0x00 },
678 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200679 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000680 0xab, 0xad, 0xda, 0xd2 },
681};
682
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100683static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000684 { 0, 16, 64, 60, 60, 60 };
685
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100686static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000687 { 0, 0, 1, 1, 1, 1 };
688
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100689static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000690{
691 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
693 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
694 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
695 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
696 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
697 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
698 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
699 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
700 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
701};
702
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100703static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000704{
705 { 0x00 },
706 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
707 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
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, 0x47, 0x3f, 0x59, 0x85 },
716 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200717 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000718 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200719 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000720 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200721 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000722 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
723 0x3d, 0x58, 0xe0, 0x91 },
724 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200725 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000726 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200727 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000728 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200729 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000730 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
731 0xc2, 0x3f, 0x45, 0x98 },
732 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200733 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000734 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200735 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000736 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200737 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000738 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
739 0x4c, 0x34, 0xae, 0xe5 },
740 { 0x00 },
741 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200742 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000743 { 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,
Paul Bakker89e80c92012-03-20 13:50:09 +0000747 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200748 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
750 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
751 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200752 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000753 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200754 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
755 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
756 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000757 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200758 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000759 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200760 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200762 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000763 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200764 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000765 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200766 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000767 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200768 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000769 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200770 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000771 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200772 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000773 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200774 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000775 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200776 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
777 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
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, 0x89, 0x80, 0x15, 0xad },
786 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
787 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
788 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
789 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
790 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
791 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
792 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
793 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000794 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200795 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000796 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200797 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000798 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200799 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000800 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200801 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000802 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200803 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000804 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200805 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000806 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200807 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000808 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200809 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000810};
811
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100812static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000813{
814 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
815 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
816 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
817 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
818 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200819 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000820 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
821 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
822 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
823 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
824 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
825 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
826 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
827 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
828 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200829 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000830 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
831 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
832 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200833 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000834 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200835 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000836 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200837 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000838 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200839 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000840 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200841 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000842 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200843 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000844 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200845 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000846 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200847 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000848 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200849 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000850};
851
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000853{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200854 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000855 unsigned char buf[64];
856 unsigned char tag_buf[16];
857 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200859 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000860
861 for( j = 0; j < 3; j++ )
862 {
863 int key_len = 128 + 64 * j;
864
865 for( i = 0; i < MAX_TESTS; i++ )
866 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100867 mbedtls_gcm_init( &ctx );
868
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200869 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100871 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200872
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500873 ret = mbedtls_gcm_setkey( &ctx, cipher,
874 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100875 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100876 /*
877 * AES-192 is an optional feature that may be unavailable when
878 * there is an alternative underlying implementation i.e. when
879 * MBEDTLS_AES_ALT is defined.
880 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300881 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100882 {
883 mbedtls_printf( "skipped\n" );
884 break;
885 }
886 else if( ret != 0 )
887 {
888 goto exit;
889 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000890
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500892 pt_len_test_data[i],
893 iv_test_data[iv_index_test_data[i]],
894 iv_len_test_data[i],
895 additional_test_data[add_index_test_data[i]],
896 add_len_test_data[i],
897 pt_test_data[pt_index_test_data[i]],
898 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100899#if defined(MBEDTLS_GCM_ALT)
900 /* Allow alternative implementations to only support 12-byte nonces. */
901 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
902 iv_len_test_data[i] != 12 )
903 {
904 mbedtls_printf( "skipped\n" );
905 break;
906 }
907#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100908 if( ret != 0 )
909 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000910
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500911 if ( memcmp( buf, ct_test_data[j * 6 + i],
912 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100913 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000914 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100915 ret = 1;
916 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000917 }
918
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200920
Paul Bakker89e80c92012-03-20 13:50:09 +0000921 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000923
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100924 mbedtls_gcm_init( &ctx );
925
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200926 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100928 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200929
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500930 ret = mbedtls_gcm_setkey( &ctx, cipher,
931 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100932 key_len );
933 if( ret != 0 )
934 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000935
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500937 pt_len_test_data[i],
938 iv_test_data[iv_index_test_data[i]],
939 iv_len_test_data[i],
940 additional_test_data[add_index_test_data[i]],
941 add_len_test_data[i],
942 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000943
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100944 if( ret != 0 )
945 goto exit;
946
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100947 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
948 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100949 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000950 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100951 ret = 1;
952 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000953 }
954
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200955 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200956
Paul Bakker89e80c92012-03-20 13:50:09 +0000957 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200959
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100960 mbedtls_gcm_init( &ctx );
961
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200962 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100964 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200965
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500966 ret = mbedtls_gcm_setkey( &ctx, cipher,
967 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100968 key_len );
969 if( ret != 0 )
970 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200971
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +0200973 iv_test_data[iv_index_test_data[i]],
974 iv_len_test_data[i] );
975 if( ret != 0 )
976 goto exit;
977
978 ret = mbedtls_gcm_update_ad( &ctx,
979 additional_test_data[add_index_test_data[i]],
980 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200981 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100982 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200983
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100984 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200985 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100986 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200987 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100988 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +0200989 32,
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 != 32 )
994 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200995
Gilles Peskinea56c4482021-04-15 17:22:35 +0200996 ret = mbedtls_gcm_update( &ctx,
997 pt_test_data[pt_index_test_data[i]] + 32,
998 rest_len,
999 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001000 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001001 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001002 if( olen != rest_len )
1003 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001004 }
1005 else
1006 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001007 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001008 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001009 pt_len_test_data[i],
1010 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001011 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001012 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001013 if( olen != pt_len_test_data[i] )
1014 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001015 }
1016
Gilles Peskine5a7be102021-06-23 21:51:32 +02001017 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001018 if( ret != 0 )
1019 goto exit;
1020
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001021 if( memcmp( buf, ct_test_data[j * 6 + i],
1022 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001023 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001024 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001025 ret = 1;
1026 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001027 }
1028
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001029 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001030
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001031 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001032 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001033
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001034 mbedtls_gcm_init( &ctx );
1035
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001036 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001037 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001038 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001039
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001040 ret = mbedtls_gcm_setkey( &ctx, cipher,
1041 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001042 key_len );
1043 if( ret != 0 )
1044 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001045
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001046 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001047 iv_test_data[iv_index_test_data[i]],
1048 iv_len_test_data[i] );
1049 if( ret != 0 )
1050 goto exit;
1051 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001052 additional_test_data[add_index_test_data[i]],
1053 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001054 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001055 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001056
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001057 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001058 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001059 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001060 ret = mbedtls_gcm_update( &ctx,
1061 ct_test_data[j * 6 + i], 32,
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 != 32 )
1066 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001067
Gilles Peskinea56c4482021-04-15 17:22:35 +02001068 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001069 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001070 rest_len,
1071 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001072 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001073 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001074 if( olen != rest_len )
1075 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001076 }
1077 else
1078 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001079 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001080 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001081 pt_len_test_data[i],
1082 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001083 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001084 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001085 if( olen != pt_len_test_data[i] )
1086 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001087 }
1088
Gilles Peskine5a7be102021-06-23 21:51:32 +02001089 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001090 if( ret != 0 )
1091 goto exit;
1092
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001093 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1094 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001095 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001096 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001097 ret = 1;
1098 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001099 }
1100
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001101 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001102
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001103 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001104 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001105 }
1106 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001107
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001108 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001109 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001110
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001111 ret = 0;
1112
1113exit:
1114 if( ret != 0 )
1115 {
1116 if( verbose != 0 )
1117 mbedtls_printf( "failed\n" );
1118 mbedtls_gcm_free( &ctx );
1119 }
1120
1121 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001122}
1123
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001124#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001125
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001126#endif /* MBEDTLS_GCM_C */