blob: 0810fd220565de0ddfad2b3bf93275162bfb62bc [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;
Paul Bakker89e80c92012-03-20 13:50:09 +0000257
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100258 GCM_VALIDATE_RET( ctx != NULL );
259 GCM_VALIDATE_RET( iv != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100260
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200261 /* IV is limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200262 /* IV is not allowed to be zero length */
Gilles Peskine295fc132021-04-15 18:32:23 +0200263 if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200265
Paul Bakker52cf16c2013-07-26 13:55:38 +0200266 memset( ctx->y, 0x00, sizeof(ctx->y) );
267 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
268
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200269 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200270 ctx->len = 0;
271 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000272
273 if( iv_len == 12 )
274 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200275 memcpy( ctx->y, iv, iv_len );
276 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000277 }
278 else
279 {
280 memset( work_buf, 0x00, 16 );
openluopworld6c8183f2021-09-17 22:15:49 +0800281 MBEDTLS_PUT_UINT32_BE( iv_len >> 29, work_buf, 8 );
282 MBEDTLS_PUT_UINT32_BE( iv_len << 3, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000283
284 p = iv;
285 while( iv_len > 0 )
286 {
287 use_len = ( iv_len < 16 ) ? iv_len : 16;
288
Paul Bakker67f9d532012-10-23 11:49:05 +0000289 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200290 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200291
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200292 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000293
294 iv_len -= use_len;
295 p += use_len;
296 }
297
Paul Bakker67f9d532012-10-23 11:49:05 +0000298 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200299 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000300
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200301 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000302 }
303
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500304 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
305 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200306 {
307 return( ret );
308 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000309
Gilles Peskine295fc132021-04-15 18:32:23 +0200310 return( 0 );
311}
312
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200313/**
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200314 * mbedtls_gcm_context::buf contains the partial state of the computation of
315 * the authentication tag.
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200316 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
317 * different stages of the computation:
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200318 * * len == 0 && add_len == 0: initial state
319 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
320 * a partial block of AD that has been
321 * xored in but not yet multiplied in.
322 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
323 * the data ends now.
324 * * len % 16 != 0: the first `len % 16` bytes have
325 * a partial block of ciphertext that has
326 * been xored in but not yet multiplied in.
327 * * len > 0 && len % 16 == 0: the authentication tag is correct if
328 * the data ends now.
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200329 */
Gilles Peskine295fc132021-04-15 18:32:23 +0200330int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
331 const unsigned char *add, size_t add_len )
332{
333 const unsigned char *p;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200334 size_t use_len, i, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200335
336 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
337
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200338 /* IV is limited to 2^64 bits, so 2^61 bytes */
Gilles Peskine295fc132021-04-15 18:32:23 +0200339 if( (uint64_t) add_len >> 61 != 0 )
340 return( MBEDTLS_ERR_GCM_BAD_INPUT );
341
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200342 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000343 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200344
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200345 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000346 {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200347 use_len = 16 - offset;
348 if( use_len > add_len )
349 use_len = add_len;
350
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200351 for( i = 0; i < use_len; i++ )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200352 ctx->buf[i+offset] ^= p[i];
353
354 if( offset + use_len == 16 )
355 gcm_mult( ctx, ctx->buf, ctx->buf );
356
357 ctx->add_len += use_len;
358 add_len -= use_len;
359 p += use_len;
360 }
361
362 ctx->add_len += add_len;
363
364 while( add_len >= 16 )
365 {
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200366 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200367 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200368
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200369 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000370
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200371 add_len -= 16;
372 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000373 }
374
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200375 if( add_len > 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200376 {
377 for( i = 0; i < add_len; i++ )
378 ctx->buf[i] ^= p[i];
379 }
380
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200381 return( 0 );
382}
383
Gilles Peskine58fc2722021-04-13 15:58:27 +0200384/* Increment the counter. */
385static void gcm_incr( unsigned char y[16] )
386{
387 size_t i;
388 for( i = 16; i > 12; i-- )
389 if( ++y[i - 1] != 0 )
390 break;
391}
392
393/* Calculate and apply the encryption mask. Process use_len bytes of data,
394 * starting at position offset in the mask block. */
395static int gcm_mask( mbedtls_gcm_context *ctx,
396 unsigned char ectr[16],
397 size_t offset, size_t use_len,
398 const unsigned char *input,
399 unsigned char *output )
400{
401 size_t i;
402 size_t olen = 0;
403 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
404
405 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
406 &olen ) ) != 0 )
407 {
408 mbedtls_platform_zeroize( ectr, 16 );
409 return( ret );
410 }
411
412 for( i = 0; i < use_len; i++ )
413 {
414 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
415 ctx->buf[offset + i] ^= input[i];
416 output[i] = ectr[offset + i] ^ input[i];
417 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
418 ctx->buf[offset + i] ^= output[i];
419 }
420 return( 0 );
421}
422
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200424 const unsigned char *input, size_t input_length,
425 unsigned char *output, size_t output_size,
426 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200427{
Janos Follath24eed8d2019-11-22 13:21:35 +0000428 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200429 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200430 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200431 size_t offset;
432 unsigned char ectr[16];
433
Gilles Peskinea56c4482021-04-15 17:22:35 +0200434 if( output_size < input_length )
435 return( MBEDTLS_ERR_GCM_BAD_INPUT );
436 GCM_VALIDATE_RET( output_length != NULL );
437 *output_length = input_length;
438
439 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200440 * on a potentially null pointer.
441 * Returning early also means that the last partial block of AD remains
442 * untouched for mbedtls_gcm_finish */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200443 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200444 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200445
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100446 GCM_VALIDATE_RET( ctx != NULL );
Gilles Peskine58fc2722021-04-13 15:58:27 +0200447 GCM_VALIDATE_RET( input != NULL );
448 GCM_VALIDATE_RET( output != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100449
Gilles Peskinea56c4482021-04-15 17:22:35 +0200450 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200452
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200453 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
454 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200455 if( ctx->len + input_length < ctx->len ||
456 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200457 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200459 }
460
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200461 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200462 {
463 gcm_mult( ctx, ctx->buf, ctx->buf );
464 }
465
Gilles Peskine58fc2722021-04-13 15:58:27 +0200466 offset = ctx->len % 16;
467 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000468 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200469 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200470 if( use_len > input_length )
471 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000472
Gilles Peskine58fc2722021-04-13 15:58:27 +0200473 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200474 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000475
Gilles Peskine58fc2722021-04-13 15:58:27 +0200476 if( offset + use_len == 16 )
477 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200478
Gilles Peskine58fc2722021-04-13 15:58:27 +0200479 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200480 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000481 p += use_len;
482 out_p += use_len;
483 }
484
Gilles Peskinea56c4482021-04-15 17:22:35 +0200485 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200486
Gilles Peskinea56c4482021-04-15 17:22:35 +0200487 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200488 {
489 gcm_incr( ctx->y );
490 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
491 return( ret );
492
493 gcm_mult( ctx, ctx->buf, ctx->buf );
494
Gilles Peskinea56c4482021-04-15 17:22:35 +0200495 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200496 p += 16;
497 out_p += 16;
498 }
499
Gilles Peskinea56c4482021-04-15 17:22:35 +0200500 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200501 {
502 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200503 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200504 return( ret );
505 }
506
507 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200508 return( 0 );
509}
510
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200512 unsigned char *output, size_t output_size,
Gilles Peskine5a7be102021-06-23 21:51:32 +0200513 size_t *output_length,
Gilles Peskine9461e452021-04-15 16:48:32 +0200514 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200515{
516 unsigned char work_buf[16];
517 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100518 uint64_t orig_len;
519 uint64_t orig_add_len;
520
521 GCM_VALIDATE_RET( ctx != NULL );
522 GCM_VALIDATE_RET( tag != NULL );
523
Gilles Peskine9461e452021-04-15 16:48:32 +0200524 /* We never pass any output in finish(). The output parameter exists only
525 * for the sake of alternative implementations. */
526 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200527 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200528 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200529
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100530 orig_len = ctx->len * 8;
531 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200532
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200533 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200534 {
535 gcm_mult( ctx, ctx->buf, ctx->buf );
536 }
537
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200538 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200539 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200540
Gilles Peskine58fc2722021-04-13 15:58:27 +0200541 if( ctx->len % 16 != 0 )
542 gcm_mult( ctx, ctx->buf, ctx->buf );
543
Andres AG821da842016-09-26 10:09:30 +0100544 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200545
Paul Bakker89e80c92012-03-20 13:50:09 +0000546 if( orig_len || orig_add_len )
547 {
548 memset( work_buf, 0x00, 16 );
549
Joe Subbiani5ecac212021-06-24 13:00:03 +0100550 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
551 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
552 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
553 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000554
Paul Bakker67f9d532012-10-23 11:49:05 +0000555 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200556 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000557
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200558 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000559
Paul Bakker67f9d532012-10-23 11:49:05 +0000560 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200561 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000562 }
563
564 return( 0 );
565}
566
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200568 int mode,
569 size_t length,
570 const unsigned char *iv,
571 size_t iv_len,
572 const unsigned char *add,
573 size_t add_len,
574 const unsigned char *input,
575 unsigned char *output,
576 size_t tag_len,
577 unsigned char *tag )
578{
Janos Follath24eed8d2019-11-22 13:21:35 +0000579 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200580 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200581
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100582 GCM_VALIDATE_RET( ctx != NULL );
583 GCM_VALIDATE_RET( iv != NULL );
584 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
585 GCM_VALIDATE_RET( length == 0 || input != NULL );
586 GCM_VALIDATE_RET( length == 0 || output != NULL );
587 GCM_VALIDATE_RET( tag != NULL );
588
Gilles Peskine295fc132021-04-15 18:32:23 +0200589 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
590 return( ret );
591
592 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200593 return( ret );
594
Gilles Peskinea56c4482021-04-15 17:22:35 +0200595 if( ( ret = mbedtls_gcm_update( ctx, input, length,
596 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200597 return( ret );
598
Gilles Peskine5a7be102021-06-23 21:51:32 +0200599 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200600 return( ret );
601
602 return( 0 );
603}
604
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000606 size_t length,
607 const unsigned char *iv,
608 size_t iv_len,
609 const unsigned char *add,
610 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200611 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000612 size_t tag_len,
613 const unsigned char *input,
614 unsigned char *output )
615{
Janos Follath24eed8d2019-11-22 13:21:35 +0000616 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000617 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200618 size_t i;
619 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000620
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100621 GCM_VALIDATE_RET( ctx != NULL );
622 GCM_VALIDATE_RET( iv != NULL );
623 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
624 GCM_VALIDATE_RET( tag != NULL );
625 GCM_VALIDATE_RET( length == 0 || input != NULL );
626 GCM_VALIDATE_RET( length == 0 || output != NULL );
627
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100629 iv, iv_len, add, add_len,
630 input, output, tag_len, check_tag ) ) != 0 )
631 {
632 return( ret );
633 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000634
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200635 /* Check tag in "constant-time" */
636 for( diff = 0, i = 0; i < tag_len; i++ )
637 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000638
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200639 if( diff != 0 )
640 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500641 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200642 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200643 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000644
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200645 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000646}
647
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200649{
k-stachowiak21298a22018-12-13 17:11:58 +0100650 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100651 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200652 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500653 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200654}
655
Jaeden Amero15263302017-09-21 12:53:48 +0100656#endif /* !MBEDTLS_GCM_ALT */
657
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200658#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000659/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200660 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000661 *
662 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
663 */
664#define MAX_TESTS 6
665
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100666static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000667 { 0, 0, 1, 1, 1, 1 };
668
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100669static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000670{
671 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
676 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
677 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200678 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000679};
680
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100681static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000682 { 12, 12, 12, 12, 8, 60 };
683
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100684static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000685 { 0, 0, 1, 1, 1, 2 };
686
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100687static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000688{
689 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690 0x00, 0x00, 0x00, 0x00 },
691 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
692 0xde, 0xca, 0xf8, 0x88 },
693 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200694 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000695 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200696 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000701};
702
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100703static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000704 { 0, 0, 0, 20, 20, 20 };
705
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100706static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000707 { 0, 0, 0, 1, 1, 1 };
708
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100709static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000710{
711 { 0x00 },
712 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200713 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000714 0xab, 0xad, 0xda, 0xd2 },
715};
716
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100717static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000718 { 0, 16, 64, 60, 60, 60 };
719
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100720static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000721 { 0, 0, 1, 1, 1, 1 };
722
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100723static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000724{
725 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
726 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
727 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
728 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
729 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
730 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
731 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
732 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
733 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
734 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
735};
736
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100737static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000738{
739 { 0x00 },
740 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
741 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
742 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200743 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000744 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200745 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000746 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200747 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000748 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
749 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
750 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200751 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000752 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200753 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000754 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200755 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000756 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
757 0x3d, 0x58, 0xe0, 0x91 },
758 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200759 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000760 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200761 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000762 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200763 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000764 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
765 0xc2, 0x3f, 0x45, 0x98 },
766 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200767 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000768 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200769 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000770 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200771 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000772 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
773 0x4c, 0x34, 0xae, 0xe5 },
774 { 0x00 },
775 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200776 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000777 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200778 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000779 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200780 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000781 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200782 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000783 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
784 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
785 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200786 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000787 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200788 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
789 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
790 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000791 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200792 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000793 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200794 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000795 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200796 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000797 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200798 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000799 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200800 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000801 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200802 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000803 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200804 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000805 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200806 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000807 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200808 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000809 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200810 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
811 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
812 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
813 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
814 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
815 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
816 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
817 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
818 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
819 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
820 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
821 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
822 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
823 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
824 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
825 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
826 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
827 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000828 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200829 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000830 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200831 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000832 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200833 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000834 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200835 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000836 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200837 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000838 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200839 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000840 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200841 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000842 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200843 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000844};
845
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100846static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000847{
848 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
849 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
850 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
851 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
852 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200853 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000854 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
855 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
856 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
857 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
858 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
859 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
860 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
861 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
862 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200863 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000864 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
865 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
866 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200867 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000868 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200869 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000870 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200871 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000872 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200873 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000874 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200875 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000876 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200877 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000878 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200879 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000880 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200881 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000882 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200883 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000884};
885
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200886int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000887{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200888 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000889 unsigned char buf[64];
890 unsigned char tag_buf[16];
891 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200893 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000894
895 for( j = 0; j < 3; j++ )
896 {
897 int key_len = 128 + 64 * j;
898
899 for( i = 0; i < MAX_TESTS; i++ )
900 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100901 mbedtls_gcm_init( &ctx );
902
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200903 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100905 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200906
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500907 ret = mbedtls_gcm_setkey( &ctx, cipher,
908 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100909 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100910 /*
911 * AES-192 is an optional feature that may be unavailable when
912 * there is an alternative underlying implementation i.e. when
913 * MBEDTLS_AES_ALT is defined.
914 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300915 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100916 {
917 mbedtls_printf( "skipped\n" );
918 break;
919 }
920 else if( ret != 0 )
921 {
922 goto exit;
923 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000924
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200925 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500926 pt_len_test_data[i],
927 iv_test_data[iv_index_test_data[i]],
928 iv_len_test_data[i],
929 additional_test_data[add_index_test_data[i]],
930 add_len_test_data[i],
931 pt_test_data[pt_index_test_data[i]],
932 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100933#if defined(MBEDTLS_GCM_ALT)
934 /* Allow alternative implementations to only support 12-byte nonces. */
935 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
936 iv_len_test_data[i] != 12 )
937 {
938 mbedtls_printf( "skipped\n" );
939 break;
940 }
941#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100942 if( ret != 0 )
943 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000944
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500945 if ( memcmp( buf, ct_test_data[j * 6 + i],
946 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100947 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000948 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100949 ret = 1;
950 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000951 }
952
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200954
Paul Bakker89e80c92012-03-20 13:50:09 +0000955 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200956 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000957
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100958 mbedtls_gcm_init( &ctx );
959
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200960 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100962 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200963
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500964 ret = mbedtls_gcm_setkey( &ctx, cipher,
965 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100966 key_len );
967 if( ret != 0 )
968 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000969
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200970 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500971 pt_len_test_data[i],
972 iv_test_data[iv_index_test_data[i]],
973 iv_len_test_data[i],
974 additional_test_data[add_index_test_data[i]],
975 add_len_test_data[i],
976 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000977
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100978 if( ret != 0 )
979 goto exit;
980
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100981 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
982 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100983 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000984 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100985 ret = 1;
986 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000987 }
988
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200990
Paul Bakker89e80c92012-03-20 13:50:09 +0000991 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200992 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200993
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100994 mbedtls_gcm_init( &ctx );
995
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200996 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200997 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100998 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200999
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001000 ret = mbedtls_gcm_setkey( &ctx, cipher,
1001 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001002 key_len );
1003 if( ret != 0 )
1004 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001005
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001006 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001007 iv_test_data[iv_index_test_data[i]],
1008 iv_len_test_data[i] );
1009 if( ret != 0 )
1010 goto exit;
1011
1012 ret = mbedtls_gcm_update_ad( &ctx,
1013 additional_test_data[add_index_test_data[i]],
1014 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001015 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001016 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001017
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001018 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001019 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001020 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001021 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001022 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001023 32,
1024 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001025 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001026 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001027 if( olen != 32 )
1028 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001029
Gilles Peskinea56c4482021-04-15 17:22:35 +02001030 ret = mbedtls_gcm_update( &ctx,
1031 pt_test_data[pt_index_test_data[i]] + 32,
1032 rest_len,
1033 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001034 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001035 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001036 if( olen != rest_len )
1037 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001038 }
1039 else
1040 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001041 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001042 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001043 pt_len_test_data[i],
1044 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001045 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001046 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001047 if( olen != pt_len_test_data[i] )
1048 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001049 }
1050
Gilles Peskine5a7be102021-06-23 21:51:32 +02001051 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001052 if( ret != 0 )
1053 goto exit;
1054
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001055 if( memcmp( buf, ct_test_data[j * 6 + i],
1056 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001057 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001058 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001059 ret = 1;
1060 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001061 }
1062
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001063 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001064
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001065 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001066 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001067
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001068 mbedtls_gcm_init( &ctx );
1069
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001070 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001071 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001072 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001073
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001074 ret = mbedtls_gcm_setkey( &ctx, cipher,
1075 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001076 key_len );
1077 if( ret != 0 )
1078 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001079
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001080 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001081 iv_test_data[iv_index_test_data[i]],
1082 iv_len_test_data[i] );
1083 if( ret != 0 )
1084 goto exit;
1085 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001086 additional_test_data[add_index_test_data[i]],
1087 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001088 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001089 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001090
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001091 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001092 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001093 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001094 ret = mbedtls_gcm_update( &ctx,
1095 ct_test_data[j * 6 + i], 32,
1096 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001097 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001098 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001099 if( olen != 32 )
1100 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001101
Gilles Peskinea56c4482021-04-15 17:22:35 +02001102 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001103 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001104 rest_len,
1105 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001106 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001107 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001108 if( olen != rest_len )
1109 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001110 }
1111 else
1112 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001113 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001114 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001115 pt_len_test_data[i],
1116 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001117 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001118 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001119 if( olen != pt_len_test_data[i] )
1120 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001121 }
1122
Gilles Peskine5a7be102021-06-23 21:51:32 +02001123 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001124 if( ret != 0 )
1125 goto exit;
1126
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001127 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1128 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001129 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001130 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001131 ret = 1;
1132 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001133 }
1134
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001135 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001136
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001137 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001138 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001139 }
1140 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001141
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001142 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001143 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001144
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001145 ret = 0;
1146
1147exit:
1148 if( ret != 0 )
1149 {
1150 if( verbose != 0 )
1151 mbedtls_printf( "failed\n" );
1152 mbedtls_gcm_free( &ctx );
1153 }
1154
1155 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001156}
1157
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001158#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001160#endif /* MBEDTLS_GCM_C */