blob: 13e72964328eedd2265070d30fc6fae50e631cbe [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker89e80c92012-03-20 13:50:09 +000018 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010019
Paul Bakker89e80c92012-03-20 13:50:09 +000020/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010021 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
22 *
23 * See also:
24 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
25 *
26 * We use the algorithm described as Shoup's method with 4-bit tables in
27 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000028 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010029
Gilles Peskinedb09ef62020-06-03 01:43:33 +020030#include "common.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000033
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/gcm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050035#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000036#include "mbedtls/error.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000041#include "aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010042#endif
43
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010045#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030047#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000048#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#define mbedtls_printf printf
50#endif /* MBEDTLS_PLATFORM_C */
51#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Jaeden Amero15263302017-09-21 12:53:48 +010053#if !defined(MBEDTLS_GCM_ALT)
54
k-stachowiak8ffc92a2018-12-12 14:21:59 +010055/* Parameter validation macros */
56#define GCM_VALIDATE_RET( cond ) \
57 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
58#define GCM_VALIDATE( cond ) \
59 MBEDTLS_INTERNAL_VALIDATE( cond )
60
Paul Bakker89e80c92012-03-20 13:50:09 +000061/*
62 * 32-bit integer manipulation macros (big endian)
63 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000064#ifndef GET_UINT32_BE
65#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000066{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000067 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
68 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
69 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
70 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000071}
72#endif
73
Paul Bakker5c2364c2012-10-01 14:41:15 +000074#ifndef PUT_UINT32_BE
75#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000076{ \
77 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
78 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
79 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
80 (b)[(i) + 3] = (unsigned char) ( (n) ); \
81}
82#endif
83
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010084/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020085 * Initialize a context
86 */
87void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
88{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010089 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020090 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
91}
92
93/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010094 * Precompute small multiples of H, that is set
95 * HH[i] || HL[i] = H times i,
96 * where i is seen as a field element as in [MGV], ie high-order bits
97 * correspond to low powers of P. The result is stored in the same way, that
98 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
99 * corresponds to P^127.
100 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200101static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000102{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200103 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000104 uint64_t hi, lo;
105 uint64_t vl, vh;
106 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200107 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200108
Paul Bakker89e80c92012-03-20 13:50:09 +0000109 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200111 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000112
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100113 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000114 GET_UINT32_BE( hi, h, 0 );
115 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000116 vh = (uint64_t) hi << 32 | lo;
117
Paul Bakker5c2364c2012-10-01 14:41:15 +0000118 GET_UINT32_BE( hi, h, 8 );
119 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000120 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200121
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100122 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000123 ctx->HL[8] = vl;
124 ctx->HH[8] = vh;
125
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200126#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100127 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100128 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100129 return( 0 );
130#endif
131
132 /* 0 corresponds to 0 in GF(2^128) */
133 ctx->HH[0] = 0;
134 ctx->HL[0] = 0;
135
Paul Bakker89e80c92012-03-20 13:50:09 +0000136 for( i = 4; i > 0; i >>= 1 )
137 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200138 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000139 vl = ( vh << 63 ) | ( vl >> 1 );
140 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
141
142 ctx->HL[i] = vl;
143 ctx->HH[i] = vh;
144 }
145
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000146 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000147 {
148 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
149 vh = *HiH;
150 vl = *HiL;
151 for( j = 1; j < i; j++ )
152 {
153 HiH[j] = vh ^ ctx->HH[j];
154 HiL[j] = vl ^ ctx->HL[j];
155 }
156 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200157
158 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000159}
160
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200161int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
162 mbedtls_cipher_id_t cipher,
163 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200164 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000165{
Janos Follath24eed8d2019-11-22 13:21:35 +0000166 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000168
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100169 GCM_VALIDATE_RET( ctx != NULL );
170 GCM_VALIDATE_RET( key != NULL );
171 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
172
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500173 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
174 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200175 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200176 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200177
Paul Bakkera0558e02013-09-10 14:25:51 +0200178 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200179 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200180
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200181 mbedtls_cipher_free( &ctx->cipher_ctx );
182
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200183 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000184 return( ret );
185
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200186 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200188 {
189 return( ret );
190 }
191
192 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
193 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000194
195 return( 0 );
196}
197
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100198/*
199 * Shoup's method for multiplication use this table with
200 * last4[x] = x times P^128
201 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
202 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000203static const uint64_t last4[16] =
204{
205 0x0000, 0x1c20, 0x3840, 0x2460,
206 0x7080, 0x6ca0, 0x48c0, 0x54e0,
207 0xe100, 0xfd20, 0xd940, 0xc560,
208 0x9180, 0x8da0, 0xa9c0, 0xb5e0
209};
210
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100211/*
212 * Sets output to x times H using the precomputed tables.
213 * x and output are seen as elements of GF(2^128) as in [MGV].
214 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200216 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000217{
218 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000219 unsigned char lo, hi, rem;
220 uint64_t zh, zl;
221
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200222#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100223 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100224 unsigned char h[16];
225
226 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
227 PUT_UINT32_BE( ctx->HH[8], h, 4 );
228 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
229 PUT_UINT32_BE( ctx->HL[8], h, 12 );
230
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200231 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100232 return;
233 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100235
Paul Bakker89e80c92012-03-20 13:50:09 +0000236 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000237
238 zh = ctx->HH[lo];
239 zl = ctx->HL[lo];
240
241 for( i = 15; i >= 0; i-- )
242 {
243 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200244 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000245
246 if( i != 15 )
247 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000248 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000249 zl = ( zh << 60 ) | ( zl >> 4 );
250 zh = ( zh >> 4 );
251 zh ^= (uint64_t) last4[rem] << 48;
252 zh ^= ctx->HH[lo];
253 zl ^= ctx->HL[lo];
254
255 }
256
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000257 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000258 zl = ( zh << 60 ) | ( zl >> 4 );
259 zh = ( zh >> 4 );
260 zh ^= (uint64_t) last4[rem] << 48;
261 zh ^= ctx->HH[hi];
262 zl ^= ctx->HL[hi];
263 }
264
Paul Bakker5c2364c2012-10-01 14:41:15 +0000265 PUT_UINT32_BE( zh >> 32, output, 0 );
266 PUT_UINT32_BE( zh, output, 4 );
267 PUT_UINT32_BE( zl >> 32, output, 8 );
268 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000269}
270
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200271int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200272 int mode,
273 const unsigned char *iv,
274 size_t iv_len,
275 const unsigned char *add,
276 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000277{
Janos Follath24eed8d2019-11-22 13:21:35 +0000278 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000279 unsigned char work_buf[16];
280 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000281 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200282 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000283
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100284 GCM_VALIDATE_RET( ctx != NULL );
285 GCM_VALIDATE_RET( iv != NULL );
286 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
287
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200288 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200289 /* IV is not allowed to be zero length */
290 if( iv_len == 0 ||
291 ( (uint64_t) iv_len ) >> 61 != 0 ||
292 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200293 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200295 }
296
Paul Bakker52cf16c2013-07-26 13:55:38 +0200297 memset( ctx->y, 0x00, sizeof(ctx->y) );
298 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
299
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200300 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200301 ctx->len = 0;
302 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000303
304 if( iv_len == 12 )
305 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200306 memcpy( ctx->y, iv, iv_len );
307 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000308 }
309 else
310 {
311 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000312 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000313
314 p = iv;
315 while( iv_len > 0 )
316 {
317 use_len = ( iv_len < 16 ) ? iv_len : 16;
318
Paul Bakker67f9d532012-10-23 11:49:05 +0000319 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200320 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200321
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200322 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000323
324 iv_len -= use_len;
325 p += use_len;
326 }
327
Paul Bakker67f9d532012-10-23 11:49:05 +0000328 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200329 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000330
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200331 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000332 }
333
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500334 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
335 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200336 {
337 return( ret );
338 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000339
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200340 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000341 p = add;
342 while( add_len > 0 )
343 {
344 use_len = ( add_len < 16 ) ? add_len : 16;
345
Paul Bakker67f9d532012-10-23 11:49:05 +0000346 for( i = 0; i < use_len; 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
351 add_len -= use_len;
352 p += use_len;
353 }
354
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200355 return( 0 );
356}
357
Gilles Peskine58fc2722021-04-13 15:58:27 +0200358/* Increment the counter. */
359static void gcm_incr( unsigned char y[16] )
360{
361 size_t i;
362 for( i = 16; i > 12; i-- )
363 if( ++y[i - 1] != 0 )
364 break;
365}
366
367/* Calculate and apply the encryption mask. Process use_len bytes of data,
368 * starting at position offset in the mask block. */
369static int gcm_mask( mbedtls_gcm_context *ctx,
370 unsigned char ectr[16],
371 size_t offset, size_t use_len,
372 const unsigned char *input,
373 unsigned char *output )
374{
375 size_t i;
376 size_t olen = 0;
377 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
378
379 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
380 &olen ) ) != 0 )
381 {
382 mbedtls_platform_zeroize( ectr, 16 );
383 return( ret );
384 }
385
386 for( i = 0; i < use_len; i++ )
387 {
388 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
389 ctx->buf[offset + i] ^= input[i];
390 output[i] = ectr[offset + i] ^ input[i];
391 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
392 ctx->buf[offset + i] ^= output[i];
393 }
394 return( 0 );
395}
396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200398 const unsigned char *input, size_t input_length,
399 unsigned char *output, size_t output_size,
400 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200401{
Janos Follath24eed8d2019-11-22 13:21:35 +0000402 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200403 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200404 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200405 size_t offset;
406 unsigned char ectr[16];
407
Gilles Peskinea56c4482021-04-15 17:22:35 +0200408 if( output_size < input_length )
409 return( MBEDTLS_ERR_GCM_BAD_INPUT );
410 GCM_VALIDATE_RET( output_length != NULL );
411 *output_length = input_length;
412
413 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
414 * on a potentially null pointer. */
415 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200416 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200417
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100418 GCM_VALIDATE_RET( ctx != NULL );
Gilles Peskine58fc2722021-04-13 15:58:27 +0200419 GCM_VALIDATE_RET( input != NULL );
420 GCM_VALIDATE_RET( output != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100421
Gilles Peskinea56c4482021-04-15 17:22:35 +0200422 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200424
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200425 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
426 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200427 if( ctx->len + input_length < ctx->len ||
428 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200429 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200431 }
432
Gilles Peskine58fc2722021-04-13 15:58:27 +0200433 offset = ctx->len % 16;
434 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000435 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200436 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200437 if( use_len > input_length )
438 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000439
Gilles Peskine58fc2722021-04-13 15:58:27 +0200440 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200441 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000442
Gilles Peskine58fc2722021-04-13 15:58:27 +0200443 if( offset + use_len == 16 )
444 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200445
Gilles Peskine58fc2722021-04-13 15:58:27 +0200446 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200447 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000448 p += use_len;
449 out_p += use_len;
450 }
451
Gilles Peskinea56c4482021-04-15 17:22:35 +0200452 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200453
Gilles Peskinea56c4482021-04-15 17:22:35 +0200454 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200455 {
456 gcm_incr( ctx->y );
457 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
458 return( ret );
459
460 gcm_mult( ctx, ctx->buf, ctx->buf );
461
Gilles Peskinea56c4482021-04-15 17:22:35 +0200462 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200463 p += 16;
464 out_p += 16;
465 }
466
Gilles Peskinea56c4482021-04-15 17:22:35 +0200467 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200468 {
469 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200470 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200471 return( ret );
472 }
473
474 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200475 return( 0 );
476}
477
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskine9461e452021-04-15 16:48:32 +0200479 unsigned char *output, size_t output_len,
480 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200481{
482 unsigned char work_buf[16];
483 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100484 uint64_t orig_len;
485 uint64_t orig_add_len;
486
487 GCM_VALIDATE_RET( ctx != NULL );
488 GCM_VALIDATE_RET( tag != NULL );
489
Gilles Peskine9461e452021-04-15 16:48:32 +0200490 /* We never pass any output in finish(). The output parameter exists only
491 * for the sake of alternative implementations. */
492 (void) output;
493 (void) output_len;
494
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100495 orig_len = ctx->len * 8;
496 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200497
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200498 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200500
Gilles Peskine58fc2722021-04-13 15:58:27 +0200501 if( ctx->len % 16 != 0 )
502 gcm_mult( ctx, ctx->buf, ctx->buf );
503
Andres AG821da842016-09-26 10:09:30 +0100504 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200505
Paul Bakker89e80c92012-03-20 13:50:09 +0000506 if( orig_len || orig_add_len )
507 {
508 memset( work_buf, 0x00, 16 );
509
Paul Bakker0ecdb232013-04-09 11:36:42 +0200510 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
511 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
512 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
513 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000514
Paul Bakker67f9d532012-10-23 11:49:05 +0000515 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200516 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000517
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200518 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000519
Paul Bakker67f9d532012-10-23 11:49:05 +0000520 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200521 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000522 }
523
524 return( 0 );
525}
526
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200527int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200528 int mode,
529 size_t length,
530 const unsigned char *iv,
531 size_t iv_len,
532 const unsigned char *add,
533 size_t add_len,
534 const unsigned char *input,
535 unsigned char *output,
536 size_t tag_len,
537 unsigned char *tag )
538{
Janos Follath24eed8d2019-11-22 13:21:35 +0000539 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200540 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200541
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100542 GCM_VALIDATE_RET( ctx != NULL );
543 GCM_VALIDATE_RET( iv != NULL );
544 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
545 GCM_VALIDATE_RET( length == 0 || input != NULL );
546 GCM_VALIDATE_RET( length == 0 || output != NULL );
547 GCM_VALIDATE_RET( tag != NULL );
548
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200550 return( ret );
551
Gilles Peskinea56c4482021-04-15 17:22:35 +0200552 if( ( ret = mbedtls_gcm_update( ctx, input, length,
553 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200554 return( ret );
555
Gilles Peskine9461e452021-04-15 16:48:32 +0200556 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200557 return( ret );
558
559 return( 0 );
560}
561
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000563 size_t length,
564 const unsigned char *iv,
565 size_t iv_len,
566 const unsigned char *add,
567 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200568 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000569 size_t tag_len,
570 const unsigned char *input,
571 unsigned char *output )
572{
Janos Follath24eed8d2019-11-22 13:21:35 +0000573 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000574 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200575 size_t i;
576 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000577
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100578 GCM_VALIDATE_RET( ctx != NULL );
579 GCM_VALIDATE_RET( iv != NULL );
580 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
581 GCM_VALIDATE_RET( tag != NULL );
582 GCM_VALIDATE_RET( length == 0 || input != NULL );
583 GCM_VALIDATE_RET( length == 0 || output != NULL );
584
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200585 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100586 iv, iv_len, add, add_len,
587 input, output, tag_len, check_tag ) ) != 0 )
588 {
589 return( ret );
590 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000591
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200592 /* Check tag in "constant-time" */
593 for( diff = 0, i = 0; i < tag_len; i++ )
594 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000595
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200596 if( diff != 0 )
597 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500598 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200600 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000601
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200602 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000603}
604
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200606{
k-stachowiak21298a22018-12-13 17:11:58 +0100607 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100608 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200609 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500610 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200611}
612
Jaeden Amero15263302017-09-21 12:53:48 +0100613#endif /* !MBEDTLS_GCM_ALT */
614
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000616/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200617 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000618 *
619 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
620 */
621#define MAX_TESTS 6
622
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100623static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000624 { 0, 0, 1, 1, 1, 1 };
625
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100626static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000627{
628 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
633 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
634 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200635 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000636};
637
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100638static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000639 { 12, 12, 12, 12, 8, 60 };
640
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100641static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 { 0, 0, 1, 1, 1, 2 };
643
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100644static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000645{
646 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00 },
648 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
649 0xde, 0xca, 0xf8, 0x88 },
650 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200651 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200653 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000654 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000656 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200657 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000658};
659
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100660static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000661 { 0, 0, 0, 20, 20, 20 };
662
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100663static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000664 { 0, 0, 0, 1, 1, 1 };
665
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100666static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000667{
668 { 0x00 },
669 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200670 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000671 0xab, 0xad, 0xda, 0xd2 },
672};
673
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100674static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000675 { 0, 16, 64, 60, 60, 60 };
676
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100677static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000678 { 0, 0, 1, 1, 1, 1 };
679
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100680static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000681{
682 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
683 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
684 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
685 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
686 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
687 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
688 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
689 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
690 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
691 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
692};
693
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100694static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000695{
696 { 0x00 },
697 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
698 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
699 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200702 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000703 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200704 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000705 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
706 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
707 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200708 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000709 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200710 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000711 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200712 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000713 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
714 0x3d, 0x58, 0xe0, 0x91 },
715 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200716 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000717 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200718 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000719 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200720 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000721 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
722 0xc2, 0x3f, 0x45, 0x98 },
723 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200724 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000725 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200726 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000727 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200728 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000729 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
730 0x4c, 0x34, 0xae, 0xe5 },
731 { 0x00 },
732 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200733 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000734 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200735 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000736 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200737 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000738 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200739 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000740 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
741 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
742 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200743 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000744 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200745 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
746 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
747 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000748 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200749 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000750 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200751 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000752 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200753 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000754 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200755 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000756 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200757 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000758 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200759 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000760 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200761 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000762 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200763 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000764 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200765 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000766 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200767 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
768 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
769 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
770 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
771 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
772 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
773 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
774 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
775 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
776 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
777 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
778 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
779 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
780 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
781 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
782 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
783 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
784 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000785 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200786 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000787 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200788 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000789 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200790 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000791 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200792 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000793 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200794 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000795 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200796 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000797 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200798 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000799 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200800 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000801};
802
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100803static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000804{
805 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
806 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
807 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
808 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
809 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200810 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000811 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
812 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
813 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
814 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
815 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
816 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
817 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
818 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
819 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200820 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000821 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
822 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
823 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200824 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000825 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200826 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000827 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200828 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000829 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200830 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000831 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200832 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000833 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200834 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000835 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200836 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000837 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200838 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000839 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200840 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000841};
842
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200843int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000844{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200845 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000846 unsigned char buf[64];
847 unsigned char tag_buf[16];
848 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200850 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000851
852 for( j = 0; j < 3; j++ )
853 {
854 int key_len = 128 + 64 * j;
855
856 for( i = 0; i < MAX_TESTS; i++ )
857 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100858 mbedtls_gcm_init( &ctx );
859
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200860 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200861 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100862 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200863
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500864 ret = mbedtls_gcm_setkey( &ctx, cipher,
865 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100866 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100867 /*
868 * AES-192 is an optional feature that may be unavailable when
869 * there is an alternative underlying implementation i.e. when
870 * MBEDTLS_AES_ALT is defined.
871 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300872 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100873 {
874 mbedtls_printf( "skipped\n" );
875 break;
876 }
877 else if( ret != 0 )
878 {
879 goto exit;
880 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000881
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200882 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500883 pt_len_test_data[i],
884 iv_test_data[iv_index_test_data[i]],
885 iv_len_test_data[i],
886 additional_test_data[add_index_test_data[i]],
887 add_len_test_data[i],
888 pt_test_data[pt_index_test_data[i]],
889 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100890#if defined(MBEDTLS_GCM_ALT)
891 /* Allow alternative implementations to only support 12-byte nonces. */
892 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
893 iv_len_test_data[i] != 12 )
894 {
895 mbedtls_printf( "skipped\n" );
896 break;
897 }
898#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100899 if( ret != 0 )
900 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000901
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500902 if ( memcmp( buf, ct_test_data[j * 6 + i],
903 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100904 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000905 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100906 ret = 1;
907 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000908 }
909
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200910 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200911
Paul Bakker89e80c92012-03-20 13:50:09 +0000912 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000914
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100915 mbedtls_gcm_init( &ctx );
916
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200917 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200918 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100919 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200920
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500921 ret = mbedtls_gcm_setkey( &ctx, cipher,
922 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100923 key_len );
924 if( ret != 0 )
925 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000926
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500928 pt_len_test_data[i],
929 iv_test_data[iv_index_test_data[i]],
930 iv_len_test_data[i],
931 additional_test_data[add_index_test_data[i]],
932 add_len_test_data[i],
933 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000934
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100935 if( ret != 0 )
936 goto exit;
937
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100938 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
939 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100940 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000941 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100942 ret = 1;
943 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000944 }
945
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200947
Paul Bakker89e80c92012-03-20 13:50:09 +0000948 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200950
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100951 mbedtls_gcm_init( &ctx );
952
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200953 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100955 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200956
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500957 ret = mbedtls_gcm_setkey( &ctx, cipher,
958 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100959 key_len );
960 if( ret != 0 )
961 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200962
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500964 iv_test_data[iv_index_test_data[i]],
965 iv_len_test_data[i],
966 additional_test_data[add_index_test_data[i]],
967 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200968 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100969 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200970
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100971 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200972 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100973 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200974 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100975 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +0200976 32,
977 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200978 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100979 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200980 if( olen != 32 )
981 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200982
Gilles Peskinea56c4482021-04-15 17:22:35 +0200983 ret = mbedtls_gcm_update( &ctx,
984 pt_test_data[pt_index_test_data[i]] + 32,
985 rest_len,
986 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200987 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100988 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200989 if( olen != rest_len )
990 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200991 }
992 else
993 {
Gilles Peskinea56c4482021-04-15 17:22:35 +0200994 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500995 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +0200996 pt_len_test_data[i],
997 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200998 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100999 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001000 if( olen != pt_len_test_data[i] )
1001 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001002 }
1003
Gilles Peskine9461e452021-04-15 16:48:32 +02001004 ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001005 if( ret != 0 )
1006 goto exit;
1007
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001008 if( memcmp( buf, ct_test_data[j * 6 + i],
1009 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001010 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001011 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001012 ret = 1;
1013 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001014 }
1015
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001016 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001017
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001018 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001020
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001021 mbedtls_gcm_init( &ctx );
1022
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001023 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001025 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001026
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001027 ret = mbedtls_gcm_setkey( &ctx, cipher,
1028 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001029 key_len );
1030 if( ret != 0 )
1031 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001034 iv_test_data[iv_index_test_data[i]],
1035 iv_len_test_data[i],
1036 additional_test_data[add_index_test_data[i]],
1037 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001038 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001039 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001040
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001041 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001042 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001043 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001044 ret = mbedtls_gcm_update( &ctx,
1045 ct_test_data[j * 6 + i], 32,
1046 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001047 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001048 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001049 if( olen != 32 )
1050 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001051
Gilles Peskinea56c4482021-04-15 17:22:35 +02001052 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001053 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001054 rest_len,
1055 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001056 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001057 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001058 if( olen != rest_len )
1059 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001060 }
1061 else
1062 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001063 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001064 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001065 pt_len_test_data[i],
1066 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001067 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001068 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001069 if( olen != pt_len_test_data[i] )
1070 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001071 }
1072
Gilles Peskine9461e452021-04-15 16:48:32 +02001073 ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001074 if( ret != 0 )
1075 goto exit;
1076
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001077 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1078 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001079 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001080 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001081 ret = 1;
1082 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001083 }
1084
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001086
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001087 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001088 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001089 }
1090 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001091
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001092 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001094
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001095 ret = 0;
1096
1097exit:
1098 if( ret != 0 )
1099 {
1100 if( verbose != 0 )
1101 mbedtls_printf( "failed\n" );
1102 mbedtls_gcm_free( &ctx );
1103 }
1104
1105 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001106}
1107
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001108#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001109
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001110#endif /* MBEDTLS_GCM_C */