blob: e7432ebae7ea7abf076c571d68cbc3ab03fb9ce9 [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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/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"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010048
Jaeden Amero15263302017-09-21 12:53:48 +010049#if !defined(MBEDTLS_GCM_ALT)
50
k-stachowiak8ffc92a2018-12-12 14:21:59 +010051/* Parameter validation macros */
52#define GCM_VALIDATE_RET( cond ) \
53 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
54#define GCM_VALIDATE( cond ) \
55 MBEDTLS_INTERNAL_VALIDATE( cond )
56
Paul Bakker89e80c92012-03-20 13:50:09 +000057/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020058 * Initialize a context
59 */
60void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
61{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010062 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020063 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
64}
65
66/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010067 * Precompute small multiples of H, that is set
68 * HH[i] || HL[i] = H times i,
69 * where i is seen as a field element as in [MGV], ie high-order bits
70 * correspond to low powers of P. The result is stored in the same way, that
71 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
72 * corresponds to P^127.
73 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000075{
Paul Bakker43aff2a2013-09-09 00:10:27 +020076 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000077 uint64_t hi, lo;
78 uint64_t vl, vh;
79 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020080 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020081
Paul Bakker89e80c92012-03-20 13:50:09 +000082 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020083 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +020084 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000085
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010086 /* pack h as two 64-bits ints, big-endian */
Joe Subbiani9231d5f2021-07-07 16:56:29 +010087 hi = MBEDTLS_GET_UINT32_BE( h, 0 );
88 lo = MBEDTLS_GET_UINT32_BE( h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000089 vh = (uint64_t) hi << 32 | lo;
90
Joe Subbiani9231d5f2021-07-07 16:56:29 +010091 hi = MBEDTLS_GET_UINT32_BE( h, 8 );
92 lo = MBEDTLS_GET_UINT32_BE( h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000093 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020094
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010095 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +000096 ctx->HL[8] = vl;
97 ctx->HH[8] = vh;
98
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100100 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100101 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100102 return( 0 );
103#endif
104
105 /* 0 corresponds to 0 in GF(2^128) */
106 ctx->HH[0] = 0;
107 ctx->HL[0] = 0;
108
Paul Bakker89e80c92012-03-20 13:50:09 +0000109 for( i = 4; i > 0; i >>= 1 )
110 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200111 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000112 vl = ( vh << 63 ) | ( vl >> 1 );
113 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
114
115 ctx->HL[i] = vl;
116 ctx->HH[i] = vh;
117 }
118
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000119 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000120 {
121 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
122 vh = *HiH;
123 vl = *HiL;
124 for( j = 1; j < i; j++ )
125 {
126 HiH[j] = vh ^ ctx->HH[j];
127 HiL[j] = vl ^ ctx->HL[j];
128 }
129 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200130
131 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000132}
133
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200134int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
135 mbedtls_cipher_id_t cipher,
136 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200137 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000138{
Janos Follath24eed8d2019-11-22 13:21:35 +0000139 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000141
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100142 GCM_VALIDATE_RET( ctx != NULL );
143 GCM_VALIDATE_RET( key != NULL );
144 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
145
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500146 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
147 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200148 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200149 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200150
Paul Bakkera0558e02013-09-10 14:25:51 +0200151 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200152 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200153
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200154 mbedtls_cipher_free( &ctx->cipher_ctx );
155
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200156 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000157 return( ret );
158
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200159 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200161 {
162 return( ret );
163 }
164
165 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
166 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000167
168 return( 0 );
169}
170
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100171/*
172 * Shoup's method for multiplication use this table with
173 * last4[x] = x times P^128
174 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
175 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000176static const uint64_t last4[16] =
177{
178 0x0000, 0x1c20, 0x3840, 0x2460,
179 0x7080, 0x6ca0, 0x48c0, 0x54e0,
180 0xe100, 0xfd20, 0xd940, 0xc560,
181 0x9180, 0x8da0, 0xa9c0, 0xb5e0
182};
183
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100184/*
185 * Sets output to x times H using the precomputed tables.
186 * x and output are seen as elements of GF(2^128) as in [MGV].
187 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200188static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200189 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000190{
191 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000192 unsigned char lo, hi, rem;
193 uint64_t zh, zl;
194
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100196 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100197 unsigned char h[16];
198
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100199 MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
200 MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 );
201 MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
202 MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100203
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200204 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100205 return;
206 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200207#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100208
Paul Bakker89e80c92012-03-20 13:50:09 +0000209 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000210
211 zh = ctx->HH[lo];
212 zl = ctx->HL[lo];
213
214 for( i = 15; i >= 0; i-- )
215 {
216 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200217 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000218
219 if( i != 15 )
220 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000221 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000222 zl = ( zh << 60 ) | ( zl >> 4 );
223 zh = ( zh >> 4 );
224 zh ^= (uint64_t) last4[rem] << 48;
225 zh ^= ctx->HH[lo];
226 zl ^= ctx->HL[lo];
227
228 }
229
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000230 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000231 zl = ( zh << 60 ) | ( zl >> 4 );
232 zh = ( zh >> 4 );
233 zh ^= (uint64_t) last4[rem] << 48;
234 zh ^= ctx->HH[hi];
235 zl ^= ctx->HL[hi];
236 }
237
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100238 MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
239 MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
240 MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
241 MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000242}
243
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200244int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200245 int mode,
246 const unsigned char *iv,
247 size_t iv_len,
248 const unsigned char *add,
249 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000250{
Janos Follath24eed8d2019-11-22 13:21:35 +0000251 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000252 unsigned char work_buf[16];
253 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000254 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200255 size_t use_len, olen = 0;
openluopworld5d5f5202021-11-05 00:13:43 +0800256 uint64_t iv_bits;
Paul Bakker89e80c92012-03-20 13:50:09 +0000257
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100258 GCM_VALIDATE_RET( ctx != NULL );
259 GCM_VALIDATE_RET( iv != NULL );
260 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
261
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200262 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200263 /* IV is not allowed to be zero length */
264 if( iv_len == 0 ||
265 ( (uint64_t) iv_len ) >> 61 != 0 ||
266 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200267 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200268 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200269 }
270
Paul Bakker52cf16c2013-07-26 13:55:38 +0200271 memset( ctx->y, 0x00, sizeof(ctx->y) );
272 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
273
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200274 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200275 ctx->len = 0;
276 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000277
278 if( iv_len == 12 )
279 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200280 memcpy( ctx->y, iv, iv_len );
281 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000282 }
283 else
284 {
285 memset( work_buf, 0x00, 16 );
openluopworld5d5f5202021-11-05 00:13:43 +0800286 iv_bits = (uint64_t)iv_len * 8;
287 MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000288
289 p = iv;
290 while( iv_len > 0 )
291 {
292 use_len = ( iv_len < 16 ) ? iv_len : 16;
293
Paul Bakker67f9d532012-10-23 11:49:05 +0000294 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200295 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200296
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200297 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000298
299 iv_len -= use_len;
300 p += use_len;
301 }
302
Paul Bakker67f9d532012-10-23 11:49:05 +0000303 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200304 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000305
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200306 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000307 }
308
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500309 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
310 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200311 {
312 return( ret );
313 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000314
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200315 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000316 p = add;
317 while( add_len > 0 )
318 {
319 use_len = ( add_len < 16 ) ? add_len : 16;
320
Paul Bakker67f9d532012-10-23 11:49:05 +0000321 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200322 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200323
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200324 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000325
326 add_len -= use_len;
327 p += use_len;
328 }
329
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200330 return( 0 );
331}
332
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200334 size_t length,
335 const unsigned char *input,
336 unsigned char *output )
337{
Janos Follath24eed8d2019-11-22 13:21:35 +0000338 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200339 unsigned char ectr[16];
340 size_t i;
341 const unsigned char *p;
342 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200343 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200344
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100345 GCM_VALIDATE_RET( ctx != NULL );
346 GCM_VALIDATE_RET( length == 0 || input != NULL );
347 GCM_VALIDATE_RET( length == 0 || output != NULL );
348
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200349 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200351
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200352 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
353 * Also check for possible overflow */
354 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100355 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200356 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200357 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200358 }
359
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200360 ctx->len += length;
361
Paul Bakker89e80c92012-03-20 13:50:09 +0000362 p = input;
363 while( length > 0 )
364 {
365 use_len = ( length < 16 ) ? length : 16;
366
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100367 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200368 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000369 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000370
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200372 &olen ) ) != 0 )
373 {
374 return( ret );
375 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000376
Paul Bakker67f9d532012-10-23 11:49:05 +0000377 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000378 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200380 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000381 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200382 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200383 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000384 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200385
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200386 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200387
Paul Bakker89e80c92012-03-20 13:50:09 +0000388 length -= use_len;
389 p += use_len;
390 out_p += use_len;
391 }
392
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200393 return( 0 );
394}
395
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200396int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200397 unsigned char *tag,
398 size_t tag_len )
399{
400 unsigned char work_buf[16];
401 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100402 uint64_t orig_len;
403 uint64_t orig_add_len;
404
405 GCM_VALIDATE_RET( ctx != NULL );
406 GCM_VALIDATE_RET( tag != NULL );
407
408 orig_len = ctx->len * 8;
409 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200410
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200411 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200412 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200413
Andres AG821da842016-09-26 10:09:30 +0100414 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200415
Paul Bakker89e80c92012-03-20 13:50:09 +0000416 if( orig_len || orig_add_len )
417 {
418 memset( work_buf, 0x00, 16 );
419
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100420 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
421 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
422 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
423 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000424
Paul Bakker67f9d532012-10-23 11:49:05 +0000425 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200426 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000427
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200428 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000429
Paul Bakker67f9d532012-10-23 11:49:05 +0000430 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200431 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000432 }
433
434 return( 0 );
435}
436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200438 int mode,
439 size_t length,
440 const unsigned char *iv,
441 size_t iv_len,
442 const unsigned char *add,
443 size_t add_len,
444 const unsigned char *input,
445 unsigned char *output,
446 size_t tag_len,
447 unsigned char *tag )
448{
Janos Follath24eed8d2019-11-22 13:21:35 +0000449 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200450
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100451 GCM_VALIDATE_RET( ctx != NULL );
452 GCM_VALIDATE_RET( iv != NULL );
453 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
454 GCM_VALIDATE_RET( length == 0 || input != NULL );
455 GCM_VALIDATE_RET( length == 0 || output != NULL );
456 GCM_VALIDATE_RET( tag != NULL );
457
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200459 return( ret );
460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200462 return( ret );
463
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200465 return( ret );
466
467 return( 0 );
468}
469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000471 size_t length,
472 const unsigned char *iv,
473 size_t iv_len,
474 const unsigned char *add,
475 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200476 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000477 size_t tag_len,
478 const unsigned char *input,
479 unsigned char *output )
480{
Janos Follath24eed8d2019-11-22 13:21:35 +0000481 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000482 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200483 size_t i;
484 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000485
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100486 GCM_VALIDATE_RET( ctx != NULL );
487 GCM_VALIDATE_RET( iv != NULL );
488 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
489 GCM_VALIDATE_RET( tag != NULL );
490 GCM_VALIDATE_RET( length == 0 || input != NULL );
491 GCM_VALIDATE_RET( length == 0 || output != NULL );
492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100494 iv, iv_len, add, add_len,
495 input, output, tag_len, check_tag ) ) != 0 )
496 {
497 return( ret );
498 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000499
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200500 /* Check tag in "constant-time" */
501 for( diff = 0, i = 0; i < tag_len; i++ )
502 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000503
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200504 if( diff != 0 )
505 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500506 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200508 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000509
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200510 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000511}
512
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200513void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200514{
k-stachowiak21298a22018-12-13 17:11:58 +0100515 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100516 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200517 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500518 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200519}
520
Jaeden Amero15263302017-09-21 12:53:48 +0100521#endif /* !MBEDTLS_GCM_ALT */
522
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000524/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200525 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000526 *
527 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
528 */
529#define MAX_TESTS 6
530
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100531static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000532 { 0, 0, 1, 1, 1, 1 };
533
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100534static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000535{
536 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
540 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
541 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
542 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200543 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000544};
545
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100546static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000547 { 12, 12, 12, 12, 8, 60 };
548
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100549static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000550 { 0, 0, 1, 1, 1, 2 };
551
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100552static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000553{
554 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555 0x00, 0x00, 0x00, 0x00 },
556 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
557 0xde, 0xca, 0xf8, 0x88 },
558 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200559 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000560 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200561 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000562 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200563 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000564 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200565 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000566};
567
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100568static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000569 { 0, 0, 0, 20, 20, 20 };
570
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100571static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000572 { 0, 0, 0, 1, 1, 1 };
573
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100574static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000575{
576 { 0x00 },
577 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200578 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000579 0xab, 0xad, 0xda, 0xd2 },
580};
581
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100582static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000583 { 0, 16, 64, 60, 60, 60 };
584
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100585static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000586 { 0, 0, 1, 1, 1, 1 };
587
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100588static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000589{
590 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
592 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
593 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
594 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
595 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
596 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
597 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
598 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
599 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
600};
601
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100602static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000603{
604 { 0x00 },
605 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
606 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
607 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200608 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000609 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200610 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000611 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200612 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
614 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
615 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200616 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000617 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200618 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000619 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200620 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000621 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
622 0x3d, 0x58, 0xe0, 0x91 },
623 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200624 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200626 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000627 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200628 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000629 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
630 0xc2, 0x3f, 0x45, 0x98 },
631 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200632 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000633 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200634 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000635 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200636 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000637 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
638 0x4c, 0x34, 0xae, 0xe5 },
639 { 0x00 },
640 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200641 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200643 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000644 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200645 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000646 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200647 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
649 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
650 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200651 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200653 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
654 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
655 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000656 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200657 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000658 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200659 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200661 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000662 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200663 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000664 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200665 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000666 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200667 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000668 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200669 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000670 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200671 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000672 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200673 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000674 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200675 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
676 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
677 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
678 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
679 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
680 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
681 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
682 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
683 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
684 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
685 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
686 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
687 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
688 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
689 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
690 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
691 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
692 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000693 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200694 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000695 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200696 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200702 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000703 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200704 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000705 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200706 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000707 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200708 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000709};
710
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100711static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000712{
713 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
714 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
715 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
716 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
717 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200718 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000719 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
720 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
721 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
722 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
723 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
724 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
725 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
726 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
727 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200728 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000729 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
730 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
731 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200732 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000733 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200734 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000735 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200736 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000737 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200738 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000739 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200740 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000741 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200742 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000743 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200744 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000745 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200746 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000747 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200748 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000749};
750
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200751int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000752{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200753 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000754 unsigned char buf[64];
755 unsigned char tag_buf[16];
756 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200757 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000758
759 for( j = 0; j < 3; j++ )
760 {
761 int key_len = 128 + 64 * j;
762
763 for( i = 0; i < MAX_TESTS; i++ )
764 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100765 mbedtls_gcm_init( &ctx );
766
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200767 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200768 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100769 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200770
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500771 ret = mbedtls_gcm_setkey( &ctx, cipher,
772 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100773 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100774 /*
775 * AES-192 is an optional feature that may be unavailable when
776 * there is an alternative underlying implementation i.e. when
777 * MBEDTLS_AES_ALT is defined.
778 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300779 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100780 {
781 mbedtls_printf( "skipped\n" );
782 break;
783 }
784 else if( ret != 0 )
785 {
786 goto exit;
787 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000788
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500790 pt_len_test_data[i],
791 iv_test_data[iv_index_test_data[i]],
792 iv_len_test_data[i],
793 additional_test_data[add_index_test_data[i]],
794 add_len_test_data[i],
795 pt_test_data[pt_index_test_data[i]],
796 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100797#if defined(MBEDTLS_GCM_ALT)
798 /* Allow alternative implementations to only support 12-byte nonces. */
799 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
800 iv_len_test_data[i] != 12 )
801 {
802 mbedtls_printf( "skipped\n" );
803 break;
804 }
805#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100806 if( ret != 0 )
807 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000808
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500809 if ( memcmp( buf, ct_test_data[j * 6 + i],
810 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100811 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000812 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100813 ret = 1;
814 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000815 }
816
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200817 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200818
Paul Bakker89e80c92012-03-20 13:50:09 +0000819 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200820 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000821
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100822 mbedtls_gcm_init( &ctx );
823
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200824 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200825 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100826 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200827
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500828 ret = mbedtls_gcm_setkey( &ctx, cipher,
829 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100830 key_len );
831 if( ret != 0 )
832 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000833
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200834 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500835 pt_len_test_data[i],
836 iv_test_data[iv_index_test_data[i]],
837 iv_len_test_data[i],
838 additional_test_data[add_index_test_data[i]],
839 add_len_test_data[i],
840 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000841
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100842 if( ret != 0 )
843 goto exit;
844
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100845 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
846 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100847 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000848 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100849 ret = 1;
850 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000851 }
852
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200853 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200854
Paul Bakker89e80c92012-03-20 13:50:09 +0000855 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200856 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200857
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 split (%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 );
867 if( ret != 0 )
868 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200869
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500871 iv_test_data[iv_index_test_data[i]],
872 iv_len_test_data[i],
873 additional_test_data[add_index_test_data[i]],
874 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200875 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100876 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200877
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100878 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200879 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100880 size_t rest_len = pt_len_test_data[i] - 32;
881 ret = mbedtls_gcm_update( &ctx, 32,
882 pt_test_data[pt_index_test_data[i]],
883 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200884 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100885 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200886
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100887 ret = mbedtls_gcm_update( &ctx, rest_len,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500888 pt_test_data[pt_index_test_data[i]] + 32,
889 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200890 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100891 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200892 }
893 else
894 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100895 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500896 pt_test_data[pt_index_test_data[i]],
897 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200898 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100899 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200900 }
901
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200902 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100903 if( ret != 0 )
904 goto exit;
905
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500906 if( memcmp( buf, ct_test_data[j * 6 + i],
907 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100908 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200909 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100910 ret = 1;
911 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200912 }
913
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200915
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200916 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200917 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200918
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100919 mbedtls_gcm_init( &ctx );
920
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200921 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100923 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200924
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100925 ret = mbedtls_gcm_setkey( &ctx, cipher,
926 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100927 key_len );
928 if( ret != 0 )
929 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200930
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100932 iv_test_data[iv_index_test_data[i]],
933 iv_len_test_data[i],
934 additional_test_data[add_index_test_data[i]],
935 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200936 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100937 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200938
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100939 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200940 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100941 size_t rest_len = pt_len_test_data[i] - 32;
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500942 ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
943 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200944 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100945 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200946
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500947 ret = mbedtls_gcm_update( &ctx, rest_len,
948 ct_test_data[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100949 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200950 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100951 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200952 }
953 else
954 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100955 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
956 ct_test_data[j * 6 + i],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100957 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200958 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100959 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200960 }
961
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200962 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100963 if( ret != 0 )
964 goto exit;
965
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100966 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
967 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100968 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200969 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100970 ret = 1;
971 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200972 }
973
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200975
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200976 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000978 }
979 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200980
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200981 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200982 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000983
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100984 ret = 0;
985
986exit:
987 if( ret != 0 )
988 {
989 if( verbose != 0 )
990 mbedtls_printf( "failed\n" );
991 mbedtls_gcm_free( &ctx );
992 }
993
994 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000995}
996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200997#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000998
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999#endif /* MBEDTLS_GCM_C */