blob: 53275c3fea60856c50916495baec57a3272724a6 [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"
Gilles Peskineed1c7f42022-09-15 20:14:22 +020035#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050036#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000037#include "mbedtls/error.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000042#include "aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010043#endif
44
Jaeden Amero15263302017-09-21 12:53:48 +010045#if !defined(MBEDTLS_GCM_ALT)
46
k-stachowiak8ffc92a2018-12-12 14:21:59 +010047/* Parameter validation macros */
48#define GCM_VALIDATE_RET( cond ) \
49 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
50#define GCM_VALIDATE( cond ) \
51 MBEDTLS_INTERNAL_VALIDATE( cond )
52
Paul Bakker89e80c92012-03-20 13:50:09 +000053/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020054 * Initialize a context
55 */
56void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
57{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010058 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020059 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
60}
61
62/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010063 * Precompute small multiples of H, that is set
64 * HH[i] || HL[i] = H times i,
65 * where i is seen as a field element as in [MGV], ie high-order bits
66 * correspond to low powers of P. The result is stored in the same way, that
67 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
68 * corresponds to P^127.
69 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000071{
Paul Bakker43aff2a2013-09-09 00:10:27 +020072 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000073 uint64_t hi, lo;
74 uint64_t vl, vh;
75 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020076 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020077
Paul Bakker89e80c92012-03-20 13:50:09 +000078 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +020080 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000081
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010082 /* pack h as two 64-bits ints, big-endian */
Joe Subbiani6a506312021-07-07 16:56:29 +010083 hi = MBEDTLS_GET_UINT32_BE( h, 0 );
84 lo = MBEDTLS_GET_UINT32_BE( h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000085 vh = (uint64_t) hi << 32 | lo;
86
Joe Subbiani6a506312021-07-07 16:56:29 +010087 hi = MBEDTLS_GET_UINT32_BE( h, 8 );
88 lo = MBEDTLS_GET_UINT32_BE( h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000089 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020090
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010091 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +000092 ctx->HL[8] = vl;
93 ctx->HH[8] = vh;
94
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020095#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010096 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +010097 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010098 return( 0 );
99#endif
100
101 /* 0 corresponds to 0 in GF(2^128) */
102 ctx->HH[0] = 0;
103 ctx->HL[0] = 0;
104
Paul Bakker89e80c92012-03-20 13:50:09 +0000105 for( i = 4; i > 0; i >>= 1 )
106 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200107 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000108 vl = ( vh << 63 ) | ( vl >> 1 );
109 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
110
111 ctx->HL[i] = vl;
112 ctx->HH[i] = vh;
113 }
114
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000115 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000116 {
117 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
118 vh = *HiH;
119 vl = *HiL;
120 for( j = 1; j < i; j++ )
121 {
122 HiH[j] = vh ^ ctx->HH[j];
123 HiL[j] = vl ^ ctx->HL[j];
124 }
125 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200126
127 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000128}
129
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200130int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
131 mbedtls_cipher_id_t cipher,
132 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200133 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000134{
Janos Follath24eed8d2019-11-22 13:21:35 +0000135 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200136 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000137
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100138 GCM_VALIDATE_RET( ctx != NULL );
139 GCM_VALIDATE_RET( key != NULL );
140 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
141
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500142 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
143 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200144 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200145 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200146
Paul Bakkera0558e02013-09-10 14:25:51 +0200147 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200148 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200149
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200150 mbedtls_cipher_free( &ctx->cipher_ctx );
151
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200152 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000153 return( ret );
154
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200155 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200157 {
158 return( ret );
159 }
160
161 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
162 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000163
164 return( 0 );
165}
166
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100167/*
168 * Shoup's method for multiplication use this table with
169 * last4[x] = x times P^128
170 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
171 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000172static const uint64_t last4[16] =
173{
174 0x0000, 0x1c20, 0x3840, 0x2460,
175 0x7080, 0x6ca0, 0x48c0, 0x54e0,
176 0xe100, 0xfd20, 0xd940, 0xc560,
177 0x9180, 0x8da0, 0xa9c0, 0xb5e0
178};
179
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100180/*
181 * Sets output to x times H using the precomputed tables.
182 * x and output are seen as elements of GF(2^128) as in [MGV].
183 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200184static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200185 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000186{
187 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000188 unsigned char lo, hi, rem;
189 uint64_t zh, zl;
190
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200191#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100192 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100193 unsigned char h[16];
194
Joe Subbiani5ecac212021-06-24 13:00:03 +0100195 MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
196 MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 );
197 MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
198 MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100199
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100201 return;
202 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100204
Paul Bakker89e80c92012-03-20 13:50:09 +0000205 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000206
207 zh = ctx->HH[lo];
208 zl = ctx->HL[lo];
209
210 for( i = 15; i >= 0; i-- )
211 {
212 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200213 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000214
215 if( i != 15 )
216 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000217 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000218 zl = ( zh << 60 ) | ( zl >> 4 );
219 zh = ( zh >> 4 );
220 zh ^= (uint64_t) last4[rem] << 48;
221 zh ^= ctx->HH[lo];
222 zl ^= ctx->HL[lo];
223
224 }
225
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000226 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000227 zl = ( zh << 60 ) | ( zl >> 4 );
228 zh = ( zh >> 4 );
229 zh ^= (uint64_t) last4[rem] << 48;
230 zh ^= ctx->HH[hi];
231 zl ^= ctx->HL[hi];
232 }
233
Joe Subbiani5ecac212021-06-24 13:00:03 +0100234 MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
235 MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
236 MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
237 MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000238}
239
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200240int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Gilles Peskine295fc132021-04-15 18:32:23 +0200241 int mode,
242 const unsigned char *iv, size_t iv_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000243{
Janos Follath24eed8d2019-11-22 13:21:35 +0000244 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000245 unsigned char work_buf[16];
246 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000247 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200248 size_t use_len, olen = 0;
openluopworldeab65ac2021-09-22 23:59:42 +0800249 uint64_t iv_bits;
Paul Bakker89e80c92012-03-20 13:50:09 +0000250
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100251 GCM_VALIDATE_RET( ctx != NULL );
252 GCM_VALIDATE_RET( iv != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100253
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200254 /* IV is limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200255 /* IV is not allowed to be zero length */
Gilles Peskine295fc132021-04-15 18:32:23 +0200256 if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200258
Paul Bakker52cf16c2013-07-26 13:55:38 +0200259 memset( ctx->y, 0x00, sizeof(ctx->y) );
260 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
261
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200262 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200263 ctx->len = 0;
264 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000265
266 if( iv_len == 12 )
267 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200268 memcpy( ctx->y, iv, iv_len );
269 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000270 }
271 else
272 {
273 memset( work_buf, 0x00, 16 );
openluopworldeab65ac2021-09-22 23:59:42 +0800274 iv_bits = (uint64_t)iv_len * 8;
275 MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000276
277 p = iv;
278 while( iv_len > 0 )
279 {
280 use_len = ( iv_len < 16 ) ? iv_len : 16;
281
Paul Bakker67f9d532012-10-23 11:49:05 +0000282 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200283 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200284
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200285 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000286
287 iv_len -= use_len;
288 p += use_len;
289 }
290
Paul Bakker67f9d532012-10-23 11:49:05 +0000291 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200292 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000293
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200294 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000295 }
296
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500297 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
298 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200299 {
300 return( ret );
301 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000302
Gilles Peskine295fc132021-04-15 18:32:23 +0200303 return( 0 );
304}
305
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200306/**
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200307 * mbedtls_gcm_context::buf contains the partial state of the computation of
308 * the authentication tag.
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200309 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
310 * different stages of the computation:
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200311 * * len == 0 && add_len == 0: initial state
312 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
313 * a partial block of AD that has been
314 * xored in but not yet multiplied in.
315 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
316 * the data ends now.
317 * * len % 16 != 0: the first `len % 16` bytes have
318 * a partial block of ciphertext that has
319 * been xored in but not yet multiplied in.
320 * * len > 0 && len % 16 == 0: the authentication tag is correct if
321 * the data ends now.
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200322 */
Gilles Peskine295fc132021-04-15 18:32:23 +0200323int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
324 const unsigned char *add, size_t add_len )
325{
326 const unsigned char *p;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200327 size_t use_len, i, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200328
329 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
330
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200331 /* IV is limited to 2^64 bits, so 2^61 bytes */
Gilles Peskine295fc132021-04-15 18:32:23 +0200332 if( (uint64_t) add_len >> 61 != 0 )
333 return( MBEDTLS_ERR_GCM_BAD_INPUT );
334
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200335 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000336 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200337
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200338 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000339 {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200340 use_len = 16 - offset;
341 if( use_len > add_len )
342 use_len = add_len;
343
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200344 for( i = 0; i < use_len; i++ )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200345 ctx->buf[i+offset] ^= p[i];
346
347 if( offset + use_len == 16 )
348 gcm_mult( ctx, ctx->buf, ctx->buf );
349
350 ctx->add_len += use_len;
351 add_len -= use_len;
352 p += use_len;
353 }
354
355 ctx->add_len += add_len;
356
357 while( add_len >= 16 )
358 {
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200359 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200360 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200361
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200362 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000363
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200364 add_len -= 16;
365 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000366 }
367
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200368 if( add_len > 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200369 {
370 for( i = 0; i < add_len; i++ )
371 ctx->buf[i] ^= p[i];
372 }
373
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200374 return( 0 );
375}
376
Gilles Peskine58fc2722021-04-13 15:58:27 +0200377/* Increment the counter. */
378static void gcm_incr( unsigned char y[16] )
379{
380 size_t i;
381 for( i = 16; i > 12; i-- )
382 if( ++y[i - 1] != 0 )
383 break;
384}
385
386/* Calculate and apply the encryption mask. Process use_len bytes of data,
387 * starting at position offset in the mask block. */
388static int gcm_mask( mbedtls_gcm_context *ctx,
389 unsigned char ectr[16],
390 size_t offset, size_t use_len,
391 const unsigned char *input,
392 unsigned char *output )
393{
394 size_t i;
395 size_t olen = 0;
396 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
397
398 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
399 &olen ) ) != 0 )
400 {
401 mbedtls_platform_zeroize( ectr, 16 );
402 return( ret );
403 }
404
405 for( i = 0; i < use_len; i++ )
406 {
407 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
408 ctx->buf[offset + i] ^= input[i];
409 output[i] = ectr[offset + i] ^ input[i];
410 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
411 ctx->buf[offset + i] ^= output[i];
412 }
413 return( 0 );
414}
415
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200417 const unsigned char *input, size_t input_length,
418 unsigned char *output, size_t output_size,
419 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200420{
Janos Follath24eed8d2019-11-22 13:21:35 +0000421 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200422 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200423 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200424 size_t offset;
Leonid Rozenboima3008e72022-04-21 17:28:18 -0700425 unsigned char ectr[16] = {0};
Gilles Peskine58fc2722021-04-13 15:58:27 +0200426
Gilles Peskinea56c4482021-04-15 17:22:35 +0200427 if( output_size < input_length )
Mateusz Starzykc48f43b2021-10-04 13:46:38 +0200428 return( MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200429 GCM_VALIDATE_RET( output_length != NULL );
430 *output_length = input_length;
431
432 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200433 * on a potentially null pointer.
434 * Returning early also means that the last partial block of AD remains
435 * untouched for mbedtls_gcm_finish */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200436 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200437 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200438
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100439 GCM_VALIDATE_RET( ctx != NULL );
Gilles Peskine58fc2722021-04-13 15:58:27 +0200440 GCM_VALIDATE_RET( input != NULL );
441 GCM_VALIDATE_RET( output != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100442
Gilles Peskinea56c4482021-04-15 17:22:35 +0200443 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200445
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200446 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
447 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200448 if( ctx->len + input_length < ctx->len ||
449 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200450 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200452 }
453
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200454 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200455 {
456 gcm_mult( ctx, ctx->buf, ctx->buf );
457 }
458
Gilles Peskine58fc2722021-04-13 15:58:27 +0200459 offset = ctx->len % 16;
460 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000461 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200462 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200463 if( use_len > input_length )
464 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000465
Gilles Peskine58fc2722021-04-13 15:58:27 +0200466 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200467 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000468
Gilles Peskine58fc2722021-04-13 15:58:27 +0200469 if( offset + use_len == 16 )
470 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200471
Gilles Peskine58fc2722021-04-13 15:58:27 +0200472 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200473 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000474 p += use_len;
475 out_p += use_len;
476 }
477
Gilles Peskinea56c4482021-04-15 17:22:35 +0200478 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200479
Gilles Peskinea56c4482021-04-15 17:22:35 +0200480 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200481 {
482 gcm_incr( ctx->y );
483 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
484 return( ret );
485
486 gcm_mult( ctx, ctx->buf, ctx->buf );
487
Gilles Peskinea56c4482021-04-15 17:22:35 +0200488 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200489 p += 16;
490 out_p += 16;
491 }
492
Gilles Peskinea56c4482021-04-15 17:22:35 +0200493 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200494 {
495 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200496 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200497 return( ret );
498 }
499
500 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200501 return( 0 );
502}
503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200505 unsigned char *output, size_t output_size,
Gilles Peskine5a7be102021-06-23 21:51:32 +0200506 size_t *output_length,
Gilles Peskine9461e452021-04-15 16:48:32 +0200507 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200508{
509 unsigned char work_buf[16];
510 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100511 uint64_t orig_len;
512 uint64_t orig_add_len;
513
514 GCM_VALIDATE_RET( ctx != NULL );
515 GCM_VALIDATE_RET( tag != NULL );
516
Gilles Peskine9461e452021-04-15 16:48:32 +0200517 /* We never pass any output in finish(). The output parameter exists only
518 * for the sake of alternative implementations. */
519 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200520 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200521 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200522
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100523 orig_len = ctx->len * 8;
524 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200525
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200526 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200527 {
528 gcm_mult( ctx, ctx->buf, ctx->buf );
529 }
530
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200531 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200533
Gilles Peskine58fc2722021-04-13 15:58:27 +0200534 if( ctx->len % 16 != 0 )
535 gcm_mult( ctx, ctx->buf, ctx->buf );
536
Andres AG821da842016-09-26 10:09:30 +0100537 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200538
Paul Bakker89e80c92012-03-20 13:50:09 +0000539 if( orig_len || orig_add_len )
540 {
541 memset( work_buf, 0x00, 16 );
542
Joe Subbiani5ecac212021-06-24 13:00:03 +0100543 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
544 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
545 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
546 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000547
Paul Bakker67f9d532012-10-23 11:49:05 +0000548 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200549 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000550
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200551 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000552
Paul Bakker67f9d532012-10-23 11:49:05 +0000553 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200554 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000555 }
556
557 return( 0 );
558}
559
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200561 int mode,
562 size_t length,
563 const unsigned char *iv,
564 size_t iv_len,
565 const unsigned char *add,
566 size_t add_len,
567 const unsigned char *input,
568 unsigned char *output,
569 size_t tag_len,
570 unsigned char *tag )
571{
Janos Follath24eed8d2019-11-22 13:21:35 +0000572 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200573 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200574
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100575 GCM_VALIDATE_RET( ctx != NULL );
576 GCM_VALIDATE_RET( iv != NULL );
577 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
578 GCM_VALIDATE_RET( length == 0 || input != NULL );
579 GCM_VALIDATE_RET( length == 0 || output != NULL );
580 GCM_VALIDATE_RET( tag != NULL );
581
Gilles Peskine295fc132021-04-15 18:32:23 +0200582 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
583 return( ret );
584
585 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200586 return( ret );
587
Gilles Peskinea56c4482021-04-15 17:22:35 +0200588 if( ( ret = mbedtls_gcm_update( ctx, input, length,
589 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200590 return( ret );
591
Gilles Peskine5a7be102021-06-23 21:51:32 +0200592 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200593 return( ret );
594
595 return( 0 );
596}
597
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000599 size_t length,
600 const unsigned char *iv,
601 size_t iv_len,
602 const unsigned char *add,
603 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200604 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000605 size_t tag_len,
606 const unsigned char *input,
607 unsigned char *output )
608{
Janos Follath24eed8d2019-11-22 13:21:35 +0000609 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000610 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200611 size_t i;
612 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000613
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100614 GCM_VALIDATE_RET( ctx != NULL );
615 GCM_VALIDATE_RET( iv != NULL );
616 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
617 GCM_VALIDATE_RET( tag != NULL );
618 GCM_VALIDATE_RET( length == 0 || input != NULL );
619 GCM_VALIDATE_RET( length == 0 || output != NULL );
620
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100622 iv, iv_len, add, add_len,
623 input, output, tag_len, check_tag ) ) != 0 )
624 {
625 return( ret );
626 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000627
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200628 /* Check tag in "constant-time" */
629 for( diff = 0, i = 0; i < tag_len; i++ )
630 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000631
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200632 if( diff != 0 )
633 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500634 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200635 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200636 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000637
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200638 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000639}
640
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200642{
k-stachowiak21298a22018-12-13 17:11:58 +0100643 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100644 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500646 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200647}
648
Jaeden Amero15263302017-09-21 12:53:48 +0100649#endif /* !MBEDTLS_GCM_ALT */
650
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000652/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200653 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000654 *
655 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
656 */
657#define MAX_TESTS 6
658
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100659static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 { 0, 0, 1, 1, 1, 1 };
661
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100662static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000663{
664 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
666 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
667 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
668 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
669 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
670 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200671 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000672};
673
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100674static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000675 { 12, 12, 12, 12, 8, 60 };
676
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100677static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000678 { 0, 0, 1, 1, 1, 2 };
679
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100680static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000681{
682 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
683 0x00, 0x00, 0x00, 0x00 },
684 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
685 0xde, 0xca, 0xf8, 0x88 },
686 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200687 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000688 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200689 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000690 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200691 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000692 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200693 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000694};
695
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100696static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 { 0, 0, 0, 20, 20, 20 };
698
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100699static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000700 { 0, 0, 0, 1, 1, 1 };
701
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100702static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000703{
704 { 0x00 },
705 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200706 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000707 0xab, 0xad, 0xda, 0xd2 },
708};
709
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100710static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000711 { 0, 16, 64, 60, 60, 60 };
712
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100713static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000714 { 0, 0, 1, 1, 1, 1 };
715
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100716static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000717{
718 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
720 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
721 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
722 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
723 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
724 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
725 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
726 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
727 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
728};
729
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100730static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000731{
732 { 0x00 },
733 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
734 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
735 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200736 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000737 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200738 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000739 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200740 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000741 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
742 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
743 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200744 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000745 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200746 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000747 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200748 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
750 0x3d, 0x58, 0xe0, 0x91 },
751 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200752 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000753 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200754 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000755 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200756 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000757 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
758 0xc2, 0x3f, 0x45, 0x98 },
759 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200760 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200762 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000763 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200764 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000765 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
766 0x4c, 0x34, 0xae, 0xe5 },
767 { 0x00 },
768 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200769 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000770 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200771 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000772 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200773 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000774 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200775 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
777 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
778 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200779 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000780 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200781 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
782 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
783 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000784 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200785 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000786 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200787 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000788 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200789 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000790 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200791 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000792 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200793 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000794 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200795 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000796 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200797 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000798 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200799 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000800 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200801 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000802 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200803 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
804 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
805 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
806 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
807 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
808 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
809 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
810 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
811 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
812 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
813 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
814 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
815 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
816 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
817 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
818 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
819 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
820 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000821 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200822 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000823 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200824 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000825 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200826 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000827 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200828 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000829 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200830 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000831 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200832 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000833 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200834 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000835 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200836 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000837};
838
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100839static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000840{
841 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
842 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
843 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
844 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
845 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200846 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000847 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
848 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
849 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
850 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
851 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
852 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
853 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
854 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
855 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200856 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000857 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
858 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
859 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200860 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000861 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200862 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000863 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200864 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000865 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200866 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000867 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200868 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000869 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200870 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000871 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200872 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000873 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200874 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000875 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200876 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000877};
878
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000880{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200881 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000882 unsigned char buf[64];
883 unsigned char tag_buf[16];
884 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200886 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000887
888 for( j = 0; j < 3; j++ )
889 {
890 int key_len = 128 + 64 * j;
891
892 for( i = 0; i < MAX_TESTS; i++ )
893 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100894 mbedtls_gcm_init( &ctx );
895
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200896 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200897 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100898 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200899
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500900 ret = mbedtls_gcm_setkey( &ctx, cipher,
901 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100902 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100903 /*
904 * AES-192 is an optional feature that may be unavailable when
905 * there is an alternative underlying implementation i.e. when
906 * MBEDTLS_AES_ALT is defined.
907 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300908 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100909 {
910 mbedtls_printf( "skipped\n" );
911 break;
912 }
913 else if( ret != 0 )
914 {
915 goto exit;
916 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000917
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200918 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500919 pt_len_test_data[i],
920 iv_test_data[iv_index_test_data[i]],
921 iv_len_test_data[i],
922 additional_test_data[add_index_test_data[i]],
923 add_len_test_data[i],
924 pt_test_data[pt_index_test_data[i]],
925 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100926#if defined(MBEDTLS_GCM_ALT)
927 /* Allow alternative implementations to only support 12-byte nonces. */
928 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
929 iv_len_test_data[i] != 12 )
930 {
931 mbedtls_printf( "skipped\n" );
932 break;
933 }
934#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100935 if( ret != 0 )
936 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000937
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500938 if ( memcmp( buf, ct_test_data[j * 6 + i],
939 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100940 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000941 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100942 ret = 1;
943 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000944 }
945
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200947
Paul Bakker89e80c92012-03-20 13:50:09 +0000948 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000950
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100951 mbedtls_gcm_init( &ctx );
952
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200953 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100955 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200956
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500957 ret = mbedtls_gcm_setkey( &ctx, cipher,
958 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100959 key_len );
960 if( ret != 0 )
961 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000962
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500964 pt_len_test_data[i],
965 iv_test_data[iv_index_test_data[i]],
966 iv_len_test_data[i],
967 additional_test_data[add_index_test_data[i]],
968 add_len_test_data[i],
969 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000970
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100971 if( ret != 0 )
972 goto exit;
973
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100974 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
975 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100976 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000977 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100978 ret = 1;
979 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000980 }
981
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200982 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200983
Paul Bakker89e80c92012-03-20 13:50:09 +0000984 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200985 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200986
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100987 mbedtls_gcm_init( &ctx );
988
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200989 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200990 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100991 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200992
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500993 ret = mbedtls_gcm_setkey( &ctx, cipher,
994 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100995 key_len );
996 if( ret != 0 )
997 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200998
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001000 iv_test_data[iv_index_test_data[i]],
1001 iv_len_test_data[i] );
1002 if( ret != 0 )
1003 goto exit;
1004
1005 ret = mbedtls_gcm_update_ad( &ctx,
1006 additional_test_data[add_index_test_data[i]],
1007 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001008 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001009 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001010
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001011 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001012 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001013 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001014 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001015 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001016 32,
1017 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001018 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001019 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001020 if( olen != 32 )
1021 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001022
Gilles Peskinea56c4482021-04-15 17:22:35 +02001023 ret = mbedtls_gcm_update( &ctx,
1024 pt_test_data[pt_index_test_data[i]] + 32,
1025 rest_len,
1026 buf + 32, sizeof( buf ) - 32, &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 != rest_len )
1030 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001031 }
1032 else
1033 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001034 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001035 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001036 pt_len_test_data[i],
1037 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001038 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001039 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001040 if( olen != pt_len_test_data[i] )
1041 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001042 }
1043
Gilles Peskine5a7be102021-06-23 21:51:32 +02001044 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001045 if( ret != 0 )
1046 goto exit;
1047
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001048 if( memcmp( buf, ct_test_data[j * 6 + i],
1049 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001050 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001051 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001052 ret = 1;
1053 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001054 }
1055
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001056 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001057
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001058 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001059 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001060
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001061 mbedtls_gcm_init( &ctx );
1062
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001063 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001064 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001065 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001066
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001067 ret = mbedtls_gcm_setkey( &ctx, cipher,
1068 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001069 key_len );
1070 if( ret != 0 )
1071 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001072
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001073 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001074 iv_test_data[iv_index_test_data[i]],
1075 iv_len_test_data[i] );
1076 if( ret != 0 )
1077 goto exit;
1078 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001079 additional_test_data[add_index_test_data[i]],
1080 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001081 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001082 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001083
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001084 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001085 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001086 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001087 ret = mbedtls_gcm_update( &ctx,
1088 ct_test_data[j * 6 + i], 32,
1089 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001090 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001091 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001092 if( olen != 32 )
1093 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001094
Gilles Peskinea56c4482021-04-15 17:22:35 +02001095 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001096 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001097 rest_len,
1098 buf + 32, sizeof( buf ) - 32, &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 != rest_len )
1102 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001103 }
1104 else
1105 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001106 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001107 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001108 pt_len_test_data[i],
1109 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001110 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001111 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001112 if( olen != pt_len_test_data[i] )
1113 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001114 }
1115
Gilles Peskine5a7be102021-06-23 21:51:32 +02001116 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001117 if( ret != 0 )
1118 goto exit;
1119
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001120 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1121 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001122 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001123 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001124 ret = 1;
1125 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001126 }
1127
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001128 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001129
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001130 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001131 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001132 }
1133 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001134
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001135 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001136 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001137
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001138 ret = 0;
1139
1140exit:
1141 if( ret != 0 )
1142 {
1143 if( verbose != 0 )
1144 mbedtls_printf( "failed\n" );
1145 mbedtls_gcm_free( &ctx );
1146 }
1147
1148 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001149}
1150
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001151#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001152
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001153#endif /* MBEDTLS_GCM_C */