blob: 390bb3e15634f78afbde38f6bb6d1740774fb37c [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;
71
Gilles Peskine449bd832023-01-11 14:50:10 +010072 if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen)) != 0) {
73 return ret;
74 }
Valerio Setti9b7a8b22023-11-16 08:24:51 +010075#else
76 if ((ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, h, h)) != 0) {
77 return ret;
78 }
79#endif
Paul Bakker89e80c92012-03-20 13:50:09 +000080
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010081 /* pack h as two 64-bits ints, big-endian */
Gilles Peskine449bd832023-01-11 14:50:10 +010082 hi = MBEDTLS_GET_UINT32_BE(h, 0);
83 lo = MBEDTLS_GET_UINT32_BE(h, 4);
Paul Bakker89e80c92012-03-20 13:50:09 +000084 vh = (uint64_t) hi << 32 | lo;
85
Gilles Peskine449bd832023-01-11 14:50:10 +010086 hi = MBEDTLS_GET_UINT32_BE(h, 8);
87 lo = MBEDTLS_GET_UINT32_BE(h, 12);
Paul Bakker89e80c92012-03-20 13:50:09 +000088 vl = (uint64_t) hi << 32 | lo;
Paul Bakker169b7f42013-06-25 14:58:00 +020089
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010090 /* 8 = 1000 corresponds to 1 in GF(2^128) */
Paul Bakker89e80c92012-03-20 13:50:09 +000091 ctx->HL[8] = vl;
92 ctx->HH[8] = vh;
93
Gilles Peskine9af58cd2023-03-10 22:29:32 +010094#if defined(MBEDTLS_AESNI_HAVE_CODE)
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010095 /* With CLMUL support, we need only h, not the rest of the table */
Gilles Peskine449bd832023-01-11 14:50:10 +010096 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
97 return 0;
98 }
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010099#endif
100
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800101#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100102 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yudf87a122023-01-10 18:17:15 +0800103 return 0;
104 }
105#endif
106
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100107 /* 0 corresponds to 0 in GF(2^128) */
108 ctx->HH[0] = 0;
109 ctx->HL[0] = 0;
110
Gilles Peskine449bd832023-01-11 14:50:10 +0100111 for (i = 4; i > 0; i >>= 1) {
112 uint32_t T = (vl & 1) * 0xe1000000U;
113 vl = (vh << 63) | (vl >> 1);
114 vh = (vh >> 1) ^ ((uint64_t) T << 32);
Paul Bakker89e80c92012-03-20 13:50:09 +0000115
116 ctx->HL[i] = vl;
117 ctx->HH[i] = vh;
118 }
119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 for (i = 2; i <= 8; i *= 2) {
Paul Bakker89e80c92012-03-20 13:50:09 +0000121 uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
122 vh = *HiH;
123 vl = *HiL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 for (j = 1; j < i; j++) {
Paul Bakker89e80c92012-03-20 13:50:09 +0000125 HiH[j] = vh ^ ctx->HH[j];
126 HiL[j] = vl ^ ctx->HL[j];
127 }
128 }
Paul Bakker43aff2a2013-09-09 00:10:27 +0200129
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000131}
132
Gilles Peskine449bd832023-01-11 14:50:10 +0100133int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
134 mbedtls_cipher_id_t cipher,
135 const unsigned char *key,
136 unsigned int keybits)
Paul Bakker89e80c92012-03-20 13:50:09 +0000137{
Janos Follath24eed8d2019-11-22 13:21:35 +0000138 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000139
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 if (keybits != 128 && keybits != 192 && keybits != 256) {
Tuvshinzaya Erdenekhuuc6b8a672022-08-05 15:31:57 +0100141 return MBEDTLS_ERR_GCM_BAD_INPUT;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200142 }
143
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100144#if defined(MBEDTLS_CIPHER_C)
145 const mbedtls_cipher_info_t *cipher_info;
146
Gilles Peskine449bd832023-01-11 14:50:10 +0100147 cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
148 MBEDTLS_MODE_ECB);
149 if (cipher_info == NULL) {
150 return MBEDTLS_ERR_GCM_BAD_INPUT;
151 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000152
Dave Rodgman85a88132023-06-24 11:41:50 +0100153 if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 return MBEDTLS_ERR_GCM_BAD_INPUT;
155 }
156
157 mbedtls_cipher_free(&ctx->cipher_ctx);
158
159 if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) {
160 return ret;
161 }
162
163 if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits,
164 MBEDTLS_ENCRYPT)) != 0) {
165 return ret;
166 }
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100167#else
168 mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
169
170 if ((ret = mbedtls_block_cipher_setup(&ctx->block_cipher_ctx, cipher)) != 0) {
171 return ret;
172 }
173
174 if ((ret = mbedtls_block_cipher_setkey(&ctx->block_cipher_ctx, key, keybits)) != 0) {
175 return ret;
176 }
177#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100178
179 if ((ret = gcm_gen_table(ctx)) != 0) {
180 return ret;
181 }
182
183 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000184}
185
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100186/*
187 * Shoup's method for multiplication use this table with
188 * last4[x] = x times P^128
189 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
190 */
Dave Rodgman5ff02452023-07-13 15:55:21 +0100191static const uint16_t last4[16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000192{
193 0x0000, 0x1c20, 0x3840, 0x2460,
194 0x7080, 0x6ca0, 0x48c0, 0x54e0,
195 0xe100, 0xfd20, 0xd940, 0xc560,
196 0x9180, 0x8da0, 0xa9c0, 0xb5e0
197};
198
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100199/*
200 * Sets output to x times H using the precomputed tables.
201 * x and output are seen as elements of GF(2^128) as in [MGV].
202 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100203static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16],
204 unsigned char output[16])
Paul Bakker89e80c92012-03-20 13:50:09 +0000205{
206 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000207 unsigned char lo, hi, rem;
208 uint64_t zh, zl;
209
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100210#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100211 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100212 unsigned char h[16];
213
Jerry Yu1ac7f6b2023-03-07 15:44:59 +0800214 /* mbedtls_aesni_gcm_mult needs big-endian input */
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0);
216 MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4);
217 MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8);
218 MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12);
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100219
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 mbedtls_aesni_gcm_mult(output, x, h);
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100221 return;
222 }
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100223#endif /* MBEDTLS_AESNI_HAVE_CODE */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100224
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800225#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100226 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yudf87a122023-01-10 18:17:15 +0800227 unsigned char h[16];
228
Jerry Yu1ac7f6b2023-03-07 15:44:59 +0800229 /* mbedtls_aesce_gcm_mult needs big-endian input */
Jerry Yudf87a122023-01-10 18:17:15 +0800230 MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0);
231 MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4);
232 MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8);
233 MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12);
234
235 mbedtls_aesce_gcm_mult(output, x, h);
236 return;
237 }
238#endif
239
Paul Bakker89e80c92012-03-20 13:50:09 +0000240 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000241
242 zh = ctx->HH[lo];
243 zl = ctx->HL[lo];
244
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 for (i = 15; i >= 0; i--) {
Paul Bakker89e80c92012-03-20 13:50:09 +0000246 lo = x[i] & 0xf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 hi = (x[i] >> 4) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000248
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 if (i != 15) {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000250 rem = (unsigned char) zl & 0xf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 zl = (zh << 60) | (zl >> 4);
252 zh = (zh >> 4);
Paul Bakker89e80c92012-03-20 13:50:09 +0000253 zh ^= (uint64_t) last4[rem] << 48;
254 zh ^= ctx->HH[lo];
255 zl ^= ctx->HL[lo];
256
257 }
258
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000259 rem = (unsigned char) zl & 0xf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 zl = (zh << 60) | (zl >> 4);
261 zh = (zh >> 4);
Paul Bakker89e80c92012-03-20 13:50:09 +0000262 zh ^= (uint64_t) last4[rem] << 48;
263 zh ^= ctx->HH[hi];
264 zl ^= ctx->HL[hi];
265 }
266
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 MBEDTLS_PUT_UINT32_BE(zh >> 32, output, 0);
268 MBEDTLS_PUT_UINT32_BE(zh, output, 4);
269 MBEDTLS_PUT_UINT32_BE(zl >> 32, output, 8);
270 MBEDTLS_PUT_UINT32_BE(zl, output, 12);
Paul Bakker89e80c92012-03-20 13:50:09 +0000271}
272
Gilles Peskine449bd832023-01-11 14:50:10 +0100273int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
274 int mode,
275 const unsigned char *iv, size_t iv_len)
Paul Bakker89e80c92012-03-20 13:50:09 +0000276{
Janos Follath24eed8d2019-11-22 13:21:35 +0000277 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000278 unsigned char work_buf[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000279 const unsigned char *p;
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100280 size_t use_len;
openluopworldeab65ac2021-09-22 23:59:42 +0800281 uint64_t iv_bits;
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100282#if defined(MBEDTLS_CIPHER_C)
283 size_t olen = 0;
284#endif
Paul Bakker89e80c92012-03-20 13:50:09 +0000285
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200286 /* IV is limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200287 /* IV is not allowed to be zero length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) {
289 return MBEDTLS_ERR_GCM_BAD_INPUT;
290 }
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200291
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 memset(ctx->y, 0x00, sizeof(ctx->y));
293 memset(ctx->buf, 0x00, sizeof(ctx->buf));
Paul Bakker52cf16c2013-07-26 13:55:38 +0200294
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200295 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200296 ctx->len = 0;
297 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000298
Gilles Peskine449bd832023-01-11 14:50:10 +0100299 if (iv_len == 12) {
300 memcpy(ctx->y, iv, iv_len);
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200301 ctx->y[15] = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 } else {
303 memset(work_buf, 0x00, 16);
304 iv_bits = (uint64_t) iv_len * 8;
305 MBEDTLS_PUT_UINT64_BE(iv_bits, work_buf, 8);
Paul Bakker89e80c92012-03-20 13:50:09 +0000306
307 p = iv;
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 while (iv_len > 0) {
309 use_len = (iv_len < 16) ? iv_len : 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000310
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 mbedtls_xor(ctx->y, ctx->y, p, use_len);
Paul Bakker169b7f42013-06-25 14:58:00 +0200312
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 gcm_mult(ctx, ctx->y, ctx->y);
Paul Bakker89e80c92012-03-20 13:50:09 +0000314
315 iv_len -= use_len;
316 p += use_len;
317 }
318
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 mbedtls_xor(ctx->y, ctx->y, work_buf, 16);
Paul Bakker89e80c92012-03-20 13:50:09 +0000320
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 gcm_mult(ctx, ctx->y, ctx->y);
Paul Bakker89e80c92012-03-20 13:50:09 +0000322 }
323
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100324
325#if defined(MBEDTLS_CIPHER_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16,
327 ctx->base_ectr, &olen)) != 0) {
328 return ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200329 }
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100330#else
331 if ((ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y,
332 ctx->base_ectr)) != 0) {
333 return ret;
334 }
335#endif
Paul Bakker89e80c92012-03-20 13:50:09 +0000336
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 return 0;
Gilles Peskine295fc132021-04-15 18:32:23 +0200338}
339
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200340/**
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200341 * mbedtls_gcm_context::buf contains the partial state of the computation of
342 * the authentication tag.
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200343 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
344 * different stages of the computation:
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200345 * * len == 0 && add_len == 0: initial state
346 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
347 * a partial block of AD that has been
348 * xored in but not yet multiplied in.
349 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
350 * the data ends now.
351 * * len % 16 != 0: the first `len % 16` bytes have
352 * a partial block of ciphertext that has
353 * been xored in but not yet multiplied in.
354 * * len > 0 && len % 16 == 0: the authentication tag is correct if
355 * the data ends now.
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200356 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100357int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx,
358 const unsigned char *add, size_t add_len)
Gilles Peskine295fc132021-04-15 18:32:23 +0200359{
360 const unsigned char *p;
Dave Rodgmand22fb732022-11-22 16:53:25 +0000361 size_t use_len, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200362
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200363 /* IV is limited to 2^64 bits, so 2^61 bytes */
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 if ((uint64_t) add_len >> 61 != 0) {
365 return MBEDTLS_ERR_GCM_BAD_INPUT;
366 }
Gilles Peskine295fc132021-04-15 18:32:23 +0200367
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200368 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000369 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200370
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 if (offset != 0) {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200372 use_len = 16 - offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 if (use_len > add_len) {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200374 use_len = add_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 }
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200376
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200378
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 if (offset + use_len == 16) {
380 gcm_mult(ctx, ctx->buf, ctx->buf);
381 }
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200382
383 ctx->add_len += use_len;
384 add_len -= use_len;
385 p += use_len;
386 }
387
388 ctx->add_len += add_len;
389
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 while (add_len >= 16) {
391 mbedtls_xor(ctx->buf, ctx->buf, p, 16);
Paul Bakker169b7f42013-06-25 14:58:00 +0200392
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 gcm_mult(ctx, ctx->buf, ctx->buf);
Paul Bakker89e80c92012-03-20 13:50:09 +0000394
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200395 add_len -= 16;
396 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000397 }
398
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 if (add_len > 0) {
400 mbedtls_xor(ctx->buf, ctx->buf, p, add_len);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200401 }
402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200404}
405
Gilles Peskine58fc2722021-04-13 15:58:27 +0200406/* Increment the counter. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100407static void gcm_incr(unsigned char y[16])
Gilles Peskine58fc2722021-04-13 15:58:27 +0200408{
409 size_t i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 for (i = 16; i > 12; i--) {
411 if (++y[i - 1] != 0) {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200412 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 }
414 }
Gilles Peskine58fc2722021-04-13 15:58:27 +0200415}
416
417/* Calculate and apply the encryption mask. Process use_len bytes of data,
418 * starting at position offset in the mask block. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100419static int gcm_mask(mbedtls_gcm_context *ctx,
420 unsigned char ectr[16],
421 size_t offset, size_t use_len,
422 const unsigned char *input,
423 unsigned char *output)
Gilles Peskine58fc2722021-04-13 15:58:27 +0200424{
Gilles Peskine58fc2722021-04-13 15:58:27 +0200425 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100426#if defined(MBEDTLS_CIPHER_C)
427 size_t olen = 0;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr,
430 &olen)) != 0) {
431 mbedtls_platform_zeroize(ectr, 16);
432 return ret;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200433 }
434
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100435#else
436
437 if ((ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ectr)) != 0) {
438 mbedtls_platform_zeroize(ectr, 16);
439 return ret;
440 }
441#endif
442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 if (ctx->mode == MBEDTLS_GCM_DECRYPT) {
444 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len);
445 }
446 mbedtls_xor(output, ectr + offset, input, use_len);
447 if (ctx->mode == MBEDTLS_GCM_ENCRYPT) {
448 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len);
449 }
Dave Rodgmand22fb732022-11-22 16:53:25 +0000450
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 return 0;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200452}
453
Gilles Peskine449bd832023-01-11 14:50:10 +0100454int mbedtls_gcm_update(mbedtls_gcm_context *ctx,
455 const unsigned char *input, size_t input_length,
456 unsigned char *output, size_t output_size,
457 size_t *output_length)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200458{
Janos Follath24eed8d2019-11-22 13:21:35 +0000459 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200460 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200461 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200462 size_t offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 unsigned char ectr[16] = { 0 };
Gilles Peskine58fc2722021-04-13 15:58:27 +0200464
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 if (output_size < input_length) {
466 return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL;
467 }
Gilles Peskinea56c4482021-04-15 17:22:35 +0200468 *output_length = input_length;
469
470 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200471 * on a potentially null pointer.
472 * Returning early also means that the last partial block of AD remains
473 * untouched for mbedtls_gcm_finish */
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 if (input_length == 0) {
475 return 0;
476 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 if (output > input && (size_t) (output - input) < input_length) {
479 return MBEDTLS_ERR_GCM_BAD_INPUT;
480 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200481
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200482 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
483 * Also check for possible overflow */
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 if (ctx->len + input_length < ctx->len ||
485 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) {
486 return MBEDTLS_ERR_GCM_BAD_INPUT;
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200487 }
488
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 if (ctx->len == 0 && ctx->add_len % 16 != 0) {
490 gcm_mult(ctx, ctx->buf, ctx->buf);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200491 }
492
Gilles Peskine58fc2722021-04-13 15:58:27 +0200493 offset = ctx->len % 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 if (offset != 0) {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200495 size_t use_len = 16 - offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 if (use_len > input_length) {
Gilles Peskinea56c4482021-04-15 17:22:35 +0200497 use_len = input_length;
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000499
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) {
501 return ret;
502 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000503
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 if (offset + use_len == 16) {
505 gcm_mult(ctx, ctx->buf, ctx->buf);
506 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200507
Gilles Peskine58fc2722021-04-13 15:58:27 +0200508 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200509 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000510 p += use_len;
511 out_p += use_len;
512 }
513
Gilles Peskinea56c4482021-04-15 17:22:35 +0200514 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200515
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 while (input_length >= 16) {
517 gcm_incr(ctx->y);
518 if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) {
519 return ret;
520 }
Gilles Peskine58fc2722021-04-13 15:58:27 +0200521
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 gcm_mult(ctx, ctx->buf, ctx->buf);
Gilles Peskine58fc2722021-04-13 15:58:27 +0200523
Gilles Peskinea56c4482021-04-15 17:22:35 +0200524 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200525 p += 16;
526 out_p += 16;
527 }
528
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 if (input_length > 0) {
530 gcm_incr(ctx->y);
531 if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) {
532 return ret;
533 }
Gilles Peskine58fc2722021-04-13 15:58:27 +0200534 }
535
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 mbedtls_platform_zeroize(ectr, sizeof(ectr));
537 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200538}
539
Gilles Peskine449bd832023-01-11 14:50:10 +0100540int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
541 unsigned char *output, size_t output_size,
542 size_t *output_length,
543 unsigned char *tag, size_t tag_len)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200544{
545 unsigned char work_buf[16];
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100546 uint64_t orig_len;
547 uint64_t orig_add_len;
548
Gilles Peskine9461e452021-04-15 16:48:32 +0200549 /* We never pass any output in finish(). The output parameter exists only
550 * for the sake of alternative implementations. */
551 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200552 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200553 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200554
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100555 orig_len = ctx->len * 8;
556 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 if (ctx->len == 0 && ctx->add_len % 16 != 0) {
559 gcm_mult(ctx, ctx->buf, ctx->buf);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200560 }
561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 if (tag_len > 16 || tag_len < 4) {
563 return MBEDTLS_ERR_GCM_BAD_INPUT;
Paul Bakker89e80c92012-03-20 13:50:09 +0000564 }
565
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 if (ctx->len % 16 != 0) {
567 gcm_mult(ctx, ctx->buf, ctx->buf);
568 }
569
570 memcpy(tag, ctx->base_ectr, tag_len);
571
572 if (orig_len || orig_add_len) {
573 memset(work_buf, 0x00, 16);
574
575 MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
576 MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4);
577 MBEDTLS_PUT_UINT32_BE((orig_len >> 32), work_buf, 8);
578 MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12);
579
580 mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16);
581
582 gcm_mult(ctx, ctx->buf, ctx->buf);
583
584 mbedtls_xor(tag, tag, ctx->buf, tag_len);
585 }
586
587 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000588}
589
Gilles Peskine449bd832023-01-11 14:50:10 +0100590int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
591 int mode,
592 size_t length,
593 const unsigned char *iv,
594 size_t iv_len,
595 const unsigned char *add,
596 size_t add_len,
597 const unsigned char *input,
598 unsigned char *output,
599 size_t tag_len,
600 unsigned char *tag)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200601{
Janos Follath24eed8d2019-11-22 13:21:35 +0000602 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200603 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200604
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) {
606 return ret;
607 }
Gilles Peskine295fc132021-04-15 18:32:23 +0200608
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) {
610 return ret;
611 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 if ((ret = mbedtls_gcm_update(ctx, input, length,
614 output, length, &olen)) != 0) {
615 return ret;
616 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200617
Gilles Peskine449bd832023-01-11 14:50:10 +0100618 if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) {
619 return ret;
620 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200621
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200623}
624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
626 size_t length,
627 const unsigned char *iv,
628 size_t iv_len,
629 const unsigned char *add,
630 size_t add_len,
631 const unsigned char *tag,
632 size_t tag_len,
633 const unsigned char *input,
634 unsigned char *output)
Paul Bakker89e80c92012-03-20 13:50:09 +0000635{
Janos Follath24eed8d2019-11-22 13:21:35 +0000636 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000637 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200638 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000639
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
641 iv, iv_len, add, add_len,
642 input, output, tag_len, check_tag)) != 0) {
643 return ret;
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100644 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000645
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200646 /* Check tag in "constant-time" */
Dave Rodgmand26a3d62023-09-11 18:25:16 +0100647 diff = mbedtls_ct_memcmp(tag, check_tag, tag_len);
Paul Bakker89e80c92012-03-20 13:50:09 +0000648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 if (diff != 0) {
650 mbedtls_platform_zeroize(output, length);
651 return MBEDTLS_ERR_GCM_AUTH_FAILED;
652 }
653
654 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000655}
656
Gilles Peskine449bd832023-01-11 14:50:10 +0100657void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200658{
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 if (ctx == NULL) {
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100660 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 }
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100662#if defined(MBEDTLS_CIPHER_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 mbedtls_cipher_free(&ctx->cipher_ctx);
Valerio Setti9b7a8b22023-11-16 08:24:51 +0100664#else
665 mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
666#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200668}
669
Jaeden Amero15263302017-09-21 12:53:48 +0100670#endif /* !MBEDTLS_GCM_ALT */
671
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200672#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000673/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200674 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000675 *
676 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
677 */
678#define MAX_TESTS 6
679
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100680static const int key_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100681{ 0, 0, 1, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000682
Yanray Wang93533b52023-05-11 16:45:59 +0800683static const unsigned char key_test_data[][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000684{
685 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
689 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
690 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
691 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200692 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000693};
694
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100695static const size_t iv_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100696{ 12, 12, 12, 12, 8, 60 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000697
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100698static const int iv_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100699{ 0, 0, 1, 1, 1, 2 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000700
Yanray Wang93533b52023-05-11 16:45:59 +0800701static const unsigned char iv_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000702{
703 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
704 0x00, 0x00, 0x00, 0x00 },
705 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
706 0xde, 0xca, 0xf8, 0x88 },
707 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200708 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000709 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200710 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000711 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200712 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000713 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200714 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000715};
716
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100717static const size_t add_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100718{ 0, 0, 0, 20, 20, 20 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000719
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100720static const int add_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100721{ 0, 0, 0, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000722
Yanray Wang93533b52023-05-11 16:45:59 +0800723static const unsigned char additional_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000724{
725 { 0x00 },
726 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200727 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000728 0xab, 0xad, 0xda, 0xd2 },
729};
730
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100731static const size_t pt_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100732{ 0, 16, 64, 60, 60, 60 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000733
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100734static const int pt_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100735{ 0, 0, 1, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000736
Yanray Wang93533b52023-05-11 16:45:59 +0800737static const unsigned char pt_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000738{
739 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
741 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
742 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
743 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
744 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
745 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
746 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
747 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
748 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
749};
750
Yanray Wangd329c692023-05-11 16:40:57 +0800751static const unsigned char ct_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000752{
753 { 0x00 },
754 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
755 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
756 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200757 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000758 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200759 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000760 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200761 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000762 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
763 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
764 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200765 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000766 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200767 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000768 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200769 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000770 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
771 0x3d, 0x58, 0xe0, 0x91 },
772 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200773 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000774 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200775 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000776 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200777 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000778 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
779 0xc2, 0x3f, 0x45, 0x98 },
780 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200781 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000782 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200783 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000784 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200785 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000786 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
787 0x4c, 0x34, 0xae, 0xe5 },
Yanray Wangd329c692023-05-11 16:40:57 +0800788#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker89e80c92012-03-20 13:50:09 +0000789 { 0x00 },
790 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200791 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000792 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200793 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000794 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200795 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000796 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200797 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000798 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
799 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
800 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200801 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000802 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200803 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
804 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
805 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000806 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200807 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000808 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200809 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000810 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200811 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000812 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200813 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000814 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200815 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000816 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200817 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000818 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200819 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000820 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200821 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000822 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200823 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000824 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200825 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
826 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
827 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
828 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
829 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
830 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
831 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
832 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
833 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
834 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
835 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
836 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
837 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
838 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
839 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
840 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
841 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
842 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000843 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200844 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000845 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200846 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000847 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200848 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000849 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200850 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000851 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200852 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000853 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200854 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000855 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200856 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000857 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200858 0x44, 0xae, 0x7e, 0x3f },
Yanray Wangd329c692023-05-11 16:40:57 +0800859#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker89e80c92012-03-20 13:50:09 +0000860};
861
Yanray Wangd329c692023-05-11 16:40:57 +0800862static const unsigned char tag_test_data[][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000863{
864 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
865 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
866 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
867 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
868 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200869 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000870 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
871 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
872 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
873 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
874 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
875 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
Yanray Wangd329c692023-05-11 16:40:57 +0800876#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker89e80c92012-03-20 13:50:09 +0000877 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
878 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
879 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200880 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000881 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
882 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
883 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200884 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000885 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200886 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000887 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200888 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000889 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200890 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000891 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200892 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000893 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200894 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000895 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200896 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000897 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200898 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000899 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200900 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Yanray Wangd329c692023-05-11 16:40:57 +0800901#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker89e80c92012-03-20 13:50:09 +0000902};
903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904int mbedtls_gcm_self_test(int verbose)
Paul Bakker89e80c92012-03-20 13:50:09 +0000905{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200906 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000907 unsigned char buf[64];
908 unsigned char tag_buf[16];
909 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200910 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200911 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000912
Gilles Peskine0cd9ab72023-03-16 13:06:14 +0100913 if (verbose != 0) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +0100914#if defined(MBEDTLS_GCM_ALT)
915 mbedtls_printf(" GCM note: alternative implementation.\n");
916#else /* MBEDTLS_GCM_ALT */
917#if defined(MBEDTLS_AESNI_HAVE_CODE)
918 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
919 mbedtls_printf(" GCM note: using AESNI.\n");
920 } else
921#endif
Jerry Yu2f26a592023-03-31 15:06:33 +0800922
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800923#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100924 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2f26a592023-03-31 15:06:33 +0800925 mbedtls_printf(" GCM note: using AESCE.\n");
926 } else
927#endif
928
Gilles Peskine7e67bd52023-03-10 22:35:24 +0100929 mbedtls_printf(" GCM note: built-in implementation.\n");
930#endif /* MBEDTLS_GCM_ALT */
931 }
932
Yanray Wangd329c692023-05-11 16:40:57 +0800933 static const int loop_limit =
934 (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS;
935
936 for (j = 0; j < loop_limit; j++) {
Paul Bakker89e80c92012-03-20 13:50:09 +0000937 int key_len = 128 + 64 * j;
938
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 for (i = 0; i < MAX_TESTS; i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 if (verbose != 0) {
941 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
942 key_len, i, "enc");
943 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200944
Arto Kinnunen0f066182023-04-20 10:02:46 +0800945 mbedtls_gcm_init(&ctx);
946
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 ret = mbedtls_gcm_setkey(&ctx, cipher,
948 key_test_data[key_index_test_data[i]],
949 key_len);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100950 /*
951 * AES-192 is an optional feature that may be unavailable when
952 * there is an alternative underlying implementation i.e. when
953 * MBEDTLS_AES_ALT is defined.
954 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) {
956 mbedtls_printf("skipped\n");
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100957 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 } else if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100959 goto exit;
960 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000961
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT,
963 pt_len_test_data[i],
964 iv_test_data[iv_index_test_data[i]],
965 iv_len_test_data[i],
966 additional_test_data[add_index_test_data[i]],
967 add_len_test_data[i],
968 pt_test_data[pt_index_test_data[i]],
969 buf, 16, tag_buf);
Steven Cooreman2222d682021-01-11 18:45:22 +0100970#if defined(MBEDTLS_GCM_ALT)
971 /* Allow alternative implementations to only support 12-byte nonces. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100972 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
973 iv_len_test_data[i] != 12) {
974 mbedtls_printf("skipped\n");
Steven Cooreman2222d682021-01-11 18:45:22 +0100975 break;
976 }
977#endif /* defined(MBEDTLS_GCM_ALT) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100978 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100979 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000981
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 if (memcmp(buf, ct_test_data[j * 6 + i],
983 pt_len_test_data[i]) != 0 ||
984 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100985 ret = 1;
986 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000987 }
988
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 if (verbose != 0) {
992 mbedtls_printf("passed\n");
993 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000994
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 if (verbose != 0) {
998 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
999 key_len, i, "dec");
1000 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001001
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 ret = mbedtls_gcm_setkey(&ctx, cipher,
1003 key_test_data[key_index_test_data[i]],
1004 key_len);
1005 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001006 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001007 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001008
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT,
1010 pt_len_test_data[i],
1011 iv_test_data[iv_index_test_data[i]],
1012 iv_len_test_data[i],
1013 additional_test_data[add_index_test_data[i]],
1014 add_len_test_data[i],
1015 ct_test_data[j * 6 + i], buf, 16, tag_buf);
Paul Bakker89e80c92012-03-20 13:50:09 +00001016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001018 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001020
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1022 pt_len_test_data[i]) != 0 ||
1023 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001024 ret = 1;
1025 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +00001026 }
1027
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001029
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 if (verbose != 0) {
1031 mbedtls_printf("passed\n");
1032 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001033
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001035
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 if (verbose != 0) {
1037 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1038 key_len, i, "enc");
1039 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 ret = mbedtls_gcm_setkey(&ctx, cipher,
1042 key_test_data[key_index_test_data[i]],
1043 key_len);
1044 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001045 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001047
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT,
1049 iv_test_data[iv_index_test_data[i]],
1050 iv_len_test_data[i]);
1051 if (ret != 0) {
Gilles Peskine295fc132021-04-15 18:32:23 +02001052 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 }
Gilles Peskine295fc132021-04-15 18:32:23 +02001054
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 ret = mbedtls_gcm_update_ad(&ctx,
1056 additional_test_data[add_index_test_data[i]],
1057 add_len_test_data[i]);
1058 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001059 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 if (pt_len_test_data[i] > 32) {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001063 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 ret = mbedtls_gcm_update(&ctx,
1065 pt_test_data[pt_index_test_data[i]],
1066 32,
1067 buf, sizeof(buf), &olen);
1068 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001069 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 }
1071 if (olen != 32) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001072 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001073 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001074
Gilles Peskine449bd832023-01-11 14:50:10 +01001075 ret = mbedtls_gcm_update(&ctx,
1076 pt_test_data[pt_index_test_data[i]] + 32,
1077 rest_len,
1078 buf + 32, sizeof(buf) - 32, &olen);
1079 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001080 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 }
1082 if (olen != rest_len) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001083 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001084 }
1085 } else {
1086 ret = mbedtls_gcm_update(&ctx,
1087 pt_test_data[pt_index_test_data[i]],
1088 pt_len_test_data[i],
1089 buf, sizeof(buf), &olen);
1090 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001091 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001092 }
1093 if (olen != pt_len_test_data[i]) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001094 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001096 }
1097
Gilles Peskine449bd832023-01-11 14:50:10 +01001098 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1099 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001100 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001102
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 if (memcmp(buf, ct_test_data[j * 6 + i],
1104 pt_len_test_data[i]) != 0 ||
1105 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001106 ret = 1;
1107 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001108 }
1109
Gilles Peskine449bd832023-01-11 14:50:10 +01001110 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001111
Gilles Peskine449bd832023-01-11 14:50:10 +01001112 if (verbose != 0) {
1113 mbedtls_printf("passed\n");
1114 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001115
Gilles Peskine449bd832023-01-11 14:50:10 +01001116 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001117
Gilles Peskine449bd832023-01-11 14:50:10 +01001118 if (verbose != 0) {
1119 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1120 key_len, i, "dec");
1121 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001122
Gilles Peskine449bd832023-01-11 14:50:10 +01001123 ret = mbedtls_gcm_setkey(&ctx, cipher,
1124 key_test_data[key_index_test_data[i]],
1125 key_len);
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 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT,
1131 iv_test_data[iv_index_test_data[i]],
1132 iv_len_test_data[i]);
1133 if (ret != 0) {
Gilles Peskine295fc132021-04-15 18:32:23 +02001134 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001135 }
1136 ret = mbedtls_gcm_update_ad(&ctx,
1137 additional_test_data[add_index_test_data[i]],
1138 add_len_test_data[i]);
1139 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001140 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001141 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001142
Gilles Peskine449bd832023-01-11 14:50:10 +01001143 if (pt_len_test_data[i] > 32) {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001144 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskine449bd832023-01-11 14:50:10 +01001145 ret = mbedtls_gcm_update(&ctx,
1146 ct_test_data[j * 6 + i], 32,
1147 buf, sizeof(buf), &olen);
1148 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001149 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001150 }
1151 if (olen != 32) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001152 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001153 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001154
Gilles Peskine449bd832023-01-11 14:50:10 +01001155 ret = mbedtls_gcm_update(&ctx,
1156 ct_test_data[j * 6 + i] + 32,
1157 rest_len,
1158 buf + 32, sizeof(buf) - 32, &olen);
1159 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001160 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001161 }
1162 if (olen != rest_len) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001163 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 }
1165 } else {
1166 ret = mbedtls_gcm_update(&ctx,
1167 ct_test_data[j * 6 + i],
1168 pt_len_test_data[i],
1169 buf, sizeof(buf), &olen);
1170 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001171 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001172 }
1173 if (olen != pt_len_test_data[i]) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001174 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001175 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001176 }
1177
Gilles Peskine449bd832023-01-11 14:50:10 +01001178 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1179 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001180 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001182
Gilles Peskine449bd832023-01-11 14:50:10 +01001183 if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1184 pt_len_test_data[i]) != 0 ||
1185 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001186 ret = 1;
1187 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001188 }
1189
Gilles Peskine449bd832023-01-11 14:50:10 +01001190 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001191
Gilles Peskine449bd832023-01-11 14:50:10 +01001192 if (verbose != 0) {
1193 mbedtls_printf("passed\n");
1194 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001195 }
1196 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001197
Gilles Peskine449bd832023-01-11 14:50:10 +01001198 if (verbose != 0) {
1199 mbedtls_printf("\n");
1200 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001201
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001202 ret = 0;
1203
1204exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001205 if (ret != 0) {
1206 if (verbose != 0) {
1207 mbedtls_printf("failed\n");
1208 }
1209 mbedtls_gcm_free(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001210 }
1211
Gilles Peskine449bd832023-01-11 14:50:10 +01001212 return ret;
Paul Bakker89e80c92012-03-20 13:50:09 +00001213}
1214
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001215#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001216
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001217#endif /* MBEDTLS_GCM_C */