blob: 23b6ebb2fe06e60bebcc45a770b7d9b371c7bfd7 [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,
Gilles Peskine295fc132021-04-15 18:32:23 +0200272 int mode,
273 const unsigned char *iv, size_t iv_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000274{
Janos Follath24eed8d2019-11-22 13:21:35 +0000275 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000276 unsigned char work_buf[16];
277 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000278 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200279 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000280
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100281 GCM_VALIDATE_RET( ctx != NULL );
282 GCM_VALIDATE_RET( iv != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100283
Gilles Peskine295fc132021-04-15 18:32:23 +0200284 /* IV is are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200285 /* IV is not allowed to be zero length */
Gilles Peskine295fc132021-04-15 18:32:23 +0200286 if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200288
Paul Bakker52cf16c2013-07-26 13:55:38 +0200289 memset( ctx->y, 0x00, sizeof(ctx->y) );
290 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
291
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200292 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200293 ctx->len = 0;
294 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000295
296 if( iv_len == 12 )
297 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200298 memcpy( ctx->y, iv, iv_len );
299 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000300 }
301 else
302 {
303 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000304 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000305
306 p = iv;
307 while( iv_len > 0 )
308 {
309 use_len = ( iv_len < 16 ) ? iv_len : 16;
310
Paul Bakker67f9d532012-10-23 11:49:05 +0000311 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200312 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200313
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200314 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000315
316 iv_len -= use_len;
317 p += use_len;
318 }
319
Paul Bakker67f9d532012-10-23 11:49:05 +0000320 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200321 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000322
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200323 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000324 }
325
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500326 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
327 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200328 {
329 return( ret );
330 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000331
Gilles Peskine295fc132021-04-15 18:32:23 +0200332 return( 0 );
333}
334
335
336int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
337 const unsigned char *add, size_t add_len )
338{
339 const unsigned char *p;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200340 size_t use_len, i, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200341
342 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
343
344 /* IV is are limited to 2^64 bits, so 2^61 bytes */
345 if( (uint64_t) add_len >> 61 != 0 )
346 return( MBEDTLS_ERR_GCM_BAD_INPUT );
347
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200348 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000349 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200350
351 if (offset)
Paul Bakker89e80c92012-03-20 13:50:09 +0000352 {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200353 use_len = 16 - offset;
354 if( use_len > add_len )
355 use_len = add_len;
356
357 for (i = 0; i < use_len; i++)
358 ctx->buf[i+offset] ^= p[i];
359
360 if( offset + use_len == 16 )
361 gcm_mult( ctx, ctx->buf, ctx->buf );
362
363 ctx->add_len += use_len;
364 add_len -= use_len;
365 p += use_len;
366 }
367
368 ctx->add_len += add_len;
369
370 while( add_len >= 16 )
371 {
372 use_len = 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000373
Paul Bakker67f9d532012-10-23 11:49:05 +0000374 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200375 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200376
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200377 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000378
379 add_len -= use_len;
380 p += use_len;
381 }
382
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200383 if ( add_len > 0 )
384 {
385 for( i = 0; i < add_len; i++ )
386 ctx->buf[i] ^= p[i];
387 }
388
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200389 return( 0 );
390}
391
Gilles Peskine58fc2722021-04-13 15:58:27 +0200392/* Increment the counter. */
393static void gcm_incr( unsigned char y[16] )
394{
395 size_t i;
396 for( i = 16; i > 12; i-- )
397 if( ++y[i - 1] != 0 )
398 break;
399}
400
401/* Calculate and apply the encryption mask. Process use_len bytes of data,
402 * starting at position offset in the mask block. */
403static int gcm_mask( mbedtls_gcm_context *ctx,
404 unsigned char ectr[16],
405 size_t offset, size_t use_len,
406 const unsigned char *input,
407 unsigned char *output )
408{
409 size_t i;
410 size_t olen = 0;
411 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
412
413 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
414 &olen ) ) != 0 )
415 {
416 mbedtls_platform_zeroize( ectr, 16 );
417 return( ret );
418 }
419
420 for( i = 0; i < use_len; i++ )
421 {
422 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
423 ctx->buf[offset + i] ^= input[i];
424 output[i] = ectr[offset + i] ^ input[i];
425 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
426 ctx->buf[offset + i] ^= output[i];
427 }
428 return( 0 );
429}
430
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200432 const unsigned char *input, size_t input_length,
433 unsigned char *output, size_t output_size,
434 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200435{
Janos Follath24eed8d2019-11-22 13:21:35 +0000436 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200437 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200438 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200439 size_t offset;
440 unsigned char ectr[16];
441
Gilles Peskinea56c4482021-04-15 17:22:35 +0200442 if( output_size < input_length )
443 return( MBEDTLS_ERR_GCM_BAD_INPUT );
444 GCM_VALIDATE_RET( output_length != NULL );
445 *output_length = input_length;
446
447 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
448 * on a potentially null pointer. */
449 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200450 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200451
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100452 GCM_VALIDATE_RET( ctx != NULL );
Gilles Peskine58fc2722021-04-13 15:58:27 +0200453 GCM_VALIDATE_RET( input != NULL );
454 GCM_VALIDATE_RET( output != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100455
Gilles Peskinea56c4482021-04-15 17:22:35 +0200456 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200457 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200458
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200459 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
460 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200461 if( ctx->len + input_length < ctx->len ||
462 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200463 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200465 }
466
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200467 if ( ( ctx->len == 0 ) && ( ctx->add_len % 16 ) )
468 {
469 gcm_mult( ctx, ctx->buf, ctx->buf );
470 }
471
Gilles Peskine58fc2722021-04-13 15:58:27 +0200472 offset = ctx->len % 16;
473 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000474 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200475 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200476 if( use_len > input_length )
477 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000478
Gilles Peskine58fc2722021-04-13 15:58:27 +0200479 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200480 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000481
Gilles Peskine58fc2722021-04-13 15:58:27 +0200482 if( offset + use_len == 16 )
483 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200484
Gilles Peskine58fc2722021-04-13 15:58:27 +0200485 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200486 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000487 p += use_len;
488 out_p += use_len;
489 }
490
Gilles Peskinea56c4482021-04-15 17:22:35 +0200491 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200492
Gilles Peskinea56c4482021-04-15 17:22:35 +0200493 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200494 {
495 gcm_incr( ctx->y );
496 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
497 return( ret );
498
499 gcm_mult( ctx, ctx->buf, ctx->buf );
500
Gilles Peskinea56c4482021-04-15 17:22:35 +0200501 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200502 p += 16;
503 out_p += 16;
504 }
505
Gilles Peskinea56c4482021-04-15 17:22:35 +0200506 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200507 {
508 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200509 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200510 return( ret );
511 }
512
513 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200514 return( 0 );
515}
516
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200517int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200518 unsigned char *output, size_t output_size,
Gilles Peskine9461e452021-04-15 16:48:32 +0200519 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200520{
521 unsigned char work_buf[16];
522 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100523 uint64_t orig_len;
524 uint64_t orig_add_len;
525
526 GCM_VALIDATE_RET( ctx != NULL );
527 GCM_VALIDATE_RET( tag != NULL );
528
Gilles Peskine9461e452021-04-15 16:48:32 +0200529 /* We never pass any output in finish(). The output parameter exists only
530 * for the sake of alternative implementations. */
531 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200532 (void) output_size;
Gilles Peskine9461e452021-04-15 16:48:32 +0200533
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100534 orig_len = ctx->len * 8;
535 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200536
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200537 if ( ( ctx->len == 0 ) && ( ctx->add_len % 16 ) )
538 {
539 gcm_mult( ctx, ctx->buf, ctx->buf );
540 }
541
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200542 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200543 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200544
Gilles Peskine58fc2722021-04-13 15:58:27 +0200545 if( ctx->len % 16 != 0 )
546 gcm_mult( ctx, ctx->buf, ctx->buf );
547
Andres AG821da842016-09-26 10:09:30 +0100548 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200549
Paul Bakker89e80c92012-03-20 13:50:09 +0000550 if( orig_len || orig_add_len )
551 {
552 memset( work_buf, 0x00, 16 );
553
Paul Bakker0ecdb232013-04-09 11:36:42 +0200554 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
555 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
556 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
557 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000558
Paul Bakker67f9d532012-10-23 11:49:05 +0000559 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200560 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000561
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200562 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000563
Paul Bakker67f9d532012-10-23 11:49:05 +0000564 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200565 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000566 }
567
568 return( 0 );
569}
570
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200571int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200572 int mode,
573 size_t length,
574 const unsigned char *iv,
575 size_t iv_len,
576 const unsigned char *add,
577 size_t add_len,
578 const unsigned char *input,
579 unsigned char *output,
580 size_t tag_len,
581 unsigned char *tag )
582{
Janos Follath24eed8d2019-11-22 13:21:35 +0000583 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200584 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200585
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100586 GCM_VALIDATE_RET( ctx != NULL );
587 GCM_VALIDATE_RET( iv != NULL );
588 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
589 GCM_VALIDATE_RET( length == 0 || input != NULL );
590 GCM_VALIDATE_RET( length == 0 || output != NULL );
591 GCM_VALIDATE_RET( tag != NULL );
592
Gilles Peskine295fc132021-04-15 18:32:23 +0200593 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
594 return( ret );
595
596 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200597 return( ret );
598
Gilles Peskinea56c4482021-04-15 17:22:35 +0200599 if( ( ret = mbedtls_gcm_update( ctx, input, length,
600 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200601 return( ret );
602
Gilles Peskine9461e452021-04-15 16:48:32 +0200603 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200604 return( ret );
605
606 return( 0 );
607}
608
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200609int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000610 size_t length,
611 const unsigned char *iv,
612 size_t iv_len,
613 const unsigned char *add,
614 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200615 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000616 size_t tag_len,
617 const unsigned char *input,
618 unsigned char *output )
619{
Janos Follath24eed8d2019-11-22 13:21:35 +0000620 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000621 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200622 size_t i;
623 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000624
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100625 GCM_VALIDATE_RET( ctx != NULL );
626 GCM_VALIDATE_RET( iv != NULL );
627 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
628 GCM_VALIDATE_RET( tag != NULL );
629 GCM_VALIDATE_RET( length == 0 || input != NULL );
630 GCM_VALIDATE_RET( length == 0 || output != NULL );
631
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200632 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100633 iv, iv_len, add, add_len,
634 input, output, tag_len, check_tag ) ) != 0 )
635 {
636 return( ret );
637 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000638
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200639 /* Check tag in "constant-time" */
640 for( diff = 0, i = 0; i < tag_len; i++ )
641 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000642
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200643 if( diff != 0 )
644 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500645 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200646 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200647 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000648
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200649 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000650}
651
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200652void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200653{
k-stachowiak21298a22018-12-13 17:11:58 +0100654 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100655 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200656 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500657 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200658}
659
Jaeden Amero15263302017-09-21 12:53:48 +0100660#endif /* !MBEDTLS_GCM_ALT */
661
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200662#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000663/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200664 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000665 *
666 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
667 */
668#define MAX_TESTS 6
669
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100670static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000671 { 0, 0, 1, 1, 1, 1 };
672
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100673static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000674{
675 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
676 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
679 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
680 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
681 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200682 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000683};
684
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100685static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000686 { 12, 12, 12, 12, 8, 60 };
687
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100688static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000689 { 0, 0, 1, 1, 1, 2 };
690
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100691static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000692{
693 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694 0x00, 0x00, 0x00, 0x00 },
695 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
696 0xde, 0xca, 0xf8, 0x88 },
697 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200702 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000703 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200704 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000705};
706
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100707static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000708 { 0, 0, 0, 20, 20, 20 };
709
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100710static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000711 { 0, 0, 0, 1, 1, 1 };
712
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100713static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000714{
715 { 0x00 },
716 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200717 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000718 0xab, 0xad, 0xda, 0xd2 },
719};
720
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100721static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000722 { 0, 16, 64, 60, 60, 60 };
723
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100724static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000725 { 0, 0, 1, 1, 1, 1 };
726
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100727static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000728{
729 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
731 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
732 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
733 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
734 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
735 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
736 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
737 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
738 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
739};
740
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100741static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000742{
743 { 0x00 },
744 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
745 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
746 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200747 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000748 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200749 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000750 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200751 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000752 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
753 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
754 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200755 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000756 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200757 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000758 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200759 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000760 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
761 0x3d, 0x58, 0xe0, 0x91 },
762 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200763 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000764 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200765 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000766 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200767 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000768 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
769 0xc2, 0x3f, 0x45, 0x98 },
770 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200771 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000772 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200773 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000774 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200775 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
777 0x4c, 0x34, 0xae, 0xe5 },
778 { 0x00 },
779 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200780 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000781 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200782 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000783 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200784 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000785 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200786 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000787 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
788 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
789 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200790 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000791 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200792 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
793 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
794 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000795 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200796 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000797 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200798 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000799 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200800 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000801 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200802 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000803 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200804 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000805 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200806 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000807 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200808 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000809 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200810 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000811 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200812 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000813 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200814 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
815 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
816 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
817 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
818 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
819 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
820 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
821 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
822 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
823 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
824 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
825 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
826 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
827 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
828 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
829 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
830 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
831 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000832 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200833 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000834 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200835 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000836 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200837 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000838 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200839 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000840 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200841 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000842 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200843 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000844 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200845 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000846 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200847 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000848};
849
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100850static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000851{
852 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
853 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
854 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
855 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
856 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200857 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000858 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
859 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
860 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
861 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
862 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
863 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
864 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
865 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
866 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200867 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000868 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
869 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
870 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200871 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000872 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200873 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000874 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200875 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000876 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200877 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000878 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200879 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000880 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200881 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000882 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200883 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000884 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200885 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000886 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200887 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000888};
889
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000891{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000893 unsigned char buf[64];
894 unsigned char tag_buf[16];
895 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200896 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200897 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000898
899 for( j = 0; j < 3; j++ )
900 {
901 int key_len = 128 + 64 * j;
902
903 for( i = 0; i < MAX_TESTS; i++ )
904 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100905 mbedtls_gcm_init( &ctx );
906
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200907 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100909 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200910
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500911 ret = mbedtls_gcm_setkey( &ctx, cipher,
912 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100913 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100914 /*
915 * AES-192 is an optional feature that may be unavailable when
916 * there is an alternative underlying implementation i.e. when
917 * MBEDTLS_AES_ALT is defined.
918 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300919 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100920 {
921 mbedtls_printf( "skipped\n" );
922 break;
923 }
924 else if( ret != 0 )
925 {
926 goto exit;
927 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000928
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200929 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500930 pt_len_test_data[i],
931 iv_test_data[iv_index_test_data[i]],
932 iv_len_test_data[i],
933 additional_test_data[add_index_test_data[i]],
934 add_len_test_data[i],
935 pt_test_data[pt_index_test_data[i]],
936 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100937#if defined(MBEDTLS_GCM_ALT)
938 /* Allow alternative implementations to only support 12-byte nonces. */
939 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
940 iv_len_test_data[i] != 12 )
941 {
942 mbedtls_printf( "skipped\n" );
943 break;
944 }
945#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100946 if( ret != 0 )
947 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000948
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500949 if ( memcmp( buf, ct_test_data[j * 6 + i],
950 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100951 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000952 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100953 ret = 1;
954 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000955 }
956
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200957 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200958
Paul Bakker89e80c92012-03-20 13:50:09 +0000959 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200960 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000961
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100962 mbedtls_gcm_init( &ctx );
963
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200964 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100966 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200967
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500968 ret = mbedtls_gcm_setkey( &ctx, cipher,
969 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100970 key_len );
971 if( ret != 0 )
972 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000973
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500975 pt_len_test_data[i],
976 iv_test_data[iv_index_test_data[i]],
977 iv_len_test_data[i],
978 additional_test_data[add_index_test_data[i]],
979 add_len_test_data[i],
980 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000981
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100982 if( ret != 0 )
983 goto exit;
984
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100985 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
986 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100987 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000988 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100989 ret = 1;
990 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000991 }
992
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200994
Paul Bakker89e80c92012-03-20 13:50:09 +0000995 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200996 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200997
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100998 mbedtls_gcm_init( &ctx );
999
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001000 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001001 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001002 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001003
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001004 ret = mbedtls_gcm_setkey( &ctx, cipher,
1005 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001006 key_len );
1007 if( ret != 0 )
1008 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001009
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001010 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001011 iv_test_data[iv_index_test_data[i]],
1012 iv_len_test_data[i] );
1013 if( ret != 0 )
1014 goto exit;
1015
1016 ret = mbedtls_gcm_update_ad( &ctx,
1017 additional_test_data[add_index_test_data[i]],
1018 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001019 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001020 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001021
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001022 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001023 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001024 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001025 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001026 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001027 32,
1028 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001029 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001030 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001031 if( olen != 32 )
1032 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001033
Gilles Peskinea56c4482021-04-15 17:22:35 +02001034 ret = mbedtls_gcm_update( &ctx,
1035 pt_test_data[pt_index_test_data[i]] + 32,
1036 rest_len,
1037 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001038 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001039 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001040 if( olen != rest_len )
1041 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001042 }
1043 else
1044 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001045 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001046 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001047 pt_len_test_data[i],
1048 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001049 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001050 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001051 if( olen != pt_len_test_data[i] )
1052 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001053 }
1054
Gilles Peskine9461e452021-04-15 16:48:32 +02001055 ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001056 if( ret != 0 )
1057 goto exit;
1058
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001059 if( memcmp( buf, ct_test_data[j * 6 + i],
1060 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001061 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001062 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001063 ret = 1;
1064 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001065 }
1066
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001067 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001068
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001069 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001070 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001071
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001072 mbedtls_gcm_init( &ctx );
1073
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001074 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001075 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001076 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001077
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001078 ret = mbedtls_gcm_setkey( &ctx, cipher,
1079 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001080 key_len );
1081 if( ret != 0 )
1082 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001083
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001084 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001085 iv_test_data[iv_index_test_data[i]],
1086 iv_len_test_data[i] );
1087 if( ret != 0 )
1088 goto exit;
1089 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001090 additional_test_data[add_index_test_data[i]],
1091 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001092 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001093 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001094
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001095 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001096 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001097 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001098 ret = mbedtls_gcm_update( &ctx,
1099 ct_test_data[j * 6 + i], 32,
1100 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001101 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001102 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001103 if( olen != 32 )
1104 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001105
Gilles Peskinea56c4482021-04-15 17:22:35 +02001106 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001107 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001108 rest_len,
1109 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001110 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001111 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001112 if( olen != rest_len )
1113 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001114 }
1115 else
1116 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001117 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001118 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001119 pt_len_test_data[i],
1120 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001121 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001122 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001123 if( olen != pt_len_test_data[i] )
1124 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001125 }
1126
Gilles Peskine9461e452021-04-15 16:48:32 +02001127 ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001128 if( ret != 0 )
1129 goto exit;
1130
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001131 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1132 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001133 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001134 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001135 ret = 1;
1136 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001137 }
1138
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001139 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001140
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001141 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001142 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001143 }
1144 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001145
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001146 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001147 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001148
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001149 ret = 0;
1150
1151exit:
1152 if( ret != 0 )
1153 {
1154 if( verbose != 0 )
1155 mbedtls_printf( "failed\n" );
1156 mbedtls_gcm_free( &ctx );
1157 }
1158
1159 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001160}
1161
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001162#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001164#endif /* MBEDTLS_GCM_C */