blob: be72f99412e00c8f77f410258cff2fd44d180c08 [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
366 for (i = 0; i < use_len; i++)
367 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 {
381 use_len = 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000382
Paul Bakker67f9d532012-10-23 11:49:05 +0000383 for( i = 0; i < use_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200384 ctx->buf[i] ^= p[i];
Paul Bakker169b7f42013-06-25 14:58:00 +0200385
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200386 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000387
388 add_len -= use_len;
389 p += use_len;
390 }
391
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200392 if( add_len > 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200393 {
394 for( i = 0; i < add_len; i++ )
395 ctx->buf[i] ^= p[i];
396 }
397
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200398 return( 0 );
399}
400
Gilles Peskine58fc2722021-04-13 15:58:27 +0200401/* Increment the counter. */
402static void gcm_incr( unsigned char y[16] )
403{
404 size_t i;
405 for( i = 16; i > 12; i-- )
406 if( ++y[i - 1] != 0 )
407 break;
408}
409
410/* Calculate and apply the encryption mask. Process use_len bytes of data,
411 * starting at position offset in the mask block. */
412static int gcm_mask( mbedtls_gcm_context *ctx,
413 unsigned char ectr[16],
414 size_t offset, size_t use_len,
415 const unsigned char *input,
416 unsigned char *output )
417{
418 size_t i;
419 size_t olen = 0;
420 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
421
422 if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
423 &olen ) ) != 0 )
424 {
425 mbedtls_platform_zeroize( ectr, 16 );
426 return( ret );
427 }
428
429 for( i = 0; i < use_len; i++ )
430 {
431 if( ctx->mode == MBEDTLS_GCM_DECRYPT )
432 ctx->buf[offset + i] ^= input[i];
433 output[i] = ectr[offset + i] ^ input[i];
434 if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
435 ctx->buf[offset + i] ^= output[i];
436 }
437 return( 0 );
438}
439
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
Gilles Peskinea56c4482021-04-15 17:22:35 +0200441 const unsigned char *input, size_t input_length,
442 unsigned char *output, size_t output_size,
443 size_t *output_length )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200444{
Janos Follath24eed8d2019-11-22 13:21:35 +0000445 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200446 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200447 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200448 size_t offset;
449 unsigned char ectr[16];
450
Gilles Peskinea56c4482021-04-15 17:22:35 +0200451 if( output_size < input_length )
452 return( MBEDTLS_ERR_GCM_BAD_INPUT );
453 GCM_VALIDATE_RET( output_length != NULL );
454 *output_length = input_length;
455
456 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200457 * on a potentially null pointer.
458 * Returning early also means that the last partial block of AD remains
459 * untouched for mbedtls_gcm_finish */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200460 if( input_length == 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200461 return( 0 );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200462
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100463 GCM_VALIDATE_RET( ctx != NULL );
Gilles Peskine58fc2722021-04-13 15:58:27 +0200464 GCM_VALIDATE_RET( input != NULL );
465 GCM_VALIDATE_RET( output != NULL );
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100466
Gilles Peskinea56c4482021-04-15 17:22:35 +0200467 if( output > input && (size_t) ( output - input ) < input_length )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200469
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200470 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
471 * Also check for possible overflow */
Gilles Peskinea56c4482021-04-15 17:22:35 +0200472 if( ctx->len + input_length < ctx->len ||
473 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull )
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200474 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200476 }
477
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200478 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200479 {
480 gcm_mult( ctx, ctx->buf, ctx->buf );
481 }
482
Gilles Peskine58fc2722021-04-13 15:58:27 +0200483 offset = ctx->len % 16;
484 if( offset != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000485 {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200486 size_t use_len = 16 - offset;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200487 if( use_len > input_length )
488 use_len = input_length;
Paul Bakker89e80c92012-03-20 13:50:09 +0000489
Gilles Peskine58fc2722021-04-13 15:58:27 +0200490 if( ( ret = gcm_mask( ctx, ectr, offset, use_len, p, out_p ) ) != 0 )
Paul Bakker43aff2a2013-09-09 00:10:27 +0200491 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +0000492
Gilles Peskine58fc2722021-04-13 15:58:27 +0200493 if( offset + use_len == 16 )
494 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker169b7f42013-06-25 14:58:00 +0200495
Gilles Peskine58fc2722021-04-13 15:58:27 +0200496 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200497 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000498 p += use_len;
499 out_p += use_len;
500 }
501
Gilles Peskinea56c4482021-04-15 17:22:35 +0200502 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200503
Gilles Peskinea56c4482021-04-15 17:22:35 +0200504 while( input_length >= 16 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200505 {
506 gcm_incr( ctx->y );
507 if( ( ret = gcm_mask( ctx, ectr, 0, 16, p, out_p ) ) != 0 )
508 return( ret );
509
510 gcm_mult( ctx, ctx->buf, ctx->buf );
511
Gilles Peskinea56c4482021-04-15 17:22:35 +0200512 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200513 p += 16;
514 out_p += 16;
515 }
516
Gilles Peskinea56c4482021-04-15 17:22:35 +0200517 if( input_length > 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200518 {
519 gcm_incr( ctx->y );
Gilles Peskinea56c4482021-04-15 17:22:35 +0200520 if( ( ret = gcm_mask( ctx, ectr, 0, input_length, p, out_p ) ) != 0 )
Gilles Peskine58fc2722021-04-13 15:58:27 +0200521 return( ret );
522 }
523
524 mbedtls_platform_zeroize( ectr, sizeof( ectr ) );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200525 return( 0 );
526}
527
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200529 unsigned char *output, size_t output_size,
Gilles Peskine9461e452021-04-15 16:48:32 +0200530 unsigned char *tag, size_t tag_len )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200531{
532 unsigned char work_buf[16];
533 size_t i;
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100534 uint64_t orig_len;
535 uint64_t orig_add_len;
536
537 GCM_VALIDATE_RET( ctx != NULL );
538 GCM_VALIDATE_RET( tag != NULL );
539
Gilles Peskine9461e452021-04-15 16:48:32 +0200540 /* We never pass any output in finish(). The output parameter exists only
541 * for the sake of alternative implementations. */
542 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200543 (void) output_size;
Gilles Peskine9461e452021-04-15 16:48:32 +0200544
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100545 orig_len = ctx->len * 8;
546 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200547
Mateusz Starzyk333f48f2021-06-07 14:42:27 +0200548 if( ctx->len == 0 && ctx->add_len % 16 != 0 )
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200549 {
550 gcm_mult( ctx, ctx->buf, ctx->buf );
551 }
552
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200553 if( tag_len > 16 || tag_len < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554 return( MBEDTLS_ERR_GCM_BAD_INPUT );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200555
Gilles Peskine58fc2722021-04-13 15:58:27 +0200556 if( ctx->len % 16 != 0 )
557 gcm_mult( ctx, ctx->buf, ctx->buf );
558
Andres AG821da842016-09-26 10:09:30 +0100559 memcpy( tag, ctx->base_ectr, tag_len );
Manuel Pégourié-Gonnard07f8fa52013-08-30 18:34:08 +0200560
Paul Bakker89e80c92012-03-20 13:50:09 +0000561 if( orig_len || orig_add_len )
562 {
563 memset( work_buf, 0x00, 16 );
564
Paul Bakker0ecdb232013-04-09 11:36:42 +0200565 PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
566 PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
567 PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
568 PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000569
Paul Bakker67f9d532012-10-23 11:49:05 +0000570 for( i = 0; i < 16; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200571 ctx->buf[i] ^= work_buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000572
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200573 gcm_mult( ctx, ctx->buf, ctx->buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000574
Paul Bakker67f9d532012-10-23 11:49:05 +0000575 for( i = 0; i < tag_len; i++ )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200576 tag[i] ^= ctx->buf[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000577 }
578
579 return( 0 );
580}
581
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200582int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200583 int mode,
584 size_t length,
585 const unsigned char *iv,
586 size_t iv_len,
587 const unsigned char *add,
588 size_t add_len,
589 const unsigned char *input,
590 unsigned char *output,
591 size_t tag_len,
592 unsigned char *tag )
593{
Janos Follath24eed8d2019-11-22 13:21:35 +0000594 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200595 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200596
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100597 GCM_VALIDATE_RET( ctx != NULL );
598 GCM_VALIDATE_RET( iv != NULL );
599 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
600 GCM_VALIDATE_RET( length == 0 || input != NULL );
601 GCM_VALIDATE_RET( length == 0 || output != NULL );
602 GCM_VALIDATE_RET( tag != NULL );
603
Gilles Peskine295fc132021-04-15 18:32:23 +0200604 if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
605 return( ret );
606
607 if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200608 return( ret );
609
Gilles Peskinea56c4482021-04-15 17:22:35 +0200610 if( ( ret = mbedtls_gcm_update( ctx, input, length,
611 output, length, &olen ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200612 return( ret );
613
Gilles Peskine9461e452021-04-15 16:48:32 +0200614 if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, tag, tag_len ) ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200615 return( ret );
616
617 return( 0 );
618}
619
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
Paul Bakker89e80c92012-03-20 13:50:09 +0000621 size_t length,
622 const unsigned char *iv,
623 size_t iv_len,
624 const unsigned char *add,
625 size_t add_len,
Paul Bakker169b7f42013-06-25 14:58:00 +0200626 const unsigned char *tag,
Paul Bakker89e80c92012-03-20 13:50:09 +0000627 size_t tag_len,
628 const unsigned char *input,
629 unsigned char *output )
630{
Janos Follath24eed8d2019-11-22 13:21:35 +0000631 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000632 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200633 size_t i;
634 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000635
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100636 GCM_VALIDATE_RET( ctx != NULL );
637 GCM_VALIDATE_RET( iv != NULL );
638 GCM_VALIDATE_RET( add_len == 0 || add != NULL );
639 GCM_VALIDATE_RET( tag != NULL );
640 GCM_VALIDATE_RET( length == 0 || input != NULL );
641 GCM_VALIDATE_RET( length == 0 || output != NULL );
642
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643 if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100644 iv, iv_len, add, add_len,
645 input, output, tag_len, check_tag ) ) != 0 )
646 {
647 return( ret );
648 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000649
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200650 /* Check tag in "constant-time" */
651 for( diff = 0, i = 0; i < tag_len; i++ )
652 diff |= tag[i] ^ check_tag[i];
Paul Bakker89e80c92012-03-20 13:50:09 +0000653
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200654 if( diff != 0 )
655 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500656 mbedtls_platform_zeroize( output, length );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657 return( MBEDTLS_ERR_GCM_AUTH_FAILED );
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200658 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000659
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200660 return( 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000661}
662
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200663void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200664{
k-stachowiak21298a22018-12-13 17:11:58 +0100665 if( ctx == NULL )
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100666 return;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200667 mbedtls_cipher_free( &ctx->cipher_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500668 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200669}
670
Jaeden Amero15263302017-09-21 12:53:48 +0100671#endif /* !MBEDTLS_GCM_ALT */
672
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000674/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200675 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000676 *
677 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
678 */
679#define MAX_TESTS 6
680
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100681static const int key_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000682 { 0, 0, 1, 1, 1, 1 };
683
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100684static const unsigned char key_test_data[MAX_TESTS][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000685{
686 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
690 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
691 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
692 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200693 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000694};
695
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100696static const size_t iv_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000697 { 12, 12, 12, 12, 8, 60 };
698
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100699static const int iv_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000700 { 0, 0, 1, 1, 1, 2 };
701
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100702static const unsigned char iv_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000703{
704 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
705 0x00, 0x00, 0x00, 0x00 },
706 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
707 0xde, 0xca, 0xf8, 0x88 },
708 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200709 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000710 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200711 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000712 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200713 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000714 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200715 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000716};
717
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100718static const size_t add_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000719 { 0, 0, 0, 20, 20, 20 };
720
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100721static const int add_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000722 { 0, 0, 0, 1, 1, 1 };
723
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100724static const unsigned char additional_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000725{
726 { 0x00 },
727 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200728 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000729 0xab, 0xad, 0xda, 0xd2 },
730};
731
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100732static const size_t pt_len_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000733 { 0, 16, 64, 60, 60, 60 };
734
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100735static const int pt_index_test_data[MAX_TESTS] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000736 { 0, 0, 1, 1, 1, 1 };
737
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100738static const unsigned char pt_test_data[MAX_TESTS][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000739{
740 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
742 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
743 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
744 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
745 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
746 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
747 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
748 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
749 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
750};
751
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100752static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000753{
754 { 0x00 },
755 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
756 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
757 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200758 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000759 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200760 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200762 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000763 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
764 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
765 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200766 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000767 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200768 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000769 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200770 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000771 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
772 0x3d, 0x58, 0xe0, 0x91 },
773 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200774 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000775 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200776 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000777 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200778 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000779 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
780 0xc2, 0x3f, 0x45, 0x98 },
781 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200782 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000783 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200784 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000785 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200786 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000787 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
788 0x4c, 0x34, 0xae, 0xe5 },
789 { 0x00 },
790 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200791 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000792 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200793 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000794 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200795 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000796 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200797 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000798 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
799 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
800 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200801 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000802 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200803 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
804 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
805 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000806 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200807 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000808 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200809 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000810 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200811 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000812 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200813 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000814 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200815 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000816 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200817 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000818 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200819 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000820 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200821 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000822 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200823 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000824 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200825 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
826 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
827 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
828 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
829 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
830 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
831 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
832 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
833 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
834 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
835 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
836 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
837 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
838 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
839 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
840 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
841 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
842 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000843 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200844 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000845 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200846 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000847 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200848 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000849 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200850 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000851 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200852 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000853 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200854 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000855 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200856 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000857 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200858 0x44, 0xae, 0x7e, 0x3f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000859};
860
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100861static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000862{
863 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
864 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
865 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
866 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
867 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200868 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000869 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
870 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
871 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
872 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
873 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
874 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
875 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
876 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
877 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200878 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000879 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
880 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
881 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200882 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000883 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200884 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000885 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200886 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000887 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200888 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000889 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200890 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000891 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200892 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000893 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200894 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000895 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200896 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000897 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200898 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Paul Bakker89e80c92012-03-20 13:50:09 +0000899};
900
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901int mbedtls_gcm_self_test( int verbose )
Paul Bakker89e80c92012-03-20 13:50:09 +0000902{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000904 unsigned char buf[64];
905 unsigned char tag_buf[16];
906 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200907 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200908 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000909
910 for( j = 0; j < 3; j++ )
911 {
912 int key_len = 128 + 64 * j;
913
914 for( i = 0; i < MAX_TESTS; i++ )
915 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100916 mbedtls_gcm_init( &ctx );
917
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200918 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100920 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200921
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500922 ret = mbedtls_gcm_setkey( &ctx, cipher,
923 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100924 key_len );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100925 /*
926 * AES-192 is an optional feature that may be unavailable when
927 * there is an alternative underlying implementation i.e. when
928 * MBEDTLS_AES_ALT is defined.
929 */
Ron Eldor9924bdc2018-10-04 10:59:13 +0300930 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100931 {
932 mbedtls_printf( "skipped\n" );
933 break;
934 }
935 else if( ret != 0 )
936 {
937 goto exit;
938 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000939
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200940 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500941 pt_len_test_data[i],
942 iv_test_data[iv_index_test_data[i]],
943 iv_len_test_data[i],
944 additional_test_data[add_index_test_data[i]],
945 add_len_test_data[i],
946 pt_test_data[pt_index_test_data[i]],
947 buf, 16, tag_buf );
Steven Cooreman2222d682021-01-11 18:45:22 +0100948#if defined(MBEDTLS_GCM_ALT)
949 /* Allow alternative implementations to only support 12-byte nonces. */
950 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
951 iv_len_test_data[i] != 12 )
952 {
953 mbedtls_printf( "skipped\n" );
954 break;
955 }
956#endif /* defined(MBEDTLS_GCM_ALT) */
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100957 if( ret != 0 )
958 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000959
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500960 if ( memcmp( buf, ct_test_data[j * 6 + i],
961 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100962 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000963 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100964 ret = 1;
965 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000966 }
967
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200968 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200969
Paul Bakker89e80c92012-03-20 13:50:09 +0000970 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200971 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +0000972
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100973 mbedtls_gcm_init( &ctx );
974
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200975 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100977 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200978
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500979 ret = mbedtls_gcm_setkey( &ctx, cipher,
980 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100981 key_len );
982 if( ret != 0 )
983 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000984
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200985 ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
Andrzej Kurekee3c4352019-01-10 03:10:02 -0500986 pt_len_test_data[i],
987 iv_test_data[iv_index_test_data[i]],
988 iv_len_test_data[i],
989 additional_test_data[add_index_test_data[i]],
990 add_len_test_data[i],
991 ct_test_data[j * 6 + i], buf, 16, tag_buf );
Paul Bakker89e80c92012-03-20 13:50:09 +0000992
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100993 if( ret != 0 )
994 goto exit;
995
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100996 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
997 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100998 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000999 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001000 ret = 1;
1001 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +00001002 }
1003
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001004 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001005
Paul Bakker89e80c92012-03-20 13:50:09 +00001006 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001007 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001008
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001009 mbedtls_gcm_init( &ctx );
1010
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001011 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001012 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001013 key_len, i, "enc" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001014
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001015 ret = mbedtls_gcm_setkey( &ctx, cipher,
1016 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001017 key_len );
1018 if( ret != 0 )
1019 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001020
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001022 iv_test_data[iv_index_test_data[i]],
1023 iv_len_test_data[i] );
1024 if( ret != 0 )
1025 goto exit;
1026
1027 ret = mbedtls_gcm_update_ad( &ctx,
1028 additional_test_data[add_index_test_data[i]],
1029 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001030 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001031 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001032
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001033 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001034 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001035 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001036 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001037 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001038 32,
1039 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001040 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001041 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001042 if( olen != 32 )
1043 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001044
Gilles Peskinea56c4482021-04-15 17:22:35 +02001045 ret = mbedtls_gcm_update( &ctx,
1046 pt_test_data[pt_index_test_data[i]] + 32,
1047 rest_len,
1048 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001049 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001050 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001051 if( olen != rest_len )
1052 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001053 }
1054 else
1055 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001056 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001057 pt_test_data[pt_index_test_data[i]],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001058 pt_len_test_data[i],
1059 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001060 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001061 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001062 if( olen != pt_len_test_data[i] )
1063 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001064 }
1065
Gilles Peskine9461e452021-04-15 16:48:32 +02001066 ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001067 if( ret != 0 )
1068 goto exit;
1069
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001070 if( memcmp( buf, ct_test_data[j * 6 + i],
1071 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001072 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001073 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001074 ret = 1;
1075 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001076 }
1077
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001079
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001080 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001081 mbedtls_printf( "passed\n" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001082
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001083 mbedtls_gcm_init( &ctx );
1084
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001085 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086 mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001087 key_len, i, "dec" );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001088
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001089 ret = mbedtls_gcm_setkey( &ctx, cipher,
1090 key_test_data[key_index_test_data[i]],
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001091 key_len );
1092 if( ret != 0 )
1093 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001094
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001095 ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
Gilles Peskine295fc132021-04-15 18:32:23 +02001096 iv_test_data[iv_index_test_data[i]],
1097 iv_len_test_data[i] );
1098 if( ret != 0 )
1099 goto exit;
1100 ret = mbedtls_gcm_update_ad( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001101 additional_test_data[add_index_test_data[i]],
1102 add_len_test_data[i] );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001103 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001104 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001105
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001106 if( pt_len_test_data[i] > 32 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001107 {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001108 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001109 ret = mbedtls_gcm_update( &ctx,
1110 ct_test_data[j * 6 + i], 32,
1111 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001112 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001113 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001114 if( olen != 32 )
1115 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001116
Gilles Peskinea56c4482021-04-15 17:22:35 +02001117 ret = mbedtls_gcm_update( &ctx,
Andrzej Kurekee3c4352019-01-10 03:10:02 -05001118 ct_test_data[j * 6 + i] + 32,
Gilles Peskinea56c4482021-04-15 17:22:35 +02001119 rest_len,
1120 buf + 32, sizeof( buf ) - 32, &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001121 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001122 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001123 if( olen != rest_len )
1124 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001125 }
1126 else
1127 {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001128 ret = mbedtls_gcm_update( &ctx,
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001129 ct_test_data[j * 6 + i],
Gilles Peskinea56c4482021-04-15 17:22:35 +02001130 pt_len_test_data[i],
1131 buf, sizeof( buf ), &olen );
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001132 if( ret != 0 )
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001133 goto exit;
Gilles Peskinea56c4482021-04-15 17:22:35 +02001134 if( olen != pt_len_test_data[i] )
1135 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001136 }
1137
Gilles Peskine9461e452021-04-15 16:48:32 +02001138 ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001139 if( ret != 0 )
1140 goto exit;
1141
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001142 if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
1143 pt_len_test_data[i] ) != 0 ||
Michał Janiszewski9aeea932018-10-30 23:00:15 +01001144 memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001145 {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001146 ret = 1;
1147 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001148 }
1149
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001150 mbedtls_gcm_free( &ctx );
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001151
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001152 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001153 mbedtls_printf( "passed\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001154 }
1155 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001156
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001157 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001158 mbedtls_printf( "\n" );
Paul Bakker89e80c92012-03-20 13:50:09 +00001159
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001160 ret = 0;
1161
1162exit:
1163 if( ret != 0 )
1164 {
1165 if( verbose != 0 )
1166 mbedtls_printf( "failed\n" );
1167 mbedtls_gcm_free( &ctx );
1168 }
1169
1170 return( ret );
Paul Bakker89e80c92012-03-20 13:50:09 +00001171}
1172
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001173#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001174
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001175#endif /* MBEDTLS_GCM_C */