blob: 337145b7182e77ef479954e7069a5bb4be75c017 [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 */
361 new_add_len = ctx->add_len + add_len;
362 if (new_add_len < ctx->add_len || new_add_len >> 61 != 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 return MBEDTLS_ERR_GCM_BAD_INPUT;
364 }
Gilles Peskine295fc132021-04-15 18:32:23 +0200365
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200366 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000367 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200368
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 if (offset != 0) {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200370 use_len = 16 - offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 if (use_len > add_len) {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200372 use_len = add_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 }
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200374
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200376
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 if (offset + use_len == 16) {
378 gcm_mult(ctx, ctx->buf, ctx->buf);
379 }
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200380
381 ctx->add_len += use_len;
382 add_len -= use_len;
383 p += use_len;
384 }
385
386 ctx->add_len += add_len;
387
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 while (add_len >= 16) {
389 mbedtls_xor(ctx->buf, ctx->buf, p, 16);
Paul Bakker169b7f42013-06-25 14:58:00 +0200390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 gcm_mult(ctx, ctx->buf, ctx->buf);
Paul Bakker89e80c92012-03-20 13:50:09 +0000392
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200393 add_len -= 16;
394 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000395 }
396
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 if (add_len > 0) {
398 mbedtls_xor(ctx->buf, ctx->buf, p, add_len);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200399 }
400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200402}
403
Gilles Peskine58fc2722021-04-13 15:58:27 +0200404/* Increment the counter. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100405static void gcm_incr(unsigned char y[16])
Gilles Peskine58fc2722021-04-13 15:58:27 +0200406{
Dave Rodgman46697da2024-01-14 12:59:49 +0000407 uint32_t x = MBEDTLS_GET_UINT32_BE(y, 12);
408 x++;
409 MBEDTLS_PUT_UINT32_BE(x, y, 12);
Gilles Peskine58fc2722021-04-13 15:58:27 +0200410}
411
412/* Calculate and apply the encryption mask. Process use_len bytes of data,
413 * starting at position offset in the mask block. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100414static int gcm_mask(mbedtls_gcm_context *ctx,
415 unsigned char ectr[16],
416 size_t offset, size_t use_len,
417 const unsigned char *input,
418 unsigned char *output)
Gilles Peskine58fc2722021-04-13 15:58:27 +0200419{
Gilles Peskine58fc2722021-04-13 15:58:27 +0200420 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Valerio Settid0eebc12023-11-20 15:17:53 +0100421
Valerio Settibd7528a2023-12-14 09:36:03 +0100422#if defined(MBEDTLS_BLOCK_CIPHER_C)
423 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ectr);
424#else
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100425 size_t olen = 0;
Valerio Settid0eebc12023-11-20 15:17:53 +0100426 ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, &olen);
Valerio Settid0eebc12023-11-20 15:17:53 +0100427#endif
428 if (ret != 0) {
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100429 mbedtls_platform_zeroize(ectr, 16);
430 return ret;
431 }
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100432
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 if (ctx->mode == MBEDTLS_GCM_DECRYPT) {
434 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len);
435 }
436 mbedtls_xor(output, ectr + offset, input, use_len);
437 if (ctx->mode == MBEDTLS_GCM_ENCRYPT) {
438 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len);
439 }
Dave Rodgmand22fb732022-11-22 16:53:25 +0000440
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 return 0;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200442}
443
Gilles Peskine449bd832023-01-11 14:50:10 +0100444int mbedtls_gcm_update(mbedtls_gcm_context *ctx,
445 const unsigned char *input, size_t input_length,
446 unsigned char *output, size_t output_size,
447 size_t *output_length)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200448{
Janos Follath24eed8d2019-11-22 13:21:35 +0000449 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200450 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200451 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200452 size_t offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 unsigned char ectr[16] = { 0 };
Gilles Peskine58fc2722021-04-13 15:58:27 +0200454
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 if (output_size < input_length) {
456 return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL;
457 }
Gilles Peskinea56c4482021-04-15 17:22:35 +0200458 *output_length = input_length;
459
460 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200461 * on a potentially null pointer.
462 * Returning early also means that the last partial block of AD remains
463 * untouched for mbedtls_gcm_finish */
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 if (input_length == 0) {
465 return 0;
466 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200467
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 if (output > input && (size_t) (output - input) < input_length) {
469 return MBEDTLS_ERR_GCM_BAD_INPUT;
470 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200471
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200472 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
473 * Also check for possible overflow */
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 if (ctx->len + input_length < ctx->len ||
475 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) {
476 return MBEDTLS_ERR_GCM_BAD_INPUT;
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200477 }
478
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 if (ctx->len == 0 && ctx->add_len % 16 != 0) {
480 gcm_mult(ctx, ctx->buf, ctx->buf);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200481 }
482
Gilles Peskine58fc2722021-04-13 15:58:27 +0200483 offset = ctx->len % 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 if (offset != 0) {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200485 size_t use_len = 16 - offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 if (use_len > input_length) {
Gilles Peskinea56c4482021-04-15 17:22:35 +0200487 use_len = input_length;
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000489
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) {
491 return ret;
492 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000493
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 if (offset + use_len == 16) {
495 gcm_mult(ctx, ctx->buf, ctx->buf);
496 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200497
Gilles Peskine58fc2722021-04-13 15:58:27 +0200498 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200499 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000500 p += use_len;
501 out_p += use_len;
502 }
503
Gilles Peskinea56c4482021-04-15 17:22:35 +0200504 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200505
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 while (input_length >= 16) {
507 gcm_incr(ctx->y);
508 if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) {
509 return ret;
510 }
Gilles Peskine58fc2722021-04-13 15:58:27 +0200511
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 gcm_mult(ctx, ctx->buf, ctx->buf);
Gilles Peskine58fc2722021-04-13 15:58:27 +0200513
Gilles Peskinea56c4482021-04-15 17:22:35 +0200514 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200515 p += 16;
516 out_p += 16;
517 }
518
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 if (input_length > 0) {
520 gcm_incr(ctx->y);
521 if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) {
522 return ret;
523 }
Gilles Peskine58fc2722021-04-13 15:58:27 +0200524 }
525
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 mbedtls_platform_zeroize(ectr, sizeof(ectr));
527 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200528}
529
Gilles Peskine449bd832023-01-11 14:50:10 +0100530int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
531 unsigned char *output, size_t output_size,
532 size_t *output_length,
533 unsigned char *tag, size_t tag_len)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200534{
535 unsigned char work_buf[16];
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100536 uint64_t orig_len;
537 uint64_t orig_add_len;
538
Gilles Peskine9461e452021-04-15 16:48:32 +0200539 /* We never pass any output in finish(). The output parameter exists only
540 * for the sake of alternative implementations. */
541 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200542 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200543 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200544
Chien Wong858bc652024-01-22 20:47:26 +0800545 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
546 * and AD length is restricted to 2^64 bits, ie 2^61 bytes so neither of
547 * the two multiplications would overflow. */
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100548 orig_len = ctx->len * 8;
549 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200550
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 if (ctx->len == 0 && ctx->add_len % 16 != 0) {
552 gcm_mult(ctx, ctx->buf, ctx->buf);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200553 }
554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 if (tag_len > 16 || tag_len < 4) {
556 return MBEDTLS_ERR_GCM_BAD_INPUT;
Paul Bakker89e80c92012-03-20 13:50:09 +0000557 }
558
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 if (ctx->len % 16 != 0) {
560 gcm_mult(ctx, ctx->buf, ctx->buf);
561 }
562
563 memcpy(tag, ctx->base_ectr, tag_len);
564
565 if (orig_len || orig_add_len) {
566 memset(work_buf, 0x00, 16);
567
568 MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
569 MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4);
570 MBEDTLS_PUT_UINT32_BE((orig_len >> 32), work_buf, 8);
571 MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12);
572
573 mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16);
574
575 gcm_mult(ctx, ctx->buf, ctx->buf);
576
577 mbedtls_xor(tag, tag, ctx->buf, tag_len);
578 }
579
580 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000581}
582
Gilles Peskine449bd832023-01-11 14:50:10 +0100583int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
584 int mode,
585 size_t length,
586 const unsigned char *iv,
587 size_t iv_len,
588 const unsigned char *add,
589 size_t add_len,
590 const unsigned char *input,
591 unsigned char *output,
592 size_t tag_len,
593 unsigned char *tag)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200594{
Janos Follath24eed8d2019-11-22 13:21:35 +0000595 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200596 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200597
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) {
599 return ret;
600 }
Gilles Peskine295fc132021-04-15 18:32:23 +0200601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) {
603 return ret;
604 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 if ((ret = mbedtls_gcm_update(ctx, input, length,
607 output, length, &olen)) != 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_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) {
612 return ret;
613 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200616}
617
Gilles Peskine449bd832023-01-11 14:50:10 +0100618int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
619 size_t length,
620 const unsigned char *iv,
621 size_t iv_len,
622 const unsigned char *add,
623 size_t add_len,
624 const unsigned char *tag,
625 size_t tag_len,
626 const unsigned char *input,
627 unsigned char *output)
Paul Bakker89e80c92012-03-20 13:50:09 +0000628{
Janos Follath24eed8d2019-11-22 13:21:35 +0000629 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000630 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200631 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
634 iv, iv_len, add, add_len,
635 input, output, tag_len, check_tag)) != 0) {
636 return ret;
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100637 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000638
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200639 /* Check tag in "constant-time" */
Dave Rodgmand26a3d62023-09-11 18:25:16 +0100640 diff = mbedtls_ct_memcmp(tag, check_tag, tag_len);
Paul Bakker89e80c92012-03-20 13:50:09 +0000641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 if (diff != 0) {
643 mbedtls_platform_zeroize(output, length);
644 return MBEDTLS_ERR_GCM_AUTH_FAILED;
645 }
646
647 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000648}
649
Gilles Peskine449bd832023-01-11 14:50:10 +0100650void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200651{
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 if (ctx == NULL) {
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100653 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 }
Valerio Settibd7528a2023-12-14 09:36:03 +0100655#if defined(MBEDTLS_BLOCK_CIPHER_C)
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100656 mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
Valerio Settibd7528a2023-12-14 09:36:03 +0100657#else
658 mbedtls_cipher_free(&ctx->cipher_ctx);
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100659#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200661}
662
Jaeden Amero15263302017-09-21 12:53:48 +0100663#endif /* !MBEDTLS_GCM_ALT */
664
Valerio Setti689c0f72023-12-20 09:53:39 +0100665#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_CCM_GCM_CAN_AES)
Paul Bakker89e80c92012-03-20 13:50:09 +0000666/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200667 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000668 *
669 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
670 */
671#define MAX_TESTS 6
672
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100673static const int key_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100674{ 0, 0, 1, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000675
Yanray Wang93533b52023-05-11 16:45:59 +0800676static const unsigned char key_test_data[][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000677{
678 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
679 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
682 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
683 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
684 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200685 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000686};
687
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100688static const size_t iv_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100689{ 12, 12, 12, 12, 8, 60 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000690
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100691static const int iv_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100692{ 0, 0, 1, 1, 1, 2 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000693
Yanray Wang93533b52023-05-11 16:45:59 +0800694static const unsigned char iv_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000695{
696 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697 0x00, 0x00, 0x00, 0x00 },
698 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
699 0xde, 0xca, 0xf8, 0x88 },
700 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200701 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000702 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200703 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000704 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200705 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000706 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200707 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000708};
709
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100710static const size_t add_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100711{ 0, 0, 0, 20, 20, 20 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000712
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100713static const int add_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100714{ 0, 0, 0, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000715
Yanray Wang93533b52023-05-11 16:45:59 +0800716static const unsigned char additional_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000717{
718 { 0x00 },
719 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200720 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000721 0xab, 0xad, 0xda, 0xd2 },
722};
723
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100724static const size_t pt_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100725{ 0, 16, 64, 60, 60, 60 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000726
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100727static const int pt_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100728{ 0, 0, 1, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000729
Yanray Wang93533b52023-05-11 16:45:59 +0800730static const unsigned char pt_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000731{
732 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
733 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
734 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
735 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
736 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
737 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
738 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
739 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
740 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
741 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
742};
743
Yanray Wangd329c692023-05-11 16:40:57 +0800744static const unsigned char ct_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000745{
746 { 0x00 },
747 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
748 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
749 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200750 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000751 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200752 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000753 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200754 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000755 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
756 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
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 },
765 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200766 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000767 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200768 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000769 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200770 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000771 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
772 0xc2, 0x3f, 0x45, 0x98 },
773 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200774 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000775 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200776 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000777 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200778 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000779 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
780 0x4c, 0x34, 0xae, 0xe5 },
Yanray Wangd329c692023-05-11 16:40:57 +0800781#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker89e80c92012-03-20 13:50:09 +0000782 { 0x00 },
783 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200784 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000785 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200786 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000787 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200788 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000789 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200790 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000791 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
792 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
793 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200794 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000795 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200796 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
797 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
798 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000799 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200800 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000801 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200802 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000803 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200804 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000805 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200806 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000807 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200808 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000809 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200810 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000811 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200812 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000813 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200814 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000815 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200816 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000817 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200818 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
819 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
820 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
821 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
822 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
823 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
824 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
825 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
826 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
827 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
828 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
829 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
830 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
831 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
832 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
833 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
834 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
835 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000836 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200837 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000838 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200839 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000840 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200841 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000842 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200843 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000844 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200845 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000846 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200847 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000848 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200849 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000850 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200851 0x44, 0xae, 0x7e, 0x3f },
Yanray Wangd329c692023-05-11 16:40:57 +0800852#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker89e80c92012-03-20 13:50:09 +0000853};
854
Yanray Wangd329c692023-05-11 16:40:57 +0800855static const unsigned char tag_test_data[][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000856{
857 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
858 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
859 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
860 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
861 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200862 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000863 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
864 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
865 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
866 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
867 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
868 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
Yanray Wangd329c692023-05-11 16:40:57 +0800869#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker89e80c92012-03-20 13:50:09 +0000870 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
871 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
872 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200873 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000874 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
875 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
876 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200877 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000878 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200879 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000880 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200881 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000882 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200883 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000884 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200885 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000886 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200887 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000888 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200889 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000890 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200891 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000892 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200893 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Yanray Wangd329c692023-05-11 16:40:57 +0800894#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker89e80c92012-03-20 13:50:09 +0000895};
896
Gilles Peskine449bd832023-01-11 14:50:10 +0100897int mbedtls_gcm_self_test(int verbose)
Paul Bakker89e80c92012-03-20 13:50:09 +0000898{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000900 unsigned char buf[64];
901 unsigned char tag_buf[16];
902 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200904 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000905
Gilles Peskine0cd9ab72023-03-16 13:06:14 +0100906 if (verbose != 0) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +0100907#if defined(MBEDTLS_GCM_ALT)
908 mbedtls_printf(" GCM note: alternative implementation.\n");
909#else /* MBEDTLS_GCM_ALT */
910#if defined(MBEDTLS_AESNI_HAVE_CODE)
911 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
912 mbedtls_printf(" GCM note: using AESNI.\n");
913 } else
914#endif
Jerry Yu2f26a592023-03-31 15:06:33 +0800915
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800916#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100917 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2f26a592023-03-31 15:06:33 +0800918 mbedtls_printf(" GCM note: using AESCE.\n");
919 } else
920#endif
921
Gilles Peskine7e67bd52023-03-10 22:35:24 +0100922 mbedtls_printf(" GCM note: built-in implementation.\n");
923#endif /* MBEDTLS_GCM_ALT */
924 }
925
Yanray Wangd329c692023-05-11 16:40:57 +0800926 static const int loop_limit =
927 (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS;
928
929 for (j = 0; j < loop_limit; j++) {
Paul Bakker89e80c92012-03-20 13:50:09 +0000930 int key_len = 128 + 64 * j;
931
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 for (i = 0; i < MAX_TESTS; i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 if (verbose != 0) {
934 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
935 key_len, i, "enc");
936 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200937
Arto Kinnunen0f066182023-04-20 10:02:46 +0800938 mbedtls_gcm_init(&ctx);
939
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 ret = mbedtls_gcm_setkey(&ctx, cipher,
941 key_test_data[key_index_test_data[i]],
942 key_len);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100943 /*
944 * AES-192 is an optional feature that may be unavailable when
945 * there is an alternative underlying implementation i.e. when
946 * MBEDTLS_AES_ALT is defined.
947 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) {
949 mbedtls_printf("skipped\n");
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100950 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 } else if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100952 goto exit;
953 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000954
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT,
956 pt_len_test_data[i],
957 iv_test_data[iv_index_test_data[i]],
958 iv_len_test_data[i],
959 additional_test_data[add_index_test_data[i]],
960 add_len_test_data[i],
961 pt_test_data[pt_index_test_data[i]],
962 buf, 16, tag_buf);
Steven Cooreman2222d682021-01-11 18:45:22 +0100963#if defined(MBEDTLS_GCM_ALT)
964 /* Allow alternative implementations to only support 12-byte nonces. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
966 iv_len_test_data[i] != 12) {
967 mbedtls_printf("skipped\n");
Steven Cooreman2222d682021-01-11 18:45:22 +0100968 break;
969 }
970#endif /* defined(MBEDTLS_GCM_ALT) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100972 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000974
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 if (memcmp(buf, ct_test_data[j * 6 + i],
976 pt_len_test_data[i]) != 0 ||
977 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100978 ret = 1;
979 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000980 }
981
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 if (verbose != 0) {
985 mbedtls_printf("passed\n");
986 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000987
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100989
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 if (verbose != 0) {
991 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
992 key_len, i, "dec");
993 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200994
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 ret = mbedtls_gcm_setkey(&ctx, cipher,
996 key_test_data[key_index_test_data[i]],
997 key_len);
998 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100999 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001001
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT,
1003 pt_len_test_data[i],
1004 iv_test_data[iv_index_test_data[i]],
1005 iv_len_test_data[i],
1006 additional_test_data[add_index_test_data[i]],
1007 add_len_test_data[i],
1008 ct_test_data[j * 6 + i], buf, 16, tag_buf);
Paul Bakker89e80c92012-03-20 13:50:09 +00001009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001011 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001013
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1015 pt_len_test_data[i]) != 0 ||
1016 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001017 ret = 1;
1018 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +00001019 }
1020
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001022
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 if (verbose != 0) {
1024 mbedtls_printf("passed\n");
1025 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001026
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001028
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 if (verbose != 0) {
1030 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1031 key_len, i, "enc");
1032 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001033
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 ret = mbedtls_gcm_setkey(&ctx, cipher,
1035 key_test_data[key_index_test_data[i]],
1036 key_len);
1037 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001038 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT,
1042 iv_test_data[iv_index_test_data[i]],
1043 iv_len_test_data[i]);
1044 if (ret != 0) {
Gilles Peskine295fc132021-04-15 18:32:23 +02001045 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 }
Gilles Peskine295fc132021-04-15 18:32:23 +02001047
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 ret = mbedtls_gcm_update_ad(&ctx,
1049 additional_test_data[add_index_test_data[i]],
1050 add_len_test_data[i]);
1051 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001052 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001054
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 if (pt_len_test_data[i] > 32) {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001056 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 ret = mbedtls_gcm_update(&ctx,
1058 pt_test_data[pt_index_test_data[i]],
1059 32,
1060 buf, sizeof(buf), &olen);
1061 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001062 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001063 }
1064 if (olen != 32) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001065 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001067
Gilles Peskine449bd832023-01-11 14:50:10 +01001068 ret = mbedtls_gcm_update(&ctx,
1069 pt_test_data[pt_index_test_data[i]] + 32,
1070 rest_len,
1071 buf + 32, sizeof(buf) - 32, &olen);
1072 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001073 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 }
1075 if (olen != rest_len) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001076 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001077 }
1078 } else {
1079 ret = mbedtls_gcm_update(&ctx,
1080 pt_test_data[pt_index_test_data[i]],
1081 pt_len_test_data[i],
1082 buf, sizeof(buf), &olen);
1083 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001084 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001085 }
1086 if (olen != pt_len_test_data[i]) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001087 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001089 }
1090
Gilles Peskine449bd832023-01-11 14:50:10 +01001091 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1092 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001093 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001094 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001095
Gilles Peskine449bd832023-01-11 14:50:10 +01001096 if (memcmp(buf, ct_test_data[j * 6 + i],
1097 pt_len_test_data[i]) != 0 ||
1098 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001099 ret = 1;
1100 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001101 }
1102
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001104
Gilles Peskine449bd832023-01-11 14:50:10 +01001105 if (verbose != 0) {
1106 mbedtls_printf("passed\n");
1107 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001108
Gilles Peskine449bd832023-01-11 14:50:10 +01001109 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001110
Gilles Peskine449bd832023-01-11 14:50:10 +01001111 if (verbose != 0) {
1112 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1113 key_len, i, "dec");
1114 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001115
Gilles Peskine449bd832023-01-11 14:50:10 +01001116 ret = mbedtls_gcm_setkey(&ctx, cipher,
1117 key_test_data[key_index_test_data[i]],
1118 key_len);
1119 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001120 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001121 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001122
Gilles Peskine449bd832023-01-11 14:50:10 +01001123 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT,
1124 iv_test_data[iv_index_test_data[i]],
1125 iv_len_test_data[i]);
1126 if (ret != 0) {
Gilles Peskine295fc132021-04-15 18:32:23 +02001127 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001128 }
1129 ret = mbedtls_gcm_update_ad(&ctx,
1130 additional_test_data[add_index_test_data[i]],
1131 add_len_test_data[i]);
1132 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001133 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001135
Gilles Peskine449bd832023-01-11 14:50:10 +01001136 if (pt_len_test_data[i] > 32) {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001137 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskine449bd832023-01-11 14:50:10 +01001138 ret = mbedtls_gcm_update(&ctx,
1139 ct_test_data[j * 6 + i], 32,
1140 buf, sizeof(buf), &olen);
1141 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001142 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001143 }
1144 if (olen != 32) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001145 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001147
Gilles Peskine449bd832023-01-11 14:50:10 +01001148 ret = mbedtls_gcm_update(&ctx,
1149 ct_test_data[j * 6 + i] + 32,
1150 rest_len,
1151 buf + 32, sizeof(buf) - 32, &olen);
1152 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001153 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 }
1155 if (olen != rest_len) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001156 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001157 }
1158 } else {
1159 ret = mbedtls_gcm_update(&ctx,
1160 ct_test_data[j * 6 + i],
1161 pt_len_test_data[i],
1162 buf, sizeof(buf), &olen);
1163 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001164 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 }
1166 if (olen != pt_len_test_data[i]) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001167 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001168 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001169 }
1170
Gilles Peskine449bd832023-01-11 14:50:10 +01001171 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1172 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001173 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001174 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001175
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1177 pt_len_test_data[i]) != 0 ||
1178 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001179 ret = 1;
1180 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001181 }
1182
Gilles Peskine449bd832023-01-11 14:50:10 +01001183 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001184
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 if (verbose != 0) {
1186 mbedtls_printf("passed\n");
1187 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001188 }
1189 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001190
Gilles Peskine449bd832023-01-11 14:50:10 +01001191 if (verbose != 0) {
1192 mbedtls_printf("\n");
1193 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001194
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001195 ret = 0;
1196
1197exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001198 if (ret != 0) {
1199 if (verbose != 0) {
1200 mbedtls_printf("failed\n");
1201 }
1202 mbedtls_gcm_free(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001203 }
1204
Gilles Peskine449bd832023-01-11 14:50:10 +01001205 return ret;
Paul Bakker89e80c92012-03-20 13:50:09 +00001206}
1207
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001208#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001209
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001210#endif /* MBEDTLS_GCM_C */