blob: 033cb590176034eca5ab906ab348e2c6bfa31495 [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
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker89e80c92012-03-20 13:50:09 +00006 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +01007
Paul Bakker89e80c92012-03-20 13:50:09 +00008/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +01009 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
10 *
11 * See also:
12 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
13 *
14 * We use the algorithm described as Shoup's method with 4-bit tables in
15 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000016 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010017
Gilles Peskinedb09ef62020-06-03 01:43:33 +020018#include "common.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000019
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020020#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000021
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000022#include "mbedtls/gcm.h"
Gilles Peskineed1c7f42022-09-15 20:14:22 +020023#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050024#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000025#include "mbedtls/error.h"
Dave Rodgmand26a3d62023-09-11 18:25:16 +010026#include "mbedtls/constant_time.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000027
Valerio Settibd7528a2023-12-14 09:36:03 +010028#if defined(MBEDTLS_BLOCK_CIPHER_C)
Valerio Setti9b7a8b22023-11-16 08:24:51 +010029#include "block_cipher_internal.h"
30#endif
31
Rich Evans00ab4702015-02-06 13:43:58 +000032#include <string.h>
33
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000035#include "aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010036#endif
37
Jerry Yudf87a122023-01-10 18:17:15 +080038#if defined(MBEDTLS_AESCE_C)
39#include "aesce.h"
40#endif
41
Jaeden Amero15263302017-09-21 12:53:48 +010042#if !defined(MBEDTLS_GCM_ALT)
43
Paul Bakker89e80c92012-03-20 13:50:09 +000044/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020045 * Initialize a context
46 */
Gilles Peskine449bd832023-01-11 14:50:10 +010047void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020048{
Gilles Peskine449bd832023-01-11 14:50:10 +010049 memset(ctx, 0, sizeof(mbedtls_gcm_context));
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020050}
51
52/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010053 * Precompute small multiples of H, that is set
54 * HH[i] || HL[i] = H times i,
55 * where i is seen as a field element as in [MGV], ie high-order bits
56 * correspond to low powers of P. The result is stored in the same way, that
57 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
58 * corresponds to P^127.
59 */
Gilles Peskine449bd832023-01-11 14:50:10 +010060static int gcm_gen_table(mbedtls_gcm_context *ctx)
Paul Bakker89e80c92012-03-20 13:50:09 +000061{
Paul Bakker43aff2a2013-09-09 00:10:27 +020062 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000063 uint64_t hi, lo;
64 uint64_t vl, vh;
65 unsigned char h[16];
Paul Bakker169b7f42013-06-25 14:58:00 +020066
Gilles Peskine449bd832023-01-11 14:50:10 +010067 memset(h, 0, 16);
Valerio Setti9b7a8b22023-11-16 08:24:51 +010068
Valerio Settibd7528a2023-12-14 09:36:03 +010069#if defined(MBEDTLS_BLOCK_CIPHER_C)
70 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, h, h);
71#else
Valerio Setti9b7a8b22023-11-16 08:24:51 +010072 size_t olen = 0;
Valerio Settid0eebc12023-11-20 15:17:53 +010073 ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen);
Valerio Settid0eebc12023-11-20 15:17:53 +010074#endif
75 if (ret != 0) {
Valerio Setti9b7a8b22023-11-16 08:24:51 +010076 return ret;
77 }
Paul Bakker89e80c92012-03-20 13:50:09 +000078
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010079 /* pack h as two 64-bits ints, big-endian */
Gilles Peskine449bd832023-01-11 14:50:10 +010080 hi = MBEDTLS_GET_UINT32_BE(h, 0);
81 lo = MBEDTLS_GET_UINT32_BE(h, 4);
Paul Bakker89e80c92012-03-20 13:50:09 +000082 vh = (uint64_t) hi << 32 | lo;
83
Gilles Peskine449bd832023-01-11 14:50:10 +010084 hi = MBEDTLS_GET_UINT32_BE(h, 8);
85 lo = MBEDTLS_GET_UINT32_BE(h, 12);
Paul Bakker89e80c92012-03-20 13:50:09 +000086 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020087
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010088 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +000089 ctx->HL[8] = vl;
90 ctx->HH[8] = vh;
91
Gilles Peskine9af58cd2023-03-10 22:29:32 +010092#if defined(MBEDTLS_AESNI_HAVE_CODE)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010093 /* With CLMUL support, we need only h, not the rest of the table */
Gilles Peskine449bd832023-01-11 14:50:10 +010094 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
95 return 0;
96 }
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010097#endif
98
Jerry Yu72fd0bd2023-08-18 16:31:01 +080099#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100100 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yudf87a122023-01-10 18:17:15 +0800101 return 0;
102 }
103#endif
104
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100105 /* 0 corresponds to 0 in GF(2^128) */
106 ctx->HH[0] = 0;
107 ctx->HL[0] = 0;
108
Gilles Peskine449bd832023-01-11 14:50:10 +0100109 for (i = 4; i > 0; i >>= 1) {
110 uint32_t T = (vl & 1) * 0xe1000000U;
111 vl = (vh << 63) | (vl >> 1);
112 vh = (vh >> 1) ^ ((uint64_t) T << 32);
Paul Bakker89e80c92012-03-20 13:50:09 +0000113
114 ctx->HL[i] = vl;
115 ctx->HH[i] = vh;
116 }
117
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 for (i = 2; i <= 8; i *= 2) {
Paul Bakker89e80c92012-03-20 13:50:09 +0000119 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
120 vh = *HiH;
121 vl = *HiL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 for (j = 1; j < i; j++) {
Paul Bakker89e80c92012-03-20 13:50:09 +0000123 HiH[j] = vh ^ ctx->HH[j];
124 HiL[j] = vl ^ ctx->HL[j];
125 }
126 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200127
Gilles Peskine449bd832023-01-11 14:50:10 +0100128 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000129}
130
Gilles Peskine449bd832023-01-11 14:50:10 +0100131int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
132 mbedtls_cipher_id_t cipher,
133 const unsigned char *key,
134 unsigned int keybits)
Paul Bakker89e80c92012-03-20 13:50:09 +0000135{
Janos Follath24eed8d2019-11-22 13:21:35 +0000136 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000137
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 if (keybits != 128 && keybits != 192 && keybits != 256) {
Tuvshinzaya Erdenekhuuc6b8a672022-08-05 15:31:57 +0100139 return MBEDTLS_ERR_GCM_BAD_INPUT;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200140 }
141
Valerio Settibd7528a2023-12-14 09:36:03 +0100142#if defined(MBEDTLS_BLOCK_CIPHER_C)
143 mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
144
145 if ((ret = mbedtls_block_cipher_setup(&ctx->block_cipher_ctx, cipher)) != 0) {
146 return ret;
147 }
148
149 if ((ret = mbedtls_block_cipher_setkey(&ctx->block_cipher_ctx, key, keybits)) != 0) {
150 return ret;
151 }
152#else
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100153 const mbedtls_cipher_info_t *cipher_info;
154
Gilles Peskine449bd832023-01-11 14:50:10 +0100155 cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
156 MBEDTLS_MODE_ECB);
157 if (cipher_info == NULL) {
158 return MBEDTLS_ERR_GCM_BAD_INPUT;
159 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000160
Dave Rodgman85a88132023-06-24 11:41:50 +0100161 if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 return MBEDTLS_ERR_GCM_BAD_INPUT;
163 }
164
165 mbedtls_cipher_free(&ctx->cipher_ctx);
166
167 if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) {
168 return ret;
169 }
170
171 if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits,
172 MBEDTLS_ENCRYPT)) != 0) {
173 return ret;
174 }
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100175#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100176
177 if ((ret = gcm_gen_table(ctx)) != 0) {
178 return ret;
179 }
180
181 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000182}
183
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100184/*
185 * Shoup's method for multiplication use this table with
186 * last4[x] = x times P^128
187 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
188 */
Dave Rodgman5ff02452023-07-13 15:55:21 +0100189static const uint16_t last4[16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000190{
191 0x0000, 0x1c20, 0x3840, 0x2460,
192 0x7080, 0x6ca0, 0x48c0, 0x54e0,
193 0xe100, 0xfd20, 0xd940, 0xc560,
194 0x9180, 0x8da0, 0xa9c0, 0xb5e0
195};
196
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100197/*
198 * Sets output to x times H using the precomputed tables.
199 * x and output are seen as elements of GF(2^128) as in [MGV].
200 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100201static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16],
202 unsigned char output[16])
Paul Bakker89e80c92012-03-20 13:50:09 +0000203{
204 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000205 unsigned char lo, hi, rem;
206 uint64_t zh, zl;
207
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100208#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100209 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100210 unsigned char h[16];
211
Jerry Yu1ac7f6b2023-03-07 15:44:59 +0800212 /* mbedtls_aesni_gcm_mult needs big-endian input */
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0);
214 MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4);
215 MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8);
216 MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12);
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 mbedtls_aesni_gcm_mult(output, x, h);
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100219 return;
220 }
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100221#endif /* MBEDTLS_AESNI_HAVE_CODE */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100222
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800223#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100224 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yudf87a122023-01-10 18:17:15 +0800225 unsigned char h[16];
226
Jerry Yu1ac7f6b2023-03-07 15:44:59 +0800227 /* mbedtls_aesce_gcm_mult needs big-endian input */
Jerry Yudf87a122023-01-10 18:17:15 +0800228 MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0);
229 MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4);
230 MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8);
231 MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12);
232
233 mbedtls_aesce_gcm_mult(output, x, h);
234 return;
235 }
236#endif
237
Paul Bakker89e80c92012-03-20 13:50:09 +0000238 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000239
240 zh = ctx->HH[lo];
241 zl = ctx->HL[lo];
242
Gilles Peskine449bd832023-01-11 14:50:10 +0100243 for (i = 15; i >= 0; i--) {
Paul Bakker89e80c92012-03-20 13:50:09 +0000244 lo = x[i] & 0xf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 hi = (x[i] >> 4) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000246
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 if (i != 15) {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000248 rem = (unsigned char) zl & 0xf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 zl = (zh << 60) | (zl >> 4);
250 zh = (zh >> 4);
Paul Bakker89e80c92012-03-20 13:50:09 +0000251 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;
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 zl = (zh << 60) | (zl >> 4);
259 zh = (zh >> 4);
Paul Bakker89e80c92012-03-20 13:50:09 +0000260 zh ^= (uint64_t) last4[rem] << 48;
261 zh ^= ctx->HH[hi];
262 zl ^= ctx->HL[hi];
263 }
264
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 MBEDTLS_PUT_UINT32_BE(zh >> 32, output, 0);
266 MBEDTLS_PUT_UINT32_BE(zh, output, 4);
267 MBEDTLS_PUT_UINT32_BE(zl >> 32, output, 8);
268 MBEDTLS_PUT_UINT32_BE(zl, output, 12);
Paul Bakker89e80c92012-03-20 13:50:09 +0000269}
270
Gilles Peskine449bd832023-01-11 14:50:10 +0100271int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
272 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];
Paul Bakker89e80c92012-03-20 13:50:09 +0000277 const unsigned char *p;
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100278 size_t use_len;
openluopworldeab65ac2021-09-22 23:59:42 +0800279 uint64_t iv_bits;
Valerio Settibd7528a2023-12-14 09:36:03 +0100280#if !defined(MBEDTLS_BLOCK_CIPHER_C)
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100281 size_t olen = 0;
282#endif
Paul Bakker89e80c92012-03-20 13:50:09 +0000283
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200284 /* IV is 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 Peskine449bd832023-01-11 14:50:10 +0100286 if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) {
287 return MBEDTLS_ERR_GCM_BAD_INPUT;
288 }
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200289
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 memset(ctx->y, 0x00, sizeof(ctx->y));
291 memset(ctx->buf, 0x00, sizeof(ctx->buf));
Paul Bakker52cf16c2013-07-26 13:55:38 +0200292
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200293 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200294 ctx->len = 0;
295 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000296
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 if (iv_len == 12) {
298 memcpy(ctx->y, iv, iv_len);
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200299 ctx->y[15] = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 } else {
301 memset(work_buf, 0x00, 16);
302 iv_bits = (uint64_t) iv_len * 8;
303 MBEDTLS_PUT_UINT64_BE(iv_bits, work_buf, 8);
Paul Bakker89e80c92012-03-20 13:50:09 +0000304
305 p = iv;
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 while (iv_len > 0) {
307 use_len = (iv_len < 16) ? iv_len : 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000308
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 mbedtls_xor(ctx->y, ctx->y, p, use_len);
Paul Bakker169b7f42013-06-25 14:58:00 +0200310
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 gcm_mult(ctx, ctx->y, ctx->y);
Paul Bakker89e80c92012-03-20 13:50:09 +0000312
313 iv_len -= use_len;
314 p += use_len;
315 }
316
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 mbedtls_xor(ctx->y, ctx->y, work_buf, 16);
Paul Bakker89e80c92012-03-20 13:50:09 +0000318
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 gcm_mult(ctx, ctx->y, ctx->y);
Paul Bakker89e80c92012-03-20 13:50:09 +0000320 }
321
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100322
Valerio Settibd7528a2023-12-14 09:36:03 +0100323#if defined(MBEDTLS_BLOCK_CIPHER_C)
Valerio Settid0eebc12023-11-20 15:17:53 +0100324 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->base_ectr);
Valerio Settibd7528a2023-12-14 09:36:03 +0100325#else
326 ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, &olen);
Valerio Settid0eebc12023-11-20 15:17:53 +0100327#endif
328 if (ret != 0) {
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100329 return ret;
330 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000331
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 return 0;
Gilles Peskine295fc132021-04-15 18:32:23 +0200333}
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.
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200338 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
339 * different stages of the computation:
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200340 * * 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 Peskine449bd832023-01-11 14:50:10 +0100352int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx,
353 const unsigned char *add, size_t add_len)
Gilles Peskine295fc132021-04-15 18:32:23 +0200354{
355 const unsigned char *p;
Dave Rodgmand22fb732022-11-22 16:53:25 +0000356 size_t use_len, offset;
Chien Wongbf4b5ed2024-01-22 20:43:54 +0800357 uint64_t new_add_len;
Gilles Peskine295fc132021-04-15 18:32:23 +0200358
Chien Wongbf4b5ed2024-01-22 20:43:54 +0800359 /* AD is limited to 2^64 bits, ie 2^61 bytes
360 * Also check for possible overflow */
Chien Wong019c2a72024-01-23 21:38:06 +0800361#if SIZE_MAX > 0xFFFFFFFFFFFFFFFFULL
362 if (add_len > 0xFFFFFFFFFFFFFFFFULL) {
363 return MBEDTLS_ERR_GCM_BAD_INPUT;
364 }
365#endif
366 new_add_len = ctx->add_len + (uint64_t) add_len;
Chien Wongbf4b5ed2024-01-22 20:43:54 +0800367 if (new_add_len < ctx->add_len || new_add_len >> 61 != 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 return MBEDTLS_ERR_GCM_BAD_INPUT;
369 }
Gilles Peskine295fc132021-04-15 18:32:23 +0200370
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200371 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000372 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200373
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 if (offset != 0) {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200375 use_len = 16 - offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 if (use_len > add_len) {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200377 use_len = add_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 }
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200379
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200381
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 if (offset + use_len == 16) {
383 gcm_mult(ctx, ctx->buf, ctx->buf);
384 }
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200385
386 ctx->add_len += use_len;
387 add_len -= use_len;
388 p += use_len;
389 }
390
391 ctx->add_len += add_len;
392
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 while (add_len >= 16) {
394 mbedtls_xor(ctx->buf, ctx->buf, p, 16);
Paul Bakker169b7f42013-06-25 14:58:00 +0200395
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 gcm_mult(ctx, ctx->buf, ctx->buf);
Paul Bakker89e80c92012-03-20 13:50:09 +0000397
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200398 add_len -= 16;
399 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000400 }
401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 if (add_len > 0) {
403 mbedtls_xor(ctx->buf, ctx->buf, p, add_len);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200404 }
405
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200407}
408
Gilles Peskine58fc2722021-04-13 15:58:27 +0200409/* Increment the counter. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100410static void gcm_incr(unsigned char y[16])
Gilles Peskine58fc2722021-04-13 15:58:27 +0200411{
Dave Rodgman46697da2024-01-14 12:59:49 +0000412 uint32_t x = MBEDTLS_GET_UINT32_BE(y, 12);
413 x++;
414 MBEDTLS_PUT_UINT32_BE(x, y, 12);
Gilles Peskine58fc2722021-04-13 15:58:27 +0200415}
416
417/* Calculate and apply the encryption mask. Process use_len bytes of data,
418 * starting at position offset in the mask block. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100419static int gcm_mask(mbedtls_gcm_context *ctx,
420 unsigned char ectr[16],
421 size_t offset, size_t use_len,
422 const unsigned char *input,
423 unsigned char *output)
Gilles Peskine58fc2722021-04-13 15:58:27 +0200424{
Gilles Peskine58fc2722021-04-13 15:58:27 +0200425 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Valerio Settid0eebc12023-11-20 15:17:53 +0100426
Valerio Settibd7528a2023-12-14 09:36:03 +0100427#if defined(MBEDTLS_BLOCK_CIPHER_C)
428 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ectr);
429#else
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100430 size_t olen = 0;
Valerio Settid0eebc12023-11-20 15:17:53 +0100431 ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, &olen);
Valerio Settid0eebc12023-11-20 15:17:53 +0100432#endif
433 if (ret != 0) {
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100434 mbedtls_platform_zeroize(ectr, 16);
435 return ret;
436 }
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100437
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 if (ctx->mode == MBEDTLS_GCM_DECRYPT) {
439 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len);
440 }
441 mbedtls_xor(output, ectr + offset, input, use_len);
442 if (ctx->mode == MBEDTLS_GCM_ENCRYPT) {
443 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len);
444 }
Dave Rodgmand22fb732022-11-22 16:53:25 +0000445
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 return 0;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200447}
448
Gilles Peskine449bd832023-01-11 14:50:10 +0100449int mbedtls_gcm_update(mbedtls_gcm_context *ctx,
450 const unsigned char *input, size_t input_length,
451 unsigned char *output, size_t output_size,
452 size_t *output_length)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200453{
Janos Follath24eed8d2019-11-22 13:21:35 +0000454 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200455 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200456 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200457 size_t offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 unsigned char ectr[16] = { 0 };
Gilles Peskine58fc2722021-04-13 15:58:27 +0200459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 if (output_size < input_length) {
461 return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL;
462 }
Gilles Peskinea56c4482021-04-15 17:22:35 +0200463 *output_length = input_length;
464
465 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200466 * on a potentially null pointer.
467 * Returning early also means that the last partial block of AD remains
468 * untouched for mbedtls_gcm_finish */
Gilles Peskine449bd832023-01-11 14:50:10 +0100469 if (input_length == 0) {
470 return 0;
471 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200472
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 if (output > input && (size_t) (output - input) < input_length) {
474 return MBEDTLS_ERR_GCM_BAD_INPUT;
475 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200476
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200477 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
478 * Also check for possible overflow */
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 if (ctx->len + input_length < ctx->len ||
480 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) {
481 return MBEDTLS_ERR_GCM_BAD_INPUT;
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200482 }
483
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 if (ctx->len == 0 && ctx->add_len % 16 != 0) {
485 gcm_mult(ctx, ctx->buf, ctx->buf);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200486 }
487
Gilles Peskine58fc2722021-04-13 15:58:27 +0200488 offset = ctx->len % 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 if (offset != 0) {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200490 size_t use_len = 16 - offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 if (use_len > input_length) {
Gilles Peskinea56c4482021-04-15 17:22:35 +0200492 use_len = input_length;
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000494
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) {
496 return ret;
497 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000498
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 if (offset + use_len == 16) {
500 gcm_mult(ctx, ctx->buf, ctx->buf);
501 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200502
Gilles Peskine58fc2722021-04-13 15:58:27 +0200503 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200504 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000505 p += use_len;
506 out_p += use_len;
507 }
508
Gilles Peskinea56c4482021-04-15 17:22:35 +0200509 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200510
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 while (input_length >= 16) {
512 gcm_incr(ctx->y);
513 if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) {
514 return ret;
515 }
Gilles Peskine58fc2722021-04-13 15:58:27 +0200516
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 gcm_mult(ctx, ctx->buf, ctx->buf);
Gilles Peskine58fc2722021-04-13 15:58:27 +0200518
Gilles Peskinea56c4482021-04-15 17:22:35 +0200519 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200520 p += 16;
521 out_p += 16;
522 }
523
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 if (input_length > 0) {
525 gcm_incr(ctx->y);
526 if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) {
527 return ret;
528 }
Gilles Peskine58fc2722021-04-13 15:58:27 +0200529 }
530
Gilles Peskine449bd832023-01-11 14:50:10 +0100531 mbedtls_platform_zeroize(ectr, sizeof(ectr));
532 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200533}
534
Gilles Peskine449bd832023-01-11 14:50:10 +0100535int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
536 unsigned char *output, size_t output_size,
537 size_t *output_length,
538 unsigned char *tag, size_t tag_len)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200539{
540 unsigned char work_buf[16];
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100541 uint64_t orig_len;
542 uint64_t orig_add_len;
543
Gilles Peskine9461e452021-04-15 16:48:32 +0200544 /* We never pass any output in finish(). The output parameter exists only
545 * for the sake of alternative implementations. */
546 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200547 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200548 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200549
Chien Wong858bc652024-01-22 20:47:26 +0800550 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
551 * and AD length is restricted to 2^64 bits, ie 2^61 bytes so neither of
552 * the two multiplications would overflow. */
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100553 orig_len = ctx->len * 8;
554 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200555
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 if (ctx->len == 0 && ctx->add_len % 16 != 0) {
557 gcm_mult(ctx, ctx->buf, ctx->buf);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200558 }
559
Gilles Peskine449bd832023-01-11 14:50:10 +0100560 if (tag_len > 16 || tag_len < 4) {
561 return MBEDTLS_ERR_GCM_BAD_INPUT;
Paul Bakker89e80c92012-03-20 13:50:09 +0000562 }
563
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 if (ctx->len % 16 != 0) {
565 gcm_mult(ctx, ctx->buf, ctx->buf);
566 }
567
568 memcpy(tag, ctx->base_ectr, tag_len);
569
570 if (orig_len || orig_add_len) {
571 memset(work_buf, 0x00, 16);
572
573 MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
574 MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4);
575 MBEDTLS_PUT_UINT32_BE((orig_len >> 32), work_buf, 8);
576 MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12);
577
578 mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16);
579
580 gcm_mult(ctx, ctx->buf, ctx->buf);
581
582 mbedtls_xor(tag, tag, ctx->buf, tag_len);
583 }
584
585 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000586}
587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
589 int mode,
590 size_t length,
591 const unsigned char *iv,
592 size_t iv_len,
593 const unsigned char *add,
594 size_t add_len,
595 const unsigned char *input,
596 unsigned char *output,
597 size_t tag_len,
598 unsigned char *tag)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200599{
Janos Follath24eed8d2019-11-22 13:21:35 +0000600 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200601 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200602
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) {
604 return ret;
605 }
Gilles Peskine295fc132021-04-15 18:32:23 +0200606
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) {
608 return ret;
609 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200610
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 if ((ret = mbedtls_gcm_update(ctx, input, length,
612 output, length, &olen)) != 0) {
613 return ret;
614 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200615
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) {
617 return ret;
618 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200619
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200621}
622
Gilles Peskine449bd832023-01-11 14:50:10 +0100623int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
624 size_t length,
625 const unsigned char *iv,
626 size_t iv_len,
627 const unsigned char *add,
628 size_t add_len,
629 const unsigned char *tag,
630 size_t tag_len,
631 const unsigned char *input,
632 unsigned char *output)
Paul Bakker89e80c92012-03-20 13:50:09 +0000633{
Janos Follath24eed8d2019-11-22 13:21:35 +0000634 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000635 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200636 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
639 iv, iv_len, add, add_len,
640 input, output, tag_len, check_tag)) != 0) {
641 return ret;
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100642 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000643
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200644 /* Check tag in "constant-time" */
Dave Rodgmand26a3d62023-09-11 18:25:16 +0100645 diff = mbedtls_ct_memcmp(tag, check_tag, tag_len);
Paul Bakker89e80c92012-03-20 13:50:09 +0000646
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 if (diff != 0) {
648 mbedtls_platform_zeroize(output, length);
649 return MBEDTLS_ERR_GCM_AUTH_FAILED;
650 }
651
652 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000653}
654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200656{
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 if (ctx == NULL) {
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100658 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 }
Valerio Settibd7528a2023-12-14 09:36:03 +0100660#if defined(MBEDTLS_BLOCK_CIPHER_C)
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100661 mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
Valerio Settibd7528a2023-12-14 09:36:03 +0100662#else
663 mbedtls_cipher_free(&ctx->cipher_ctx);
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100664#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200666}
667
Jaeden Amero15263302017-09-21 12:53:48 +0100668#endif /* !MBEDTLS_GCM_ALT */
669
Valerio Setti689c0f72023-12-20 09:53:39 +0100670#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_CCM_GCM_CAN_AES)
Paul Bakker89e80c92012-03-20 13:50:09 +0000671/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200672 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000673 *
674 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
675 */
676#define MAX_TESTS 6
677
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100678static const int key_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100679{ 0, 0, 1, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000680
Yanray Wang93533b52023-05-11 16:45:59 +0800681static const unsigned char key_test_data[][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000682{
683 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
687 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
688 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
689 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200690 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000691};
692
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100693static const size_t iv_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100694{ 12, 12, 12, 12, 8, 60 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000695
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100696static const int iv_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100697{ 0, 0, 1, 1, 1, 2 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000698
Yanray Wang93533b52023-05-11 16:45:59 +0800699static const unsigned char iv_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000700{
701 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702 0x00, 0x00, 0x00, 0x00 },
703 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
704 0xde, 0xca, 0xf8, 0x88 },
705 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200706 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000707 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200708 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000709 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200710 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000711 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200712 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000713};
714
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100715static const size_t add_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100716{ 0, 0, 0, 20, 20, 20 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000717
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100718static const int add_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100719{ 0, 0, 0, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000720
Yanray Wang93533b52023-05-11 16:45:59 +0800721static const unsigned char additional_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000722{
723 { 0x00 },
724 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200725 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000726 0xab, 0xad, 0xda, 0xd2 },
727};
728
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100729static const size_t pt_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100730{ 0, 16, 64, 60, 60, 60 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000731
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100732static const int pt_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100733{ 0, 0, 1, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000734
Yanray Wang93533b52023-05-11 16:45:59 +0800735static const unsigned char pt_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000736{
737 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
738 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
739 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
740 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
741 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
742 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
743 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
744 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
745 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
746 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
747};
748
Yanray Wangd329c692023-05-11 16:40:57 +0800749static const unsigned char ct_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000750{
751 { 0x00 },
752 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
753 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
754 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200755 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000756 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200757 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000758 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200759 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000760 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
761 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
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 },
770 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200771 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000772 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200773 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000774 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200775 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
777 0xc2, 0x3f, 0x45, 0x98 },
778 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200779 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000780 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200781 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000782 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200783 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000784 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
785 0x4c, 0x34, 0xae, 0xe5 },
Yanray Wangd329c692023-05-11 16:40:57 +0800786#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker89e80c92012-03-20 13:50:09 +0000787 { 0x00 },
788 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200789 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000790 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200791 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000792 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200793 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000794 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200795 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000796 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
797 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
798 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200799 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000800 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200801 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
802 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
803 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000804 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200805 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000806 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200807 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000808 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200809 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000810 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200811 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000812 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200813 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000814 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200815 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000816 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200817 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000818 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200819 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000820 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200821 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000822 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200823 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
824 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
825 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
826 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
827 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
828 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
829 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
830 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
831 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
832 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
833 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
834 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
835 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
836 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
837 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
838 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
839 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
840 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000841 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200842 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000843 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200844 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000845 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200846 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000847 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200848 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000849 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200850 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000851 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200852 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000853 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200854 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000855 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200856 0x44, 0xae, 0x7e, 0x3f },
Yanray Wangd329c692023-05-11 16:40:57 +0800857#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker89e80c92012-03-20 13:50:09 +0000858};
859
Yanray Wangd329c692023-05-11 16:40:57 +0800860static const unsigned char tag_test_data[][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000861{
862 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
863 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
864 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
865 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
866 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200867 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000868 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
869 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
870 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
871 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
872 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
873 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
Yanray Wangd329c692023-05-11 16:40:57 +0800874#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker89e80c92012-03-20 13:50:09 +0000875 { 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 },
Yanray Wangd329c692023-05-11 16:40:57 +0800899#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker89e80c92012-03-20 13:50:09 +0000900};
901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902int mbedtls_gcm_self_test(int verbose)
Paul Bakker89e80c92012-03-20 13:50:09 +0000903{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000905 unsigned char buf[64];
906 unsigned char tag_buf[16];
907 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200909 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000910
Gilles Peskine0cd9ab72023-03-16 13:06:14 +0100911 if (verbose != 0) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +0100912#if defined(MBEDTLS_GCM_ALT)
913 mbedtls_printf(" GCM note: alternative implementation.\n");
914#else /* MBEDTLS_GCM_ALT */
915#if defined(MBEDTLS_AESNI_HAVE_CODE)
916 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
917 mbedtls_printf(" GCM note: using AESNI.\n");
918 } else
919#endif
Jerry Yu2f26a592023-03-31 15:06:33 +0800920
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800921#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100922 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2f26a592023-03-31 15:06:33 +0800923 mbedtls_printf(" GCM note: using AESCE.\n");
924 } else
925#endif
926
Gilles Peskine7e67bd52023-03-10 22:35:24 +0100927 mbedtls_printf(" GCM note: built-in implementation.\n");
928#endif /* MBEDTLS_GCM_ALT */
929 }
930
Yanray Wangd329c692023-05-11 16:40:57 +0800931 static const int loop_limit =
932 (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS;
933
934 for (j = 0; j < loop_limit; j++) {
Paul Bakker89e80c92012-03-20 13:50:09 +0000935 int key_len = 128 + 64 * j;
936
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 for (i = 0; i < MAX_TESTS; i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 if (verbose != 0) {
939 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
940 key_len, i, "enc");
941 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200942
Arto Kinnunen0f066182023-04-20 10:02:46 +0800943 mbedtls_gcm_init(&ctx);
944
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 ret = mbedtls_gcm_setkey(&ctx, cipher,
946 key_test_data[key_index_test_data[i]],
947 key_len);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100948 /*
949 * AES-192 is an optional feature that may be unavailable when
950 * there is an alternative underlying implementation i.e. when
951 * MBEDTLS_AES_ALT is defined.
952 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) {
954 mbedtls_printf("skipped\n");
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100955 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 } else if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100957 goto exit;
958 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000959
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT,
961 pt_len_test_data[i],
962 iv_test_data[iv_index_test_data[i]],
963 iv_len_test_data[i],
964 additional_test_data[add_index_test_data[i]],
965 add_len_test_data[i],
966 pt_test_data[pt_index_test_data[i]],
967 buf, 16, tag_buf);
Steven Cooreman2222d682021-01-11 18:45:22 +0100968#if defined(MBEDTLS_GCM_ALT)
969 /* Allow alternative implementations to only support 12-byte nonces. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
971 iv_len_test_data[i] != 12) {
972 mbedtls_printf("skipped\n");
Steven Cooreman2222d682021-01-11 18:45:22 +0100973 break;
974 }
975#endif /* defined(MBEDTLS_GCM_ALT) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100976 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100977 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100978 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000979
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 if (memcmp(buf, ct_test_data[j * 6 + i],
981 pt_len_test_data[i]) != 0 ||
982 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100983 ret = 1;
984 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000985 }
986
Gilles Peskine449bd832023-01-11 14:50:10 +0100987 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200988
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 if (verbose != 0) {
990 mbedtls_printf("passed\n");
991 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000992
Gilles Peskine449bd832023-01-11 14:50:10 +0100993 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100994
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 if (verbose != 0) {
996 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
997 key_len, i, "dec");
998 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200999
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 ret = mbedtls_gcm_setkey(&ctx, cipher,
1001 key_test_data[key_index_test_data[i]],
1002 key_len);
1003 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001004 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001006
Gilles Peskine449bd832023-01-11 14:50:10 +01001007 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT,
1008 pt_len_test_data[i],
1009 iv_test_data[iv_index_test_data[i]],
1010 iv_len_test_data[i],
1011 additional_test_data[add_index_test_data[i]],
1012 add_len_test_data[i],
1013 ct_test_data[j * 6 + i], buf, 16, tag_buf);
Paul Bakker89e80c92012-03-20 13:50:09 +00001014
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001016 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001018
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1020 pt_len_test_data[i]) != 0 ||
1021 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001022 ret = 1;
1023 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +00001024 }
1025
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001027
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 if (verbose != 0) {
1029 mbedtls_printf("passed\n");
1030 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001031
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001033
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 if (verbose != 0) {
1035 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1036 key_len, i, "enc");
1037 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001038
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 ret = mbedtls_gcm_setkey(&ctx, cipher,
1040 key_test_data[key_index_test_data[i]],
1041 key_len);
1042 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001043 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001045
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT,
1047 iv_test_data[iv_index_test_data[i]],
1048 iv_len_test_data[i]);
1049 if (ret != 0) {
Gilles Peskine295fc132021-04-15 18:32:23 +02001050 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001051 }
Gilles Peskine295fc132021-04-15 18:32:23 +02001052
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 ret = mbedtls_gcm_update_ad(&ctx,
1054 additional_test_data[add_index_test_data[i]],
1055 add_len_test_data[i]);
1056 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001057 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001059
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 if (pt_len_test_data[i] > 32) {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001061 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 ret = mbedtls_gcm_update(&ctx,
1063 pt_test_data[pt_index_test_data[i]],
1064 32,
1065 buf, sizeof(buf), &olen);
1066 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001067 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001068 }
1069 if (olen != 32) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001070 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001071 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001072
Gilles Peskine449bd832023-01-11 14:50:10 +01001073 ret = mbedtls_gcm_update(&ctx,
1074 pt_test_data[pt_index_test_data[i]] + 32,
1075 rest_len,
1076 buf + 32, sizeof(buf) - 32, &olen);
1077 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001078 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001079 }
1080 if (olen != rest_len) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001081 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001082 }
1083 } else {
1084 ret = mbedtls_gcm_update(&ctx,
1085 pt_test_data[pt_index_test_data[i]],
1086 pt_len_test_data[i],
1087 buf, sizeof(buf), &olen);
1088 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001089 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001090 }
1091 if (olen != pt_len_test_data[i]) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001092 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001094 }
1095
Gilles Peskine449bd832023-01-11 14:50:10 +01001096 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1097 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001098 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001099 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001100
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 if (memcmp(buf, ct_test_data[j * 6 + i],
1102 pt_len_test_data[i]) != 0 ||
1103 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001104 ret = 1;
1105 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001106 }
1107
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001109
Gilles Peskine449bd832023-01-11 14:50:10 +01001110 if (verbose != 0) {
1111 mbedtls_printf("passed\n");
1112 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001113
Gilles Peskine449bd832023-01-11 14:50:10 +01001114 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001115
Gilles Peskine449bd832023-01-11 14:50:10 +01001116 if (verbose != 0) {
1117 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1118 key_len, i, "dec");
1119 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001120
Gilles Peskine449bd832023-01-11 14:50:10 +01001121 ret = mbedtls_gcm_setkey(&ctx, cipher,
1122 key_test_data[key_index_test_data[i]],
1123 key_len);
1124 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001125 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001126 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001127
Gilles Peskine449bd832023-01-11 14:50:10 +01001128 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT,
1129 iv_test_data[iv_index_test_data[i]],
1130 iv_len_test_data[i]);
1131 if (ret != 0) {
Gilles Peskine295fc132021-04-15 18:32:23 +02001132 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 }
1134 ret = mbedtls_gcm_update_ad(&ctx,
1135 additional_test_data[add_index_test_data[i]],
1136 add_len_test_data[i]);
1137 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001138 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001140
Gilles Peskine449bd832023-01-11 14:50:10 +01001141 if (pt_len_test_data[i] > 32) {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001142 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskine449bd832023-01-11 14:50:10 +01001143 ret = mbedtls_gcm_update(&ctx,
1144 ct_test_data[j * 6 + i], 32,
1145 buf, sizeof(buf), &olen);
1146 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001147 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001148 }
1149 if (olen != 32) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001150 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001152
Gilles Peskine449bd832023-01-11 14:50:10 +01001153 ret = mbedtls_gcm_update(&ctx,
1154 ct_test_data[j * 6 + i] + 32,
1155 rest_len,
1156 buf + 32, sizeof(buf) - 32, &olen);
1157 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001158 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001159 }
1160 if (olen != rest_len) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001161 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001162 }
1163 } else {
1164 ret = mbedtls_gcm_update(&ctx,
1165 ct_test_data[j * 6 + i],
1166 pt_len_test_data[i],
1167 buf, sizeof(buf), &olen);
1168 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001169 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 }
1171 if (olen != pt_len_test_data[i]) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001172 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001174 }
1175
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1177 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001178 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001179 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001180
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1182 pt_len_test_data[i]) != 0 ||
1183 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001184 ret = 1;
1185 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001186 }
1187
Gilles Peskine449bd832023-01-11 14:50:10 +01001188 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001189
Gilles Peskine449bd832023-01-11 14:50:10 +01001190 if (verbose != 0) {
1191 mbedtls_printf("passed\n");
1192 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001193 }
1194 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001195
Gilles Peskine449bd832023-01-11 14:50:10 +01001196 if (verbose != 0) {
1197 mbedtls_printf("\n");
1198 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001199
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001200 ret = 0;
1201
1202exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001203 if (ret != 0) {
1204 if (verbose != 0) {
1205 mbedtls_printf("failed\n");
1206 }
1207 mbedtls_gcm_free(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001208 }
1209
Gilles Peskine449bd832023-01-11 14:50:10 +01001210 return ret;
Paul Bakker89e80c92012-03-20 13:50:09 +00001211}
1212
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001213#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001214
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001215#endif /* MBEDTLS_GCM_C */