blob: 6d07f8787f22ed13f46c24a0c26b557b00ec58af [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/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020062 * Initialize a context
63 */
64void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
65{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010066 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020067 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
68}
69
70/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010071 * Precompute small multiples of H, that is set
72 * HH[i] || HL[i] = H times i,
73 * where i is seen as a field element as in [MGV], ie high-order bits
74 * correspond to low powers of P. The result is stored in the same way, that
75 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
76 * corresponds to P^127.
77 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000079{
Paul Bakker43aff2a2013-09-09 00:10:27 +020080 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000081 uint64_t hi, lo;
82 uint64_t vl, vh;
83 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020084 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020085
Paul Bakker89e80c92012-03-20 13:50:09 +000086 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020087 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +020088 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000089
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010090 /* pack h as two 64-bits ints, big-endian */
Joe Subbiani6a506312021-07-07 16:56:29 +010091 hi = MBEDTLS_GET_UINT32_BE( h, 0 );
92 lo = MBEDTLS_GET_UINT32_BE( h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000093 vh = (uint64_t) hi << 32 | lo;
94
Joe Subbiani6a506312021-07-07 16:56:29 +010095 hi = MBEDTLS_GET_UINT32_BE( h, 8 );
96 lo = MBEDTLS_GET_UINT32_BE( h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000097 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020098
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010099 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000100 ctx->HL[8] = vl;
101 ctx->HH[8] = vh;
102
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100104 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100105 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100106 return( 0 );
107#endif
108
109 /* 0 corresponds to 0 in GF(2^128) */
110 ctx->HH[0] = 0;
111 ctx->HL[0] = 0;
112
Paul Bakker89e80c92012-03-20 13:50:09 +0000113 for( i = 4; i > 0; i >>= 1 )
114 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200115 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000116 vl = ( vh << 63 ) | ( vl >> 1 );
117 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
118
119 ctx->HL[i] = vl;
120 ctx->HH[i] = vh;
121 }
122
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000123 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000124 {
125 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
126 vh = *HiH;
127 vl = *HiL;
128 for( j = 1; j < i; j++ )
129 {
130 HiH[j] = vh ^ ctx->HH[j];
131 HiL[j] = vl ^ ctx->HL[j];
132 }
133 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200134
135 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000136}
137
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200138int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
139 mbedtls_cipher_id_t cipher,
140 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200141 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000142{
Janos Follath24eed8d2019-11-22 13:21:35 +0000143 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200144 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000145
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100146 GCM_VALIDATE_RET( ctx != NULL );
147 GCM_VALIDATE_RET( key != NULL );
148 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
149
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500150 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
151 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200152 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200153 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200154
Paul Bakkera0558e02013-09-10 14:25:51 +0200155 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200157
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200158 mbedtls_cipher_free( &ctx->cipher_ctx );
159
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200160 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000161 return( ret );
162
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200163 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200164 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200165 {
166 return( ret );
167 }
168
169 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
170 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000171
172 return( 0 );
173}
174
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100175/*
176 * Shoup's method for multiplication use this table with
177 * last4[x] = x times P^128
178 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
179 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000180static const uint64_t last4[16] =
181{
182 0x0000, 0x1c20, 0x3840, 0x2460,
183 0x7080, 0x6ca0, 0x48c0, 0x54e0,
184 0xe100, 0xfd20, 0xd940, 0xc560,
185 0x9180, 0x8da0, 0xa9c0, 0xb5e0
186};
187
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100188/*
189 * Sets output to x times H using the precomputed tables.
190 * x and output are seen as elements of GF(2^128) as in [MGV].
191 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200193 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000194{
195 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000196 unsigned char lo, hi, rem;
197 uint64_t zh, zl;
198
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200199#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100200 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100201 unsigned char h[16];
202
Joe Subbiani5ecac212021-06-24 13:00:03 +0100203 MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
204 MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 );
205 MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
206 MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100207
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100209 return;
210 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100212
Paul Bakker89e80c92012-03-20 13:50:09 +0000213 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000214
215 zh = ctx->HH[lo];
216 zl = ctx->HL[lo];
217
218 for( i = 15; i >= 0; i-- )
219 {
220 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200221 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000222
223 if( i != 15 )
224 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000225 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000226 zl = ( zh << 60 ) | ( zl >> 4 );
227 zh = ( zh >> 4 );
228 zh ^= (uint64_t) last4[rem] << 48;
229 zh ^= ctx->HH[lo];
230 zl ^= ctx->HL[lo];
231
232 }
233
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000234 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000235 zl = ( zh << 60 ) | ( zl >> 4 );
236 zh = ( zh >> 4 );
237 zh ^= (uint64_t) last4[rem] << 48;
238 zh ^= ctx->HH[hi];
239 zl ^= ctx->HL[hi];
240 }
241
Joe Subbiani5ecac212021-06-24 13:00:03 +0100242 MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
243 MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
244 MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
245 MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000246}
247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Gilles Peskine295fc132021-04-15 18:32:23 +0200249 int mode,
250 const unsigned char *iv, size_t iv_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000251{
Janos Follath24eed8d2019-11-22 13:21:35 +0000252 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000253 unsigned char work_buf[16];
254 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000255 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200256 size_t use_len, olen = 0;
openluopworldeab65ac2021-09-22 23:59:42 +0800257 uint64_t iv_bits;
Paul Bakker89e80c92012-03-20 13:50:09 +0000258
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100259 GCM_VALIDATE_RET( ctx != NULL );
260 GCM_VALIDATE_RET( iv != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100261
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200262 /* IV is limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200263 /* IV is not allowed to be zero length */
Gilles Peskine295fc132021-04-15 18:32:23 +0200264 if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200265 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200266
Paul Bakker52cf16c2013-07-26 13:55:38 +0200267 memset( ctx->y, 0x00, sizeof(ctx->y) );
268 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
269
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200270 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200271 ctx->len = 0;
272 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000273
274 if( iv_len == 12 )
275 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200276 memcpy( ctx->y, iv, iv_len );
277 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000278 }
279 else
280 {
281 memset( work_buf, 0x00, 16 );
openluopworldeab65ac2021-09-22 23:59:42 +0800282 iv_bits = (uint64_t)iv_len * 8;
283 MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000284
285 p = iv;
286 while( iv_len > 0 )
287 {
288 use_len = ( iv_len < 16 ) ? iv_len : 16;
289
Paul Bakker67f9d532012-10-23 11:49:05 +0000290 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200291 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200292
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200293 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000294
295 iv_len -= use_len;
296 p += use_len;
297 }
298
Paul Bakker67f9d532012-10-23 11:49:05 +0000299 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200300 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000301
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200302 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000303 }
304
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500305 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
306 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200307 {
308 return( ret );
309 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000310
Gilles Peskine295fc132021-04-15 18:32:23 +0200311 return( 0 );
312}
313
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200314/**
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200315 * mbedtls_gcm_context::buf contains the partial state of the computation of
316 * the authentication tag.
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200317 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
318 * different stages of the computation:
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200319 * * len == 0 && add_len == 0: initial state
320 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
321 * a partial block of AD that has been
322 * xored in but not yet multiplied in.
323 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
324 * the data ends now.
325 * * len % 16 != 0: the first `len % 16` bytes have
326 * a partial block of ciphertext that has
327 * been xored in but not yet multiplied in.
328 * * len > 0 && len % 16 == 0: the authentication tag is correct if
329 * the data ends now.
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200330 */
Gilles Peskine295fc132021-04-15 18:32:23 +0200331int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
332 const unsigned char *add, size_t add_len )
333{
334 const unsigned char *p;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200335 size_t use_len, i, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200336
337 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
338
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200339 /* IV is limited to 2^64 bits, so 2^61 bytes */
Gilles Peskine295fc132021-04-15 18:32:23 +0200340 if( (uint64_t) add_len >> 61 != 0 )
341 return( MBEDTLS_ERR_GCM_BAD_INPUT );
342
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200343 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000344 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200345
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200346 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000347 {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200348 use_len = 16 - offset;
349 if( use_len > add_len )
350 use_len = add_len;
351
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200352 for( i = 0; i < use_len; i++ )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200353 ctx->buf[i+offset] ^= p[i];
354
355 if( offset + use_len == 16 )
356 gcm_mult( ctx, ctx->buf, ctx->buf );
357
358 ctx->add_len += use_len;
359 add_len -= use_len;
360 p += use_len;
361 }
362
363 ctx->add_len += add_len;
364
365 while( add_len >= 16 )
366 {
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200367 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200368 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200369
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200370 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000371
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200372 add_len -= 16;
373 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000374 }
375
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200376 if( add_len > 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200377 {
378 for( i = 0; i < add_len; i++ )
379 ctx->buf[i] ^= p[i];
380 }
381
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200382 return( 0 );
383}
384
Gilles Peskine58fc2722021-04-13 15:58:27 +0200385/* Increment the counter. */
386static void gcm_incr( unsigned char y[16] )
387{
388 size_t i;
389 for( i = 16; i > 12; i-- )
390 if( ++y[i - 1] != 0 )
391 break;
392}
393
394/* Calculate and apply the encryption mask. Process use_len bytes of data,
395 * starting at position offset in the mask block. */
396static int gcm_mask( mbedtls_gcm_context *ctx,
397 unsigned char ectr[16],
398 size_t offset, size_t use_len,
399 const unsigned char *input,
400 unsigned char *output )
401{
402 size_t i;
403 size_t olen = 0;
404 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
405
406 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
407 &olen ) ) != 0 )
408 {
409 mbedtls_platform_zeroize( ectr, 16 );
410 return( ret );
411 }
412
413 for( i = 0; i < use_len; i++ )
414 {
415 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
416 ctx->buf[offset + i] ^= input[i];
417 output[i] = ectr[offset + i] ^ input[i];
418 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
419 ctx->buf[offset + i] ^= output[i];
420 }
421 return( 0 );
422}
423
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200425 const unsigned char *input, size_t input_length,
426 unsigned char *output, size_t output_size,
427 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200428{
Janos Follath24eed8d2019-11-22 13:21:35 +0000429 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200430 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200431 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200432 size_t offset;
Leonid Rozenboima3008e72022-04-21 17:28:18 -0700433 unsigned char ectr[16] = {0};
Gilles Peskine58fc2722021-04-13 15:58:27 +0200434
Gilles Peskinea56c4482021-04-15 17:22:35 +0200435 if( output_size < input_length )
Mateusz Starzykc48f43b2021-10-04 13:46:38 +0200436 return( MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200437 GCM_VALIDATE_RET( output_length != NULL );
438 *output_length = input_length;
439
440 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200441 * on a potentially null pointer.
442 * Returning early also means that the last partial block of AD remains
443 * untouched for mbedtls_gcm_finish */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200444 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200445 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200446
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100447 GCM_VALIDATE_RET( ctx != NULL );
Gilles Peskine58fc2722021-04-13 15:58:27 +0200448 GCM_VALIDATE_RET( input != NULL );
449 GCM_VALIDATE_RET( output != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100450
Gilles Peskinea56c4482021-04-15 17:22:35 +0200451 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200453
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200454 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
455 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200456 if( ctx->len + input_length < ctx->len ||
457 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200458 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200460 }
461
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200462 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200463 {
464 gcm_mult( ctx, ctx->buf, ctx->buf );
465 }
466
Gilles Peskine58fc2722021-04-13 15:58:27 +0200467 offset = ctx->len % 16;
468 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000469 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200470 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200471 if( use_len > input_length )
472 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000473
Gilles Peskine58fc2722021-04-13 15:58:27 +0200474 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200475 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000476
Gilles Peskine58fc2722021-04-13 15:58:27 +0200477 if( offset + use_len == 16 )
478 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200479
Gilles Peskine58fc2722021-04-13 15:58:27 +0200480 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200481 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000482 p += use_len;
483 out_p += use_len;
484 }
485
Gilles Peskinea56c4482021-04-15 17:22:35 +0200486 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200487
Gilles Peskinea56c4482021-04-15 17:22:35 +0200488 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200489 {
490 gcm_incr( ctx->y );
491 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
492 return( ret );
493
494 gcm_mult( ctx, ctx->buf, ctx->buf );
495
Gilles Peskinea56c4482021-04-15 17:22:35 +0200496 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200497 p += 16;
498 out_p += 16;
499 }
500
Gilles Peskinea56c4482021-04-15 17:22:35 +0200501 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200502 {
503 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200504 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200505 return( ret );
506 }
507
508 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200509 return( 0 );
510}
511
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200513 unsigned char *output, size_t output_size,
Gilles Peskine5a7be102021-06-23 21:51:32 +0200514 size_t *output_length,
Gilles Peskine9461e452021-04-15 16:48:32 +0200515 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200516{
517 unsigned char work_buf[16];
518 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100519 uint64_t orig_len;
520 uint64_t orig_add_len;
521
522 GCM_VALIDATE_RET( ctx != NULL );
523 GCM_VALIDATE_RET( tag != NULL );
524
Gilles Peskine9461e452021-04-15 16:48:32 +0200525 /* We never pass any output in finish(). The output parameter exists only
526 * for the sake of alternative implementations. */
527 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200528 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200529 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200530
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100531 orig_len = ctx->len * 8;
532 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200533
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200534 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200535 {
536 gcm_mult( ctx, ctx->buf, ctx->buf );
537 }
538
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200539 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200540 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200541
Gilles Peskine58fc2722021-04-13 15:58:27 +0200542 if( ctx->len % 16 != 0 )
543 gcm_mult( ctx, ctx->buf, ctx->buf );
544
Andres AG821da842016-09-26 10:09:30 +0100545 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200546
Paul Bakker89e80c92012-03-20 13:50:09 +0000547 if( orig_len || orig_add_len )
548 {
549 memset( work_buf, 0x00, 16 );
550
Joe Subbiani5ecac212021-06-24 13:00:03 +0100551 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
552 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
553 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
554 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000555
Paul Bakker67f9d532012-10-23 11:49:05 +0000556 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200557 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000558
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200559 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000560
Paul Bakker67f9d532012-10-23 11:49:05 +0000561 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200562 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000563 }
564
565 return( 0 );
566}
567
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200568int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200569 int mode,
570 size_t length,
571 const unsigned char *iv,
572 size_t iv_len,
573 const unsigned char *add,
574 size_t add_len,
575 const unsigned char *input,
576 unsigned char *output,
577 size_t tag_len,
578 unsigned char *tag )
579{
Janos Follath24eed8d2019-11-22 13:21:35 +0000580 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200581 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200582
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100583 GCM_VALIDATE_RET( ctx != NULL );
584 GCM_VALIDATE_RET( iv != NULL );
585 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
586 GCM_VALIDATE_RET( length == 0 || input != NULL );
587 GCM_VALIDATE_RET( length == 0 || output != NULL );
588 GCM_VALIDATE_RET( tag != NULL );
589
Gilles Peskine295fc132021-04-15 18:32:23 +0200590 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
591 return( ret );
592
593 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200594 return( ret );
595
Gilles Peskinea56c4482021-04-15 17:22:35 +0200596 if( ( ret = mbedtls_gcm_update( ctx, input, length,
597 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200598 return( ret );
599
Gilles Peskine5a7be102021-06-23 21:51:32 +0200600 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200601 return( ret );
602
603 return( 0 );
604}
605
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200606int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000607 size_t length,
608 const unsigned char *iv,
609 size_t iv_len,
610 const unsigned char *add,
611 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200612 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000613 size_t tag_len,
614 const unsigned char *input,
615 unsigned char *output )
616{
Janos Follath24eed8d2019-11-22 13:21:35 +0000617 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000618 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200619 size_t i;
620 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000621
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100622 GCM_VALIDATE_RET( ctx != NULL );
623 GCM_VALIDATE_RET( iv != NULL );
624 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
625 GCM_VALIDATE_RET( tag != NULL );
626 GCM_VALIDATE_RET( length == 0 || input != NULL );
627 GCM_VALIDATE_RET( length == 0 || output != NULL );
628
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100630 iv, iv_len, add, add_len,
631 input, output, tag_len, check_tag ) ) != 0 )
632 {
633 return( ret );
634 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000635
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200636 /* Check tag in "constant-time" */
637 for( diff = 0, i = 0; i < tag_len; i++ )
638 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000639
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200640 if( diff != 0 )
641 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500642 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200644 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000645
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200646 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000647}
648
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200650{
k-stachowiak21298a22018-12-13 17:11:58 +0100651 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100652 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500654 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200655}
656
Jaeden Amero15263302017-09-21 12:53:48 +0100657#endif /* !MBEDTLS_GCM_ALT */
658
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200659#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000660/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200661 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000662 *
663 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
664 */
665#define MAX_TESTS 6
666
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100667static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000668 { 0, 0, 1, 1, 1, 1 };
669
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100670static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000671{
672 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
676 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
677 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
678 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200679 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000680};
681
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100682static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000683 { 12, 12, 12, 12, 8, 60 };
684
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100685static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000686 { 0, 0, 1, 1, 1, 2 };
687
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100688static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000689{
690 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691 0x00, 0x00, 0x00, 0x00 },
692 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
693 0xde, 0xca, 0xf8, 0x88 },
694 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200695 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000696 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200697 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000698 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200699 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000700 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200701 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000702};
703
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100704static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000705 { 0, 0, 0, 20, 20, 20 };
706
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100707static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000708 { 0, 0, 0, 1, 1, 1 };
709
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100710static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000711{
712 { 0x00 },
713 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200714 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000715 0xab, 0xad, 0xda, 0xd2 },
716};
717
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100718static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000719 { 0, 16, 64, 60, 60, 60 };
720
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100721static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000722 { 0, 0, 1, 1, 1, 1 };
723
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100724static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000725{
726 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
728 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
729 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
730 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
731 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
732 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
733 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
734 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
735 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
736};
737
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100738static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000739{
740 { 0x00 },
741 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
742 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
743 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200744 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000745 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200746 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000747 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200748 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
750 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
751 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200752 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000753 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200754 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000755 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200756 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000757 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
758 0x3d, 0x58, 0xe0, 0x91 },
759 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200760 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200762 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000763 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200764 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000765 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
766 0xc2, 0x3f, 0x45, 0x98 },
767 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200768 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000769 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200770 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000771 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200772 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000773 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
774 0x4c, 0x34, 0xae, 0xe5 },
775 { 0x00 },
776 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200777 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000778 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200779 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000780 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200781 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000782 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200783 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000784 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
785 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
786 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200787 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000788 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200789 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
790 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
791 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000792 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200793 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000794 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200795 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000796 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200797 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000798 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200799 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000800 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200801 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000802 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200803 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000804 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200805 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000806 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200807 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000808 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200809 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000810 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200811 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
812 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
813 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
814 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
815 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
816 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
817 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
818 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
819 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
820 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
821 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
822 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
823 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
824 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
825 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
826 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
827 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
828 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000829 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200830 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000831 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200832 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000833 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200834 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000835 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200836 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000837 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200838 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000839 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200840 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000841 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200842 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000843 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200844 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000845};
846
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100847static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000848{
849 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
850 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
851 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
852 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
853 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200854 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000855 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
856 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
857 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
858 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
859 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
860 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
861 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
862 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
863 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200864 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000865 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
866 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
867 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200868 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000869 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200870 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000871 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200872 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000873 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200874 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000875 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200876 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000877 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200878 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000879 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200880 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000881 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200882 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000883 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200884 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000885};
886
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200887int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000888{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000890 unsigned char buf[64];
891 unsigned char tag_buf[16];
892 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200894 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000895
896 for( j = 0; j < 3; j++ )
897 {
898 int key_len = 128 + 64 * j;
899
900 for( i = 0; i < MAX_TESTS; i++ )
901 {
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, "enc" );
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 );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100911 /*
912 * AES-192 is an optional feature that may be unavailable when
913 * there is an alternative underlying implementation i.e. when
914 * MBEDTLS_AES_ALT is defined.
915 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300916 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100917 {
918 mbedtls_printf( "skipped\n" );
919 break;
920 }
921 else if( ret != 0 )
922 {
923 goto exit;
924 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000925
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200926 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500927 pt_len_test_data[i],
928 iv_test_data[iv_index_test_data[i]],
929 iv_len_test_data[i],
930 additional_test_data[add_index_test_data[i]],
931 add_len_test_data[i],
932 pt_test_data[pt_index_test_data[i]],
933 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100934#if defined(MBEDTLS_GCM_ALT)
935 /* Allow alternative implementations to only support 12-byte nonces. */
936 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
937 iv_len_test_data[i] != 12 )
938 {
939 mbedtls_printf( "skipped\n" );
940 break;
941 }
942#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100943 if( ret != 0 )
944 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000945
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500946 if ( memcmp( buf, ct_test_data[j * 6 + i],
947 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100948 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000949 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100950 ret = 1;
951 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000952 }
953
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200955
Paul Bakker89e80c92012-03-20 13:50:09 +0000956 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200957 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000958
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100959 mbedtls_gcm_init( &ctx );
960
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200961 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200962 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100963 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200964
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500965 ret = mbedtls_gcm_setkey( &ctx, cipher,
966 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100967 key_len );
968 if( ret != 0 )
969 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000970
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200971 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500972 pt_len_test_data[i],
973 iv_test_data[iv_index_test_data[i]],
974 iv_len_test_data[i],
975 additional_test_data[add_index_test_data[i]],
976 add_len_test_data[i],
977 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000978
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100979 if( ret != 0 )
980 goto exit;
981
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100982 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
983 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100984 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000985 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100986 ret = 1;
987 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000988 }
989
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200990 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200991
Paul Bakker89e80c92012-03-20 13:50:09 +0000992 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200994
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100995 mbedtls_gcm_init( &ctx );
996
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200997 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200998 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100999 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001000
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001001 ret = mbedtls_gcm_setkey( &ctx, cipher,
1002 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001003 key_len );
1004 if( ret != 0 )
1005 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001006
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001007 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001008 iv_test_data[iv_index_test_data[i]],
1009 iv_len_test_data[i] );
1010 if( ret != 0 )
1011 goto exit;
1012
1013 ret = mbedtls_gcm_update_ad( &ctx,
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;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001022 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001023 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001024 32,
1025 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001026 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001027 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001028 if( olen != 32 )
1029 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001030
Gilles Peskinea56c4482021-04-15 17:22:35 +02001031 ret = mbedtls_gcm_update( &ctx,
1032 pt_test_data[pt_index_test_data[i]] + 32,
1033 rest_len,
1034 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001035 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001036 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001037 if( olen != rest_len )
1038 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001039 }
1040 else
1041 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001042 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001043 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001044 pt_len_test_data[i],
1045 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001046 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001047 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001048 if( olen != pt_len_test_data[i] )
1049 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001050 }
1051
Gilles Peskine5a7be102021-06-23 21:51:32 +02001052 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001053 if( ret != 0 )
1054 goto exit;
1055
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001056 if( memcmp( buf, ct_test_data[j * 6 + i],
1057 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001058 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001059 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001060 ret = 1;
1061 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001062 }
1063
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001064 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001065
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001066 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001067 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001068
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001069 mbedtls_gcm_init( &ctx );
1070
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001071 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001072 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001073 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001074
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001075 ret = mbedtls_gcm_setkey( &ctx, cipher,
1076 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001077 key_len );
1078 if( ret != 0 )
1079 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001080
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001081 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001082 iv_test_data[iv_index_test_data[i]],
1083 iv_len_test_data[i] );
1084 if( ret != 0 )
1085 goto exit;
1086 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001087 additional_test_data[add_index_test_data[i]],
1088 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001089 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001090 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001091
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001092 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001093 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001094 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001095 ret = mbedtls_gcm_update( &ctx,
1096 ct_test_data[j * 6 + i], 32,
1097 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001098 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001099 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001100 if( olen != 32 )
1101 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001102
Gilles Peskinea56c4482021-04-15 17:22:35 +02001103 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001104 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001105 rest_len,
1106 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001107 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001108 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001109 if( olen != rest_len )
1110 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001111 }
1112 else
1113 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001114 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001115 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001116 pt_len_test_data[i],
1117 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001118 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001119 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001120 if( olen != pt_len_test_data[i] )
1121 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001122 }
1123
Gilles Peskine5a7be102021-06-23 21:51:32 +02001124 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001125 if( ret != 0 )
1126 goto exit;
1127
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001128 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1129 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001130 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001131 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001132 ret = 1;
1133 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001134 }
1135
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001136 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001137
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001138 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001139 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001140 }
1141 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001142
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001143 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001144 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001145
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001146 ret = 0;
1147
1148exit:
1149 if( ret != 0 )
1150 {
1151 if( verbose != 0 )
1152 mbedtls_printf( "failed\n" );
1153 mbedtls_gcm_free( &ctx );
1154 }
1155
1156 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001157}
1158
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001159#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001160
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001161#endif /* MBEDTLS_GCM_C */