blob: 948268ca5d1e2c9be591f1e45c89c6fb453cd3e9 [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"
Ron Eldor9924bdc2018-10-04 10:59:13 +030047#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000048#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#define mbedtls_printf printf
50#endif /* MBEDTLS_PLATFORM_C */
51#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Jaeden Amero15263302017-09-21 12:53:48 +010053#if !defined(MBEDTLS_GCM_ALT)
54
k-stachowiak8ffc92a2018-12-12 14:21:59 +010055/* Parameter validation macros */
56#define GCM_VALIDATE_RET( cond ) \
57 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
58#define GCM_VALIDATE( cond ) \
59 MBEDTLS_INTERNAL_VALIDATE( cond )
60
Paul Bakker89e80c92012-03-20 13:50:09 +000061/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020062 * Initialize a context
63 */
64void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
65{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010066 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020067 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
68}
69
70/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010071 * Precompute small multiples of H, that is set
72 * HH[i] || HL[i] = H times i,
73 * where i is seen as a field element as in [MGV], ie high-order bits
74 * correspond to low powers of P. The result is stored in the same way, that
75 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
76 * corresponds to P^127.
77 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000079{
Paul Bakker43aff2a2013-09-09 00:10:27 +020080 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000081 uint64_t hi, lo;
82 uint64_t vl, vh;
83 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020084 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020085
Paul Bakker89e80c92012-03-20 13:50:09 +000086 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020087 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +020088 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000089
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010090 /* pack h as two 64-bits ints, big-endian */
Joe Subbiani9231d5f2021-07-07 16:56:29 +010091 hi = MBEDTLS_GET_UINT32_BE( h, 0 );
92 lo = MBEDTLS_GET_UINT32_BE( h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000093 vh = (uint64_t) hi << 32 | lo;
94
Joe Subbiani9231d5f2021-07-07 16:56:29 +010095 hi = MBEDTLS_GET_UINT32_BE( h, 8 );
96 lo = MBEDTLS_GET_UINT32_BE( h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000097 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020098
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010099 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000100 ctx->HL[8] = vl;
101 ctx->HH[8] = vh;
102
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100104 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100105 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100106 return( 0 );
107#endif
108
109 /* 0 corresponds to 0 in GF(2^128) */
110 ctx->HH[0] = 0;
111 ctx->HL[0] = 0;
112
Paul Bakker89e80c92012-03-20 13:50:09 +0000113 for( i = 4; i > 0; i >>= 1 )
114 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200115 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000116 vl = ( vh << 63 ) | ( vl >> 1 );
117 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
118
119 ctx->HL[i] = vl;
120 ctx->HH[i] = vh;
121 }
122
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000123 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000124 {
125 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
126 vh = *HiH;
127 vl = *HiL;
128 for( j = 1; j < i; j++ )
129 {
130 HiH[j] = vh ^ ctx->HH[j];
131 HiL[j] = vl ^ ctx->HL[j];
132 }
133 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200134
135 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000136}
137
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200138int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
139 mbedtls_cipher_id_t cipher,
140 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200141 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000142{
Janos Follath24eed8d2019-11-22 13:21:35 +0000143 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200144 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000145
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100146 GCM_VALIDATE_RET( ctx != NULL );
147 GCM_VALIDATE_RET( key != NULL );
148 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
149
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500150 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
151 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200152 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200153 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200154
Paul Bakkera0558e02013-09-10 14:25:51 +0200155 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200157
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200158 mbedtls_cipher_free( &ctx->cipher_ctx );
159
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200160 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000161 return( ret );
162
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200163 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200164 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200165 {
166 return( ret );
167 }
168
169 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
170 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000171
172 return( 0 );
173}
174
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100175/*
176 * Shoup's method for multiplication use this table with
177 * last4[x] = x times P^128
178 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
179 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000180static const uint64_t last4[16] =
181{
182 0x0000, 0x1c20, 0x3840, 0x2460,
183 0x7080, 0x6ca0, 0x48c0, 0x54e0,
184 0xe100, 0xfd20, 0xd940, 0xc560,
185 0x9180, 0x8da0, 0xa9c0, 0xb5e0
186};
187
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100188/*
189 * Sets output to x times H using the precomputed tables.
190 * x and output are seen as elements of GF(2^128) as in [MGV].
191 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200193 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000194{
195 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000196 unsigned char lo, hi, rem;
197 uint64_t zh, zl;
198
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200199#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100200 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100201 unsigned char h[16];
202
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100203 MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
204 MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 );
205 MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
206 MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100207
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100209 return;
210 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100212
Paul Bakker89e80c92012-03-20 13:50:09 +0000213 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000214
215 zh = ctx->HH[lo];
216 zl = ctx->HL[lo];
217
218 for( i = 15; i >= 0; i-- )
219 {
220 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200221 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000222
223 if( i != 15 )
224 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000225 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000226 zl = ( zh << 60 ) | ( zl >> 4 );
227 zh = ( zh >> 4 );
228 zh ^= (uint64_t) last4[rem] << 48;
229 zh ^= ctx->HH[lo];
230 zl ^= ctx->HL[lo];
231
232 }
233
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000234 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000235 zl = ( zh << 60 ) | ( zl >> 4 );
236 zh = ( zh >> 4 );
237 zh ^= (uint64_t) last4[rem] << 48;
238 zh ^= ctx->HH[hi];
239 zl ^= ctx->HL[hi];
240 }
241
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100242 MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
243 MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
244 MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
245 MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000246}
247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200249 int mode,
250 const unsigned char *iv,
251 size_t iv_len,
252 const unsigned char *add,
253 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000254{
Janos Follath24eed8d2019-11-22 13:21:35 +0000255 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000256 unsigned char work_buf[16];
257 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000258 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200259 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000260
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100261 GCM_VALIDATE_RET( ctx != NULL );
262 GCM_VALIDATE_RET( iv != NULL );
263 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
264
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200265 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200266 /* IV is not allowed to be zero length */
267 if( iv_len == 0 ||
268 ( (uint64_t) iv_len ) >> 61 != 0 ||
269 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200270 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200271 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200272 }
273
Paul Bakker52cf16c2013-07-26 13:55:38 +0200274 memset( ctx->y, 0x00, sizeof(ctx->y) );
275 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
276
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200277 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200278 ctx->len = 0;
279 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000280
281 if( iv_len == 12 )
282 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200283 memcpy( ctx->y, iv, iv_len );
284 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000285 }
286 else
287 {
288 memset( work_buf, 0x00, 16 );
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100289 MBEDTLS_PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000290
291 p = iv;
292 while( iv_len > 0 )
293 {
294 use_len = ( iv_len < 16 ) ? iv_len : 16;
295
Paul Bakker67f9d532012-10-23 11:49:05 +0000296 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200297 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200298
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200299 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000300
301 iv_len -= use_len;
302 p += use_len;
303 }
304
Paul Bakker67f9d532012-10-23 11:49:05 +0000305 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200306 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000307
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200308 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000309 }
310
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500311 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
312 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200313 {
314 return( ret );
315 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000316
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200317 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000318 p = add;
319 while( add_len > 0 )
320 {
321 use_len = ( add_len < 16 ) ? add_len : 16;
322
Paul Bakker67f9d532012-10-23 11:49:05 +0000323 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200324 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200325
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200326 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000327
328 add_len -= use_len;
329 p += use_len;
330 }
331
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200332 return( 0 );
333}
334
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200336 size_t length,
337 const unsigned char *input,
338 unsigned char *output )
339{
Janos Follath24eed8d2019-11-22 13:21:35 +0000340 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200341 unsigned char ectr[16];
342 size_t i;
343 const unsigned char *p;
344 unsigned char *out_p = output;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200345 size_t use_len, olen = 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200346
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100347 GCM_VALIDATE_RET( ctx != NULL );
348 GCM_VALIDATE_RET( length == 0 || input != NULL );
349 GCM_VALIDATE_RET( length == 0 || output != NULL );
350
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200351 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200353
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200354 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
355 * Also check for possible overflow */
356 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100357 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200358 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200360 }
361
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200362 ctx->len += length;
363
Paul Bakker89e80c92012-03-20 13:50:09 +0000364 p = input;
365 while( length > 0 )
366 {
367 use_len = ( length < 16 ) ? length : 16;
368
Paul Bakker3d2dc0f2013-02-27 14:52:37 +0100369 for( i = 16; i > 12; i-- )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200370 if( ++ctx->y[i - 1] != 0 )
Paul Bakkerfc5183c2012-04-18 14:17:01 +0000371 break;
Paul Bakker89e80c92012-03-20 13:50:09 +0000372
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
Paul Bakker43aff2a2013-09-09 00:10:27 +0200374 &olen ) ) != 0 )
375 {
376 return( ret );
377 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000378
Paul Bakker67f9d532012-10-23 11:49:05 +0000379 for( i = 0; i < use_len; i++ )
Paul Bakker89e80c92012-03-20 13:50:09 +0000380 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200382 ctx->buf[i] ^= p[i];
Paul Bakker67f9d532012-10-23 11:49:05 +0000383 out_p[i] = ectr[i] ^ p[i];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200384 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200385 ctx->buf[i] ^= out_p[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000386 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200387
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200388 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200389
Paul Bakker89e80c92012-03-20 13:50:09 +0000390 length -= use_len;
391 p += use_len;
392 out_p += use_len;
393 }
394
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200395 return( 0 );
396}
397
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200399 unsigned char *tag,
400 size_t tag_len )
401{
402 unsigned char work_buf[16];
403 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100404 uint64_t orig_len;
405 uint64_t orig_add_len;
406
407 GCM_VALIDATE_RET( ctx != NULL );
408 GCM_VALIDATE_RET( tag != NULL );
409
410 orig_len = ctx->len * 8;
411 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200412
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200413 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200415
Andres AG821da842016-09-26 10:09:30 +0100416 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200417
Paul Bakker89e80c92012-03-20 13:50:09 +0000418 if( orig_len || orig_add_len )
419 {
420 memset( work_buf, 0x00, 16 );
421
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100422 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
423 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
424 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
425 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000426
Paul Bakker67f9d532012-10-23 11:49:05 +0000427 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200428 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000429
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200430 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000431
Paul Bakker67f9d532012-10-23 11:49:05 +0000432 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200433 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000434 }
435
436 return( 0 );
437}
438
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200440 int mode,
441 size_t length,
442 const unsigned char *iv,
443 size_t iv_len,
444 const unsigned char *add,
445 size_t add_len,
446 const unsigned char *input,
447 unsigned char *output,
448 size_t tag_len,
449 unsigned char *tag )
450{
Janos Follath24eed8d2019-11-22 13:21:35 +0000451 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200452
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100453 GCM_VALIDATE_RET( ctx != NULL );
454 GCM_VALIDATE_RET( iv != NULL );
455 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
456 GCM_VALIDATE_RET( length == 0 || input != NULL );
457 GCM_VALIDATE_RET( length == 0 || output != NULL );
458 GCM_VALIDATE_RET( tag != NULL );
459
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200461 return( ret );
462
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200463 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200464 return( ret );
465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200467 return( ret );
468
469 return( 0 );
470}
471
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000473 size_t length,
474 const unsigned char *iv,
475 size_t iv_len,
476 const unsigned char *add,
477 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200478 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000479 size_t tag_len,
480 const unsigned char *input,
481 unsigned char *output )
482{
Janos Follath24eed8d2019-11-22 13:21:35 +0000483 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000484 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200485 size_t i;
486 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000487
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100488 GCM_VALIDATE_RET( ctx != NULL );
489 GCM_VALIDATE_RET( iv != NULL );
490 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
491 GCM_VALIDATE_RET( tag != NULL );
492 GCM_VALIDATE_RET( length == 0 || input != NULL );
493 GCM_VALIDATE_RET( length == 0 || output != NULL );
494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100496 iv, iv_len, add, add_len,
497 input, output, tag_len, check_tag ) ) != 0 )
498 {
499 return( ret );
500 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000501
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200502 /* Check tag in "constant-time" */
503 for( diff = 0, i = 0; i < tag_len; i++ )
504 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000505
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200506 if( diff != 0 )
507 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500508 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200510 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000511
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200512 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000513}
514
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200515void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200516{
k-stachowiak21298a22018-12-13 17:11:58 +0100517 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100518 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500520 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200521}
522
Jaeden Amero15263302017-09-21 12:53:48 +0100523#endif /* !MBEDTLS_GCM_ALT */
524
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000526/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200527 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000528 *
529 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
530 */
531#define MAX_TESTS 6
532
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100533static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000534 { 0, 0, 1, 1, 1, 1 };
535
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100536static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000537{
538 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
542 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
543 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
544 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200545 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000546};
547
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100548static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000549 { 12, 12, 12, 12, 8, 60 };
550
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100551static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000552 { 0, 0, 1, 1, 1, 2 };
553
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100554static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000555{
556 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0x00, 0x00, 0x00, 0x00 },
558 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
559 0xde, 0xca, 0xf8, 0x88 },
560 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200561 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000562 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200563 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000564 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200565 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000566 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200567 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000568};
569
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100570static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000571 { 0, 0, 0, 20, 20, 20 };
572
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100573static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000574 { 0, 0, 0, 1, 1, 1 };
575
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100576static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000577{
578 { 0x00 },
579 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200580 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000581 0xab, 0xad, 0xda, 0xd2 },
582};
583
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100584static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000585 { 0, 16, 64, 60, 60, 60 };
586
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100587static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000588 { 0, 0, 1, 1, 1, 1 };
589
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100590static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000591{
592 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
594 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
595 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
596 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
597 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
598 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
599 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
600 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
601 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
602};
603
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100604static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000605{
606 { 0x00 },
607 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
608 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
609 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200610 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000611 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200612 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200614 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000615 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
616 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
617 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200618 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000619 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200620 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000621 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200622 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000623 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
624 0x3d, 0x58, 0xe0, 0x91 },
625 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200626 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000627 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200628 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000629 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200630 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000631 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
632 0xc2, 0x3f, 0x45, 0x98 },
633 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200634 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000635 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200636 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000637 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200638 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000639 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
640 0x4c, 0x34, 0xae, 0xe5 },
641 { 0x00 },
642 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200643 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000644 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200645 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000646 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200647 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000648 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200649 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000650 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
651 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
652 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200653 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000654 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
656 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
657 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000658 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200659 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200661 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000662 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200663 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000664 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200665 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000666 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200667 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000668 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200669 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000670 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200671 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000672 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200673 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000674 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200675 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000676 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200677 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
678 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
679 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
680 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
681 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
682 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
683 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
684 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
685 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
686 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
687 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
688 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
689 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
690 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
691 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
692 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
693 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
694 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000695 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200696 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200702 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000703 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200704 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000705 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200706 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000707 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200708 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000709 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200710 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000711};
712
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100713static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000714{
715 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
716 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
717 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
718 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
719 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200720 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000721 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
722 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
723 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
724 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
725 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
726 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
727 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
728 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
729 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200730 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000731 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
732 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
733 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200734 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000735 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200736 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000737 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200738 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000739 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200740 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000741 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200742 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000743 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200744 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000745 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200746 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000747 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200748 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200750 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000751};
752
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200753int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000754{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200755 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000756 unsigned char buf[64];
757 unsigned char tag_buf[16];
758 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200759 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000760
761 for( j = 0; j < 3; j++ )
762 {
763 int key_len = 128 + 64 * j;
764
765 for( i = 0; i < MAX_TESTS; i++ )
766 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100767 mbedtls_gcm_init( &ctx );
768
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200769 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200770 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100771 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200772
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500773 ret = mbedtls_gcm_setkey( &ctx, cipher,
774 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100775 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100776 /*
777 * AES-192 is an optional feature that may be unavailable when
778 * there is an alternative underlying implementation i.e. when
779 * MBEDTLS_AES_ALT is defined.
780 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300781 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100782 {
783 mbedtls_printf( "skipped\n" );
784 break;
785 }
786 else if( ret != 0 )
787 {
788 goto exit;
789 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000790
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200791 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500792 pt_len_test_data[i],
793 iv_test_data[iv_index_test_data[i]],
794 iv_len_test_data[i],
795 additional_test_data[add_index_test_data[i]],
796 add_len_test_data[i],
797 pt_test_data[pt_index_test_data[i]],
798 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100799#if defined(MBEDTLS_GCM_ALT)
800 /* Allow alternative implementations to only support 12-byte nonces. */
801 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
802 iv_len_test_data[i] != 12 )
803 {
804 mbedtls_printf( "skipped\n" );
805 break;
806 }
807#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100808 if( ret != 0 )
809 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000810
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500811 if ( memcmp( buf, ct_test_data[j * 6 + i],
812 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100813 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000814 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100815 ret = 1;
816 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000817 }
818
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200819 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200820
Paul Bakker89e80c92012-03-20 13:50:09 +0000821 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200822 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000823
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100824 mbedtls_gcm_init( &ctx );
825
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200826 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200827 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100828 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200829
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500830 ret = mbedtls_gcm_setkey( &ctx, cipher,
831 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100832 key_len );
833 if( ret != 0 )
834 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000835
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200836 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500837 pt_len_test_data[i],
838 iv_test_data[iv_index_test_data[i]],
839 iv_len_test_data[i],
840 additional_test_data[add_index_test_data[i]],
841 add_len_test_data[i],
842 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000843
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100844 if( ret != 0 )
845 goto exit;
846
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100847 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
848 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100849 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000850 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100851 ret = 1;
852 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000853 }
854
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200856
Paul Bakker89e80c92012-03-20 13:50:09 +0000857 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200859
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100860 mbedtls_gcm_init( &ctx );
861
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200862 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100864 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200865
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500866 ret = mbedtls_gcm_setkey( &ctx, cipher,
867 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100868 key_len );
869 if( ret != 0 )
870 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200871
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500873 iv_test_data[iv_index_test_data[i]],
874 iv_len_test_data[i],
875 additional_test_data[add_index_test_data[i]],
876 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200877 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100878 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200879
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100880 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200881 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100882 size_t rest_len = pt_len_test_data[i] - 32;
883 ret = mbedtls_gcm_update( &ctx, 32,
884 pt_test_data[pt_index_test_data[i]],
885 buf );
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
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100889 ret = mbedtls_gcm_update( &ctx, rest_len,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500890 pt_test_data[pt_index_test_data[i]] + 32,
891 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200892 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100893 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200894 }
895 else
896 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100897 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500898 pt_test_data[pt_index_test_data[i]],
899 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200900 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100901 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200902 }
903
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100905 if( ret != 0 )
906 goto exit;
907
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500908 if( memcmp( buf, ct_test_data[j * 6 + i],
909 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100910 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200911 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100912 ret = 1;
913 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200914 }
915
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200917
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200918 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200920
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100921 mbedtls_gcm_init( &ctx );
922
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200923 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100925 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200926
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100927 ret = mbedtls_gcm_setkey( &ctx, cipher,
928 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100929 key_len );
930 if( ret != 0 )
931 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200932
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100934 iv_test_data[iv_index_test_data[i]],
935 iv_len_test_data[i],
936 additional_test_data[add_index_test_data[i]],
937 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200938 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100939 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200940
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100941 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200942 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100943 size_t rest_len = pt_len_test_data[i] - 32;
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500944 ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
945 buf );
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
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500949 ret = mbedtls_gcm_update( &ctx, rest_len,
950 ct_test_data[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100951 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200952 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100953 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200954 }
955 else
956 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100957 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
958 ct_test_data[j * 6 + i],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100959 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200960 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100961 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200962 }
963
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200964 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100965 if( ret != 0 )
966 goto exit;
967
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100968 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
969 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100970 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200971 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100972 ret = 1;
973 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200974 }
975
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200977
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200978 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000980 }
981 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200982
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200983 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200984 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000985
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100986 ret = 0;
987
988exit:
989 if( ret != 0 )
990 {
991 if( verbose != 0 )
992 mbedtls_printf( "failed\n" );
993 mbedtls_gcm_free( &ctx );
994 }
995
996 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000997}
998
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001000
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001001#endif /* MBEDTLS_GCM_C */