blob: 02265ce897de1deb06330f3a6ab4c2f6a4cc8af9 [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/**
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200336 * mbedtls_gcm_context::buf contains the partial state of the computation of
337 * the authentication tag.
338 * mbedtls_gcm_context::::add_len and mbedtls_gcm_context::len indicate
339 * differenet stages of the computation:
340 * * len == 0 && add_len == 0: initial state
341 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
342 * a partial block of AD that has been
343 * xored in but not yet multiplied in.
344 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
345 * the data ends now.
346 * * len % 16 != 0: the first `len % 16` bytes have
347 * a partial block of ciphertext that has
348 * been xored in but not yet multiplied in.
349 * * len > 0 && len % 16 == 0: the authentication tag is correct if
350 * the data ends now.
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200351 */
Gilles Peskine295fc132021-04-15 18:32:23 +0200352int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
353 const unsigned char *add, size_t add_len )
354{
355 const unsigned char *p;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200356 size_t use_len, i, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200357
358 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
359
360 /* IV is are limited to 2^64 bits, so 2^61 bytes */
361 if( (uint64_t) add_len >> 61 != 0 )
362 return( MBEDTLS_ERR_GCM_BAD_INPUT );
363
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200364 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000365 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200366
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200367 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000368 {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200369 use_len = 16 - offset;
370 if( use_len > add_len )
371 use_len = add_len;
372
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200373 for ( i = 0; i < use_len; i++ )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200374 ctx->buf[i+offset] ^= p[i];
375
376 if( offset + use_len == 16 )
377 gcm_mult( ctx, ctx->buf, ctx->buf );
378
379 ctx->add_len += use_len;
380 add_len -= use_len;
381 p += use_len;
382 }
383
384 ctx->add_len += add_len;
385
386 while( add_len >= 16 )
387 {
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200388 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200389 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200390
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200391 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000392
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200393 add_len -= 16;
394 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000395 }
396
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200397 if( add_len > 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200398 {
399 for( i = 0; i < add_len; i++ )
400 ctx->buf[i] ^= p[i];
401 }
402
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200403 return( 0 );
404}
405
Gilles Peskine58fc2722021-04-13 15:58:27 +0200406/* Increment the counter. */
407static void gcm_incr( unsigned char y[16] )
408{
409 size_t i;
410 for( i = 16; i > 12; i-- )
411 if( ++y[i - 1] != 0 )
412 break;
413}
414
415/* Calculate and apply the encryption mask. Process use_len bytes of data,
416 * starting at position offset in the mask block. */
417static int gcm_mask( mbedtls_gcm_context *ctx,
418 unsigned char ectr[16],
419 size_t offset, size_t use_len,
420 const unsigned char *input,
421 unsigned char *output )
422{
423 size_t i;
424 size_t olen = 0;
425 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
426
427 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
428 &olen ) ) != 0 )
429 {
430 mbedtls_platform_zeroize( ectr, 16 );
431 return( ret );
432 }
433
434 for( i = 0; i < use_len; i++ )
435 {
436 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
437 ctx->buf[offset + i] ^= input[i];
438 output[i] = ectr[offset + i] ^ input[i];
439 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
440 ctx->buf[offset + i] ^= output[i];
441 }
442 return( 0 );
443}
444
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200445int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200446 const unsigned char *input, size_t input_length,
447 unsigned char *output, size_t output_size,
448 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200449{
Janos Follath24eed8d2019-11-22 13:21:35 +0000450 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200451 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200452 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200453 size_t offset;
454 unsigned char ectr[16];
455
Gilles Peskinea56c4482021-04-15 17:22:35 +0200456 if( output_size < input_length )
457 return( MBEDTLS_ERR_GCM_BAD_INPUT );
458 GCM_VALIDATE_RET( output_length != NULL );
459 *output_length = input_length;
460
461 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200462 * on a potentially null pointer.
463 * Returning early also means that the last partial block of AD remains
464 * untouched for mbedtls_gcm_finish */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200465 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200466 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200467
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100468 GCM_VALIDATE_RET( ctx != NULL );
Gilles Peskine58fc2722021-04-13 15:58:27 +0200469 GCM_VALIDATE_RET( input != NULL );
470 GCM_VALIDATE_RET( output != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100471
Gilles Peskinea56c4482021-04-15 17:22:35 +0200472 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200474
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200475 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
476 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200477 if( ctx->len + input_length < ctx->len ||
478 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200479 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200480 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200481 }
482
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200483 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200484 {
485 gcm_mult( ctx, ctx->buf, ctx->buf );
486 }
487
Gilles Peskine58fc2722021-04-13 15:58:27 +0200488 offset = ctx->len % 16;
489 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000490 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200491 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200492 if( use_len > input_length )
493 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000494
Gilles Peskine58fc2722021-04-13 15:58:27 +0200495 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200496 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000497
Gilles Peskine58fc2722021-04-13 15:58:27 +0200498 if( offset + use_len == 16 )
499 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200500
Gilles Peskine58fc2722021-04-13 15:58:27 +0200501 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200502 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000503 p += use_len;
504 out_p += use_len;
505 }
506
Gilles Peskinea56c4482021-04-15 17:22:35 +0200507 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200508
Gilles Peskinea56c4482021-04-15 17:22:35 +0200509 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200510 {
511 gcm_incr( ctx->y );
512 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
513 return( ret );
514
515 gcm_mult( ctx, ctx->buf, ctx->buf );
516
Gilles Peskinea56c4482021-04-15 17:22:35 +0200517 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200518 p += 16;
519 out_p += 16;
520 }
521
Gilles Peskinea56c4482021-04-15 17:22:35 +0200522 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200523 {
524 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200525 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200526 return( ret );
527 }
528
529 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200530 return( 0 );
531}
532
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200533int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200534 unsigned char *output, size_t output_size,
Gilles Peskine9461e452021-04-15 16:48:32 +0200535 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200536{
537 unsigned char work_buf[16];
538 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100539 uint64_t orig_len;
540 uint64_t orig_add_len;
541
542 GCM_VALIDATE_RET( ctx != NULL );
543 GCM_VALIDATE_RET( tag != NULL );
544
Gilles Peskine9461e452021-04-15 16:48:32 +0200545 /* We never pass any output in finish(). The output parameter exists only
546 * for the sake of alternative implementations. */
547 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200548 (void) output_size;
Gilles Peskine9461e452021-04-15 16:48:32 +0200549
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100550 orig_len = ctx->len * 8;
551 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200552
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200553 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200554 {
555 gcm_mult( ctx, ctx->buf, ctx->buf );
556 }
557
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200558 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200560
Gilles Peskine58fc2722021-04-13 15:58:27 +0200561 if( ctx->len % 16 != 0 )
562 gcm_mult( ctx, ctx->buf, ctx->buf );
563
Andres AG821da842016-09-26 10:09:30 +0100564 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200565
Paul Bakker89e80c92012-03-20 13:50:09 +0000566 if( orig_len || orig_add_len )
567 {
568 memset( work_buf, 0x00, 16 );
569
Paul Bakker0ecdb232013-04-09 11:36:42 +0200570 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
571 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
572 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
573 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000574
Paul Bakker67f9d532012-10-23 11:49:05 +0000575 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200576 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000577
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200578 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000579
Paul Bakker67f9d532012-10-23 11:49:05 +0000580 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200581 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000582 }
583
584 return( 0 );
585}
586
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200588 int mode,
589 size_t length,
590 const unsigned char *iv,
591 size_t iv_len,
592 const unsigned char *add,
593 size_t add_len,
594 const unsigned char *input,
595 unsigned char *output,
596 size_t tag_len,
597 unsigned char *tag )
598{
Janos Follath24eed8d2019-11-22 13:21:35 +0000599 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200600 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200601
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100602 GCM_VALIDATE_RET( ctx != NULL );
603 GCM_VALIDATE_RET( iv != NULL );
604 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
605 GCM_VALIDATE_RET( length == 0 || input != NULL );
606 GCM_VALIDATE_RET( length == 0 || output != NULL );
607 GCM_VALIDATE_RET( tag != NULL );
608
Gilles Peskine295fc132021-04-15 18:32:23 +0200609 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
610 return( ret );
611
612 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200613 return( ret );
614
Gilles Peskinea56c4482021-04-15 17:22:35 +0200615 if( ( ret = mbedtls_gcm_update( ctx, input, length,
616 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200617 return( ret );
618
Gilles Peskine9461e452021-04-15 16:48:32 +0200619 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200620 return( ret );
621
622 return( 0 );
623}
624
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000626 size_t length,
627 const unsigned char *iv,
628 size_t iv_len,
629 const unsigned char *add,
630 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200631 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000632 size_t tag_len,
633 const unsigned char *input,
634 unsigned char *output )
635{
Janos Follath24eed8d2019-11-22 13:21:35 +0000636 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000637 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200638 size_t i;
639 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000640
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100641 GCM_VALIDATE_RET( ctx != NULL );
642 GCM_VALIDATE_RET( iv != NULL );
643 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
644 GCM_VALIDATE_RET( tag != NULL );
645 GCM_VALIDATE_RET( length == 0 || input != NULL );
646 GCM_VALIDATE_RET( length == 0 || output != NULL );
647
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100649 iv, iv_len, add, add_len,
650 input, output, tag_len, check_tag ) ) != 0 )
651 {
652 return( ret );
653 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000654
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200655 /* Check tag in "constant-time" */
656 for( diff = 0, i = 0; i < tag_len; i++ )
657 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000658
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200659 if( diff != 0 )
660 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500661 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200662 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200663 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000664
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200665 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000666}
667
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200668void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200669{
k-stachowiak21298a22018-12-13 17:11:58 +0100670 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100671 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200672 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500673 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200674}
675
Jaeden Amero15263302017-09-21 12:53:48 +0100676#endif /* !MBEDTLS_GCM_ALT */
677
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200678#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000679/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200680 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000681 *
682 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
683 */
684#define MAX_TESTS 6
685
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100686static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000687 { 0, 0, 1, 1, 1, 1 };
688
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100689static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000690{
691 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
695 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
696 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
697 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000699};
700
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100701static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000702 { 12, 12, 12, 12, 8, 60 };
703
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100704static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000705 { 0, 0, 1, 1, 1, 2 };
706
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100707static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000708{
709 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710 0x00, 0x00, 0x00, 0x00 },
711 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
712 0xde, 0xca, 0xf8, 0x88 },
713 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200714 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000715 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200716 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000717 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200718 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000719 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200720 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000721};
722
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100723static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000724 { 0, 0, 0, 20, 20, 20 };
725
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100726static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000727 { 0, 0, 0, 1, 1, 1 };
728
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100729static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000730{
731 { 0x00 },
732 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200733 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000734 0xab, 0xad, 0xda, 0xd2 },
735};
736
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100737static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000738 { 0, 16, 64, 60, 60, 60 };
739
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100740static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000741 { 0, 0, 1, 1, 1, 1 };
742
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100743static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000744{
745 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
746 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
747 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
748 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
749 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
750 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
751 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
752 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
753 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
754 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
755};
756
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100757static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000758{
759 { 0x00 },
760 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
761 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
762 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200763 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000764 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200765 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000766 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200767 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000768 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
769 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
770 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200771 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000772 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200773 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000774 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200775 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
777 0x3d, 0x58, 0xe0, 0x91 },
778 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200779 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000780 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200781 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000782 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200783 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000784 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
785 0xc2, 0x3f, 0x45, 0x98 },
786 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200787 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000788 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200789 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000790 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200791 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000792 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
793 0x4c, 0x34, 0xae, 0xe5 },
794 { 0x00 },
795 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200796 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000797 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200798 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000799 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200800 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000801 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200802 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000803 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
804 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
805 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200806 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000807 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200808 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
809 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
810 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000811 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200812 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000813 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200814 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000815 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200816 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000817 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200818 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000819 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200820 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000821 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200822 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000823 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200824 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000825 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200826 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000827 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200828 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000829 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200830 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
831 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
832 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
833 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
834 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
835 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
836 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
837 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
838 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
839 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
840 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
841 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
842 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
843 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
844 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
845 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
846 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
847 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000848 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200849 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000850 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200851 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000852 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200853 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000854 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200855 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000856 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200857 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000858 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200859 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000860 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200861 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000862 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200863 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000864};
865
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100866static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000867{
868 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
869 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
870 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
871 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
872 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200873 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000874 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
875 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
876 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
877 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
878 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
879 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
880 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
881 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
882 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200883 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000884 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
885 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
886 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200887 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000888 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200889 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000890 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200891 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000892 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200893 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000894 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200895 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000896 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200897 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000898 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200899 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000900 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200901 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000902 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200903 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000904};
905
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200906int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000907{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000909 unsigned char buf[64];
910 unsigned char tag_buf[16];
911 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200912 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200913 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000914
915 for( j = 0; j < 3; j++ )
916 {
917 int key_len = 128 + 64 * j;
918
919 for( i = 0; i < MAX_TESTS; i++ )
920 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100921 mbedtls_gcm_init( &ctx );
922
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200923 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100925 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200926
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500927 ret = mbedtls_gcm_setkey( &ctx, cipher,
928 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100929 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100930 /*
931 * AES-192 is an optional feature that may be unavailable when
932 * there is an alternative underlying implementation i.e. when
933 * MBEDTLS_AES_ALT is defined.
934 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300935 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100936 {
937 mbedtls_printf( "skipped\n" );
938 break;
939 }
940 else if( ret != 0 )
941 {
942 goto exit;
943 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000944
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200945 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500946 pt_len_test_data[i],
947 iv_test_data[iv_index_test_data[i]],
948 iv_len_test_data[i],
949 additional_test_data[add_index_test_data[i]],
950 add_len_test_data[i],
951 pt_test_data[pt_index_test_data[i]],
952 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100953#if defined(MBEDTLS_GCM_ALT)
954 /* Allow alternative implementations to only support 12-byte nonces. */
955 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
956 iv_len_test_data[i] != 12 )
957 {
958 mbedtls_printf( "skipped\n" );
959 break;
960 }
961#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100962 if( ret != 0 )
963 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000964
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500965 if ( memcmp( buf, ct_test_data[j * 6 + i],
966 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100967 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000968 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100969 ret = 1;
970 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000971 }
972
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200973 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200974
Paul Bakker89e80c92012-03-20 13:50:09 +0000975 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000977
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100978 mbedtls_gcm_init( &ctx );
979
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200980 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100982 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200983
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500984 ret = mbedtls_gcm_setkey( &ctx, cipher,
985 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100986 key_len );
987 if( ret != 0 )
988 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000989
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200990 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500991 pt_len_test_data[i],
992 iv_test_data[iv_index_test_data[i]],
993 iv_len_test_data[i],
994 additional_test_data[add_index_test_data[i]],
995 add_len_test_data[i],
996 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000997
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100998 if( ret != 0 )
999 goto exit;
1000
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001001 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1002 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001003 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +00001004 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001005 ret = 1;
1006 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +00001007 }
1008
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001009 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001010
Paul Bakker89e80c92012-03-20 13:50:09 +00001011 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001012 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001013
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001014 mbedtls_gcm_init( &ctx );
1015
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001016 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001018 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001019
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001020 ret = mbedtls_gcm_setkey( &ctx, cipher,
1021 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001022 key_len );
1023 if( ret != 0 )
1024 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001025
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001026 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001027 iv_test_data[iv_index_test_data[i]],
1028 iv_len_test_data[i] );
1029 if( ret != 0 )
1030 goto exit;
1031
1032 ret = mbedtls_gcm_update_ad( &ctx,
1033 additional_test_data[add_index_test_data[i]],
1034 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001035 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001036 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001037
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001038 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001039 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001040 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001041 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001042 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001043 32,
1044 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001045 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001046 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001047 if( olen != 32 )
1048 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001049
Gilles Peskinea56c4482021-04-15 17:22:35 +02001050 ret = mbedtls_gcm_update( &ctx,
1051 pt_test_data[pt_index_test_data[i]] + 32,
1052 rest_len,
1053 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001054 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001055 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001056 if( olen != rest_len )
1057 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001058 }
1059 else
1060 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001061 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001062 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001063 pt_len_test_data[i],
1064 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001065 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001066 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001067 if( olen != pt_len_test_data[i] )
1068 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001069 }
1070
Gilles Peskine9461e452021-04-15 16:48:32 +02001071 ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001072 if( ret != 0 )
1073 goto exit;
1074
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001075 if( memcmp( buf, ct_test_data[j * 6 + i],
1076 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001077 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001078 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001079 ret = 1;
1080 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001081 }
1082
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001083 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001084
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001085 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001087
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001088 mbedtls_gcm_init( &ctx );
1089
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001090 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001092 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001093
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001094 ret = mbedtls_gcm_setkey( &ctx, cipher,
1095 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001096 key_len );
1097 if( ret != 0 )
1098 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001099
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001100 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001101 iv_test_data[iv_index_test_data[i]],
1102 iv_len_test_data[i] );
1103 if( ret != 0 )
1104 goto exit;
1105 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001106 additional_test_data[add_index_test_data[i]],
1107 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001108 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001109 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001110
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001111 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001112 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001113 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001114 ret = mbedtls_gcm_update( &ctx,
1115 ct_test_data[j * 6 + i], 32,
1116 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001117 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001118 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001119 if( olen != 32 )
1120 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001121
Gilles Peskinea56c4482021-04-15 17:22:35 +02001122 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001123 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001124 rest_len,
1125 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001126 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001127 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001128 if( olen != rest_len )
1129 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001130 }
1131 else
1132 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001133 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001134 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001135 pt_len_test_data[i],
1136 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001137 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001138 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001139 if( olen != pt_len_test_data[i] )
1140 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001141 }
1142
Gilles Peskine9461e452021-04-15 16:48:32 +02001143 ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001144 if( ret != 0 )
1145 goto exit;
1146
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001147 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1148 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001149 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001150 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001151 ret = 1;
1152 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001153 }
1154
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001155 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001156
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001157 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001158 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001159 }
1160 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001161
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001162 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001163 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001164
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001165 ret = 0;
1166
1167exit:
1168 if( ret != 0 )
1169 {
1170 if( verbose != 0 )
1171 mbedtls_printf( "failed\n" );
1172 mbedtls_gcm_free( &ctx );
1173 }
1174
1175 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001176}
1177
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001178#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001179
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001180#endif /* MBEDTLS_GCM_C */