blob: b575c8f31654bdac72595774d017dddc6958e1da [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;
openluopworld2beb5f32021-09-17 16:40:22 +0800257 size_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 );
openluopworld2beb5f32021-09-17 16:40:22 +0800282 iv_bits = iv_len << 3;
283 MBEDTLS_PUT_UINT32_BE( (iv_bits >> 32), work_buf, 8 );
284 MBEDTLS_PUT_UINT32_BE( iv_bits, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000285
286 p = iv;
287 while( iv_len > 0 )
288 {
289 use_len = ( iv_len < 16 ) ? iv_len : 16;
290
Paul Bakker67f9d532012-10-23 11:49:05 +0000291 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200292 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200293
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200294 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000295
296 iv_len -= use_len;
297 p += use_len;
298 }
299
Paul Bakker67f9d532012-10-23 11:49:05 +0000300 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200301 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000302
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200303 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000304 }
305
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500306 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
307 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200308 {
309 return( ret );
310 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000311
Gilles Peskine295fc132021-04-15 18:32:23 +0200312 return( 0 );
313}
314
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200315/**
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200316 * mbedtls_gcm_context::buf contains the partial state of the computation of
317 * the authentication tag.
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200318 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
319 * different stages of the computation:
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200320 * * len == 0 && add_len == 0: initial state
321 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
322 * a partial block of AD that has been
323 * xored in but not yet multiplied in.
324 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
325 * the data ends now.
326 * * len % 16 != 0: the first `len % 16` bytes have
327 * a partial block of ciphertext that has
328 * been xored in but not yet multiplied in.
329 * * len > 0 && len % 16 == 0: the authentication tag is correct if
330 * the data ends now.
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200331 */
Gilles Peskine295fc132021-04-15 18:32:23 +0200332int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
333 const unsigned char *add, size_t add_len )
334{
335 const unsigned char *p;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200336 size_t use_len, i, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200337
338 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
339
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200340 /* IV is limited to 2^64 bits, so 2^61 bytes */
Gilles Peskine295fc132021-04-15 18:32:23 +0200341 if( (uint64_t) add_len >> 61 != 0 )
342 return( MBEDTLS_ERR_GCM_BAD_INPUT );
343
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200344 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000345 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200346
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200347 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000348 {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200349 use_len = 16 - offset;
350 if( use_len > add_len )
351 use_len = add_len;
352
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200353 for( i = 0; i < use_len; i++ )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200354 ctx->buf[i+offset] ^= p[i];
355
356 if( offset + use_len == 16 )
357 gcm_mult( ctx, ctx->buf, ctx->buf );
358
359 ctx->add_len += use_len;
360 add_len -= use_len;
361 p += use_len;
362 }
363
364 ctx->add_len += add_len;
365
366 while( add_len >= 16 )
367 {
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200368 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200369 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200370
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200371 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000372
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200373 add_len -= 16;
374 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000375 }
376
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200377 if( add_len > 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200378 {
379 for( i = 0; i < add_len; i++ )
380 ctx->buf[i] ^= p[i];
381 }
382
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200383 return( 0 );
384}
385
Gilles Peskine58fc2722021-04-13 15:58:27 +0200386/* Increment the counter. */
387static void gcm_incr( unsigned char y[16] )
388{
389 size_t i;
390 for( i = 16; i > 12; i-- )
391 if( ++y[i - 1] != 0 )
392 break;
393}
394
395/* Calculate and apply the encryption mask. Process use_len bytes of data,
396 * starting at position offset in the mask block. */
397static int gcm_mask( mbedtls_gcm_context *ctx,
398 unsigned char ectr[16],
399 size_t offset, size_t use_len,
400 const unsigned char *input,
401 unsigned char *output )
402{
403 size_t i;
404 size_t olen = 0;
405 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
406
407 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
408 &olen ) ) != 0 )
409 {
410 mbedtls_platform_zeroize( ectr, 16 );
411 return( ret );
412 }
413
414 for( i = 0; i < use_len; i++ )
415 {
416 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
417 ctx->buf[offset + i] ^= input[i];
418 output[i] = ectr[offset + i] ^ input[i];
419 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
420 ctx->buf[offset + i] ^= output[i];
421 }
422 return( 0 );
423}
424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200426 const unsigned char *input, size_t input_length,
427 unsigned char *output, size_t output_size,
428 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200429{
Janos Follath24eed8d2019-11-22 13:21:35 +0000430 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200431 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200432 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200433 size_t offset;
434 unsigned char ectr[16];
435
Gilles Peskinea56c4482021-04-15 17:22:35 +0200436 if( output_size < input_length )
437 return( MBEDTLS_ERR_GCM_BAD_INPUT );
438 GCM_VALIDATE_RET( output_length != NULL );
439 *output_length = input_length;
440
441 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200442 * on a potentially null pointer.
443 * Returning early also means that the last partial block of AD remains
444 * untouched for mbedtls_gcm_finish */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200445 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200446 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200447
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100448 GCM_VALIDATE_RET( ctx != NULL );
Gilles Peskine58fc2722021-04-13 15:58:27 +0200449 GCM_VALIDATE_RET( input != NULL );
450 GCM_VALIDATE_RET( output != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100451
Gilles Peskinea56c4482021-04-15 17:22:35 +0200452 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200454
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200455 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
456 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200457 if( ctx->len + input_length < ctx->len ||
458 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200459 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200461 }
462
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200463 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200464 {
465 gcm_mult( ctx, ctx->buf, ctx->buf );
466 }
467
Gilles Peskine58fc2722021-04-13 15:58:27 +0200468 offset = ctx->len % 16;
469 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000470 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200471 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200472 if( use_len > input_length )
473 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000474
Gilles Peskine58fc2722021-04-13 15:58:27 +0200475 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200476 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000477
Gilles Peskine58fc2722021-04-13 15:58:27 +0200478 if( offset + use_len == 16 )
479 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200480
Gilles Peskine58fc2722021-04-13 15:58:27 +0200481 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200482 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000483 p += use_len;
484 out_p += use_len;
485 }
486
Gilles Peskinea56c4482021-04-15 17:22:35 +0200487 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200488
Gilles Peskinea56c4482021-04-15 17:22:35 +0200489 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200490 {
491 gcm_incr( ctx->y );
492 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
493 return( ret );
494
495 gcm_mult( ctx, ctx->buf, ctx->buf );
496
Gilles Peskinea56c4482021-04-15 17:22:35 +0200497 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200498 p += 16;
499 out_p += 16;
500 }
501
Gilles Peskinea56c4482021-04-15 17:22:35 +0200502 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200503 {
504 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200505 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200506 return( ret );
507 }
508
509 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200510 return( 0 );
511}
512
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200513int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200514 unsigned char *output, size_t output_size,
Gilles Peskine5a7be102021-06-23 21:51:32 +0200515 size_t *output_length,
Gilles Peskine9461e452021-04-15 16:48:32 +0200516 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200517{
518 unsigned char work_buf[16];
519 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100520 uint64_t orig_len;
521 uint64_t orig_add_len;
522
523 GCM_VALIDATE_RET( ctx != NULL );
524 GCM_VALIDATE_RET( tag != NULL );
525
Gilles Peskine9461e452021-04-15 16:48:32 +0200526 /* We never pass any output in finish(). The output parameter exists only
527 * for the sake of alternative implementations. */
528 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200529 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200530 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200531
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100532 orig_len = ctx->len * 8;
533 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200534
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200535 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200536 {
537 gcm_mult( ctx, ctx->buf, ctx->buf );
538 }
539
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200540 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200541 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200542
Gilles Peskine58fc2722021-04-13 15:58:27 +0200543 if( ctx->len % 16 != 0 )
544 gcm_mult( ctx, ctx->buf, ctx->buf );
545
Andres AG821da842016-09-26 10:09:30 +0100546 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200547
Paul Bakker89e80c92012-03-20 13:50:09 +0000548 if( orig_len || orig_add_len )
549 {
550 memset( work_buf, 0x00, 16 );
551
Joe Subbiani5ecac212021-06-24 13:00:03 +0100552 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
553 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
554 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
555 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000556
Paul Bakker67f9d532012-10-23 11:49:05 +0000557 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200558 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000559
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200560 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000561
Paul Bakker67f9d532012-10-23 11:49:05 +0000562 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200563 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000564 }
565
566 return( 0 );
567}
568
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200570 int mode,
571 size_t length,
572 const unsigned char *iv,
573 size_t iv_len,
574 const unsigned char *add,
575 size_t add_len,
576 const unsigned char *input,
577 unsigned char *output,
578 size_t tag_len,
579 unsigned char *tag )
580{
Janos Follath24eed8d2019-11-22 13:21:35 +0000581 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200582 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200583
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100584 GCM_VALIDATE_RET( ctx != NULL );
585 GCM_VALIDATE_RET( iv != NULL );
586 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
587 GCM_VALIDATE_RET( length == 0 || input != NULL );
588 GCM_VALIDATE_RET( length == 0 || output != NULL );
589 GCM_VALIDATE_RET( tag != NULL );
590
Gilles Peskine295fc132021-04-15 18:32:23 +0200591 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
592 return( ret );
593
594 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200595 return( ret );
596
Gilles Peskinea56c4482021-04-15 17:22:35 +0200597 if( ( ret = mbedtls_gcm_update( ctx, input, length,
598 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200599 return( ret );
600
Gilles Peskine5a7be102021-06-23 21:51:32 +0200601 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200602 return( ret );
603
604 return( 0 );
605}
606
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000608 size_t length,
609 const unsigned char *iv,
610 size_t iv_len,
611 const unsigned char *add,
612 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200613 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000614 size_t tag_len,
615 const unsigned char *input,
616 unsigned char *output )
617{
Janos Follath24eed8d2019-11-22 13:21:35 +0000618 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000619 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200620 size_t i;
621 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000622
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100623 GCM_VALIDATE_RET( ctx != NULL );
624 GCM_VALIDATE_RET( iv != NULL );
625 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
626 GCM_VALIDATE_RET( tag != NULL );
627 GCM_VALIDATE_RET( length == 0 || input != NULL );
628 GCM_VALIDATE_RET( length == 0 || output != NULL );
629
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200630 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100631 iv, iv_len, add, add_len,
632 input, output, tag_len, check_tag ) ) != 0 )
633 {
634 return( ret );
635 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000636
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200637 /* Check tag in "constant-time" */
638 for( diff = 0, i = 0; i < tag_len; i++ )
639 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000640
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200641 if( diff != 0 )
642 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500643 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200645 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000646
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200647 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000648}
649
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200651{
k-stachowiak21298a22018-12-13 17:11:58 +0100652 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100653 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500655 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200656}
657
Jaeden Amero15263302017-09-21 12:53:48 +0100658#endif /* !MBEDTLS_GCM_ALT */
659
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000661/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200662 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000663 *
664 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
665 */
666#define MAX_TESTS 6
667
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100668static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000669 { 0, 0, 1, 1, 1, 1 };
670
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100671static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000672{
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
677 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
678 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
679 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200680 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000681};
682
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100683static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000684 { 12, 12, 12, 12, 8, 60 };
685
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100686static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000687 { 0, 0, 1, 1, 1, 2 };
688
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100689static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000690{
691 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692 0x00, 0x00, 0x00, 0x00 },
693 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
694 0xde, 0xca, 0xf8, 0x88 },
695 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200696 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200702 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000703};
704
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100705static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000706 { 0, 0, 0, 20, 20, 20 };
707
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100708static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000709 { 0, 0, 0, 1, 1, 1 };
710
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100711static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000712{
713 { 0x00 },
714 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200715 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000716 0xab, 0xad, 0xda, 0xd2 },
717};
718
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100719static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000720 { 0, 16, 64, 60, 60, 60 };
721
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100722static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000723 { 0, 0, 1, 1, 1, 1 };
724
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100725static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000726{
727 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
729 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
730 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
731 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
732 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
733 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
734 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
735 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
736 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
737};
738
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100739static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000740{
741 { 0x00 },
742 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
743 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
744 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200745 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000746 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200747 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000748 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200749 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000750 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
751 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
752 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200753 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000754 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200755 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000756 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200757 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000758 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
759 0x3d, 0x58, 0xe0, 0x91 },
760 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200761 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000762 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200763 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000764 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200765 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000766 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
767 0xc2, 0x3f, 0x45, 0x98 },
768 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200769 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000770 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200771 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000772 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200773 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000774 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
775 0x4c, 0x34, 0xae, 0xe5 },
776 { 0x00 },
777 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200778 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000779 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200780 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000781 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200782 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000783 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200784 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000785 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
786 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
787 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200788 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000789 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200790 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
791 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
792 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000793 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200794 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000795 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200796 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000797 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200798 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000799 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200800 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000801 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200802 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000803 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200804 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000805 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200806 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000807 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200808 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000809 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200810 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000811 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200812 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
813 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
814 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
815 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
816 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
817 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
818 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
819 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
820 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
821 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
822 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
823 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
824 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
825 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
826 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
827 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
828 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
829 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000830 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200831 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000832 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200833 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000834 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200835 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000836 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200837 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000838 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200839 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000840 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200841 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000842 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200843 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000844 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200845 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000846};
847
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100848static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000849{
850 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
851 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
852 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
853 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
854 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200855 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000856 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
857 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
858 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
859 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
860 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
861 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
862 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
863 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
864 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200865 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000866 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
867 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
868 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200869 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000870 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200871 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000872 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200873 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000874 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200875 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000876 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200877 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000878 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200879 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000880 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200881 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000882 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200883 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000884 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200885 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000886};
887
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200888int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000889{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000891 unsigned char buf[64];
892 unsigned char tag_buf[16];
893 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200894 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200895 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000896
897 for( j = 0; j < 3; j++ )
898 {
899 int key_len = 128 + 64 * j;
900
901 for( i = 0; i < MAX_TESTS; i++ )
902 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100903 mbedtls_gcm_init( &ctx );
904
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200905 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200906 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100907 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200908
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500909 ret = mbedtls_gcm_setkey( &ctx, cipher,
910 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100911 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100912 /*
913 * AES-192 is an optional feature that may be unavailable when
914 * there is an alternative underlying implementation i.e. when
915 * MBEDTLS_AES_ALT is defined.
916 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300917 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100918 {
919 mbedtls_printf( "skipped\n" );
920 break;
921 }
922 else if( ret != 0 )
923 {
924 goto exit;
925 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000926
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500928 pt_len_test_data[i],
929 iv_test_data[iv_index_test_data[i]],
930 iv_len_test_data[i],
931 additional_test_data[add_index_test_data[i]],
932 add_len_test_data[i],
933 pt_test_data[pt_index_test_data[i]],
934 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100935#if defined(MBEDTLS_GCM_ALT)
936 /* Allow alternative implementations to only support 12-byte nonces. */
937 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
938 iv_len_test_data[i] != 12 )
939 {
940 mbedtls_printf( "skipped\n" );
941 break;
942 }
943#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100944 if( ret != 0 )
945 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000946
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500947 if ( memcmp( buf, ct_test_data[j * 6 + i],
948 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100949 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000950 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100951 ret = 1;
952 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000953 }
954
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200955 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200956
Paul Bakker89e80c92012-03-20 13:50:09 +0000957 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000959
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100960 mbedtls_gcm_init( &ctx );
961
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200962 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100964 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200965
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500966 ret = mbedtls_gcm_setkey( &ctx, cipher,
967 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100968 key_len );
969 if( ret != 0 )
970 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000971
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500973 pt_len_test_data[i],
974 iv_test_data[iv_index_test_data[i]],
975 iv_len_test_data[i],
976 additional_test_data[add_index_test_data[i]],
977 add_len_test_data[i],
978 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000979
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100980 if( ret != 0 )
981 goto exit;
982
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100983 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
984 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100985 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000986 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100987 ret = 1;
988 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000989 }
990
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200991 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200992
Paul Bakker89e80c92012-03-20 13:50:09 +0000993 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200994 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200995
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100996 mbedtls_gcm_init( &ctx );
997
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200998 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001000 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001001
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001002 ret = mbedtls_gcm_setkey( &ctx, cipher,
1003 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001004 key_len );
1005 if( ret != 0 )
1006 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001007
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001008 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001009 iv_test_data[iv_index_test_data[i]],
1010 iv_len_test_data[i] );
1011 if( ret != 0 )
1012 goto exit;
1013
1014 ret = mbedtls_gcm_update_ad( &ctx,
1015 additional_test_data[add_index_test_data[i]],
1016 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001017 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001018 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001019
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001020 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001021 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001022 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001023 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001024 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001025 32,
1026 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001027 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001028 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001029 if( olen != 32 )
1030 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001031
Gilles Peskinea56c4482021-04-15 17:22:35 +02001032 ret = mbedtls_gcm_update( &ctx,
1033 pt_test_data[pt_index_test_data[i]] + 32,
1034 rest_len,
1035 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001036 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001037 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001038 if( olen != rest_len )
1039 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001040 }
1041 else
1042 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001043 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001044 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001045 pt_len_test_data[i],
1046 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001047 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001048 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001049 if( olen != pt_len_test_data[i] )
1050 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001051 }
1052
Gilles Peskine5a7be102021-06-23 21:51:32 +02001053 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001054 if( ret != 0 )
1055 goto exit;
1056
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001057 if( memcmp( buf, ct_test_data[j * 6 + i],
1058 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001059 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001060 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001061 ret = 1;
1062 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001063 }
1064
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001065 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001066
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001067 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001068 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001069
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001070 mbedtls_gcm_init( &ctx );
1071
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001072 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001073 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001074 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001075
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001076 ret = mbedtls_gcm_setkey( &ctx, cipher,
1077 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001078 key_len );
1079 if( ret != 0 )
1080 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001081
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001082 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001083 iv_test_data[iv_index_test_data[i]],
1084 iv_len_test_data[i] );
1085 if( ret != 0 )
1086 goto exit;
1087 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001088 additional_test_data[add_index_test_data[i]],
1089 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001090 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001091 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001092
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001093 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001094 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001095 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001096 ret = mbedtls_gcm_update( &ctx,
1097 ct_test_data[j * 6 + i], 32,
1098 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001099 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001100 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001101 if( olen != 32 )
1102 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001103
Gilles Peskinea56c4482021-04-15 17:22:35 +02001104 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001105 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001106 rest_len,
1107 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001108 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001109 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001110 if( olen != rest_len )
1111 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001112 }
1113 else
1114 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001115 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001116 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001117 pt_len_test_data[i],
1118 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001119 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001120 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001121 if( olen != pt_len_test_data[i] )
1122 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001123 }
1124
Gilles Peskine5a7be102021-06-23 21:51:32 +02001125 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001126 if( ret != 0 )
1127 goto exit;
1128
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001129 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1130 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001131 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001132 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001133 ret = 1;
1134 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001135 }
1136
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001137 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001138
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001139 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001140 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001141 }
1142 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001143
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001144 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001145 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001146
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001147 ret = 0;
1148
1149exit:
1150 if( ret != 0 )
1151 {
1152 if( verbose != 0 )
1153 mbedtls_printf( "failed\n" );
1154 mbedtls_gcm_free( &ctx );
1155 }
1156
1157 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001158}
1159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001160#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001161
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001162#endif /* MBEDTLS_GCM_C */