blob: b3105d80d6a158d29cdd8495d8e4faa3385c0d77 [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker89e80c92012-03-20 13:50:09 +000018 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010019
Paul Bakker89e80c92012-03-20 13:50:09 +000020/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010021 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
22 *
23 * See also:
24 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
25 *
26 * We use the algorithm described as Shoup's method with 4-bit tables in
27 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000028 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010029
Gilles Peskinedb09ef62020-06-03 01:43:33 +020030#include "common.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000033
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/gcm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050035#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000036#include "mbedtls/error.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000041#include "aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010042#endif
43
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010045#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030047#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000048#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#define mbedtls_printf printf
50#endif /* MBEDTLS_PLATFORM_C */
51#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Jaeden Amero15263302017-09-21 12:53:48 +010053#if !defined(MBEDTLS_GCM_ALT)
54
k-stachowiak8ffc92a2018-12-12 14:21:59 +010055/* Parameter validation macros */
56#define GCM_VALIDATE_RET( cond ) \
57 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
58#define GCM_VALIDATE( cond ) \
59 MBEDTLS_INTERNAL_VALIDATE( cond )
60
Paul Bakker89e80c92012-03-20 13:50:09 +000061/*
62 * 32-bit integer manipulation macros (big endian)
63 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000064#ifndef GET_UINT32_BE
65#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000066{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000067 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
68 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
69 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
70 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000071}
72#endif
73
Paul Bakker5c2364c2012-10-01 14:41:15 +000074#ifndef PUT_UINT32_BE
75#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000076{ \
77 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
78 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
79 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
80 (b)[(i) + 3] = (unsigned char) ( (n) ); \
81}
82#endif
83
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010084/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020085 * Initialize a context
86 */
87void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
88{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010089 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020090 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
91}
92
93/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010094 * Precompute small multiples of H, that is set
95 * HH[i] || HL[i] = H times i,
96 * where i is seen as a field element as in [MGV], ie high-order bits
97 * correspond to low powers of P. The result is stored in the same way, that
98 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
99 * corresponds to P^127.
100 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200101static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000102{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200103 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000104 uint64_t hi, lo;
105 uint64_t vl, vh;
106 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200107 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200108
Paul Bakker89e80c92012-03-20 13:50:09 +0000109 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200111 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000112
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100113 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000114 GET_UINT32_BE( hi, h, 0 );
115 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000116 vh = (uint64_t) hi << 32 | lo;
117
Paul Bakker5c2364c2012-10-01 14:41:15 +0000118 GET_UINT32_BE( hi, h, 8 );
119 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000120 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200121
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100122 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000123 ctx->HL[8] = vl;
124 ctx->HH[8] = vh;
125
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200126#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100127 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100128 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100129 return( 0 );
130#endif
131
132 /* 0 corresponds to 0 in GF(2^128) */
133 ctx->HH[0] = 0;
134 ctx->HL[0] = 0;
135
Paul Bakker89e80c92012-03-20 13:50:09 +0000136 for( i = 4; i > 0; i >>= 1 )
137 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200138 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000139 vl = ( vh << 63 ) | ( vl >> 1 );
140 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
141
142 ctx->HL[i] = vl;
143 ctx->HH[i] = vh;
144 }
145
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000146 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000147 {
148 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
149 vh = *HiH;
150 vl = *HiL;
151 for( j = 1; j < i; j++ )
152 {
153 HiH[j] = vh ^ ctx->HH[j];
154 HiL[j] = vl ^ ctx->HL[j];
155 }
156 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200157
158 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000159}
160
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200161int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
162 mbedtls_cipher_id_t cipher,
163 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200164 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000165{
Janos Follath24eed8d2019-11-22 13:21:35 +0000166 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000168
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100169 GCM_VALIDATE_RET( ctx != NULL );
170 GCM_VALIDATE_RET( key != NULL );
171 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
172
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500173 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
174 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200175 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200176 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200177
Paul Bakkera0558e02013-09-10 14:25:51 +0200178 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200179 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200180
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200181 mbedtls_cipher_free( &ctx->cipher_ctx );
182
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200183 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000184 return( ret );
185
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200186 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200188 {
189 return( ret );
190 }
191
192 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
193 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000194
195 return( 0 );
196}
197
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100198/*
199 * Shoup's method for multiplication use this table with
200 * last4[x] = x times P^128
201 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
202 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000203static const uint64_t last4[16] =
204{
205 0x0000, 0x1c20, 0x3840, 0x2460,
206 0x7080, 0x6ca0, 0x48c0, 0x54e0,
207 0xe100, 0xfd20, 0xd940, 0xc560,
208 0x9180, 0x8da0, 0xa9c0, 0xb5e0
209};
210
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100211/*
212 * Sets output to x times H using the precomputed tables.
213 * x and output are seen as elements of GF(2^128) as in [MGV].
214 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200216 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000217{
218 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000219 unsigned char lo, hi, rem;
220 uint64_t zh, zl;
221
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200222#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100223 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100224 unsigned char h[16];
225
226 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
227 PUT_UINT32_BE( ctx->HH[8], h, 4 );
228 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
229 PUT_UINT32_BE( ctx->HL[8], h, 12 );
230
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200231 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100232 return;
233 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100235
Paul Bakker89e80c92012-03-20 13:50:09 +0000236 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000237
238 zh = ctx->HH[lo];
239 zl = ctx->HL[lo];
240
241 for( i = 15; i >= 0; i-- )
242 {
243 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200244 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000245
246 if( i != 15 )
247 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000248 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000249 zl = ( zh << 60 ) | ( zl >> 4 );
250 zh = ( zh >> 4 );
251 zh ^= (uint64_t) last4[rem] << 48;
252 zh ^= ctx->HH[lo];
253 zl ^= ctx->HL[lo];
254
255 }
256
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000257 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000258 zl = ( zh << 60 ) | ( zl >> 4 );
259 zh = ( zh >> 4 );
260 zh ^= (uint64_t) last4[rem] << 48;
261 zh ^= ctx->HH[hi];
262 zl ^= ctx->HL[hi];
263 }
264
Paul Bakker5c2364c2012-10-01 14:41:15 +0000265 PUT_UINT32_BE( zh >> 32, output, 0 );
266 PUT_UINT32_BE( zh, output, 4 );
267 PUT_UINT32_BE( zl >> 32, output, 8 );
268 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000269}
270
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200271int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200272 int mode,
273 const unsigned char *iv,
274 size_t iv_len,
275 const unsigned char *add,
276 size_t add_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000277{
Janos Follath24eed8d2019-11-22 13:21:35 +0000278 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000279 unsigned char work_buf[16];
280 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000281 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200282 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000283
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100284 GCM_VALIDATE_RET( ctx != NULL );
285 GCM_VALIDATE_RET( iv != NULL );
286 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
287
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200288 /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200289 /* IV is not allowed to be zero length */
290 if( iv_len == 0 ||
291 ( (uint64_t) iv_len ) >> 61 != 0 ||
292 ( (uint64_t) add_len ) >> 61 != 0 )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200293 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200295 }
296
Paul Bakker52cf16c2013-07-26 13:55:38 +0200297 memset( ctx->y, 0x00, sizeof(ctx->y) );
298 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
299
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200300 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200301 ctx->len = 0;
302 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000303
304 if( iv_len == 12 )
305 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200306 memcpy( ctx->y, iv, iv_len );
307 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000308 }
309 else
310 {
311 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000312 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000313
314 p = iv;
315 while( iv_len > 0 )
316 {
317 use_len = ( iv_len < 16 ) ? iv_len : 16;
318
Paul Bakker67f9d532012-10-23 11:49:05 +0000319 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200320 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200321
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200322 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000323
324 iv_len -= use_len;
325 p += use_len;
326 }
327
Paul Bakker67f9d532012-10-23 11:49:05 +0000328 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200329 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000330
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200331 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000332 }
333
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500334 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
335 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200336 {
337 return( ret );
338 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000339
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200340 ctx->add_len = add_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000341 p = add;
342 while( add_len > 0 )
343 {
344 use_len = ( add_len < 16 ) ? add_len : 16;
345
Paul Bakker67f9d532012-10-23 11:49:05 +0000346 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200347 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200348
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200349 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000350
351 add_len -= use_len;
352 p += use_len;
353 }
354
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200355 return( 0 );
356}
357
Gilles Peskine58fc2722021-04-13 15:58:27 +0200358/* Increment the counter. */
359static void gcm_incr( unsigned char y[16] )
360{
361 size_t i;
362 for( i = 16; i > 12; i-- )
363 if( ++y[i - 1] != 0 )
364 break;
365}
366
367/* Calculate and apply the encryption mask. Process use_len bytes of data,
368 * starting at position offset in the mask block. */
369static int gcm_mask( mbedtls_gcm_context *ctx,
370 unsigned char ectr[16],
371 size_t offset, size_t use_len,
372 const unsigned char *input,
373 unsigned char *output )
374{
375 size_t i;
376 size_t olen = 0;
377 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
378
379 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
380 &olen ) ) != 0 )
381 {
382 mbedtls_platform_zeroize( ectr, 16 );
383 return( ret );
384 }
385
386 for( i = 0; i < use_len; i++ )
387 {
388 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
389 ctx->buf[offset + i] ^= input[i];
390 output[i] = ectr[offset + i] ^ input[i];
391 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
392 ctx->buf[offset + i] ^= output[i];
393 }
394 return( 0 );
395}
396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200398 size_t length,
399 const unsigned char *input,
400 unsigned char *output )
401{
Janos Follath24eed8d2019-11-22 13:21:35 +0000402 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200403 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200404 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200405 size_t offset;
406 unsigned char ectr[16];
407
408 /* Exit early if length==0 so that we don't do any pointer arithmetic on
409 * a potentially null pointer. */
410 if( length == 0 )
411 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200412
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100413 GCM_VALIDATE_RET( ctx != NULL );
Gilles Peskine58fc2722021-04-13 15:58:27 +0200414 GCM_VALIDATE_RET( input != NULL );
415 GCM_VALIDATE_RET( output != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100416
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200417 if( output > input && (size_t) ( output - input ) < length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200419
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200420 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
421 * Also check for possible overflow */
422 if( ctx->len + length < ctx->len ||
Manuel Pégourié-Gonnard1e075622015-12-10 14:46:25 +0100423 (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200424 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200426 }
427
Gilles Peskine58fc2722021-04-13 15:58:27 +0200428 offset = ctx->len % 16;
429 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000430 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200431 size_t use_len = 16 - offset;
432 if( use_len > length )
433 use_len = length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000434
Gilles Peskine58fc2722021-04-13 15:58:27 +0200435 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200436 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000437
Gilles Peskine58fc2722021-04-13 15:58:27 +0200438 if( offset + use_len == 16 )
439 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200440
Gilles Peskine58fc2722021-04-13 15:58:27 +0200441 ctx->len += use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000442 length -= use_len;
443 p += use_len;
444 out_p += use_len;
445 }
446
Gilles Peskine58fc2722021-04-13 15:58:27 +0200447 ctx->len += length;
448
449 while( length >= 16 )
450 {
451 gcm_incr( ctx->y );
452 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
453 return( ret );
454
455 gcm_mult( ctx, ctx->buf, ctx->buf );
456
457 length -= 16;
458 p += 16;
459 out_p += 16;
460 }
461
462 if( length > 0 )
463 {
464 gcm_incr( ctx->y );
465 if( ( ret = gcm_mask( ctx, ectr, 0, length, p, out_p ) ) != 0 )
466 return( ret );
467 }
468
469 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200470 return( 0 );
471}
472
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200474 unsigned char *tag,
475 size_t tag_len )
476{
477 unsigned char work_buf[16];
478 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100479 uint64_t orig_len;
480 uint64_t orig_add_len;
481
482 GCM_VALIDATE_RET( ctx != NULL );
483 GCM_VALIDATE_RET( tag != NULL );
484
485 orig_len = ctx->len * 8;
486 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200487
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200488 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200490
Gilles Peskine58fc2722021-04-13 15:58:27 +0200491 if( ctx->len % 16 != 0 )
492 gcm_mult( ctx, ctx->buf, ctx->buf );
493
Andres AG821da842016-09-26 10:09:30 +0100494 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200495
Paul Bakker89e80c92012-03-20 13:50:09 +0000496 if( orig_len || orig_add_len )
497 {
498 memset( work_buf, 0x00, 16 );
499
Paul Bakker0ecdb232013-04-09 11:36:42 +0200500 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
501 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
502 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
503 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000504
Paul Bakker67f9d532012-10-23 11:49:05 +0000505 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200506 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000507
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200508 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000509
Paul Bakker67f9d532012-10-23 11:49:05 +0000510 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200511 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000512 }
513
514 return( 0 );
515}
516
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200517int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200518 int mode,
519 size_t length,
520 const unsigned char *iv,
521 size_t iv_len,
522 const unsigned char *add,
523 size_t add_len,
524 const unsigned char *input,
525 unsigned char *output,
526 size_t tag_len,
527 unsigned char *tag )
528{
Janos Follath24eed8d2019-11-22 13:21:35 +0000529 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200530
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100531 GCM_VALIDATE_RET( ctx != NULL );
532 GCM_VALIDATE_RET( iv != NULL );
533 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
534 GCM_VALIDATE_RET( length == 0 || input != NULL );
535 GCM_VALIDATE_RET( length == 0 || output != NULL );
536 GCM_VALIDATE_RET( tag != NULL );
537
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200538 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200539 return( ret );
540
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200541 if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200542 return( ret );
543
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200544 if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200545 return( ret );
546
547 return( 0 );
548}
549
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200550int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000551 size_t length,
552 const unsigned char *iv,
553 size_t iv_len,
554 const unsigned char *add,
555 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200556 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000557 size_t tag_len,
558 const unsigned char *input,
559 unsigned char *output )
560{
Janos Follath24eed8d2019-11-22 13:21:35 +0000561 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000562 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200563 size_t i;
564 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000565
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100566 GCM_VALIDATE_RET( ctx != NULL );
567 GCM_VALIDATE_RET( iv != NULL );
568 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
569 GCM_VALIDATE_RET( tag != NULL );
570 GCM_VALIDATE_RET( length == 0 || input != NULL );
571 GCM_VALIDATE_RET( length == 0 || output != NULL );
572
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100574 iv, iv_len, add, add_len,
575 input, output, tag_len, check_tag ) ) != 0 )
576 {
577 return( ret );
578 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000579
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200580 /* Check tag in "constant-time" */
581 for( diff = 0, i = 0; i < tag_len; i++ )
582 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000583
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200584 if( diff != 0 )
585 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500586 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200588 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000589
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200590 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000591}
592
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200594{
k-stachowiak21298a22018-12-13 17:11:58 +0100595 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100596 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500598 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200599}
600
Jaeden Amero15263302017-09-21 12:53:48 +0100601#endif /* !MBEDTLS_GCM_ALT */
602
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200603#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000604/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200605 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000606 *
607 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
608 */
609#define MAX_TESTS 6
610
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100611static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000612 { 0, 0, 1, 1, 1, 1 };
613
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100614static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000615{
616 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
620 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
621 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
622 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200623 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000624};
625
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100626static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000627 { 12, 12, 12, 12, 8, 60 };
628
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100629static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000630 { 0, 0, 1, 1, 1, 2 };
631
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100632static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000633{
634 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00 },
636 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
637 0xde, 0xca, 0xf8, 0x88 },
638 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200639 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000640 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200641 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000642 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200643 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000644 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200645 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000646};
647
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100648static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000649 { 0, 0, 0, 20, 20, 20 };
650
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100651static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000652 { 0, 0, 0, 1, 1, 1 };
653
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100654static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000655{
656 { 0x00 },
657 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200658 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000659 0xab, 0xad, 0xda, 0xd2 },
660};
661
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100662static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000663 { 0, 16, 64, 60, 60, 60 };
664
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100665static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000666 { 0, 0, 1, 1, 1, 1 };
667
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100668static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000669{
670 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
672 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
673 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
674 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
675 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
676 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
677 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
678 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
679 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
680};
681
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100682static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000683{
684 { 0x00 },
685 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
686 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
687 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200688 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000689 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200690 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000691 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200692 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000693 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
694 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
695 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200696 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
702 0x3d, 0x58, 0xe0, 0x91 },
703 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200704 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000705 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200706 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000707 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200708 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000709 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
710 0xc2, 0x3f, 0x45, 0x98 },
711 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200712 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000713 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200714 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000715 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200716 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000717 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
718 0x4c, 0x34, 0xae, 0xe5 },
719 { 0x00 },
720 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200721 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000722 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200723 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000724 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200725 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000726 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200727 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000728 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
729 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
730 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200731 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000732 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200733 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
734 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
735 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000736 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200737 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000738 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200739 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000740 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200741 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000742 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200743 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000744 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200745 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000746 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200747 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000748 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200749 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000750 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200751 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000752 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200753 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000754 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200755 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
756 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
757 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
758 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
759 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
760 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
761 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
762 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
763 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
764 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
765 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
766 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
767 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
768 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
769 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
770 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
771 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
772 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000773 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200774 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000775 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200776 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000777 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200778 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000779 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200780 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000781 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200782 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000783 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200784 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000785 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200786 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000787 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200788 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000789};
790
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100791static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000792{
793 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
794 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
795 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
796 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
797 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200798 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000799 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
800 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
801 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
802 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
803 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
804 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
805 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
806 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
807 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200808 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000809 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
810 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
811 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200812 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000813 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200814 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000815 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200816 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000817 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200818 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000819 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200820 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000821 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200822 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000823 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200824 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000825 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200826 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000827 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200828 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000829};
830
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200831int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000832{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200833 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000834 unsigned char buf[64];
835 unsigned char tag_buf[16];
836 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Paul Bakker89e80c92012-03-20 13:50:09 +0000838
839 for( j = 0; j < 3; j++ )
840 {
841 int key_len = 128 + 64 * j;
842
843 for( i = 0; i < MAX_TESTS; i++ )
844 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100845 mbedtls_gcm_init( &ctx );
846
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200847 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200848 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100849 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200850
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500851 ret = mbedtls_gcm_setkey( &ctx, cipher,
852 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100853 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100854 /*
855 * AES-192 is an optional feature that may be unavailable when
856 * there is an alternative underlying implementation i.e. when
857 * MBEDTLS_AES_ALT is defined.
858 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300859 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100860 {
861 mbedtls_printf( "skipped\n" );
862 break;
863 }
864 else if( ret != 0 )
865 {
866 goto exit;
867 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000868
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500870 pt_len_test_data[i],
871 iv_test_data[iv_index_test_data[i]],
872 iv_len_test_data[i],
873 additional_test_data[add_index_test_data[i]],
874 add_len_test_data[i],
875 pt_test_data[pt_index_test_data[i]],
876 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100877#if defined(MBEDTLS_GCM_ALT)
878 /* Allow alternative implementations to only support 12-byte nonces. */
879 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
880 iv_len_test_data[i] != 12 )
881 {
882 mbedtls_printf( "skipped\n" );
883 break;
884 }
885#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100886 if( ret != 0 )
887 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000888
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500889 if ( memcmp( buf, ct_test_data[j * 6 + i],
890 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100891 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000892 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100893 ret = 1;
894 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000895 }
896
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200897 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200898
Paul Bakker89e80c92012-03-20 13:50:09 +0000899 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000901
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100902 mbedtls_gcm_init( &ctx );
903
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200904 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200905 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100906 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200907
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500908 ret = mbedtls_gcm_setkey( &ctx, cipher,
909 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100910 key_len );
911 if( ret != 0 )
912 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000913
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500915 pt_len_test_data[i],
916 iv_test_data[iv_index_test_data[i]],
917 iv_len_test_data[i],
918 additional_test_data[add_index_test_data[i]],
919 add_len_test_data[i],
920 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000921
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100922 if( ret != 0 )
923 goto exit;
924
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100925 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
926 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100927 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000928 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100929 ret = 1;
930 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000931 }
932
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200934
Paul Bakker89e80c92012-03-20 13:50:09 +0000935 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200937
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100938 mbedtls_gcm_init( &ctx );
939
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200940 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100942 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200943
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500944 ret = mbedtls_gcm_setkey( &ctx, cipher,
945 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100946 key_len );
947 if( ret != 0 )
948 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200949
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500951 iv_test_data[iv_index_test_data[i]],
952 iv_len_test_data[i],
953 additional_test_data[add_index_test_data[i]],
954 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200955 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100956 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200957
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100958 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200959 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100960 size_t rest_len = pt_len_test_data[i] - 32;
961 ret = mbedtls_gcm_update( &ctx, 32,
962 pt_test_data[pt_index_test_data[i]],
963 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200964 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100965 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200966
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100967 ret = mbedtls_gcm_update( &ctx, rest_len,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500968 pt_test_data[pt_index_test_data[i]] + 32,
969 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200970 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100971 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200972 }
973 else
974 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100975 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500976 pt_test_data[pt_index_test_data[i]],
977 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200978 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100979 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200980 }
981
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200982 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100983 if( ret != 0 )
984 goto exit;
985
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500986 if( memcmp( buf, ct_test_data[j * 6 + i],
987 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100988 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200989 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100990 ret = 1;
991 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200992 }
993
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200994 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200995
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200996 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200997 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200998
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100999 mbedtls_gcm_init( &ctx );
1000
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001001 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001003 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001004
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001005 ret = mbedtls_gcm_setkey( &ctx, cipher,
1006 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001007 key_len );
1008 if( ret != 0 )
1009 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001010
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001011 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001012 iv_test_data[iv_index_test_data[i]],
1013 iv_len_test_data[i],
1014 additional_test_data[add_index_test_data[i]],
1015 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001016 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001017 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001018
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001019 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001020 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001021 size_t rest_len = pt_len_test_data[i] - 32;
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001022 ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
1023 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001024 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001025 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001026
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001027 ret = mbedtls_gcm_update( &ctx, rest_len,
1028 ct_test_data[j * 6 + i] + 32,
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001029 buf + 32 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001030 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001031 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001032 }
1033 else
1034 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001035 ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
1036 ct_test_data[j * 6 + i],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001037 buf );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001038 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001039 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001040 }
1041
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001042 ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001043 if( ret != 0 )
1044 goto exit;
1045
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001046 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1047 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001048 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001049 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001050 ret = 1;
1051 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001052 }
1053
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001054 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001055
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001056 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001057 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001058 }
1059 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001060
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001061 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001063
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001064 ret = 0;
1065
1066exit:
1067 if( ret != 0 )
1068 {
1069 if( verbose != 0 )
1070 mbedtls_printf( "failed\n" );
1071 mbedtls_gcm_free( &ctx );
1072 }
1073
1074 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001075}
1076
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001078
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001079#endif /* MBEDTLS_GCM_C */