blob: d0b73379a617130f0af901765a724c113f51e8f7 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker89e80c92012-03-20 13:50:09 +000018 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010019
Paul Bakker89e80c92012-03-20 13:50:09 +000020/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010021 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
22 *
23 * See also:
24 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
25 *
26 * We use the algorithm described as Shoup's method with 4-bit tables in
27 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000028 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010029
Gilles Peskinedb09ef62020-06-03 01:43:33 +020030#include "common.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000033
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/gcm.h"
Gilles Peskine7705a462022-09-15 20:14:22 +020035#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050036#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000037#include "mbedtls/error.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010043#endif
44
Jaeden Amero15263302017-09-21 12:53:48 +010045#if !defined(MBEDTLS_GCM_ALT)
46
k-stachowiak8ffc92a2018-12-12 14:21:59 +010047/* Parameter validation macros */
48#define GCM_VALIDATE_RET( cond ) \
49 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
50#define GCM_VALIDATE( cond ) \
51 MBEDTLS_INTERNAL_VALIDATE( cond )
52
Paul Bakker89e80c92012-03-20 13:50:09 +000053/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020054 * Initialize a context
55 */
56void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
57{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010058 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020059 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
60}
61
62/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010063 * Precompute small multiples of H, that is set
64 * HH[i] || HL[i] = H times i,
65 * where i is seen as a field element as in [MGV], ie high-order bits
66 * correspond to low powers of P. The result is stored in the same way, that
67 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
68 * corresponds to P^127.
69 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000071{
Paul Bakker43aff2a2013-09-09 00:10:27 +020072 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000073 uint64_t hi, lo;
74 uint64_t vl, vh;
75 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020076 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020077
Paul Bakker89e80c92012-03-20 13:50:09 +000078 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +020080 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000081
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010082 /* pack h as two 64-bits ints, big-endian */
Joe Subbiani9231d5f2021-07-07 16:56:29 +010083 hi = MBEDTLS_GET_UINT32_BE( h, 0 );
84 lo = MBEDTLS_GET_UINT32_BE( h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000085 vh = (uint64_t) hi << 32 | lo;
86
Joe Subbiani9231d5f2021-07-07 16:56:29 +010087 hi = MBEDTLS_GET_UINT32_BE( h, 8 );
88 lo = MBEDTLS_GET_UINT32_BE( h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000089 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020090
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010091 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +000092 ctx->HL[8] = vl;
93 ctx->HH[8] = vh;
94
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020095#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010096 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +010097 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010098 return( 0 );
99#endif
100
101 /* 0 corresponds to 0 in GF(2^128) */
102 ctx->HH[0] = 0;
103 ctx->HL[0] = 0;
104
Paul Bakker89e80c92012-03-20 13:50:09 +0000105 for( i = 4; i > 0; i >>= 1 )
106 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200107 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000108 vl = ( vh << 63 ) | ( vl >> 1 );
109 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
110
111 ctx->HL[i] = vl;
112 ctx->HH[i] = vh;
113 }
114
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000115 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000116 {
117 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
118 vh = *HiH;
119 vl = *HiL;
120 for( j = 1; j < i; j++ )
121 {
122 HiH[j] = vh ^ ctx->HH[j];
123 HiL[j] = vl ^ ctx->HL[j];
124 }
125 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200126
127 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000128}
129
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200130int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
131 mbedtls_cipher_id_t cipher,
132 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200133 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000134{
Janos Follath24eed8d2019-11-22 13:21:35 +0000135 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200136 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000137
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100138 GCM_VALIDATE_RET( ctx != NULL );
139 GCM_VALIDATE_RET( key != NULL );
140 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
141
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500142 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
143 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200144 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200145 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200146
Paul Bakkera0558e02013-09-10 14:25:51 +0200147 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200148 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200149
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200150 mbedtls_cipher_free( &ctx->cipher_ctx );
151
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200152 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000153 return( ret );
154
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200155 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200157 {
158 return( ret );
159 }
160
161 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
162 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000163
164 return( 0 );
165}
166
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100167/*
168 * Shoup's method for multiplication use this table with
169 * last4[x] = x times P^128
170 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
171 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000172static const uint64_t last4[16] =
173{
174 0x0000, 0x1c20, 0x3840, 0x2460,
175 0x7080, 0x6ca0, 0x48c0, 0x54e0,
176 0xe100, 0xfd20, 0xd940, 0xc560,
177 0x9180, 0x8da0, 0xa9c0, 0xb5e0
178};
179
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100180/*
181 * Sets output to x times H using the precomputed tables.
182 * x and output are seen as elements of GF(2^128) as in [MGV].
183 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200184static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200185 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000186{
187 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000188 unsigned char lo, hi, rem;
189 uint64_t zh, zl;
190
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200191#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100192 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100193 unsigned char h[16];
194
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100195 MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
196 MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 );
197 MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
198 MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100199
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100201 return;
202 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100204
Paul Bakker89e80c92012-03-20 13:50:09 +0000205 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000206
207 zh = ctx->HH[lo];
208 zl = ctx->HL[lo];
209
210 for( i = 15; i >= 0; i-- )
211 {
212 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200213 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000214
215 if( i != 15 )
216 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000217 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000218 zl = ( zh << 60 ) | ( zl >> 4 );
219 zh = ( zh >> 4 );
220 zh ^= (uint64_t) last4[rem] << 48;
221 zh ^= ctx->HH[lo];
222 zl ^= ctx->HL[lo];
223
224 }
225
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000226 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000227 zl = ( zh << 60 ) | ( zl >> 4 );
228 zh = ( zh >> 4 );
229 zh ^= (uint64_t) last4[rem] << 48;
230 zh ^= ctx->HH[hi];
231 zl ^= ctx->HL[hi];
232 }
233
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100234 MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
235 MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
236 MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
237 MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000238}
239
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200240int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200241 int mode,
242 const unsigned char *iv,
243 size_t iv_len,
244 const unsigned char *add,
245 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000246{
Janos Follath24eed8d2019-11-22 13:21:35 +0000247 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000248 unsigned char work_buf[16];
249 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000250 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200251 size_t use_len, olen = 0;
openluopworld5d5f5202021-11-05 00:13:43 +0800252 uint64_t iv_bits;
Paul Bakker89e80c92012-03-20 13:50:09 +0000253
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100254 GCM_VALIDATE_RET( ctx != NULL );
255 GCM_VALIDATE_RET( iv != NULL );
256 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
257
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200258 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200259 /* IV is not allowed to be zero length */
260 if( iv_len == 0 ||
261 ( (uint64_t) iv_len ) >> 61 != 0 ||
262 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200263 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200265 }
266
Paul Bakker52cf16c2013-07-26 13:55:38 +0200267 memset( ctx->y, 0x00, sizeof(ctx->y) );
268 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
269
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200270 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200271 ctx->len = 0;
272 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000273
274 if( iv_len == 12 )
275 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200276 memcpy( ctx->y, iv, iv_len );
277 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000278 }
279 else
280 {
281 memset( work_buf, 0x00, 16 );
openluopworld5d5f5202021-11-05 00:13:43 +0800282 iv_bits = (uint64_t)iv_len * 8;
283 MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000284
285 p = iv;
286 while( iv_len > 0 )
287 {
288 use_len = ( iv_len < 16 ) ? iv_len : 16;
289
Paul Bakker67f9d532012-10-23 11:49:05 +0000290 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200291 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200292
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200293 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000294
295 iv_len -= use_len;
296 p += use_len;
297 }
298
Paul Bakker67f9d532012-10-23 11:49:05 +0000299 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200300 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000301
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200302 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000303 }
304
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500305 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
306 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200307 {
308 return( ret );
309 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000310
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200311 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000312 p = add;
313 while( add_len > 0 )
314 {
315 use_len = ( add_len < 16 ) ? add_len : 16;
316
Paul Bakker67f9d532012-10-23 11:49:05 +0000317 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200318 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200319
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200320 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000321
322 add_len -= use_len;
323 p += use_len;
324 }
325
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200326 return( 0 );
327}
328
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200330 size_t length,
331 const unsigned char *input,
332 unsigned char *output )
333{
Janos Follath24eed8d2019-11-22 13:21:35 +0000334 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200335 unsigned char ectr[16];
336 size_t i;
337 const unsigned char *p;
338 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200339 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200340
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100341 GCM_VALIDATE_RET( ctx != NULL );
342 GCM_VALIDATE_RET( length == 0 || input != NULL );
343 GCM_VALIDATE_RET( length == 0 || output != NULL );
344
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200345 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200347
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200348 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
349 * Also check for possible overflow */
350 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100351 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200352 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200354 }
355
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200356 ctx->len += length;
357
Paul Bakker89e80c92012-03-20 13:50:09 +0000358 p = input;
359 while( length > 0 )
360 {
361 use_len = ( length < 16 ) ? length : 16;
362
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100363 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200364 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000365 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000366
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200367 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200368 &olen ) ) != 0 )
369 {
370 return( ret );
371 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000372
Paul Bakker67f9d532012-10-23 11:49:05 +0000373 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000374 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200376 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000377 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200379 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000380 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200381
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200382 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200383
Paul Bakker89e80c92012-03-20 13:50:09 +0000384 length -= use_len;
385 p += use_len;
386 out_p += use_len;
387 }
388
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200389 return( 0 );
390}
391
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200393 unsigned char *tag,
394 size_t tag_len )
395{
396 unsigned char work_buf[16];
397 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100398 uint64_t orig_len;
399 uint64_t orig_add_len;
400
401 GCM_VALIDATE_RET( ctx != NULL );
402 GCM_VALIDATE_RET( tag != NULL );
403
404 orig_len = ctx->len * 8;
405 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200406
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200407 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200409
Andres AG821da842016-09-26 10:09:30 +0100410 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200411
Paul Bakker89e80c92012-03-20 13:50:09 +0000412 if( orig_len || orig_add_len )
413 {
414 memset( work_buf, 0x00, 16 );
415
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100416 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
417 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
418 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
419 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000420
Paul Bakker67f9d532012-10-23 11:49:05 +0000421 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200422 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000423
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200424 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000425
Paul Bakker67f9d532012-10-23 11:49:05 +0000426 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200427 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000428 }
429
430 return( 0 );
431}
432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200434 int mode,
435 size_t length,
436 const unsigned char *iv,
437 size_t iv_len,
438 const unsigned char *add,
439 size_t add_len,
440 const unsigned char *input,
441 unsigned char *output,
442 size_t tag_len,
443 unsigned char *tag )
444{
Janos Follath24eed8d2019-11-22 13:21:35 +0000445 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200446
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100447 GCM_VALIDATE_RET( ctx != NULL );
448 GCM_VALIDATE_RET( iv != NULL );
449 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
450 GCM_VALIDATE_RET( length == 0 || input != NULL );
451 GCM_VALIDATE_RET( length == 0 || output != NULL );
452 GCM_VALIDATE_RET( tag != NULL );
453
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200455 return( ret );
456
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200457 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200458 return( ret );
459
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200461 return( ret );
462
463 return( 0 );
464}
465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000467 size_t length,
468 const unsigned char *iv,
469 size_t iv_len,
470 const unsigned char *add,
471 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200472 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000473 size_t tag_len,
474 const unsigned char *input,
475 unsigned char *output )
476{
Janos Follath24eed8d2019-11-22 13:21:35 +0000477 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000478 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200479 size_t i;
480 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000481
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100482 GCM_VALIDATE_RET( ctx != NULL );
483 GCM_VALIDATE_RET( iv != NULL );
484 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
485 GCM_VALIDATE_RET( tag != NULL );
486 GCM_VALIDATE_RET( length == 0 || input != NULL );
487 GCM_VALIDATE_RET( length == 0 || output != NULL );
488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100490 iv, iv_len, add, add_len,
491 input, output, tag_len, check_tag ) ) != 0 )
492 {
493 return( ret );
494 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000495
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200496 /* Check tag in "constant-time" */
497 for( diff = 0, i = 0; i < tag_len; i++ )
498 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000499
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200500 if( diff != 0 )
501 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500502 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200504 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000505
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200506 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000507}
508
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200510{
k-stachowiak21298a22018-12-13 17:11:58 +0100511 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100512 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200513 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500514 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200515}
516
Jaeden Amero15263302017-09-21 12:53:48 +0100517#endif /* !MBEDTLS_GCM_ALT */
518
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000520/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200521 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000522 *
523 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
524 */
525#define MAX_TESTS 6
526
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100527static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000528 { 0, 0, 1, 1, 1, 1 };
529
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100530static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000531{
532 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
535 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
536 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
537 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
538 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200539 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000540};
541
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100542static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000543 { 12, 12, 12, 12, 8, 60 };
544
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100545static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000546 { 0, 0, 1, 1, 1, 2 };
547
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100548static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000549{
550 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551 0x00, 0x00, 0x00, 0x00 },
552 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
553 0xde, 0xca, 0xf8, 0x88 },
554 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200555 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000556 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200557 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000558 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200559 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000560 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200561 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000562};
563
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100564static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000565 { 0, 0, 0, 20, 20, 20 };
566
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100567static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000568 { 0, 0, 0, 1, 1, 1 };
569
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100570static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000571{
572 { 0x00 },
573 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200574 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000575 0xab, 0xad, 0xda, 0xd2 },
576};
577
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100578static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000579 { 0, 16, 64, 60, 60, 60 };
580
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100581static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000582 { 0, 0, 1, 1, 1, 1 };
583
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100584static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000585{
586 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
588 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
589 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
590 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
591 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
592 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
593 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
594 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
595 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
596};
597
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100598static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000599{
600 { 0x00 },
601 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
602 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
603 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200604 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000605 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200606 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000607 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200608 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000609 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
610 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
611 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200612 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200614 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200616 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000617 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
618 0x3d, 0x58, 0xe0, 0x91 },
619 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200620 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000621 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200622 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000623 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200624 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
626 0xc2, 0x3f, 0x45, 0x98 },
627 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200628 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000629 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200630 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000631 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200632 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000633 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
634 0x4c, 0x34, 0xae, 0xe5 },
635 { 0x00 },
636 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200637 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000638 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200639 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000640 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200641 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200643 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000644 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
645 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
646 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200647 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200649 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
650 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
651 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200653 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000654 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000656 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200657 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000658 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200659 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200661 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000662 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200663 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000664 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200665 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000666 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200667 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000668 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200669 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000670 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200671 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
672 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
673 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
674 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
675 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
676 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
677 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
678 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
679 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
680 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
681 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
682 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
683 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
684 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
685 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
686 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
687 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
688 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000689 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200690 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000691 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200692 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000693 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200694 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000695 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200696 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200702 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000703 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200704 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000705};
706
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100707static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000708{
709 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
710 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
711 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
712 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
713 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200714 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000715 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
716 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
717 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
718 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
719 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
720 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
721 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
722 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
723 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200724 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000725 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
726 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
727 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200728 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000729 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200730 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000731 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200732 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000733 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200734 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000735 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200736 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000737 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200738 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000739 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200740 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000741 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200742 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000743 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200744 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000745};
746
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200747int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000748{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000750 unsigned char buf[64];
751 unsigned char tag_buf[16];
752 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200753 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000754
755 for( j = 0; j < 3; j++ )
756 {
757 int key_len = 128 + 64 * j;
758
759 for( i = 0; i < MAX_TESTS; i++ )
760 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100761 mbedtls_gcm_init( &ctx );
762
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200763 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200764 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100765 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200766
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500767 ret = mbedtls_gcm_setkey( &ctx, cipher,
768 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100769 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100770 /*
771 * AES-192 is an optional feature that may be unavailable when
772 * there is an alternative underlying implementation i.e. when
773 * MBEDTLS_AES_ALT is defined.
774 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300775 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100776 {
777 mbedtls_printf( "skipped\n" );
778 break;
779 }
780 else if( ret != 0 )
781 {
782 goto exit;
783 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000784
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200785 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500786 pt_len_test_data[i],
787 iv_test_data[iv_index_test_data[i]],
788 iv_len_test_data[i],
789 additional_test_data[add_index_test_data[i]],
790 add_len_test_data[i],
791 pt_test_data[pt_index_test_data[i]],
792 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100793#if defined(MBEDTLS_GCM_ALT)
794 /* Allow alternative implementations to only support 12-byte nonces. */
795 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
796 iv_len_test_data[i] != 12 )
797 {
798 mbedtls_printf( "skipped\n" );
799 break;
800 }
801#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100802 if( ret != 0 )
803 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000804
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500805 if ( memcmp( buf, ct_test_data[j * 6 + i],
806 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100807 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000808 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100809 ret = 1;
810 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000811 }
812
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200814
Paul Bakker89e80c92012-03-20 13:50:09 +0000815 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200816 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000817
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100818 mbedtls_gcm_init( &ctx );
819
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200820 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200821 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100822 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200823
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500824 ret = mbedtls_gcm_setkey( &ctx, cipher,
825 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100826 key_len );
827 if( ret != 0 )
828 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000829
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200830 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500831 pt_len_test_data[i],
832 iv_test_data[iv_index_test_data[i]],
833 iv_len_test_data[i],
834 additional_test_data[add_index_test_data[i]],
835 add_len_test_data[i],
836 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000837
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100838 if( ret != 0 )
839 goto exit;
840
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100841 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
842 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100843 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000844 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100845 ret = 1;
846 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000847 }
848
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200850
Paul Bakker89e80c92012-03-20 13:50:09 +0000851 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200853
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100854 mbedtls_gcm_init( &ctx );
855
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200856 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100858 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200859
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500860 ret = mbedtls_gcm_setkey( &ctx, cipher,
861 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100862 key_len );
863 if( ret != 0 )
864 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200865
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500867 iv_test_data[iv_index_test_data[i]],
868 iv_len_test_data[i],
869 additional_test_data[add_index_test_data[i]],
870 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200871 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100872 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200873
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100874 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200875 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100876 size_t rest_len = pt_len_test_data[i] - 32;
877 ret = mbedtls_gcm_update( &ctx, 32,
878 pt_test_data[pt_index_test_data[i]],
879 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200880 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100881 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200882
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100883 ret = mbedtls_gcm_update( &ctx, rest_len,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500884 pt_test_data[pt_index_test_data[i]] + 32,
885 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200886 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100887 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200888 }
889 else
890 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100891 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500892 pt_test_data[pt_index_test_data[i]],
893 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200894 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100895 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200896 }
897
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200898 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100899 if( ret != 0 )
900 goto exit;
901
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 Bakkerb9d3cfa2013-06-26 15:07:16 +0200905 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100906 ret = 1;
907 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200908 }
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 Bakkerb9d3cfa2013-06-26 15:07:16 +0200912 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200914
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 split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100919 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200920
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100921 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 Bakkerb9d3cfa2013-06-26 15:07:16 +0200926
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100928 iv_test_data[iv_index_test_data[i]],
929 iv_len_test_data[i],
930 additional_test_data[add_index_test_data[i]],
931 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200932 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100933 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200934
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100935 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200936 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100937 size_t rest_len = pt_len_test_data[i] - 32;
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500938 ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
939 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200940 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100941 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200942
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500943 ret = mbedtls_gcm_update( &ctx, rest_len,
944 ct_test_data[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100945 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200946 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100947 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200948 }
949 else
950 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100951 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
952 ct_test_data[j * 6 + i],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100953 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200954 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100955 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200956 }
957
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100959 if( ret != 0 )
960 goto exit;
961
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100962 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
963 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100964 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200965 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100966 ret = 1;
967 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200968 }
969
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200970 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200971
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200972 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200973 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000974 }
975 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200976
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200977 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200978 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000979
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100980 ret = 0;
981
982exit:
983 if( ret != 0 )
984 {
985 if( verbose != 0 )
986 mbedtls_printf( "failed\n" );
987 mbedtls_gcm_free( &ctx );
988 }
989
990 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000991}
992
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +0000994
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995#endif /* MBEDTLS_GCM_C */