blob: c677ca4d7005f076e0ac9937ae27bb1072f7cb59 [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;
Gilles Peskine295fc132021-04-15 18:32:23 +0200357
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200358 /* IV is limited to 2^64 bits, so 2^61 bytes */
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 if ((uint64_t) add_len >> 61 != 0) {
360 return MBEDTLS_ERR_GCM_BAD_INPUT;
361 }
Gilles Peskine295fc132021-04-15 18:32:23 +0200362
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200363 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000364 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200365
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 if (offset != 0) {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200367 use_len = 16 - offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 if (use_len > add_len) {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200369 use_len = add_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 }
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200371
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200373
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 if (offset + use_len == 16) {
375 gcm_mult(ctx, ctx->buf, ctx->buf);
376 }
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200377
378 ctx->add_len += use_len;
379 add_len -= use_len;
380 p += use_len;
381 }
382
383 ctx->add_len += add_len;
384
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 while (add_len >= 16) {
386 mbedtls_xor(ctx->buf, ctx->buf, p, 16);
Paul Bakker169b7f42013-06-25 14:58:00 +0200387
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 gcm_mult(ctx, ctx->buf, ctx->buf);
Paul Bakker89e80c92012-03-20 13:50:09 +0000389
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200390 add_len -= 16;
391 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000392 }
393
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 if (add_len > 0) {
395 mbedtls_xor(ctx->buf, ctx->buf, p, add_len);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200396 }
397
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200399}
400
Gilles Peskine58fc2722021-04-13 15:58:27 +0200401/* Increment the counter. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100402static void gcm_incr(unsigned char y[16])
Gilles Peskine58fc2722021-04-13 15:58:27 +0200403{
Dave Rodgman46697da2024-01-14 12:59:49 +0000404 uint32_t x = MBEDTLS_GET_UINT32_BE(y, 12);
405 x++;
406 MBEDTLS_PUT_UINT32_BE(x, y, 12);
Gilles Peskine58fc2722021-04-13 15:58:27 +0200407}
408
409/* Calculate and apply the encryption mask. Process use_len bytes of data,
410 * starting at position offset in the mask block. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100411static int gcm_mask(mbedtls_gcm_context *ctx,
412 unsigned char ectr[16],
413 size_t offset, size_t use_len,
414 const unsigned char *input,
415 unsigned char *output)
Gilles Peskine58fc2722021-04-13 15:58:27 +0200416{
Gilles Peskine58fc2722021-04-13 15:58:27 +0200417 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Valerio Settid0eebc12023-11-20 15:17:53 +0100418
Valerio Settibd7528a2023-12-14 09:36:03 +0100419#if defined(MBEDTLS_BLOCK_CIPHER_C)
420 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ectr);
421#else
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100422 size_t olen = 0;
Valerio Settid0eebc12023-11-20 15:17:53 +0100423 ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, &olen);
Valerio Settid0eebc12023-11-20 15:17:53 +0100424#endif
425 if (ret != 0) {
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100426 mbedtls_platform_zeroize(ectr, 16);
427 return ret;
428 }
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100429
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 if (ctx->mode == MBEDTLS_GCM_DECRYPT) {
431 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len);
432 }
433 mbedtls_xor(output, ectr + offset, input, use_len);
434 if (ctx->mode == MBEDTLS_GCM_ENCRYPT) {
435 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len);
436 }
Dave Rodgmand22fb732022-11-22 16:53:25 +0000437
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 return 0;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200439}
440
Gilles Peskine449bd832023-01-11 14:50:10 +0100441int mbedtls_gcm_update(mbedtls_gcm_context *ctx,
442 const unsigned char *input, size_t input_length,
443 unsigned char *output, size_t output_size,
444 size_t *output_length)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200445{
Janos Follath24eed8d2019-11-22 13:21:35 +0000446 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200447 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200448 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200449 size_t offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 unsigned char ectr[16] = { 0 };
Gilles Peskine58fc2722021-04-13 15:58:27 +0200451
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 if (output_size < input_length) {
453 return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL;
454 }
Gilles Peskinea56c4482021-04-15 17:22:35 +0200455 *output_length = input_length;
456
457 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200458 * on a potentially null pointer.
459 * Returning early also means that the last partial block of AD remains
460 * untouched for mbedtls_gcm_finish */
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 if (input_length == 0) {
462 return 0;
463 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200464
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 if (output > input && (size_t) (output - input) < input_length) {
466 return MBEDTLS_ERR_GCM_BAD_INPUT;
467 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200468
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200469 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
470 * Also check for possible overflow */
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 if (ctx->len + input_length < ctx->len ||
472 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) {
473 return MBEDTLS_ERR_GCM_BAD_INPUT;
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200474 }
475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 if (ctx->len == 0 && ctx->add_len % 16 != 0) {
477 gcm_mult(ctx, ctx->buf, ctx->buf);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200478 }
479
Gilles Peskine58fc2722021-04-13 15:58:27 +0200480 offset = ctx->len % 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 if (offset != 0) {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200482 size_t use_len = 16 - offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 if (use_len > input_length) {
Gilles Peskinea56c4482021-04-15 17:22:35 +0200484 use_len = input_length;
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000486
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) {
488 return ret;
489 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000490
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 if (offset + use_len == 16) {
492 gcm_mult(ctx, ctx->buf, ctx->buf);
493 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200494
Gilles Peskine58fc2722021-04-13 15:58:27 +0200495 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200496 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000497 p += use_len;
498 out_p += use_len;
499 }
500
Gilles Peskinea56c4482021-04-15 17:22:35 +0200501 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 while (input_length >= 16) {
504 gcm_incr(ctx->y);
505 if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) {
506 return ret;
507 }
Gilles Peskine58fc2722021-04-13 15:58:27 +0200508
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 gcm_mult(ctx, ctx->buf, ctx->buf);
Gilles Peskine58fc2722021-04-13 15:58:27 +0200510
Gilles Peskinea56c4482021-04-15 17:22:35 +0200511 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200512 p += 16;
513 out_p += 16;
514 }
515
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 if (input_length > 0) {
517 gcm_incr(ctx->y);
518 if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) {
519 return ret;
520 }
Gilles Peskine58fc2722021-04-13 15:58:27 +0200521 }
522
Gilles Peskine449bd832023-01-11 14:50:10 +0100523 mbedtls_platform_zeroize(ectr, sizeof(ectr));
524 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200525}
526
Gilles Peskine449bd832023-01-11 14:50:10 +0100527int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
528 unsigned char *output, size_t output_size,
529 size_t *output_length,
530 unsigned char *tag, size_t tag_len)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200531{
532 unsigned char work_buf[16];
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100533 uint64_t orig_len;
534 uint64_t orig_add_len;
535
Gilles Peskine9461e452021-04-15 16:48:32 +0200536 /* We never pass any output in finish(). The output parameter exists only
537 * for the sake of alternative implementations. */
538 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200539 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200540 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200541
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100542 orig_len = ctx->len * 8;
543 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 if (ctx->len == 0 && ctx->add_len % 16 != 0) {
546 gcm_mult(ctx, ctx->buf, ctx->buf);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200547 }
548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 if (tag_len > 16 || tag_len < 4) {
550 return MBEDTLS_ERR_GCM_BAD_INPUT;
Paul Bakker89e80c92012-03-20 13:50:09 +0000551 }
552
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 if (ctx->len % 16 != 0) {
554 gcm_mult(ctx, ctx->buf, ctx->buf);
555 }
556
557 memcpy(tag, ctx->base_ectr, tag_len);
558
559 if (orig_len || orig_add_len) {
560 memset(work_buf, 0x00, 16);
561
562 MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
563 MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4);
564 MBEDTLS_PUT_UINT32_BE((orig_len >> 32), work_buf, 8);
565 MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12);
566
567 mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16);
568
569 gcm_mult(ctx, ctx->buf, ctx->buf);
570
571 mbedtls_xor(tag, tag, ctx->buf, tag_len);
572 }
573
574 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000575}
576
Gilles Peskine449bd832023-01-11 14:50:10 +0100577int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
578 int mode,
579 size_t length,
580 const unsigned char *iv,
581 size_t iv_len,
582 const unsigned char *add,
583 size_t add_len,
584 const unsigned char *input,
585 unsigned char *output,
586 size_t tag_len,
587 unsigned char *tag)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200588{
Janos Follath24eed8d2019-11-22 13:21:35 +0000589 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200590 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200591
Gilles Peskine449bd832023-01-11 14:50:10 +0100592 if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) {
593 return ret;
594 }
Gilles Peskine295fc132021-04-15 18:32:23 +0200595
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) {
597 return ret;
598 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200599
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 if ((ret = mbedtls_gcm_update(ctx, input, length,
601 output, length, &olen)) != 0) {
602 return ret;
603 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200604
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) {
606 return ret;
607 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200608
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200610}
611
Gilles Peskine449bd832023-01-11 14:50:10 +0100612int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
613 size_t length,
614 const unsigned char *iv,
615 size_t iv_len,
616 const unsigned char *add,
617 size_t add_len,
618 const unsigned char *tag,
619 size_t tag_len,
620 const unsigned char *input,
621 unsigned char *output)
Paul Bakker89e80c92012-03-20 13:50:09 +0000622{
Janos Follath24eed8d2019-11-22 13:21:35 +0000623 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000624 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200625 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
628 iv, iv_len, add, add_len,
629 input, output, tag_len, check_tag)) != 0) {
630 return ret;
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100631 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000632
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200633 /* Check tag in "constant-time" */
Dave Rodgmand26a3d62023-09-11 18:25:16 +0100634 diff = mbedtls_ct_memcmp(tag, check_tag, tag_len);
Paul Bakker89e80c92012-03-20 13:50:09 +0000635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 if (diff != 0) {
637 mbedtls_platform_zeroize(output, length);
638 return MBEDTLS_ERR_GCM_AUTH_FAILED;
639 }
640
641 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000642}
643
Gilles Peskine449bd832023-01-11 14:50:10 +0100644void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200645{
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 if (ctx == NULL) {
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100647 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 }
Valerio Settibd7528a2023-12-14 09:36:03 +0100649#if defined(MBEDTLS_BLOCK_CIPHER_C)
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100650 mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
Valerio Settibd7528a2023-12-14 09:36:03 +0100651#else
652 mbedtls_cipher_free(&ctx->cipher_ctx);
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100653#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200655}
656
Jaeden Amero15263302017-09-21 12:53:48 +0100657#endif /* !MBEDTLS_GCM_ALT */
658
Valerio Setti689c0f72023-12-20 09:53:39 +0100659#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_CCM_GCM_CAN_AES)
Paul Bakker89e80c92012-03-20 13:50:09 +0000660/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200661 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000662 *
663 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
664 */
665#define MAX_TESTS 6
666
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100667static const int key_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100668{ 0, 0, 1, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000669
Yanray Wang93533b52023-05-11 16:45:59 +0800670static const unsigned char key_test_data[][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000671{
672 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
676 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
677 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
678 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200679 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000680};
681
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100682static const size_t iv_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100683{ 12, 12, 12, 12, 8, 60 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000684
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100685static const int iv_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100686{ 0, 0, 1, 1, 1, 2 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000687
Yanray Wang93533b52023-05-11 16:45:59 +0800688static const unsigned char iv_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000689{
690 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691 0x00, 0x00, 0x00, 0x00 },
692 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
693 0xde, 0xca, 0xf8, 0x88 },
694 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200695 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000696 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200697 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000698 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200699 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000700 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200701 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000702};
703
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100704static const size_t add_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100705{ 0, 0, 0, 20, 20, 20 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000706
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100707static const int add_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100708{ 0, 0, 0, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000709
Yanray Wang93533b52023-05-11 16:45:59 +0800710static const unsigned char additional_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000711{
712 { 0x00 },
713 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200714 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000715 0xab, 0xad, 0xda, 0xd2 },
716};
717
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100718static const size_t pt_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100719{ 0, 16, 64, 60, 60, 60 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000720
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100721static const int pt_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100722{ 0, 0, 1, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000723
Yanray Wang93533b52023-05-11 16:45:59 +0800724static const unsigned char pt_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000725{
726 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
728 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
729 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
730 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
731 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
732 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
733 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
734 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
735 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
736};
737
Yanray Wangd329c692023-05-11 16:40:57 +0800738static const unsigned char ct_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000739{
740 { 0x00 },
741 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
742 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
743 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200744 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000745 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200746 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000747 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200748 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
750 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
751 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200752 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000753 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200754 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000755 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200756 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000757 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
758 0x3d, 0x58, 0xe0, 0x91 },
759 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200760 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200762 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000763 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200764 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000765 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
766 0xc2, 0x3f, 0x45, 0x98 },
767 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200768 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000769 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200770 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000771 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200772 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000773 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
774 0x4c, 0x34, 0xae, 0xe5 },
Yanray Wangd329c692023-05-11 16:40:57 +0800775#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 { 0x00 },
777 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200778 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000779 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200780 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000781 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200782 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000783 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200784 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000785 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
786 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
787 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200788 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000789 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200790 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
791 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
792 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000793 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200794 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000795 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200796 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000797 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200798 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000799 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200800 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000801 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200802 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000803 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200804 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000805 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200806 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000807 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200808 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000809 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200810 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000811 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200812 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
813 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
814 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
815 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
816 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
817 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
818 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
819 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
820 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
821 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
822 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
823 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
824 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
825 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
826 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
827 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
828 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
829 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000830 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200831 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000832 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200833 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000834 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200835 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000836 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200837 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000838 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200839 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000840 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200841 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000842 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200843 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000844 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200845 0x44, 0xae, 0x7e, 0x3f },
Yanray Wangd329c692023-05-11 16:40:57 +0800846#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker89e80c92012-03-20 13:50:09 +0000847};
848
Yanray Wangd329c692023-05-11 16:40:57 +0800849static const unsigned char tag_test_data[][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000850{
851 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
852 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
853 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
854 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
855 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200856 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000857 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
858 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
859 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
860 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
861 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
862 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
Yanray Wangd329c692023-05-11 16:40:57 +0800863#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker89e80c92012-03-20 13:50:09 +0000864 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
865 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
866 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200867 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000868 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
869 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
870 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200871 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000872 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200873 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000874 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200875 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000876 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200877 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000878 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200879 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000880 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200881 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000882 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200883 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000884 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200885 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000886 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200887 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Yanray Wangd329c692023-05-11 16:40:57 +0800888#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker89e80c92012-03-20 13:50:09 +0000889};
890
Gilles Peskine449bd832023-01-11 14:50:10 +0100891int mbedtls_gcm_self_test(int verbose)
Paul Bakker89e80c92012-03-20 13:50:09 +0000892{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000894 unsigned char buf[64];
895 unsigned char tag_buf[16];
896 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200897 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200898 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000899
Gilles Peskine0cd9ab72023-03-16 13:06:14 +0100900 if (verbose != 0) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +0100901#if defined(MBEDTLS_GCM_ALT)
902 mbedtls_printf(" GCM note: alternative implementation.\n");
903#else /* MBEDTLS_GCM_ALT */
904#if defined(MBEDTLS_AESNI_HAVE_CODE)
905 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
906 mbedtls_printf(" GCM note: using AESNI.\n");
907 } else
908#endif
Jerry Yu2f26a592023-03-31 15:06:33 +0800909
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800910#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100911 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2f26a592023-03-31 15:06:33 +0800912 mbedtls_printf(" GCM note: using AESCE.\n");
913 } else
914#endif
915
Gilles Peskine7e67bd52023-03-10 22:35:24 +0100916 mbedtls_printf(" GCM note: built-in implementation.\n");
917#endif /* MBEDTLS_GCM_ALT */
918 }
919
Yanray Wangd329c692023-05-11 16:40:57 +0800920 static const int loop_limit =
921 (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS;
922
923 for (j = 0; j < loop_limit; j++) {
Paul Bakker89e80c92012-03-20 13:50:09 +0000924 int key_len = 128 + 64 * j;
925
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 for (i = 0; i < MAX_TESTS; i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 if (verbose != 0) {
928 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
929 key_len, i, "enc");
930 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200931
Arto Kinnunen0f066182023-04-20 10:02:46 +0800932 mbedtls_gcm_init(&ctx);
933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 ret = mbedtls_gcm_setkey(&ctx, cipher,
935 key_test_data[key_index_test_data[i]],
936 key_len);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100937 /*
938 * AES-192 is an optional feature that may be unavailable when
939 * there is an alternative underlying implementation i.e. when
940 * MBEDTLS_AES_ALT is defined.
941 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) {
943 mbedtls_printf("skipped\n");
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100944 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 } else if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100946 goto exit;
947 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000948
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT,
950 pt_len_test_data[i],
951 iv_test_data[iv_index_test_data[i]],
952 iv_len_test_data[i],
953 additional_test_data[add_index_test_data[i]],
954 add_len_test_data[i],
955 pt_test_data[pt_index_test_data[i]],
956 buf, 16, tag_buf);
Steven Cooreman2222d682021-01-11 18:45:22 +0100957#if defined(MBEDTLS_GCM_ALT)
958 /* Allow alternative implementations to only support 12-byte nonces. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
960 iv_len_test_data[i] != 12) {
961 mbedtls_printf("skipped\n");
Steven Cooreman2222d682021-01-11 18:45:22 +0100962 break;
963 }
964#endif /* defined(MBEDTLS_GCM_ALT) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100966 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000968
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 if (memcmp(buf, ct_test_data[j * 6 + i],
970 pt_len_test_data[i]) != 0 ||
971 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100972 ret = 1;
973 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000974 }
975
Gilles Peskine449bd832023-01-11 14:50:10 +0100976 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200977
Gilles Peskine449bd832023-01-11 14:50:10 +0100978 if (verbose != 0) {
979 mbedtls_printf("passed\n");
980 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000981
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 if (verbose != 0) {
985 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
986 key_len, i, "dec");
987 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200988
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 ret = mbedtls_gcm_setkey(&ctx, cipher,
990 key_test_data[key_index_test_data[i]],
991 key_len);
992 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100993 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000995
Gilles Peskine449bd832023-01-11 14:50:10 +0100996 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT,
997 pt_len_test_data[i],
998 iv_test_data[iv_index_test_data[i]],
999 iv_len_test_data[i],
1000 additional_test_data[add_index_test_data[i]],
1001 add_len_test_data[i],
1002 ct_test_data[j * 6 + i], buf, 16, tag_buf);
Paul Bakker89e80c92012-03-20 13:50:09 +00001003
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001005 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001007
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1009 pt_len_test_data[i]) != 0 ||
1010 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001011 ret = 1;
1012 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +00001013 }
1014
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 if (verbose != 0) {
1018 mbedtls_printf("passed\n");
1019 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001020
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001022
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 if (verbose != 0) {
1024 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1025 key_len, i, "enc");
1026 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001027
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 ret = mbedtls_gcm_setkey(&ctx, cipher,
1029 key_test_data[key_index_test_data[i]],
1030 key_len);
1031 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001032 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001034
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT,
1036 iv_test_data[iv_index_test_data[i]],
1037 iv_len_test_data[i]);
1038 if (ret != 0) {
Gilles Peskine295fc132021-04-15 18:32:23 +02001039 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 }
Gilles Peskine295fc132021-04-15 18:32:23 +02001041
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 ret = mbedtls_gcm_update_ad(&ctx,
1043 additional_test_data[add_index_test_data[i]],
1044 add_len_test_data[i]);
1045 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001046 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001048
Gilles Peskine449bd832023-01-11 14:50:10 +01001049 if (pt_len_test_data[i] > 32) {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001050 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskine449bd832023-01-11 14:50:10 +01001051 ret = mbedtls_gcm_update(&ctx,
1052 pt_test_data[pt_index_test_data[i]],
1053 32,
1054 buf, sizeof(buf), &olen);
1055 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001056 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 }
1058 if (olen != 32) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001059 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001061
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 ret = mbedtls_gcm_update(&ctx,
1063 pt_test_data[pt_index_test_data[i]] + 32,
1064 rest_len,
1065 buf + 32, sizeof(buf) - 32, &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 != rest_len) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001070 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001071 }
1072 } else {
1073 ret = mbedtls_gcm_update(&ctx,
1074 pt_test_data[pt_index_test_data[i]],
1075 pt_len_test_data[i],
1076 buf, sizeof(buf), &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 != pt_len_test_data[i]) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001081 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001082 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001083 }
1084
Gilles Peskine449bd832023-01-11 14:50:10 +01001085 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1086 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001087 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001089
Gilles Peskine449bd832023-01-11 14:50:10 +01001090 if (memcmp(buf, ct_test_data[j * 6 + i],
1091 pt_len_test_data[i]) != 0 ||
1092 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001093 ret = 1;
1094 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001095 }
1096
Gilles Peskine449bd832023-01-11 14:50:10 +01001097 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001098
Gilles Peskine449bd832023-01-11 14:50:10 +01001099 if (verbose != 0) {
1100 mbedtls_printf("passed\n");
1101 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001102
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001104
Gilles Peskine449bd832023-01-11 14:50:10 +01001105 if (verbose != 0) {
1106 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1107 key_len, i, "dec");
1108 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001109
Gilles Peskine449bd832023-01-11 14:50:10 +01001110 ret = mbedtls_gcm_setkey(&ctx, cipher,
1111 key_test_data[key_index_test_data[i]],
1112 key_len);
1113 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001114 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001115 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001116
Gilles Peskine449bd832023-01-11 14:50:10 +01001117 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT,
1118 iv_test_data[iv_index_test_data[i]],
1119 iv_len_test_data[i]);
1120 if (ret != 0) {
Gilles Peskine295fc132021-04-15 18:32:23 +02001121 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001122 }
1123 ret = mbedtls_gcm_update_ad(&ctx,
1124 additional_test_data[add_index_test_data[i]],
1125 add_len_test_data[i]);
1126 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001127 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001128 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001129
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 if (pt_len_test_data[i] > 32) {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001131 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 ret = mbedtls_gcm_update(&ctx,
1133 ct_test_data[j * 6 + i], 32,
1134 buf, sizeof(buf), &olen);
1135 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001136 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001137 }
1138 if (olen != 32) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001139 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001141
Gilles Peskine449bd832023-01-11 14:50:10 +01001142 ret = mbedtls_gcm_update(&ctx,
1143 ct_test_data[j * 6 + i] + 32,
1144 rest_len,
1145 buf + 32, sizeof(buf) - 32, &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 != rest_len) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001150 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 }
1152 } else {
1153 ret = mbedtls_gcm_update(&ctx,
1154 ct_test_data[j * 6 + i],
1155 pt_len_test_data[i],
1156 buf, sizeof(buf), &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 != pt_len_test_data[i]) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001161 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001162 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001163 }
1164
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1166 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001167 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001168 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001169
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1171 pt_len_test_data[i]) != 0 ||
1172 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001173 ret = 1;
1174 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001175 }
1176
Gilles Peskine449bd832023-01-11 14:50:10 +01001177 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001178
Gilles Peskine449bd832023-01-11 14:50:10 +01001179 if (verbose != 0) {
1180 mbedtls_printf("passed\n");
1181 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001182 }
1183 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001184
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 if (verbose != 0) {
1186 mbedtls_printf("\n");
1187 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001188
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001189 ret = 0;
1190
1191exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001192 if (ret != 0) {
1193 if (verbose != 0) {
1194 mbedtls_printf("failed\n");
1195 }
1196 mbedtls_gcm_free(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001197 }
1198
Gilles Peskine449bd832023-01-11 14:50:10 +01001199 return ret;
Paul Bakker89e80c92012-03-20 13:50:09 +00001200}
1201
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001202#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001203
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001204#endif /* MBEDTLS_GCM_C */