blob: a3a3e48102fa8a99ac5874713587e10d583eddec [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/*
62 * 32-bit integer manipulation macros (big endian)
63 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000064#ifndef GET_UINT32_BE
65#define GET_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000066{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000067 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
68 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
69 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
70 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakker89e80c92012-03-20 13:50:09 +000071}
72#endif
73
Paul Bakker5c2364c2012-10-01 14:41:15 +000074#ifndef PUT_UINT32_BE
75#define PUT_UINT32_BE(n,b,i) \
Paul Bakker89e80c92012-03-20 13:50:09 +000076{ \
77 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
78 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
79 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
80 (b)[(i) + 3] = (unsigned char) ( (n) ); \
81}
82#endif
83
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010084/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020085 * Initialize a context
86 */
87void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
88{
k-stachowiak8ffc92a2018-12-12 14:21:59 +010089 GCM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020090 memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
91}
92
93/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010094 * Precompute small multiples of H, that is set
95 * HH[i] || HL[i] = H times i,
96 * where i is seen as a field element as in [MGV], ie high-order bits
97 * correspond to low powers of P. The result is stored in the same way, that
98 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
99 * corresponds to P^127.
100 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200101static int gcm_gen_table( mbedtls_gcm_context *ctx )
Paul Bakker89e80c92012-03-20 13:50:09 +0000102{
Paul Bakker43aff2a2013-09-09 00:10:27 +0200103 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +0000104 uint64_t hi, lo;
105 uint64_t vl, vh;
106 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +0200107 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +0200108
Paul Bakker89e80c92012-03-20 13:50:09 +0000109 memset( h, 0, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200111 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000112
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100113 /* pack h as two 64-bits ints, big-endian */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000114 GET_UINT32_BE( hi, h, 0 );
115 GET_UINT32_BE( lo, h, 4 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000116 vh = (uint64_t) hi << 32 | lo;
117
Paul Bakker5c2364c2012-10-01 14:41:15 +0000118 GET_UINT32_BE( hi, h, 8 );
119 GET_UINT32_BE( lo, h, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000120 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +0200121
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100122 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +0000123 ctx->HL[8] = vl;
124 ctx->HH[8] = vh;
125
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200126#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100127 /* With CLMUL support, we need only h, not the rest of the table */
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100128 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100129 return( 0 );
130#endif
131
132 /* 0 corresponds to 0 in GF(2^128) */
133 ctx->HH[0] = 0;
134 ctx->HL[0] = 0;
135
Paul Bakker89e80c92012-03-20 13:50:09 +0000136 for( i = 4; i > 0; i >>= 1 )
137 {
Paul Bakker0ecdb232013-04-09 11:36:42 +0200138 uint32_t T = ( vl & 1 ) * 0xe1000000U;
Paul Bakker89e80c92012-03-20 13:50:09 +0000139 vl = ( vh << 63 ) | ( vl >> 1 );
140 vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
141
142 ctx->HL[i] = vl;
143 ctx->HH[i] = vh;
144 }
145
Manuel Pégourié-Gonnard85fadb72015-02-14 14:57:25 +0000146 for( i = 2; i <= 8; i *= 2 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000147 {
148 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
149 vh = *HiH;
150 vl = *HiL;
151 for( j = 1; j < i; j++ )
152 {
153 HiH[j] = vh ^ ctx->HH[j];
154 HiL[j] = vl ^ ctx->HL[j];
155 }
156 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200157
158 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000159}
160
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200161int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
162 mbedtls_cipher_id_t cipher,
163 const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200164 unsigned int keybits )
Paul Bakker89e80c92012-03-20 13:50:09 +0000165{
Janos Follath24eed8d2019-11-22 13:21:35 +0000166 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000168
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100169 GCM_VALIDATE_RET( ctx != NULL );
170 GCM_VALIDATE_RET( key != NULL );
171 GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
172
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500173 cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
174 MBEDTLS_MODE_ECB );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200175 if( cipher_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200176 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakker43aff2a2013-09-09 00:10:27 +0200177
Paul Bakkera0558e02013-09-10 14:25:51 +0200178 if( cipher_info->block_size != 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200179 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkera0558e02013-09-10 14:25:51 +0200180
Manuel Pégourié-Gonnard43b08572015-05-27 17:23:30 +0200181 mbedtls_cipher_free( &ctx->cipher_ctx );
182
Manuel Pégourié-Gonnard8473f872015-05-14 13:51:45 +0200183 if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000184 return( ret );
185
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200186 if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 MBEDTLS_ENCRYPT ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200188 {
189 return( ret );
190 }
191
192 if( ( ret = gcm_gen_table( ctx ) ) != 0 )
193 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000194
195 return( 0 );
196}
197
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100198/*
199 * Shoup's method for multiplication use this table with
200 * last4[x] = x times P^128
201 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
202 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000203static const uint64_t last4[16] =
204{
205 0x0000, 0x1c20, 0x3840, 0x2460,
206 0x7080, 0x6ca0, 0x48c0, 0x54e0,
207 0xe100, 0xfd20, 0xd940, 0xc560,
208 0x9180, 0x8da0, 0xa9c0, 0xb5e0
209};
210
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100211/*
212 * Sets output to x times H using the precomputed tables.
213 * x and output are seen as elements of GF(2^128) as in [MGV].
214 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200216 unsigned char output[16] )
Paul Bakker89e80c92012-03-20 13:50:09 +0000217{
218 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000219 unsigned char lo, hi, rem;
220 uint64_t zh, zl;
221
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200222#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100223 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100224 unsigned char h[16];
225
226 PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
227 PUT_UINT32_BE( ctx->HH[8], h, 4 );
228 PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
229 PUT_UINT32_BE( ctx->HL[8], h, 12 );
230
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200231 mbedtls_aesni_gcm_mult( output, x, h );
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100232 return;
233 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100235
Paul Bakker89e80c92012-03-20 13:50:09 +0000236 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000237
238 zh = ctx->HH[lo];
239 zl = ctx->HL[lo];
240
241 for( i = 15; i >= 0; i-- )
242 {
243 lo = x[i] & 0xf;
k-stachowiak67badb42019-10-22 13:25:06 +0200244 hi = ( x[i] >> 4 ) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000245
246 if( i != 15 )
247 {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000248 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000249 zl = ( zh << 60 ) | ( zl >> 4 );
250 zh = ( zh >> 4 );
251 zh ^= (uint64_t) last4[rem] << 48;
252 zh ^= ctx->HH[lo];
253 zl ^= ctx->HL[lo];
254
255 }
256
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000257 rem = (unsigned char) zl & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000258 zl = ( zh << 60 ) | ( zl >> 4 );
259 zh = ( zh >> 4 );
260 zh ^= (uint64_t) last4[rem] << 48;
261 zh ^= ctx->HH[hi];
262 zl ^= ctx->HL[hi];
263 }
264
Paul Bakker5c2364c2012-10-01 14:41:15 +0000265 PUT_UINT32_BE( zh >> 32, output, 0 );
266 PUT_UINT32_BE( zh, output, 4 );
267 PUT_UINT32_BE( zl >> 32, output, 8 );
268 PUT_UINT32_BE( zl, output, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000269}
270
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200271int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
Gilles Peskine295fc132021-04-15 18:32:23 +0200272 int mode,
273 const unsigned char *iv, size_t iv_len )
Paul Bakker89e80c92012-03-20 13:50:09 +0000274{
Janos Follath24eed8d2019-11-22 13:21:35 +0000275 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000276 unsigned char work_buf[16];
277 size_t i;
Paul Bakker89e80c92012-03-20 13:50:09 +0000278 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200279 size_t use_len, olen = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000280
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100281 GCM_VALIDATE_RET( ctx != NULL );
282 GCM_VALIDATE_RET( iv != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100283
Gilles Peskine295fc132021-04-15 18:32:23 +0200284 /* IV is are limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200285 /* IV is not allowed to be zero length */
Gilles Peskine295fc132021-04-15 18:32:23 +0200286 if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200288
Paul Bakker52cf16c2013-07-26 13:55:38 +0200289 memset( ctx->y, 0x00, sizeof(ctx->y) );
290 memset( ctx->buf, 0x00, sizeof(ctx->buf) );
291
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200292 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200293 ctx->len = 0;
294 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000295
296 if( iv_len == 12 )
297 {
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200298 memcpy( ctx->y, iv, iv_len );
299 ctx->y[15] = 1;
Paul Bakker89e80c92012-03-20 13:50:09 +0000300 }
301 else
302 {
303 memset( work_buf, 0x00, 16 );
Paul Bakker5c2364c2012-10-01 14:41:15 +0000304 PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000305
306 p = iv;
307 while( iv_len > 0 )
308 {
309 use_len = ( iv_len < 16 ) ? iv_len : 16;
310
Paul Bakker67f9d532012-10-23 11:49:05 +0000311 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200312 ctx->y[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200313
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200314 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000315
316 iv_len -= use_len;
317 p += use_len;
318 }
319
Paul Bakker67f9d532012-10-23 11:49:05 +0000320 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200321 ctx->y[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000322
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200323 gcm_mult( ctx, ctx->y, ctx->y );
Paul Bakker89e80c92012-03-20 13:50:09 +0000324 }
325
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500326 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
327 ctx->base_ectr, &olen ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200328 {
329 return( ret );
330 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000331
Gilles Peskine295fc132021-04-15 18:32:23 +0200332 return( 0 );
333}
334
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200335/**
336 * mbedtls_gcm_context::buf contains different data type, depending
337 * on the values of mbedtls_gcm_context::::add_len and
338 * mbedtls_gcm_context::len:
339 * * When add_len % 16 == 0 and len == 0: initial state.
340 * * When add_len % 16 != 0 and len == 0: the first `add_len % 16` bytes
341 * of buf have a partial AD block xored in and not yet multiplied in.
342 * * When len != 0: the first `add_len % 16` bytes of buf have partial
343 * ciphertext xored in and not yet multiplied in.
344 */
Gilles Peskine295fc132021-04-15 18:32:23 +0200345int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
346 const unsigned char *add, size_t add_len )
347{
348 const unsigned char *p;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200349 size_t use_len, i, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200350
351 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
352
353 /* IV is are limited to 2^64 bits, so 2^61 bytes */
354 if( (uint64_t) add_len >> 61 != 0 )
355 return( MBEDTLS_ERR_GCM_BAD_INPUT );
356
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200357 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000358 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200359
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200360 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000361 {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200362 use_len = 16 - offset;
363 if( use_len > add_len )
364 use_len = add_len;
365
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200366 for ( i = 0; i < use_len; i++ )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200367 ctx->buf[i+offset] ^= p[i];
368
369 if( offset + use_len == 16 )
370 gcm_mult( ctx, ctx->buf, ctx->buf );
371
372 ctx->add_len += use_len;
373 add_len -= use_len;
374 p += use_len;
375 }
376
377 ctx->add_len += add_len;
378
379 while( add_len >= 16 )
380 {
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200381 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200382 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200383
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200384 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000385
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200386 add_len -= 16;
387 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000388 }
389
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200390 if( add_len > 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200391 {
392 for( i = 0; i < add_len; i++ )
393 ctx->buf[i] ^= p[i];
394 }
395
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200396 return( 0 );
397}
398
Gilles Peskine58fc2722021-04-13 15:58:27 +0200399/* Increment the counter. */
400static void gcm_incr( unsigned char y[16] )
401{
402 size_t i;
403 for( i = 16; i > 12; i-- )
404 if( ++y[i - 1] != 0 )
405 break;
406}
407
408/* Calculate and apply the encryption mask. Process use_len bytes of data,
409 * starting at position offset in the mask block. */
410static int gcm_mask( mbedtls_gcm_context *ctx,
411 unsigned char ectr[16],
412 size_t offset, size_t use_len,
413 const unsigned char *input,
414 unsigned char *output )
415{
416 size_t i;
417 size_t olen = 0;
418 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
419
420 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
421 &olen ) ) != 0 )
422 {
423 mbedtls_platform_zeroize( ectr, 16 );
424 return( ret );
425 }
426
427 for( i = 0; i < use_len; i++ )
428 {
429 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
430 ctx->buf[offset + i] ^= input[i];
431 output[i] = ectr[offset + i] ^ input[i];
432 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
433 ctx->buf[offset + i] ^= output[i];
434 }
435 return( 0 );
436}
437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200439 const unsigned char *input, size_t input_length,
440 unsigned char *output, size_t output_size,
441 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200442{
Janos Follath24eed8d2019-11-22 13:21:35 +0000443 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200444 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200445 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200446 size_t offset;
447 unsigned char ectr[16];
448
Gilles Peskinea56c4482021-04-15 17:22:35 +0200449 if( output_size < input_length )
450 return( MBEDTLS_ERR_GCM_BAD_INPUT );
451 GCM_VALIDATE_RET( output_length != NULL );
452 *output_length = input_length;
453
454 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200455 * on a potentially null pointer.
456 * Returning early also means that the last partial block of AD remains
457 * untouched for mbedtls_gcm_finish */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200458 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200459 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200460
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100461 GCM_VALIDATE_RET( ctx != NULL );
Gilles Peskine58fc2722021-04-13 15:58:27 +0200462 GCM_VALIDATE_RET( input != NULL );
463 GCM_VALIDATE_RET( output != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100464
Gilles Peskinea56c4482021-04-15 17:22:35 +0200465 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200467
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200468 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
469 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200470 if( ctx->len + input_length < ctx->len ||
471 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200472 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200474 }
475
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200476 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200477 {
478 gcm_mult( ctx, ctx->buf, ctx->buf );
479 }
480
Gilles Peskine58fc2722021-04-13 15:58:27 +0200481 offset = ctx->len % 16;
482 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000483 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200484 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200485 if( use_len > input_length )
486 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000487
Gilles Peskine58fc2722021-04-13 15:58:27 +0200488 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200489 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000490
Gilles Peskine58fc2722021-04-13 15:58:27 +0200491 if( offset + use_len == 16 )
492 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200493
Gilles Peskine58fc2722021-04-13 15:58:27 +0200494 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200495 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000496 p += use_len;
497 out_p += use_len;
498 }
499
Gilles Peskinea56c4482021-04-15 17:22:35 +0200500 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200501
Gilles Peskinea56c4482021-04-15 17:22:35 +0200502 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200503 {
504 gcm_incr( ctx->y );
505 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
506 return( ret );
507
508 gcm_mult( ctx, ctx->buf, ctx->buf );
509
Gilles Peskinea56c4482021-04-15 17:22:35 +0200510 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200511 p += 16;
512 out_p += 16;
513 }
514
Gilles Peskinea56c4482021-04-15 17:22:35 +0200515 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200516 {
517 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200518 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200519 return( ret );
520 }
521
522 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200523 return( 0 );
524}
525
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200527 unsigned char *output, size_t output_size,
Gilles Peskine9461e452021-04-15 16:48:32 +0200528 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200529{
530 unsigned char work_buf[16];
531 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100532 uint64_t orig_len;
533 uint64_t orig_add_len;
534
535 GCM_VALIDATE_RET( ctx != NULL );
536 GCM_VALIDATE_RET( tag != NULL );
537
Gilles Peskine9461e452021-04-15 16:48:32 +0200538 /* We never pass any output in finish(). The output parameter exists only
539 * for the sake of alternative implementations. */
540 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200541 (void) output_size;
Gilles Peskine9461e452021-04-15 16:48:32 +0200542
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100543 orig_len = ctx->len * 8;
544 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200545
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200546 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200547 {
548 gcm_mult( ctx, ctx->buf, ctx->buf );
549 }
550
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200551 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200553
Gilles Peskine58fc2722021-04-13 15:58:27 +0200554 if( ctx->len % 16 != 0 )
555 gcm_mult( ctx, ctx->buf, ctx->buf );
556
Andres AG821da842016-09-26 10:09:30 +0100557 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200558
Paul Bakker89e80c92012-03-20 13:50:09 +0000559 if( orig_len || orig_add_len )
560 {
561 memset( work_buf, 0x00, 16 );
562
Paul Bakker0ecdb232013-04-09 11:36:42 +0200563 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
564 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
565 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
566 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000567
Paul Bakker67f9d532012-10-23 11:49:05 +0000568 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200569 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000570
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200571 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000572
Paul Bakker67f9d532012-10-23 11:49:05 +0000573 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200574 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000575 }
576
577 return( 0 );
578}
579
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200580int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200581 int mode,
582 size_t length,
583 const unsigned char *iv,
584 size_t iv_len,
585 const unsigned char *add,
586 size_t add_len,
587 const unsigned char *input,
588 unsigned char *output,
589 size_t tag_len,
590 unsigned char *tag )
591{
Janos Follath24eed8d2019-11-22 13:21:35 +0000592 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200593 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200594
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100595 GCM_VALIDATE_RET( ctx != NULL );
596 GCM_VALIDATE_RET( iv != NULL );
597 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
598 GCM_VALIDATE_RET( length == 0 || input != NULL );
599 GCM_VALIDATE_RET( length == 0 || output != NULL );
600 GCM_VALIDATE_RET( tag != NULL );
601
Gilles Peskine295fc132021-04-15 18:32:23 +0200602 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
603 return( ret );
604
605 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200606 return( ret );
607
Gilles Peskinea56c4482021-04-15 17:22:35 +0200608 if( ( ret = mbedtls_gcm_update( ctx, input, length,
609 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200610 return( ret );
611
Gilles Peskine9461e452021-04-15 16:48:32 +0200612 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200613 return( ret );
614
615 return( 0 );
616}
617
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000619 size_t length,
620 const unsigned char *iv,
621 size_t iv_len,
622 const unsigned char *add,
623 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200624 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000625 size_t tag_len,
626 const unsigned char *input,
627 unsigned char *output )
628{
Janos Follath24eed8d2019-11-22 13:21:35 +0000629 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000630 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200631 size_t i;
632 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000633
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100634 GCM_VALIDATE_RET( ctx != NULL );
635 GCM_VALIDATE_RET( iv != NULL );
636 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
637 GCM_VALIDATE_RET( tag != NULL );
638 GCM_VALIDATE_RET( length == 0 || input != NULL );
639 GCM_VALIDATE_RET( length == 0 || output != NULL );
640
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100642 iv, iv_len, add, add_len,
643 input, output, tag_len, check_tag ) ) != 0 )
644 {
645 return( ret );
646 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000647
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200648 /* Check tag in "constant-time" */
649 for( diff = 0, i = 0; i < tag_len; i++ )
650 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000651
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200652 if( diff != 0 )
653 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500654 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200656 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000657
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200658 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000659}
660
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200661void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200662{
k-stachowiak21298a22018-12-13 17:11:58 +0100663 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100664 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200665 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500666 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200667}
668
Jaeden Amero15263302017-09-21 12:53:48 +0100669#endif /* !MBEDTLS_GCM_ALT */
670
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200671#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000672/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200673 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000674 *
675 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
676 */
677#define MAX_TESTS 6
678
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100679static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000680 { 0, 0, 1, 1, 1, 1 };
681
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100682static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000683{
684 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
688 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
689 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
690 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200691 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000692};
693
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100694static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000695 { 12, 12, 12, 12, 8, 60 };
696
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100697static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000698 { 0, 0, 1, 1, 1, 2 };
699
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100700static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000701{
702 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703 0x00, 0x00, 0x00, 0x00 },
704 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
705 0xde, 0xca, 0xf8, 0x88 },
706 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200707 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000708 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200709 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000710 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200711 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000712 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200713 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000714};
715
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100716static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000717 { 0, 0, 0, 20, 20, 20 };
718
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100719static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000720 { 0, 0, 0, 1, 1, 1 };
721
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100722static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000723{
724 { 0x00 },
725 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200726 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000727 0xab, 0xad, 0xda, 0xd2 },
728};
729
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100730static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000731 { 0, 16, 64, 60, 60, 60 };
732
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100733static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000734 { 0, 0, 1, 1, 1, 1 };
735
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100736static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000737{
738 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
740 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
741 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
742 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
743 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
744 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
745 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
746 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
747 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
748};
749
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100750static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000751{
752 { 0x00 },
753 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
754 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
755 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200756 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000757 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200758 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000759 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200760 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
762 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
763 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200764 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000765 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200766 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000767 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200768 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000769 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
770 0x3d, 0x58, 0xe0, 0x91 },
771 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200772 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000773 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200774 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000775 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200776 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000777 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
778 0xc2, 0x3f, 0x45, 0x98 },
779 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200780 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000781 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200782 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000783 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200784 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000785 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
786 0x4c, 0x34, 0xae, 0xe5 },
787 { 0x00 },
788 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200789 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000790 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200791 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000792 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200793 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000794 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200795 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000796 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
797 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
798 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200799 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000800 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200801 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
802 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
803 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000804 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200805 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000806 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200807 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000808 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200809 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000810 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200811 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000812 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200813 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000814 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200815 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000816 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200817 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000818 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200819 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000820 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200821 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000822 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200823 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
824 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
825 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
826 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
827 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
828 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
829 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
830 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
831 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
832 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
833 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
834 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
835 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
836 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
837 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
838 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
839 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
840 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000841 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200842 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000843 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200844 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000845 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200846 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000847 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200848 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000849 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200850 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000851 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200852 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000853 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200854 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000855 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200856 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000857};
858
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100859static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000860{
861 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
862 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
863 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
864 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
865 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200866 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000867 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
868 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
869 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
870 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
871 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
872 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
873 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
874 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
875 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200876 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000877 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
878 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
879 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200880 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000881 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200882 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000883 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200884 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000885 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200886 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000887 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200888 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000889 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200890 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000891 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200892 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000893 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200894 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000895 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200896 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000897};
898
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000900{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000902 unsigned char buf[64];
903 unsigned char tag_buf[16];
904 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200905 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200906 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000907
908 for( j = 0; j < 3; j++ )
909 {
910 int key_len = 128 + 64 * j;
911
912 for( i = 0; i < MAX_TESTS; i++ )
913 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100914 mbedtls_gcm_init( &ctx );
915
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200916 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200917 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100918 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200919
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500920 ret = mbedtls_gcm_setkey( &ctx, cipher,
921 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100922 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100923 /*
924 * AES-192 is an optional feature that may be unavailable when
925 * there is an alternative underlying implementation i.e. when
926 * MBEDTLS_AES_ALT is defined.
927 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300928 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100929 {
930 mbedtls_printf( "skipped\n" );
931 break;
932 }
933 else if( ret != 0 )
934 {
935 goto exit;
936 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000937
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200938 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500939 pt_len_test_data[i],
940 iv_test_data[iv_index_test_data[i]],
941 iv_len_test_data[i],
942 additional_test_data[add_index_test_data[i]],
943 add_len_test_data[i],
944 pt_test_data[pt_index_test_data[i]],
945 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100946#if defined(MBEDTLS_GCM_ALT)
947 /* Allow alternative implementations to only support 12-byte nonces. */
948 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
949 iv_len_test_data[i] != 12 )
950 {
951 mbedtls_printf( "skipped\n" );
952 break;
953 }
954#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100955 if( ret != 0 )
956 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000957
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500958 if ( memcmp( buf, ct_test_data[j * 6 + i],
959 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100960 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000961 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100962 ret = 1;
963 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000964 }
965
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200967
Paul Bakker89e80c92012-03-20 13:50:09 +0000968 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000970
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100971 mbedtls_gcm_init( &ctx );
972
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200973 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100975 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200976
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500977 ret = mbedtls_gcm_setkey( &ctx, cipher,
978 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100979 key_len );
980 if( ret != 0 )
981 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000982
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500984 pt_len_test_data[i],
985 iv_test_data[iv_index_test_data[i]],
986 iv_len_test_data[i],
987 additional_test_data[add_index_test_data[i]],
988 add_len_test_data[i],
989 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000990
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100991 if( ret != 0 )
992 goto exit;
993
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100994 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
995 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100996 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000997 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100998 ret = 1;
999 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +00001000 }
1001
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001003
Paul Bakker89e80c92012-03-20 13:50:09 +00001004 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001005 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001006
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001007 mbedtls_gcm_init( &ctx );
1008
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001009 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001010 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001011 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001012
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001013 ret = mbedtls_gcm_setkey( &ctx, cipher,
1014 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001015 key_len );
1016 if( ret != 0 )
1017 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001018
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001020 iv_test_data[iv_index_test_data[i]],
1021 iv_len_test_data[i] );
1022 if( ret != 0 )
1023 goto exit;
1024
1025 ret = mbedtls_gcm_update_ad( &ctx,
1026 additional_test_data[add_index_test_data[i]],
1027 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001028 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001029 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001030
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001031 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001032 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001033 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001034 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001035 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001036 32,
1037 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001038 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001039 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001040 if( olen != 32 )
1041 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001042
Gilles Peskinea56c4482021-04-15 17:22:35 +02001043 ret = mbedtls_gcm_update( &ctx,
1044 pt_test_data[pt_index_test_data[i]] + 32,
1045 rest_len,
1046 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001047 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001048 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001049 if( olen != rest_len )
1050 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001051 }
1052 else
1053 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001054 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001055 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001056 pt_len_test_data[i],
1057 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001058 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001059 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001060 if( olen != pt_len_test_data[i] )
1061 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001062 }
1063
Gilles Peskine9461e452021-04-15 16:48:32 +02001064 ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001065 if( ret != 0 )
1066 goto exit;
1067
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001068 if( memcmp( buf, ct_test_data[j * 6 + i],
1069 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001070 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001071 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001072 ret = 1;
1073 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001074 }
1075
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001076 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001077
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001078 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001079 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001080
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001081 mbedtls_gcm_init( &ctx );
1082
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001083 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001084 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001085 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001086
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001087 ret = mbedtls_gcm_setkey( &ctx, cipher,
1088 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001089 key_len );
1090 if( ret != 0 )
1091 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001092
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001094 iv_test_data[iv_index_test_data[i]],
1095 iv_len_test_data[i] );
1096 if( ret != 0 )
1097 goto exit;
1098 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001099 additional_test_data[add_index_test_data[i]],
1100 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001101 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001102 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001103
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001104 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001105 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001106 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001107 ret = mbedtls_gcm_update( &ctx,
1108 ct_test_data[j * 6 + i], 32,
1109 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001110 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001111 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001112 if( olen != 32 )
1113 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001114
Gilles Peskinea56c4482021-04-15 17:22:35 +02001115 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001116 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001117 rest_len,
1118 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001119 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001120 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001121 if( olen != rest_len )
1122 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001123 }
1124 else
1125 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001126 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001127 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001128 pt_len_test_data[i],
1129 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001130 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001131 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001132 if( olen != pt_len_test_data[i] )
1133 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001134 }
1135
Gilles Peskine9461e452021-04-15 16:48:32 +02001136 ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001137 if( ret != 0 )
1138 goto exit;
1139
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001140 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1141 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001142 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001143 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001144 ret = 1;
1145 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001146 }
1147
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001148 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001149
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001150 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001151 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001152 }
1153 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001154
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001155 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001156 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001157
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001158 ret = 0;
1159
1160exit:
1161 if( ret != 0 )
1162 {
1163 if( verbose != 0 )
1164 mbedtls_printf( "failed\n" );
1165 mbedtls_gcm_free( &ctx );
1166 }
1167
1168 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001169}
1170
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001171#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001172
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001173#endif /* MBEDTLS_GCM_C */