blob: 8181ec88aac3d84c4d4084e28d2b8a99b3bbe1ec [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 Setti9b7a8b22023-11-16 08:24:51 +010028#if !defined(MBEDTLS_CIPHER_C)
29#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
69#if defined(MBEDTLS_CIPHER_C)
70 size_t olen = 0;
Valerio Settid0eebc12023-11-20 15:17:53 +010071 ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen);
Valerio Setti9b7a8b22023-11-16 08:24:51 +010072#else
Valerio Settid0eebc12023-11-20 15:17:53 +010073 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, h, h);
74#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 Setti9b7a8b22023-11-16 08:24:51 +0100142#if defined(MBEDTLS_CIPHER_C)
143 const mbedtls_cipher_info_t *cipher_info;
144
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
146 MBEDTLS_MODE_ECB);
147 if (cipher_info == NULL) {
148 return MBEDTLS_ERR_GCM_BAD_INPUT;
149 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000150
Dave Rodgman85a88132023-06-24 11:41:50 +0100151 if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 return MBEDTLS_ERR_GCM_BAD_INPUT;
153 }
154
155 mbedtls_cipher_free(&ctx->cipher_ctx);
156
157 if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) {
158 return ret;
159 }
160
161 if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits,
162 MBEDTLS_ENCRYPT)) != 0) {
163 return ret;
164 }
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100165#else
166 mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
167
168 if ((ret = mbedtls_block_cipher_setup(&ctx->block_cipher_ctx, cipher)) != 0) {
169 return ret;
170 }
171
172 if ((ret = mbedtls_block_cipher_setkey(&ctx->block_cipher_ctx, key, keybits)) != 0) {
173 return ret;
174 }
175#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 Setti9b7a8b22023-11-16 08:24:51 +0100280#if defined(MBEDTLS_CIPHER_C)
281 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
323#if defined(MBEDTLS_CIPHER_C)
Valerio Settid0eebc12023-11-20 15:17:53 +0100324 ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, &olen);
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100325#else
Valerio Settid0eebc12023-11-20 15:17:53 +0100326 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->base_ectr);
327#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{
404 size_t i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 for (i = 16; i > 12; i--) {
406 if (++y[i - 1] != 0) {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200407 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 }
409 }
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 Setti9b7a8b22023-11-16 08:24:51 +0100422#if defined(MBEDTLS_CIPHER_C)
423 size_t olen = 0;
Valerio Settid0eebc12023-11-20 15:17:53 +0100424 ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, &olen);
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100425#else
Valerio Settid0eebc12023-11-20 15:17:53 +0100426 ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ectr);
427#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
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100545 orig_len = ctx->len * 8;
546 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200547
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 if (ctx->len == 0 && ctx->add_len % 16 != 0) {
549 gcm_mult(ctx, ctx->buf, ctx->buf);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200550 }
551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 if (tag_len > 16 || tag_len < 4) {
553 return MBEDTLS_ERR_GCM_BAD_INPUT;
Paul Bakker89e80c92012-03-20 13:50:09 +0000554 }
555
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 if (ctx->len % 16 != 0) {
557 gcm_mult(ctx, ctx->buf, ctx->buf);
558 }
559
560 memcpy(tag, ctx->base_ectr, tag_len);
561
562 if (orig_len || orig_add_len) {
563 memset(work_buf, 0x00, 16);
564
565 MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
566 MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4);
567 MBEDTLS_PUT_UINT32_BE((orig_len >> 32), work_buf, 8);
568 MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12);
569
570 mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16);
571
572 gcm_mult(ctx, ctx->buf, ctx->buf);
573
574 mbedtls_xor(tag, tag, ctx->buf, tag_len);
575 }
576
577 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000578}
579
Gilles Peskine449bd832023-01-11 14:50:10 +0100580int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
581 int mode,
582 size_t length,
583 const unsigned char *iv,
584 size_t iv_len,
585 const unsigned char *add,
586 size_t add_len,
587 const unsigned char *input,
588 unsigned char *output,
589 size_t tag_len,
590 unsigned char *tag)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200591{
Janos Follath24eed8d2019-11-22 13:21:35 +0000592 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200593 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200594
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) {
596 return ret;
597 }
Gilles Peskine295fc132021-04-15 18:32:23 +0200598
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) {
600 return ret;
601 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200602
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 if ((ret = mbedtls_gcm_update(ctx, input, length,
604 output, length, &olen)) != 0) {
605 return ret;
606 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) {
609 return ret;
610 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200611
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200613}
614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
616 size_t length,
617 const unsigned char *iv,
618 size_t iv_len,
619 const unsigned char *add,
620 size_t add_len,
621 const unsigned char *tag,
622 size_t tag_len,
623 const unsigned char *input,
624 unsigned char *output)
Paul Bakker89e80c92012-03-20 13:50:09 +0000625{
Janos Follath24eed8d2019-11-22 13:21:35 +0000626 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000627 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200628 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
631 iv, iv_len, add, add_len,
632 input, output, tag_len, check_tag)) != 0) {
633 return ret;
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100634 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000635
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200636 /* Check tag in "constant-time" */
Dave Rodgmand26a3d62023-09-11 18:25:16 +0100637 diff = mbedtls_ct_memcmp(tag, check_tag, tag_len);
Paul Bakker89e80c92012-03-20 13:50:09 +0000638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 if (diff != 0) {
640 mbedtls_platform_zeroize(output, length);
641 return MBEDTLS_ERR_GCM_AUTH_FAILED;
642 }
643
644 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000645}
646
Gilles Peskine449bd832023-01-11 14:50:10 +0100647void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200648{
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 if (ctx == NULL) {
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100650 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 }
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100652#if defined(MBEDTLS_CIPHER_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 mbedtls_cipher_free(&ctx->cipher_ctx);
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100654#else
655 mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
656#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200658}
659
Jaeden Amero15263302017-09-21 12:53:48 +0100660#endif /* !MBEDTLS_GCM_ALT */
661
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200662#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000663/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200664 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000665 *
666 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
667 */
668#define MAX_TESTS 6
669
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100670static const int key_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100671{ 0, 0, 1, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000672
Yanray Wang93533b52023-05-11 16:45:59 +0800673static const unsigned char key_test_data[][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000674{
675 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
676 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
679 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
680 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
681 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200682 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000683};
684
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100685static const size_t iv_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100686{ 12, 12, 12, 12, 8, 60 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000687
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100688static const int iv_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100689{ 0, 0, 1, 1, 1, 2 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000690
Yanray Wang93533b52023-05-11 16:45:59 +0800691static const unsigned char iv_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000692{
693 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694 0x00, 0x00, 0x00, 0x00 },
695 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
696 0xde, 0xca, 0xf8, 0x88 },
697 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200698 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000699 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200700 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000701 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200702 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000703 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200704 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000705};
706
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100707static const size_t add_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100708{ 0, 0, 0, 20, 20, 20 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000709
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100710static const int add_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100711{ 0, 0, 0, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000712
Yanray Wang93533b52023-05-11 16:45:59 +0800713static const unsigned char additional_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000714{
715 { 0x00 },
716 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200717 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000718 0xab, 0xad, 0xda, 0xd2 },
719};
720
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100721static const size_t pt_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100722{ 0, 16, 64, 60, 60, 60 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000723
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100724static const int pt_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100725{ 0, 0, 1, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000726
Yanray Wang93533b52023-05-11 16:45:59 +0800727static const unsigned char pt_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000728{
729 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
731 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
732 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
733 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
734 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
735 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
736 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
737 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
738 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
739};
740
Yanray Wangd329c692023-05-11 16:40:57 +0800741static const unsigned char ct_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000742{
743 { 0x00 },
744 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
745 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
746 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200747 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000748 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200749 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000750 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200751 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000752 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
753 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
754 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200755 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000756 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200757 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000758 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200759 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000760 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
761 0x3d, 0x58, 0xe0, 0x91 },
762 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200763 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000764 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200765 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000766 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200767 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000768 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
769 0xc2, 0x3f, 0x45, 0x98 },
770 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200771 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000772 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200773 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000774 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200775 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
777 0x4c, 0x34, 0xae, 0xe5 },
Yanray Wangd329c692023-05-11 16:40:57 +0800778#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker89e80c92012-03-20 13:50:09 +0000779 { 0x00 },
780 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200781 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000782 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200783 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000784 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200785 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000786 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200787 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000788 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
789 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
790 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200791 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000792 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200793 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
794 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
795 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000796 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200797 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000798 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200799 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000800 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200801 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000802 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200803 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000804 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200805 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000806 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200807 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000808 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200809 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000810 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200811 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000812 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200813 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000814 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200815 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
816 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
817 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
818 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
819 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
820 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
821 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
822 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
823 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
824 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
825 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
826 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
827 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
828 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
829 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
830 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
831 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
832 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000833 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200834 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000835 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200836 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000837 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200838 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000839 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200840 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000841 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200842 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000843 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200844 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000845 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200846 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000847 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200848 0x44, 0xae, 0x7e, 0x3f },
Yanray Wangd329c692023-05-11 16:40:57 +0800849#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker89e80c92012-03-20 13:50:09 +0000850};
851
Yanray Wangd329c692023-05-11 16:40:57 +0800852static const unsigned char tag_test_data[][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000853{
854 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
855 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
856 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
857 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
858 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200859 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000860 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
861 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
862 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
863 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
864 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
865 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
Yanray Wangd329c692023-05-11 16:40:57 +0800866#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker89e80c92012-03-20 13:50:09 +0000867 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
868 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
869 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200870 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000871 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
872 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
873 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200874 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000875 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200876 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000877 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200878 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000879 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200880 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000881 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200882 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000883 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200884 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000885 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200886 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000887 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200888 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000889 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200890 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Yanray Wangd329c692023-05-11 16:40:57 +0800891#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker89e80c92012-03-20 13:50:09 +0000892};
893
Gilles Peskine449bd832023-01-11 14:50:10 +0100894int mbedtls_gcm_self_test(int verbose)
Paul Bakker89e80c92012-03-20 13:50:09 +0000895{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200896 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000897 unsigned char buf[64];
898 unsigned char tag_buf[16];
899 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200901 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000902
Gilles Peskine0cd9ab72023-03-16 13:06:14 +0100903 if (verbose != 0) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +0100904#if defined(MBEDTLS_GCM_ALT)
905 mbedtls_printf(" GCM note: alternative implementation.\n");
906#else /* MBEDTLS_GCM_ALT */
907#if defined(MBEDTLS_AESNI_HAVE_CODE)
908 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
909 mbedtls_printf(" GCM note: using AESNI.\n");
910 } else
911#endif
Jerry Yu2f26a592023-03-31 15:06:33 +0800912
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800913#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100914 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2f26a592023-03-31 15:06:33 +0800915 mbedtls_printf(" GCM note: using AESCE.\n");
916 } else
917#endif
918
Gilles Peskine7e67bd52023-03-10 22:35:24 +0100919 mbedtls_printf(" GCM note: built-in implementation.\n");
920#endif /* MBEDTLS_GCM_ALT */
921 }
922
Yanray Wangd329c692023-05-11 16:40:57 +0800923 static const int loop_limit =
924 (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS;
925
926 for (j = 0; j < loop_limit; j++) {
Paul Bakker89e80c92012-03-20 13:50:09 +0000927 int key_len = 128 + 64 * j;
928
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 for (i = 0; i < MAX_TESTS; i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 if (verbose != 0) {
931 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
932 key_len, i, "enc");
933 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200934
Arto Kinnunen0f066182023-04-20 10:02:46 +0800935 mbedtls_gcm_init(&ctx);
936
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 ret = mbedtls_gcm_setkey(&ctx, cipher,
938 key_test_data[key_index_test_data[i]],
939 key_len);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100940 /*
941 * AES-192 is an optional feature that may be unavailable when
942 * there is an alternative underlying implementation i.e. when
943 * MBEDTLS_AES_ALT is defined.
944 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) {
946 mbedtls_printf("skipped\n");
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100947 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 } else if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100949 goto exit;
950 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000951
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT,
953 pt_len_test_data[i],
954 iv_test_data[iv_index_test_data[i]],
955 iv_len_test_data[i],
956 additional_test_data[add_index_test_data[i]],
957 add_len_test_data[i],
958 pt_test_data[pt_index_test_data[i]],
959 buf, 16, tag_buf);
Steven Cooreman2222d682021-01-11 18:45:22 +0100960#if defined(MBEDTLS_GCM_ALT)
961 /* Allow alternative implementations to only support 12-byte nonces. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
963 iv_len_test_data[i] != 12) {
964 mbedtls_printf("skipped\n");
Steven Cooreman2222d682021-01-11 18:45:22 +0100965 break;
966 }
967#endif /* defined(MBEDTLS_GCM_ALT) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100969 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000971
Gilles Peskine449bd832023-01-11 14:50:10 +0100972 if (memcmp(buf, ct_test_data[j * 6 + i],
973 pt_len_test_data[i]) != 0 ||
974 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100975 ret = 1;
976 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000977 }
978
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200980
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 if (verbose != 0) {
982 mbedtls_printf("passed\n");
983 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000984
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100986
Gilles Peskine449bd832023-01-11 14:50:10 +0100987 if (verbose != 0) {
988 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
989 key_len, i, "dec");
990 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200991
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 ret = mbedtls_gcm_setkey(&ctx, cipher,
993 key_test_data[key_index_test_data[i]],
994 key_len);
995 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100996 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000998
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT,
1000 pt_len_test_data[i],
1001 iv_test_data[iv_index_test_data[i]],
1002 iv_len_test_data[i],
1003 additional_test_data[add_index_test_data[i]],
1004 add_len_test_data[i],
1005 ct_test_data[j * 6 + i], buf, 16, tag_buf);
Paul Bakker89e80c92012-03-20 13:50:09 +00001006
Gilles Peskine449bd832023-01-11 14:50:10 +01001007 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001008 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001010
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1012 pt_len_test_data[i]) != 0 ||
1013 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001014 ret = 1;
1015 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +00001016 }
1017
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 if (verbose != 0) {
1021 mbedtls_printf("passed\n");
1022 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001023
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001025
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 if (verbose != 0) {
1027 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1028 key_len, i, "enc");
1029 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001030
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 ret = mbedtls_gcm_setkey(&ctx, cipher,
1032 key_test_data[key_index_test_data[i]],
1033 key_len);
1034 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001035 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001037
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT,
1039 iv_test_data[iv_index_test_data[i]],
1040 iv_len_test_data[i]);
1041 if (ret != 0) {
Gilles Peskine295fc132021-04-15 18:32:23 +02001042 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 }
Gilles Peskine295fc132021-04-15 18:32:23 +02001044
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 ret = mbedtls_gcm_update_ad(&ctx,
1046 additional_test_data[add_index_test_data[i]],
1047 add_len_test_data[i]);
1048 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001049 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001051
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 if (pt_len_test_data[i] > 32) {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001053 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskine449bd832023-01-11 14:50:10 +01001054 ret = mbedtls_gcm_update(&ctx,
1055 pt_test_data[pt_index_test_data[i]],
1056 32,
1057 buf, sizeof(buf), &olen);
1058 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001059 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 }
1061 if (olen != 32) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001062 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001063 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001064
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 ret = mbedtls_gcm_update(&ctx,
1066 pt_test_data[pt_index_test_data[i]] + 32,
1067 rest_len,
1068 buf + 32, sizeof(buf) - 32, &olen);
1069 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001070 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001071 }
1072 if (olen != rest_len) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001073 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 }
1075 } else {
1076 ret = mbedtls_gcm_update(&ctx,
1077 pt_test_data[pt_index_test_data[i]],
1078 pt_len_test_data[i],
1079 buf, sizeof(buf), &olen);
1080 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001081 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001082 }
1083 if (olen != pt_len_test_data[i]) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001084 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001085 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001086 }
1087
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1089 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001090 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001091 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001092
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 if (memcmp(buf, ct_test_data[j * 6 + i],
1094 pt_len_test_data[i]) != 0 ||
1095 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001096 ret = 1;
1097 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001098 }
1099
Gilles Peskine449bd832023-01-11 14:50:10 +01001100 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001101
Gilles Peskine449bd832023-01-11 14:50:10 +01001102 if (verbose != 0) {
1103 mbedtls_printf("passed\n");
1104 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001105
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001107
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 if (verbose != 0) {
1109 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1110 key_len, i, "dec");
1111 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001112
Gilles Peskine449bd832023-01-11 14:50:10 +01001113 ret = mbedtls_gcm_setkey(&ctx, cipher,
1114 key_test_data[key_index_test_data[i]],
1115 key_len);
1116 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001117 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001118 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001119
Gilles Peskine449bd832023-01-11 14:50:10 +01001120 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT,
1121 iv_test_data[iv_index_test_data[i]],
1122 iv_len_test_data[i]);
1123 if (ret != 0) {
Gilles Peskine295fc132021-04-15 18:32:23 +02001124 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001125 }
1126 ret = mbedtls_gcm_update_ad(&ctx,
1127 additional_test_data[add_index_test_data[i]],
1128 add_len_test_data[i]);
1129 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001130 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001132
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 if (pt_len_test_data[i] > 32) {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001134 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskine449bd832023-01-11 14:50:10 +01001135 ret = mbedtls_gcm_update(&ctx,
1136 ct_test_data[j * 6 + i], 32,
1137 buf, sizeof(buf), &olen);
1138 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001139 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 }
1141 if (olen != 32) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001142 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001143 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001144
Gilles Peskine449bd832023-01-11 14:50:10 +01001145 ret = mbedtls_gcm_update(&ctx,
1146 ct_test_data[j * 6 + i] + 32,
1147 rest_len,
1148 buf + 32, sizeof(buf) - 32, &olen);
1149 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001150 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 }
1152 if (olen != rest_len) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001153 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 }
1155 } else {
1156 ret = mbedtls_gcm_update(&ctx,
1157 ct_test_data[j * 6 + i],
1158 pt_len_test_data[i],
1159 buf, sizeof(buf), &olen);
1160 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001161 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001162 }
1163 if (olen != pt_len_test_data[i]) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001164 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001166 }
1167
Gilles Peskine449bd832023-01-11 14:50:10 +01001168 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1169 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001170 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001171 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001172
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1174 pt_len_test_data[i]) != 0 ||
1175 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001176 ret = 1;
1177 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001178 }
1179
Gilles Peskine449bd832023-01-11 14:50:10 +01001180 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001181
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 if (verbose != 0) {
1183 mbedtls_printf("passed\n");
1184 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001185 }
1186 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001187
Gilles Peskine449bd832023-01-11 14:50:10 +01001188 if (verbose != 0) {
1189 mbedtls_printf("\n");
1190 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001191
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001192 ret = 0;
1193
1194exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001195 if (ret != 0) {
1196 if (verbose != 0) {
1197 mbedtls_printf("failed\n");
1198 }
1199 mbedtls_gcm_free(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001200 }
1201
Gilles Peskine449bd832023-01-11 14:50:10 +01001202 return ret;
Paul Bakker89e80c92012-03-20 13:50:09 +00001203}
1204
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001205#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001206
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001207#endif /* MBEDTLS_GCM_C */