blob: c8254876dd84d617270a938db0295b735bce258e [file] [log] [blame]
Paul Bakker89e80c92012-03-20 13:50:09 +00001/*
2 * NIST SP800-38D compliant GCM implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker89e80c92012-03-20 13:50:09 +000018 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010019
Paul Bakker89e80c92012-03-20 13:50:09 +000020/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010021 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
22 *
23 * See also:
24 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
25 *
26 * We use the algorithm described as Shoup's method with 4-bit tables in
27 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000028 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010029
Gilles Peskinedb09ef62020-06-03 01:43:33 +020030#include "common.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000033
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/gcm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050035#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000036#include "mbedtls/error.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000041#include "aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010042#endif
43
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +010045#include "mbedtls/aes.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030047#if !defined(MBEDTLS_PLATFORM_C)
Rich Evans00ab4702015-02-06 13:43:58 +000048#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#define mbedtls_printf printf
50#endif /* MBEDTLS_PLATFORM_C */
51#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Jaeden Amero15263302017-09-21 12:53:48 +010053#if !defined(MBEDTLS_GCM_ALT)
54
k-stachowiak8ffc92a2018-12-12 14:21:59 +010055/* Parameter validation macros */
56#define GCM_VALIDATE_RET( cond ) \
57 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
58#define GCM_VALIDATE( cond ) \
59 MBEDTLS_INTERNAL_VALIDATE( cond )
60
Paul Bakker89e80c92012-03-20 13:50:09 +000061/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020062 * Initialize a context
63 */
64void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
65{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010066 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020067 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
68}
69
70/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010071 * Precompute small multiples of H, that is set
72 * HH[i] || HL[i] = H times i,
73 * where i is seen as a field element as in [MGV], ie high-order bits
74 * correspond to low powers of P. The result is stored in the same way, that
75 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
76 * corresponds to P^127.
77 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +000079{
Paul Bakker43aff2a2013-09-09 00:10:27 +020080 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000081 uint64_t hi, lo;
82 uint64_t vl, vh;
83 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020084 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020085
Paul Bakker89e80c92012-03-20 13:50:09 +000086 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020087 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +020088 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +000089
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010090 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +000091 GET_UINT32_BE( hi, h, 0 );
92 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +000093 vh = (uint64_t) hi << 32 | lo;
94
Paul Bakker5c2364c2012-10-01 14:41:15 +000095 GET_UINT32_BE( hi, h, 8 );
96 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +000097 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020098
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010099 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000100 ctx->HL[8] = vl;
101 ctx->HH[8] = vh;
102
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100104 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100105 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100106 return( 0 );
107#endif
108
109 /* 0 corresponds to 0 in GF(2^128) */
110 ctx->HH[0] = 0;
111 ctx->HL[0] = 0;
112
Paul Bakker89e80c92012-03-20 13:50:09 +0000113 for( i = 4; i > 0; i >>= 1 )
114 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200115 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000116 vl = ( vh << 63 ) | ( vl >> 1 );
117 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
118
119 ctx->HL[i] = vl;
120 ctx->HH[i] = vh;
121 }
122
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000123 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000124 {
125 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
126 vh = *HiH;
127 vl = *HiL;
128 for( j = 1; j < i; j++ )
129 {
130 HiH[j] = vh ^ ctx->HH[j];
131 HiL[j] = vl ^ ctx->HL[j];
132 }
133 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200134
135 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000136}
137
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200138int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
139 mbedtls_cipher_id_t cipher,
140 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200141 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000142{
Janos Follath24eed8d2019-11-22 13:21:35 +0000143 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200144 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000145
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100146 GCM_VALIDATE_RET( ctx != NULL );
147 GCM_VALIDATE_RET( key != NULL );
148 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
149
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500150 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
151 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200152 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200153 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200154
Paul Bakkera0558e02013-09-10 14:25:51 +0200155 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200157
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200158 mbedtls_cipher_free( &ctx->cipher_ctx );
159
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200160 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000161 return( ret );
162
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200163 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200164 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200165 {
166 return( ret );
167 }
168
169 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
170 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000171
172 return( 0 );
173}
174
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100175/*
176 * Shoup's method for multiplication use this table with
177 * last4[x] = x times P^128
178 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
179 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000180static const uint64_t last4[16] =
181{
182 0x0000, 0x1c20, 0x3840, 0x2460,
183 0x7080, 0x6ca0, 0x48c0, 0x54e0,
184 0xe100, 0xfd20, 0xd940, 0xc560,
185 0x9180, 0x8da0, 0xa9c0, 0xb5e0
186};
187
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100188/*
189 * Sets output to x times H using the precomputed tables.
190 * x and output are seen as elements of GF(2^128) as in [MGV].
191 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200193 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000194{
195 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000196 unsigned char lo, hi, rem;
197 uint64_t zh, zl;
198
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200199#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100200 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100201 unsigned char h[16];
202
203 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
204 PUT_UINT32_BE( ctx->HH[8], h, 4 );
205 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
206 PUT_UINT32_BE( ctx->HL[8], h, 12 );
207
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100209 return;
210 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100212
Paul Bakker89e80c92012-03-20 13:50:09 +0000213 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000214
215 zh = ctx->HH[lo];
216 zl = ctx->HL[lo];
217
218 for( i = 15; i >= 0; i-- )
219 {
220 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200221 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000222
223 if( i != 15 )
224 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000225 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000226 zl = ( zh << 60 ) | ( zl >> 4 );
227 zh = ( zh >> 4 );
228 zh ^= (uint64_t) last4[rem] << 48;
229 zh ^= ctx->HH[lo];
230 zl ^= ctx->HL[lo];
231
232 }
233
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000234 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000235 zl = ( zh << 60 ) | ( zl >> 4 );
236 zh = ( zh >> 4 );
237 zh ^= (uint64_t) last4[rem] << 48;
238 zh ^= ctx->HH[hi];
239 zl ^= ctx->HL[hi];
240 }
241
Paul Bakker5c2364c2012-10-01 14:41:15 +0000242 PUT_UINT32_BE( zh >> 32, output, 0 );
243 PUT_UINT32_BE( zh, output, 4 );
244 PUT_UINT32_BE( zl >> 32, output, 8 );
245 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000246}
247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Gilles Peskine295fc132021-04-15 18:32:23 +0200249 int mode,
250 const unsigned char *iv, size_t iv_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000251{
Janos Follath24eed8d2019-11-22 13:21:35 +0000252 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000253 unsigned char work_buf[16];
254 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000255 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200256 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000257
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100258 GCM_VALIDATE_RET( ctx != NULL );
259 GCM_VALIDATE_RET( iv != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100260
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200261 /* IV is limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200262 /* IV is not allowed to be zero length */
Gilles Peskine295fc132021-04-15 18:32:23 +0200263 if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200265
Paul Bakker52cf16c2013-07-26 13:55:38 +0200266 memset( ctx->y, 0x00, sizeof(ctx->y) );
267 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
268
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200269 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200270 ctx->len = 0;
271 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000272
273 if( iv_len == 12 )
274 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200275 memcpy( ctx->y, iv, iv_len );
276 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000277 }
278 else
279 {
280 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000281 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000282
283 p = iv;
284 while( iv_len > 0 )
285 {
286 use_len = ( iv_len < 16 ) ? iv_len : 16;
287
Paul Bakker67f9d532012-10-23 11:49:05 +0000288 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200289 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200290
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200291 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000292
293 iv_len -= use_len;
294 p += use_len;
295 }
296
Paul Bakker67f9d532012-10-23 11:49:05 +0000297 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200298 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000299
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200300 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000301 }
302
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500303 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
304 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200305 {
306 return( ret );
307 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000308
Gilles Peskine295fc132021-04-15 18:32:23 +0200309 return( 0 );
310}
311
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200312/**
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200313 * mbedtls_gcm_context::buf contains the partial state of the computation of
314 * the authentication tag.
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200315 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
316 * different stages of the computation:
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200317 * * len == 0 && add_len == 0: initial state
318 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
319 * a partial block of AD that has been
320 * xored in but not yet multiplied in.
321 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
322 * the data ends now.
323 * * len % 16 != 0: the first `len % 16` bytes have
324 * a partial block of ciphertext that has
325 * been xored in but not yet multiplied in.
326 * * len > 0 && len % 16 == 0: the authentication tag is correct if
327 * the data ends now.
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200328 */
Gilles Peskine295fc132021-04-15 18:32:23 +0200329int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
330 const unsigned char *add, size_t add_len )
331{
332 const unsigned char *p;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200333 size_t use_len, i, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200334
335 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
336
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200337 /* IV is limited to 2^64 bits, so 2^61 bytes */
Gilles Peskine295fc132021-04-15 18:32:23 +0200338 if( (uint64_t) add_len >> 61 != 0 )
339 return( MBEDTLS_ERR_GCM_BAD_INPUT );
340
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200341 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000342 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200343
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200344 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000345 {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200346 use_len = 16 - offset;
347 if( use_len > add_len )
348 use_len = add_len;
349
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200350 for( i = 0; i < use_len; i++ )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200351 ctx->buf[i+offset] ^= p[i];
352
353 if( offset + use_len == 16 )
354 gcm_mult( ctx, ctx->buf, ctx->buf );
355
356 ctx->add_len += use_len;
357 add_len -= use_len;
358 p += use_len;
359 }
360
361 ctx->add_len += add_len;
362
363 while( add_len >= 16 )
364 {
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200365 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200366 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200367
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200368 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000369
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200370 add_len -= 16;
371 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000372 }
373
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200374 if( add_len > 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200375 {
376 for( i = 0; i < add_len; i++ )
377 ctx->buf[i] ^= p[i];
378 }
379
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200380 return( 0 );
381}
382
Gilles Peskine58fc2722021-04-13 15:58:27 +0200383/* Increment the counter. */
384static void gcm_incr( unsigned char y[16] )
385{
386 size_t i;
387 for( i = 16; i > 12; i-- )
388 if( ++y[i - 1] != 0 )
389 break;
390}
391
392/* Calculate and apply the encryption mask. Process use_len bytes of data,
393 * starting at position offset in the mask block. */
394static int gcm_mask( mbedtls_gcm_context *ctx,
395 unsigned char ectr[16],
396 size_t offset, size_t use_len,
397 const unsigned char *input,
398 unsigned char *output )
399{
400 size_t i;
401 size_t olen = 0;
402 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
403
404 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
405 &olen ) ) != 0 )
406 {
407 mbedtls_platform_zeroize( ectr, 16 );
408 return( ret );
409 }
410
411 for( i = 0; i < use_len; i++ )
412 {
413 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
414 ctx->buf[offset + i] ^= input[i];
415 output[i] = ectr[offset + i] ^ input[i];
416 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
417 ctx->buf[offset + i] ^= output[i];
418 }
419 return( 0 );
420}
421
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200423 const unsigned char *input, size_t input_length,
424 unsigned char *output, size_t output_size,
425 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200426{
Janos Follath24eed8d2019-11-22 13:21:35 +0000427 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200428 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200429 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200430 size_t offset;
431 unsigned char ectr[16];
432
Gilles Peskinea56c4482021-04-15 17:22:35 +0200433 if( output_size < input_length )
434 return( MBEDTLS_ERR_GCM_BAD_INPUT );
435 GCM_VALIDATE_RET( output_length != NULL );
436 *output_length = input_length;
437
438 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200439 * on a potentially null pointer.
440 * Returning early also means that the last partial block of AD remains
441 * untouched for mbedtls_gcm_finish */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200442 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200443 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200444
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100445 GCM_VALIDATE_RET( ctx != NULL );
Gilles Peskine58fc2722021-04-13 15:58:27 +0200446 GCM_VALIDATE_RET( input != NULL );
447 GCM_VALIDATE_RET( output != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100448
Gilles Peskinea56c4482021-04-15 17:22:35 +0200449 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200451
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200452 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
453 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200454 if( ctx->len + input_length < ctx->len ||
455 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200456 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200457 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200458 }
459
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200460 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200461 {
462 gcm_mult( ctx, ctx->buf, ctx->buf );
463 }
464
Gilles Peskine58fc2722021-04-13 15:58:27 +0200465 offset = ctx->len % 16;
466 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000467 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200468 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200469 if( use_len > input_length )
470 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000471
Gilles Peskine58fc2722021-04-13 15:58:27 +0200472 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200473 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000474
Gilles Peskine58fc2722021-04-13 15:58:27 +0200475 if( offset + use_len == 16 )
476 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200477
Gilles Peskine58fc2722021-04-13 15:58:27 +0200478 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200479 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000480 p += use_len;
481 out_p += use_len;
482 }
483
Gilles Peskinea56c4482021-04-15 17:22:35 +0200484 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200485
Gilles Peskinea56c4482021-04-15 17:22:35 +0200486 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200487 {
488 gcm_incr( ctx->y );
489 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
490 return( ret );
491
492 gcm_mult( ctx, ctx->buf, ctx->buf );
493
Gilles Peskinea56c4482021-04-15 17:22:35 +0200494 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200495 p += 16;
496 out_p += 16;
497 }
498
Gilles Peskinea56c4482021-04-15 17:22:35 +0200499 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200500 {
501 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200502 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200503 return( ret );
504 }
505
506 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200507 return( 0 );
508}
509
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200511 unsigned char *output, size_t output_size,
Gilles Peskine5a7be102021-06-23 21:51:32 +0200512 size_t *output_length,
Gilles Peskine9461e452021-04-15 16:48:32 +0200513 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200514{
515 unsigned char work_buf[16];
516 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100517 uint64_t orig_len;
518 uint64_t orig_add_len;
519
520 GCM_VALIDATE_RET( ctx != NULL );
521 GCM_VALIDATE_RET( tag != NULL );
522
Gilles Peskine9461e452021-04-15 16:48:32 +0200523 /* We never pass any output in finish(). The output parameter exists only
524 * for the sake of alternative implementations. */
525 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200526 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200527 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200528
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100529 orig_len = ctx->len * 8;
530 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200531
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200532 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200533 {
534 gcm_mult( ctx, ctx->buf, ctx->buf );
535 }
536
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200537 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200538 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200539
Gilles Peskine58fc2722021-04-13 15:58:27 +0200540 if( ctx->len % 16 != 0 )
541 gcm_mult( ctx, ctx->buf, ctx->buf );
542
Andres AG821da842016-09-26 10:09:30 +0100543 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200544
Paul Bakker89e80c92012-03-20 13:50:09 +0000545 if( orig_len || orig_add_len )
546 {
547 memset( work_buf, 0x00, 16 );
548
Paul Bakker0ecdb232013-04-09 11:36:42 +0200549 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
550 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
551 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
552 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000553
Paul Bakker67f9d532012-10-23 11:49:05 +0000554 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200555 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000556
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200557 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000558
Paul Bakker67f9d532012-10-23 11:49:05 +0000559 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200560 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000561 }
562
563 return( 0 );
564}
565
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200567 int mode,
568 size_t length,
569 const unsigned char *iv,
570 size_t iv_len,
571 const unsigned char *add,
572 size_t add_len,
573 const unsigned char *input,
574 unsigned char *output,
575 size_t tag_len,
576 unsigned char *tag )
577{
Janos Follath24eed8d2019-11-22 13:21:35 +0000578 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200579 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200580
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100581 GCM_VALIDATE_RET( ctx != NULL );
582 GCM_VALIDATE_RET( iv != NULL );
583 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
584 GCM_VALIDATE_RET( length == 0 || input != NULL );
585 GCM_VALIDATE_RET( length == 0 || output != NULL );
586 GCM_VALIDATE_RET( tag != NULL );
587
Gilles Peskine295fc132021-04-15 18:32:23 +0200588 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
589 return( ret );
590
591 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200592 return( ret );
593
Gilles Peskinea56c4482021-04-15 17:22:35 +0200594 if( ( ret = mbedtls_gcm_update( ctx, input, length,
595 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200596 return( ret );
597
Gilles Peskine5a7be102021-06-23 21:51:32 +0200598 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200599 return( ret );
600
601 return( 0 );
602}
603
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000605 size_t length,
606 const unsigned char *iv,
607 size_t iv_len,
608 const unsigned char *add,
609 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200610 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000611 size_t tag_len,
612 const unsigned char *input,
613 unsigned char *output )
614{
Janos Follath24eed8d2019-11-22 13:21:35 +0000615 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000616 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200617 size_t i;
618 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000619
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100620 GCM_VALIDATE_RET( ctx != NULL );
621 GCM_VALIDATE_RET( iv != NULL );
622 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
623 GCM_VALIDATE_RET( tag != NULL );
624 GCM_VALIDATE_RET( length == 0 || input != NULL );
625 GCM_VALIDATE_RET( length == 0 || output != NULL );
626
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100628 iv, iv_len, add, add_len,
629 input, output, tag_len, check_tag ) ) != 0 )
630 {
631 return( ret );
632 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000633
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200634 /* Check tag in "constant-time" */
635 for( diff = 0, i = 0; i < tag_len; i++ )
636 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000637
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200638 if( diff != 0 )
639 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500640 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200642 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000643
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200644 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000645}
646
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200648{
k-stachowiak21298a22018-12-13 17:11:58 +0100649 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100650 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500652 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200653}
654
Jaeden Amero15263302017-09-21 12:53:48 +0100655#endif /* !MBEDTLS_GCM_ALT */
656
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000658/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200659 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000660 *
661 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
662 */
663#define MAX_TESTS 6
664
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100665static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000666 { 0, 0, 1, 1, 1, 1 };
667
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100668static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000669{
670 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
674 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
675 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
676 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200677 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000678};
679
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100680static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000681 { 12, 12, 12, 12, 8, 60 };
682
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100683static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000684 { 0, 0, 1, 1, 1, 2 };
685
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100686static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000687{
688 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689 0x00, 0x00, 0x00, 0x00 },
690 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
691 0xde, 0xca, 0xf8, 0x88 },
692 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200693 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000694 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200695 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000696 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200697 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000698 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200699 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000700};
701
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100702static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000703 { 0, 0, 0, 20, 20, 20 };
704
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100705static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000706 { 0, 0, 0, 1, 1, 1 };
707
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100708static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000709{
710 { 0x00 },
711 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200712 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000713 0xab, 0xad, 0xda, 0xd2 },
714};
715
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100716static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000717 { 0, 16, 64, 60, 60, 60 };
718
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100719static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000720 { 0, 0, 1, 1, 1, 1 };
721
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100722static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000723{
724 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
726 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
727 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
728 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
729 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
730 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
731 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
732 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
733 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
734};
735
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100736static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000737{
738 { 0x00 },
739 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
740 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
741 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200742 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000743 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200744 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000745 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200746 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000747 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
748 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
749 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200750 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000751 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200752 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000753 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200754 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000755 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
756 0x3d, 0x58, 0xe0, 0x91 },
757 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200758 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000759 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200760 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200762 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000763 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
764 0xc2, 0x3f, 0x45, 0x98 },
765 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200766 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000767 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200768 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000769 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200770 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000771 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
772 0x4c, 0x34, 0xae, 0xe5 },
773 { 0x00 },
774 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200775 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200777 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000778 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200779 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000780 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200781 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000782 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
783 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
784 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200785 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000786 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200787 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
788 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
789 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000790 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200791 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000792 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200793 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000794 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200795 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000796 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200797 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000798 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200799 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000800 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200801 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000802 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200803 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000804 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200805 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000806 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200807 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000808 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200809 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
810 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
811 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
812 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
813 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
814 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
815 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
816 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
817 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
818 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
819 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
820 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
821 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
822 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
823 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
824 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
825 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
826 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000827 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200828 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000829 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200830 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000831 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200832 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000833 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200834 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000835 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200836 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000837 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200838 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000839 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200840 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000841 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200842 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000843};
844
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100845static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000846{
847 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
848 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
849 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
850 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
851 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200852 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000853 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
854 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
855 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
856 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
857 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
858 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
859 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
860 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
861 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200862 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000863 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
864 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
865 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200866 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000867 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200868 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000869 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200870 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000871 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200872 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000873 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200874 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000875 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200876 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000877 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200878 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000879 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200880 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000881 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200882 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000883};
884
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000886{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200887 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000888 unsigned char buf[64];
889 unsigned char tag_buf[16];
890 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200892 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000893
894 for( j = 0; j < 3; j++ )
895 {
896 int key_len = 128 + 64 * j;
897
898 for( i = 0; i < MAX_TESTS; i++ )
899 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100900 mbedtls_gcm_init( &ctx );
901
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200902 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100904 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200905
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500906 ret = mbedtls_gcm_setkey( &ctx, cipher,
907 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100908 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100909 /*
910 * AES-192 is an optional feature that may be unavailable when
911 * there is an alternative underlying implementation i.e. when
912 * MBEDTLS_AES_ALT is defined.
913 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300914 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100915 {
916 mbedtls_printf( "skipped\n" );
917 break;
918 }
919 else if( ret != 0 )
920 {
921 goto exit;
922 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000923
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500925 pt_len_test_data[i],
926 iv_test_data[iv_index_test_data[i]],
927 iv_len_test_data[i],
928 additional_test_data[add_index_test_data[i]],
929 add_len_test_data[i],
930 pt_test_data[pt_index_test_data[i]],
931 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100932#if defined(MBEDTLS_GCM_ALT)
933 /* Allow alternative implementations to only support 12-byte nonces. */
934 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
935 iv_len_test_data[i] != 12 )
936 {
937 mbedtls_printf( "skipped\n" );
938 break;
939 }
940#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100941 if( ret != 0 )
942 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000943
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500944 if ( memcmp( buf, ct_test_data[j * 6 + i],
945 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100946 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000947 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100948 ret = 1;
949 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000950 }
951
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200952 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200953
Paul Bakker89e80c92012-03-20 13:50:09 +0000954 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200955 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000956
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100957 mbedtls_gcm_init( &ctx );
958
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200959 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200960 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100961 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200962
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500963 ret = mbedtls_gcm_setkey( &ctx, cipher,
964 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100965 key_len );
966 if( ret != 0 )
967 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000968
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500970 pt_len_test_data[i],
971 iv_test_data[iv_index_test_data[i]],
972 iv_len_test_data[i],
973 additional_test_data[add_index_test_data[i]],
974 add_len_test_data[i],
975 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000976
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100977 if( ret != 0 )
978 goto exit;
979
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100980 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
981 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100982 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000983 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100984 ret = 1;
985 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000986 }
987
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200988 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200989
Paul Bakker89e80c92012-03-20 13:50:09 +0000990 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200991 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200992
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100993 mbedtls_gcm_init( &ctx );
994
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200995 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200996 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100997 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200998
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500999 ret = mbedtls_gcm_setkey( &ctx, cipher,
1000 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001001 key_len );
1002 if( ret != 0 )
1003 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001004
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001005 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001006 iv_test_data[iv_index_test_data[i]],
1007 iv_len_test_data[i] );
1008 if( ret != 0 )
1009 goto exit;
1010
1011 ret = mbedtls_gcm_update_ad( &ctx,
1012 additional_test_data[add_index_test_data[i]],
1013 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001014 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001015 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001016
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001017 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001018 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001019 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001020 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001021 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001022 32,
1023 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001024 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001025 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001026 if( olen != 32 )
1027 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001028
Gilles Peskinea56c4482021-04-15 17:22:35 +02001029 ret = mbedtls_gcm_update( &ctx,
1030 pt_test_data[pt_index_test_data[i]] + 32,
1031 rest_len,
1032 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001033 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001034 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001035 if( olen != rest_len )
1036 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001037 }
1038 else
1039 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001040 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001041 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001042 pt_len_test_data[i],
1043 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001044 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001045 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001046 if( olen != pt_len_test_data[i] )
1047 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001048 }
1049
Gilles Peskine5a7be102021-06-23 21:51:32 +02001050 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001051 if( ret != 0 )
1052 goto exit;
1053
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001054 if( memcmp( buf, ct_test_data[j * 6 + i],
1055 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001056 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001057 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001058 ret = 1;
1059 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001060 }
1061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001063
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001064 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001065 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001066
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001067 mbedtls_gcm_init( &ctx );
1068
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001069 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001070 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001071 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001072
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001073 ret = mbedtls_gcm_setkey( &ctx, cipher,
1074 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001075 key_len );
1076 if( ret != 0 )
1077 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001078
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001079 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001080 iv_test_data[iv_index_test_data[i]],
1081 iv_len_test_data[i] );
1082 if( ret != 0 )
1083 goto exit;
1084 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001085 additional_test_data[add_index_test_data[i]],
1086 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001087 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001088 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001089
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001090 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001091 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001092 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001093 ret = mbedtls_gcm_update( &ctx,
1094 ct_test_data[j * 6 + i], 32,
1095 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001096 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001097 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001098 if( olen != 32 )
1099 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001100
Gilles Peskinea56c4482021-04-15 17:22:35 +02001101 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001102 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001103 rest_len,
1104 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001105 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001106 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001107 if( olen != rest_len )
1108 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001109 }
1110 else
1111 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001112 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001113 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001114 pt_len_test_data[i],
1115 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001116 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001117 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001118 if( olen != pt_len_test_data[i] )
1119 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001120 }
1121
Gilles Peskine5a7be102021-06-23 21:51:32 +02001122 ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001123 if( ret != 0 )
1124 goto exit;
1125
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001126 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1127 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001128 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001129 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001130 ret = 1;
1131 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001132 }
1133
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001134 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001135
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001136 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001137 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001138 }
1139 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001140
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001141 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001142 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001143
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001144 ret = 0;
1145
1146exit:
1147 if( ret != 0 )
1148 {
1149 if( verbose != 0 )
1150 mbedtls_printf( "failed\n" );
1151 mbedtls_gcm_free( &ctx );
1152 }
1153
1154 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001155}
1156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001157#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001158
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001159#endif /* MBEDTLS_GCM_C */