blob: fca0c612970366a917f4ce34463b85d075a5b060 [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"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010048
Jaeden Amero15263302017-09-21 12:53:48 +010049#if !defined(MBEDTLS_GCM_ALT)
50
k-stachowiak8ffc92a2018-12-12 14:21:59 +010051/* Parameter validation macros */
52#define GCM_VALIDATE_RET( cond ) \
53 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
54#define GCM_VALIDATE( cond ) \
55 MBEDTLS_INTERNAL_VALIDATE( cond )
56
Paul Bakker89e80c92012-03-20 13:50:09 +000057/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020058 * Initialize a context
59 */
60void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
61{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010062 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020063 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
64}
65
66/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010067 * Precompute small multiples of H, that is set
68 * HH[i] || HL[i] = H times i,
69 * where i is seen as a field element as in [MGV], ie high-order bits
70 * correspond to low powers of P. The result is stored in the same way, that
71 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
72 * corresponds to P^127.
73 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000075{
Paul Bakker43aff2a2013-09-09 00:10:27 +020076 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000077 uint64_t hi, lo;
78 uint64_t vl, vh;
79 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020080 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020081
Paul Bakker89e80c92012-03-20 13:50:09 +000082 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020083 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +020084 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000085
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010086 /* pack h as two 64-bits ints, big-endian */
Joe Subbiani6a506312021-07-07 16:56:29 +010087 hi = MBEDTLS_GET_UINT32_BE( h, 0 );
88 lo = MBEDTLS_GET_UINT32_BE( h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000089 vh = (uint64_t) hi << 32 | lo;
90
Joe Subbiani6a506312021-07-07 16:56:29 +010091 hi = MBEDTLS_GET_UINT32_BE( h, 8 );
92 lo = MBEDTLS_GET_UINT32_BE( h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000093 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020094
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010095 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +000096 ctx->HL[8] = vl;
97 ctx->HH[8] = vh;
98
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100100 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100101 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100102 return( 0 );
103#endif
104
105 /* 0 corresponds to 0 in GF(2^128) */
106 ctx->HH[0] = 0;
107 ctx->HL[0] = 0;
108
Paul Bakker89e80c92012-03-20 13:50:09 +0000109 for( i = 4; i > 0; i >>= 1 )
110 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200111 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000112 vl = ( vh << 63 ) | ( vl >> 1 );
113 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
114
115 ctx->HL[i] = vl;
116 ctx->HH[i] = vh;
117 }
118
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000119 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000120 {
121 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
122 vh = *HiH;
123 vl = *HiL;
124 for( j = 1; j < i; j++ )
125 {
126 HiH[j] = vh ^ ctx->HH[j];
127 HiL[j] = vl ^ ctx->HL[j];
128 }
129 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200130
131 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000132}
133
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200134int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
135 mbedtls_cipher_id_t cipher,
136 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200137 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000138{
Janos Follath24eed8d2019-11-22 13:21:35 +0000139 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000141
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100142 GCM_VALIDATE_RET( ctx != NULL );
143 GCM_VALIDATE_RET( key != NULL );
144 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
145
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500146 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
147 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200148 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200149 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200150
Paul Bakkera0558e02013-09-10 14:25:51 +0200151 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200152 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200153
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200154 mbedtls_cipher_free( &ctx->cipher_ctx );
155
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200156 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000157 return( ret );
158
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200159 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200161 {
162 return( ret );
163 }
164
165 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
166 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000167
168 return( 0 );
169}
170
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100171/*
172 * Shoup's method for multiplication use this table with
173 * last4[x] = x times P^128
174 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
175 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000176static const uint64_t last4[16] =
177{
178 0x0000, 0x1c20, 0x3840, 0x2460,
179 0x7080, 0x6ca0, 0x48c0, 0x54e0,
180 0xe100, 0xfd20, 0xd940, 0xc560,
181 0x9180, 0x8da0, 0xa9c0, 0xb5e0
182};
183
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100184/*
185 * Sets output to x times H using the precomputed tables.
186 * x and output are seen as elements of GF(2^128) as in [MGV].
187 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200188static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200189 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000190{
191 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000192 unsigned char lo, hi, rem;
193 uint64_t zh, zl;
194
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100196 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100197 unsigned char h[16];
198
Joe Subbiani5ecac212021-06-24 13:00:03 +0100199 MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
200 MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 );
201 MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
202 MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100203
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200204 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100205 return;
206 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200207#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100208
Paul Bakker89e80c92012-03-20 13:50:09 +0000209 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000210
211 zh = ctx->HH[lo];
212 zl = ctx->HL[lo];
213
214 for( i = 15; i >= 0; i-- )
215 {
216 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200217 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000218
219 if( i != 15 )
220 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000221 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000222 zl = ( zh << 60 ) | ( zl >> 4 );
223 zh = ( zh >> 4 );
224 zh ^= (uint64_t) last4[rem] << 48;
225 zh ^= ctx->HH[lo];
226 zl ^= ctx->HL[lo];
227
228 }
229
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000230 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000231 zl = ( zh << 60 ) | ( zl >> 4 );
232 zh = ( zh >> 4 );
233 zh ^= (uint64_t) last4[rem] << 48;
234 zh ^= ctx->HH[hi];
235 zl ^= ctx->HL[hi];
236 }
237
Joe Subbiani5ecac212021-06-24 13:00:03 +0100238 MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
239 MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
240 MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
241 MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000242}
243
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200244int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Gilles Peskine295fc132021-04-15 18:32:23 +0200245 int mode,
246 const unsigned char *iv, size_t iv_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000247{
Janos Follath24eed8d2019-11-22 13:21:35 +0000248 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000249 unsigned char work_buf[16];
250 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000251 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200252 size_t use_len, olen = 0;
openluopworldeab65ac2021-09-22 23:59:42 +0800253 uint64_t iv_bits;
Paul Bakker89e80c92012-03-20 13:50:09 +0000254
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100255 GCM_VALIDATE_RET( ctx != NULL );
256 GCM_VALIDATE_RET( iv != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100257
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200258 /* IV is limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200259 /* IV is not allowed to be zero length */
Gilles Peskine295fc132021-04-15 18:32:23 +0200260 if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200261 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200262
Paul Bakker52cf16c2013-07-26 13:55:38 +0200263 memset( ctx->y, 0x00, sizeof(ctx->y) );
264 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
265
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200266 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200267 ctx->len = 0;
268 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000269
270 if( iv_len == 12 )
271 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200272 memcpy( ctx->y, iv, iv_len );
273 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000274 }
275 else
276 {
277 memset( work_buf, 0x00, 16 );
openluopworldeab65ac2021-09-22 23:59:42 +0800278 iv_bits = (uint64_t)iv_len * 8;
279 MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000280
281 p = iv;
282 while( iv_len > 0 )
283 {
284 use_len = ( iv_len < 16 ) ? iv_len : 16;
285
Paul Bakker67f9d532012-10-23 11:49:05 +0000286 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200287 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200288
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200289 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000290
291 iv_len -= use_len;
292 p += use_len;
293 }
294
Paul Bakker67f9d532012-10-23 11:49:05 +0000295 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200296 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000297
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200298 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000299 }
300
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500301 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
302 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200303 {
304 return( ret );
305 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000306
Gilles Peskine295fc132021-04-15 18:32:23 +0200307 return( 0 );
308}
309
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200310/**
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200311 * mbedtls_gcm_context::buf contains the partial state of the computation of
312 * the authentication tag.
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200313 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
314 * different stages of the computation:
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200315 * * len == 0 && add_len == 0: initial state
316 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
317 * a partial block of AD that has been
318 * xored in but not yet multiplied in.
319 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
320 * the data ends now.
321 * * len % 16 != 0: the first `len % 16` bytes have
322 * a partial block of ciphertext that has
323 * been xored in but not yet multiplied in.
324 * * len > 0 && len % 16 == 0: the authentication tag is correct if
325 * the data ends now.
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200326 */
Gilles Peskine295fc132021-04-15 18:32:23 +0200327int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
328 const unsigned char *add, size_t add_len )
329{
330 const unsigned char *p;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200331 size_t use_len, i, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200332
333 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
334
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200335 /* IV is limited to 2^64 bits, so 2^61 bytes */
Gilles Peskine295fc132021-04-15 18:32:23 +0200336 if( (uint64_t) add_len >> 61 != 0 )
337 return( MBEDTLS_ERR_GCM_BAD_INPUT );
338
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200339 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000340 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200341
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200342 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000343 {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200344 use_len = 16 - offset;
345 if( use_len > add_len )
346 use_len = add_len;
347
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200348 for( i = 0; i < use_len; i++ )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200349 ctx->buf[i+offset] ^= p[i];
350
351 if( offset + use_len == 16 )
352 gcm_mult( ctx, ctx->buf, ctx->buf );
353
354 ctx->add_len += use_len;
355 add_len -= use_len;
356 p += use_len;
357 }
358
359 ctx->add_len += add_len;
360
361 while( add_len >= 16 )
362 {
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200363 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200364 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200365
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200366 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000367
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200368 add_len -= 16;
369 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000370 }
371
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200372 if( add_len > 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200373 {
374 for( i = 0; i < add_len; i++ )
375 ctx->buf[i] ^= p[i];
376 }
377
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200378 return( 0 );
379}
380
Gilles Peskine58fc2722021-04-13 15:58:27 +0200381/* Increment the counter. */
382static void gcm_incr( unsigned char y[16] )
383{
384 size_t i;
385 for( i = 16; i > 12; i-- )
386 if( ++y[i - 1] != 0 )
387 break;
388}
389
390/* Calculate and apply the encryption mask. Process use_len bytes of data,
391 * starting at position offset in the mask block. */
392static int gcm_mask( mbedtls_gcm_context *ctx,
393 unsigned char ectr[16],
394 size_t offset, size_t use_len,
395 const unsigned char *input,
396 unsigned char *output )
397{
398 size_t i;
399 size_t olen = 0;
400 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
401
402 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
403 &olen ) ) != 0 )
404 {
405 mbedtls_platform_zeroize( ectr, 16 );
406 return( ret );
407 }
408
409 for( i = 0; i < use_len; i++ )
410 {
411 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
412 ctx->buf[offset + i] ^= input[i];
413 output[i] = ectr[offset + i] ^ input[i];
414 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
415 ctx->buf[offset + i] ^= output[i];
416 }
417 return( 0 );
418}
419
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200421 const unsigned char *input, size_t input_length,
422 unsigned char *output, size_t output_size,
423 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200424{
Janos Follath24eed8d2019-11-22 13:21:35 +0000425 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200426 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200427 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200428 size_t offset;
Leonid Rozenboima3008e72022-04-21 17:28:18 -0700429 unsigned char ectr[16] = {0};
Gilles Peskine58fc2722021-04-13 15:58:27 +0200430
Gilles Peskinea56c4482021-04-15 17:22:35 +0200431 if( output_size < input_length )
Mateusz Starzykc48f43b2021-10-04 13:46:38 +0200432 return( MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200433 GCM_VALIDATE_RET( output_length != NULL );
434 *output_length = input_length;
435
436 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200437 * on a potentially null pointer.
438 * Returning early also means that the last partial block of AD remains
439 * untouched for mbedtls_gcm_finish */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200440 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200441 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200442
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100443 GCM_VALIDATE_RET( ctx != NULL );
Gilles Peskine58fc2722021-04-13 15:58:27 +0200444 GCM_VALIDATE_RET( input != NULL );
445 GCM_VALIDATE_RET( output != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100446
Gilles Peskinea56c4482021-04-15 17:22:35 +0200447 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200449
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200450 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
451 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200452 if( ctx->len + input_length < ctx->len ||
453 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200454 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200456 }
457
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200458 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200459 {
460 gcm_mult( ctx, ctx->buf, ctx->buf );
461 }
462
Gilles Peskine58fc2722021-04-13 15:58:27 +0200463 offset = ctx->len % 16;
464 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000465 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200466 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200467 if( use_len > input_length )
468 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000469
Gilles Peskine58fc2722021-04-13 15:58:27 +0200470 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200471 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000472
Gilles Peskine58fc2722021-04-13 15:58:27 +0200473 if( offset + use_len == 16 )
474 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200475
Gilles Peskine58fc2722021-04-13 15:58:27 +0200476 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200477 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000478 p += use_len;
479 out_p += use_len;
480 }
481
Gilles Peskinea56c4482021-04-15 17:22:35 +0200482 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200483
Gilles Peskinea56c4482021-04-15 17:22:35 +0200484 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200485 {
486 gcm_incr( ctx->y );
487 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
488 return( ret );
489
490 gcm_mult( ctx, ctx->buf, ctx->buf );
491
Gilles Peskinea56c4482021-04-15 17:22:35 +0200492 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200493 p += 16;
494 out_p += 16;
495 }
496
Gilles Peskinea56c4482021-04-15 17:22:35 +0200497 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200498 {
499 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200500 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200501 return( ret );
502 }
503
504 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200505 return( 0 );
506}
507
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200509 unsigned char *output, size_t output_size,
Gilles Peskine5a7be102021-06-23 21:51:32 +0200510 size_t *output_length,
Gilles Peskine9461e452021-04-15 16:48:32 +0200511 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200512{
513 unsigned char work_buf[16];
514 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100515 uint64_t orig_len;
516 uint64_t orig_add_len;
517
518 GCM_VALIDATE_RET( ctx != NULL );
519 GCM_VALIDATE_RET( tag != NULL );
520
Gilles Peskine9461e452021-04-15 16:48:32 +0200521 /* We never pass any output in finish(). The output parameter exists only
522 * for the sake of alternative implementations. */
523 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200524 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200525 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200526
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100527 orig_len = ctx->len * 8;
528 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200529
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200530 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200531 {
532 gcm_mult( ctx, ctx->buf, ctx->buf );
533 }
534
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200535 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200537
Gilles Peskine58fc2722021-04-13 15:58:27 +0200538 if( ctx->len % 16 != 0 )
539 gcm_mult( ctx, ctx->buf, ctx->buf );
540
Andres AG821da842016-09-26 10:09:30 +0100541 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200542
Paul Bakker89e80c92012-03-20 13:50:09 +0000543 if( orig_len || orig_add_len )
544 {
545 memset( work_buf, 0x00, 16 );
546
Joe Subbiani5ecac212021-06-24 13:00:03 +0100547 MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
548 MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
549 MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
550 MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000551
Paul Bakker67f9d532012-10-23 11:49:05 +0000552 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200553 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000554
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200555 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000556
Paul Bakker67f9d532012-10-23 11:49:05 +0000557 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200558 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000559 }
560
561 return( 0 );
562}
563
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200565 int mode,
566 size_t length,
567 const unsigned char *iv,
568 size_t iv_len,
569 const unsigned char *add,
570 size_t add_len,
571 const unsigned char *input,
572 unsigned char *output,
573 size_t tag_len,
574 unsigned char *tag )
575{
Janos Follath24eed8d2019-11-22 13:21:35 +0000576 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200577 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200578
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100579 GCM_VALIDATE_RET( ctx != NULL );
580 GCM_VALIDATE_RET( iv != NULL );
581 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
582 GCM_VALIDATE_RET( length == 0 || input != NULL );
583 GCM_VALIDATE_RET( length == 0 || output != NULL );
584 GCM_VALIDATE_RET( tag != NULL );
585
Gilles Peskine295fc132021-04-15 18:32:23 +0200586 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
587 return( ret );
588
589 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200590 return( ret );
591
Gilles Peskinea56c4482021-04-15 17:22:35 +0200592 if( ( ret = mbedtls_gcm_update( ctx, input, length,
593 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200594 return( ret );
595
Gilles Peskine5a7be102021-06-23 21:51:32 +0200596 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200597 return( ret );
598
599 return( 0 );
600}
601
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000603 size_t length,
604 const unsigned char *iv,
605 size_t iv_len,
606 const unsigned char *add,
607 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200608 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000609 size_t tag_len,
610 const unsigned char *input,
611 unsigned char *output )
612{
Janos Follath24eed8d2019-11-22 13:21:35 +0000613 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000614 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200615 size_t i;
616 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000617
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100618 GCM_VALIDATE_RET( ctx != NULL );
619 GCM_VALIDATE_RET( iv != NULL );
620 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
621 GCM_VALIDATE_RET( tag != NULL );
622 GCM_VALIDATE_RET( length == 0 || input != NULL );
623 GCM_VALIDATE_RET( length == 0 || output != NULL );
624
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100626 iv, iv_len, add, add_len,
627 input, output, tag_len, check_tag ) ) != 0 )
628 {
629 return( ret );
630 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000631
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200632 /* Check tag in "constant-time" */
633 for( diff = 0, i = 0; i < tag_len; i++ )
634 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000635
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200636 if( diff != 0 )
637 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500638 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200640 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000641
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200642 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000643}
644
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200646{
k-stachowiak21298a22018-12-13 17:11:58 +0100647 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100648 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500650 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200651}
652
Jaeden Amero15263302017-09-21 12:53:48 +0100653#endif /* !MBEDTLS_GCM_ALT */
654
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000656/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200657 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000658 *
659 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
660 */
661#define MAX_TESTS 6
662
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100663static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000664 { 0, 0, 1, 1, 1, 1 };
665
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100666static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000667{
668 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
672 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
673 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
674 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200675 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000676};
677
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100678static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000679 { 12, 12, 12, 12, 8, 60 };
680
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100681static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000682 { 0, 0, 1, 1, 1, 2 };
683
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100684static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000685{
686 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687 0x00, 0x00, 0x00, 0x00 },
688 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
689 0xde, 0xca, 0xf8, 0x88 },
690 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200691 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000692 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200693 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000694 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200695 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000696 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200697 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000698};
699
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100700static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 { 0, 0, 0, 20, 20, 20 };
702
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100703static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000704 { 0, 0, 0, 1, 1, 1 };
705
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100706static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000707{
708 { 0x00 },
709 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200710 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000711 0xab, 0xad, 0xda, 0xd2 },
712};
713
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100714static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000715 { 0, 16, 64, 60, 60, 60 };
716
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100717static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000718 { 0, 0, 1, 1, 1, 1 };
719
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100720static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000721{
722 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
724 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
725 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
726 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
727 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
728 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
729 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
730 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
731 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
732};
733
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100734static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000735{
736 { 0x00 },
737 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
738 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
739 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200740 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000741 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200742 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000743 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200744 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000745 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
746 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
747 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200748 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200750 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000751 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200752 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000753 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
754 0x3d, 0x58, 0xe0, 0x91 },
755 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200756 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000757 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200758 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000759 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200760 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
762 0xc2, 0x3f, 0x45, 0x98 },
763 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200764 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000765 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200766 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000767 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200768 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000769 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
770 0x4c, 0x34, 0xae, 0xe5 },
771 { 0x00 },
772 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200773 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000774 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200775 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200777 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000778 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200779 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000780 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
781 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
782 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200783 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000784 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200785 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
786 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
787 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000788 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200789 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000790 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200791 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000792 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200793 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000794 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200795 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000796 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200797 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000798 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200799 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000800 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200801 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000802 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200803 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000804 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200805 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000806 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200807 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
808 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
809 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
810 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
811 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
812 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
813 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
814 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
815 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
816 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
817 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
818 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
819 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
820 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
821 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
822 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
823 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
824 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000825 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200826 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000827 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200828 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000829 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200830 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000831 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200832 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000833 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200834 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000835 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200836 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000837 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200838 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000839 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200840 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000841};
842
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100843static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000844{
845 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
846 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
847 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
848 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
849 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200850 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000851 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
852 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
853 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
854 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
855 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
856 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
857 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
858 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
859 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200860 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000861 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
862 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
863 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200864 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000865 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200866 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000867 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200868 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000869 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200870 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000871 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200872 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000873 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200874 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000875 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200876 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000877 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200878 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000879 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200880 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000881};
882
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000884{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000886 unsigned char buf[64];
887 unsigned char tag_buf[16];
888 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200890 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000891
892 for( j = 0; j < 3; j++ )
893 {
894 int key_len = 128 + 64 * j;
895
896 for( i = 0; i < MAX_TESTS; i++ )
897 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100898 mbedtls_gcm_init( &ctx );
899
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200900 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100902 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200903
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500904 ret = mbedtls_gcm_setkey( &ctx, cipher,
905 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100906 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100907 /*
908 * AES-192 is an optional feature that may be unavailable when
909 * there is an alternative underlying implementation i.e. when
910 * MBEDTLS_AES_ALT is defined.
911 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300912 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100913 {
914 mbedtls_printf( "skipped\n" );
915 break;
916 }
917 else if( ret != 0 )
918 {
919 goto exit;
920 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000921
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500923 pt_len_test_data[i],
924 iv_test_data[iv_index_test_data[i]],
925 iv_len_test_data[i],
926 additional_test_data[add_index_test_data[i]],
927 add_len_test_data[i],
928 pt_test_data[pt_index_test_data[i]],
929 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100930#if defined(MBEDTLS_GCM_ALT)
931 /* Allow alternative implementations to only support 12-byte nonces. */
932 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
933 iv_len_test_data[i] != 12 )
934 {
935 mbedtls_printf( "skipped\n" );
936 break;
937 }
938#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100939 if( ret != 0 )
940 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000941
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500942 if ( memcmp( buf, ct_test_data[j * 6 + i],
943 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100944 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000945 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100946 ret = 1;
947 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000948 }
949
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200951
Paul Bakker89e80c92012-03-20 13:50:09 +0000952 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000954
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100955 mbedtls_gcm_init( &ctx );
956
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200957 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100959 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200960
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500961 ret = mbedtls_gcm_setkey( &ctx, cipher,
962 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100963 key_len );
964 if( ret != 0 )
965 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000966
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200967 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500968 pt_len_test_data[i],
969 iv_test_data[iv_index_test_data[i]],
970 iv_len_test_data[i],
971 additional_test_data[add_index_test_data[i]],
972 add_len_test_data[i],
973 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000974
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100975 if( ret != 0 )
976 goto exit;
977
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100978 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
979 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100980 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000981 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100982 ret = 1;
983 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000984 }
985
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200987
Paul Bakker89e80c92012-03-20 13:50:09 +0000988 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200990
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100991 mbedtls_gcm_init( &ctx );
992
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200993 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200994 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100995 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200996
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500997 ret = mbedtls_gcm_setkey( &ctx, cipher,
998 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100999 key_len );
1000 if( ret != 0 )
1001 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001002
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001003 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001004 iv_test_data[iv_index_test_data[i]],
1005 iv_len_test_data[i] );
1006 if( ret != 0 )
1007 goto exit;
1008
1009 ret = mbedtls_gcm_update_ad( &ctx,
1010 additional_test_data[add_index_test_data[i]],
1011 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001012 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001013 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001014
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001015 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001016 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001017 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001018 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001019 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001020 32,
1021 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001022 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001023 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001024 if( olen != 32 )
1025 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001026
Gilles Peskinea56c4482021-04-15 17:22:35 +02001027 ret = mbedtls_gcm_update( &ctx,
1028 pt_test_data[pt_index_test_data[i]] + 32,
1029 rest_len,
1030 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001031 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001032 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001033 if( olen != rest_len )
1034 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001035 }
1036 else
1037 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001038 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001039 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001040 pt_len_test_data[i],
1041 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001042 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001043 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001044 if( olen != pt_len_test_data[i] )
1045 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001046 }
1047
Gilles Peskine5a7be102021-06-23 21:51:32 +02001048 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001049 if( ret != 0 )
1050 goto exit;
1051
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001052 if( memcmp( buf, ct_test_data[j * 6 + i],
1053 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001054 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001055 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001056 ret = 1;
1057 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001058 }
1059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001060 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001061
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001062 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001063 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001064
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001065 mbedtls_gcm_init( &ctx );
1066
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001067 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001068 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001069 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001070
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001071 ret = mbedtls_gcm_setkey( &ctx, cipher,
1072 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001073 key_len );
1074 if( ret != 0 )
1075 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001076
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001078 iv_test_data[iv_index_test_data[i]],
1079 iv_len_test_data[i] );
1080 if( ret != 0 )
1081 goto exit;
1082 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001083 additional_test_data[add_index_test_data[i]],
1084 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001085 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001086 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001087
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001088 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001089 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001090 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001091 ret = mbedtls_gcm_update( &ctx,
1092 ct_test_data[j * 6 + i], 32,
1093 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001094 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001095 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001096 if( olen != 32 )
1097 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001098
Gilles Peskinea56c4482021-04-15 17:22:35 +02001099 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001100 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001101 rest_len,
1102 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001103 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001104 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001105 if( olen != rest_len )
1106 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001107 }
1108 else
1109 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001110 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001111 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001112 pt_len_test_data[i],
1113 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001114 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001115 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001116 if( olen != pt_len_test_data[i] )
1117 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001118 }
1119
Gilles Peskine5a7be102021-06-23 21:51:32 +02001120 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001121 if( ret != 0 )
1122 goto exit;
1123
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001124 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1125 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001126 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001127 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001128 ret = 1;
1129 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001130 }
1131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001132 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001133
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001134 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001135 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001136 }
1137 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001138
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001139 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001140 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001141
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001142 ret = 0;
1143
1144exit:
1145 if( ret != 0 )
1146 {
1147 if( verbose != 0 )
1148 mbedtls_printf( "failed\n" );
1149 mbedtls_gcm_free( &ctx );
1150 }
1151
1152 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001153}
1154
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001155#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001157#endif /* MBEDTLS_GCM_C */