blob: c8618be7ce6c0a1a4706d8d06cd81857a8d7f6a0 [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
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker89e80c92012-03-20 13:50:09 +000018 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010019
Paul Bakker89e80c92012-03-20 13:50:09 +000020/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010021 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
22 *
23 * See also:
24 * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
25 *
26 * We use the algorithm described as Shoup's method with 4-bit tables in
27 * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
Paul Bakker89e80c92012-03-20 13:50:09 +000028 */
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010029
Gilles Peskinedb09ef62020-06-03 01:43:33 +020030#include "common.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_GCM_C)
Paul Bakker89e80c92012-03-20 13:50:09 +000033
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/gcm.h"
Gilles Peskineed1c7f42022-09-15 20:14:22 +020035#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050036#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000037#include "mbedtls/error.h"
Dave Rodgmand26a3d62023-09-11 18:25:16 +010038#include "mbedtls/constant_time.h"
Paul Bakker89e80c92012-03-20 13:50:09 +000039
Rich Evans00ab4702015-02-06 13:43:58 +000040#include <string.h>
41
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000043#include "aesni.h"
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +010044#endif
45
Jerry Yudf87a122023-01-10 18:17:15 +080046#if defined(MBEDTLS_AESCE_C)
47#include "aesce.h"
48#endif
49
Jaeden Amero15263302017-09-21 12:53:48 +010050#if !defined(MBEDTLS_GCM_ALT)
51
Paul Bakker89e80c92012-03-20 13:50:09 +000052/*
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020053 * Initialize a context
54 */
Gilles Peskine449bd832023-01-11 14:50:10 +010055void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020056{
Gilles Peskine449bd832023-01-11 14:50:10 +010057 memset(ctx, 0, sizeof(mbedtls_gcm_context));
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +020058}
59
60/*
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +010061 * Precompute small multiples of H, that is set
62 * HH[i] || HL[i] = H times i,
63 * where i is seen as a field element as in [MGV], ie high-order bits
64 * correspond to low powers of P. The result is stored in the same way, that
65 * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
66 * corresponds to P^127.
67 */
Gilles Peskine449bd832023-01-11 14:50:10 +010068static int gcm_gen_table(mbedtls_gcm_context *ctx)
Paul Bakker89e80c92012-03-20 13:50:09 +000069{
Paul Bakker43aff2a2013-09-09 00:10:27 +020070 int ret, i, j;
Paul Bakker89e80c92012-03-20 13:50:09 +000071 uint64_t hi, lo;
72 uint64_t vl, vh;
73 unsigned char h[16];
Paul Bakker43aff2a2013-09-09 00:10:27 +020074 size_t olen = 0;
Paul Bakker169b7f42013-06-25 14:58:00 +020075
Gilles Peskine449bd832023-01-11 14:50:10 +010076 memset(h, 0, 16);
77 if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen)) != 0) {
78 return ret;
79 }
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;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200139 const mbedtls_cipher_info_t *cipher_info;
Paul Bakker89e80c92012-03-20 13:50:09 +0000140
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 if (keybits != 128 && keybits != 192 && keybits != 256) {
Tuvshinzaya Erdenekhuuc6b8a672022-08-05 15:31:57 +0100142 return MBEDTLS_ERR_GCM_BAD_INPUT;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200143 }
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 }
165
166 if ((ret = gcm_gen_table(ctx)) != 0) {
167 return ret;
168 }
169
170 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000171}
172
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100173/*
174 * Shoup's method for multiplication use this table with
175 * last4[x] = x times P^128
176 * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
177 */
Dave Rodgman5ff02452023-07-13 15:55:21 +0100178static const uint16_t last4[16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000179{
180 0x0000, 0x1c20, 0x3840, 0x2460,
181 0x7080, 0x6ca0, 0x48c0, 0x54e0,
182 0xe100, 0xfd20, 0xd940, 0xc560,
183 0x9180, 0x8da0, 0xa9c0, 0xb5e0
184};
185
Manuel Pégourié-Gonnard9d574822013-12-25 15:41:25 +0100186/*
187 * Sets output to x times H using the precomputed tables.
188 * x and output are seen as elements of GF(2^128) as in [MGV].
189 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100190static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16],
191 unsigned char output[16])
Paul Bakker89e80c92012-03-20 13:50:09 +0000192{
193 int i = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000194 unsigned char lo, hi, rem;
195 uint64_t zh, zl;
196
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100197#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100199 unsigned char h[16];
200
Jerry Yu1ac7f6b2023-03-07 15:44:59 +0800201 /* mbedtls_aesni_gcm_mult needs big-endian input */
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0);
203 MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4);
204 MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8);
205 MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12);
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100206
Gilles Peskine449bd832023-01-11 14:50:10 +0100207 mbedtls_aesni_gcm_mult(output, x, h);
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100208 return;
209 }
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100210#endif /* MBEDTLS_AESNI_HAVE_CODE */
Manuel Pégourié-Gonnard80637c72013-12-26 16:09:58 +0100211
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800212#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100213 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yudf87a122023-01-10 18:17:15 +0800214 unsigned char h[16];
215
Jerry Yu1ac7f6b2023-03-07 15:44:59 +0800216 /* mbedtls_aesce_gcm_mult needs big-endian input */
Jerry Yudf87a122023-01-10 18:17:15 +0800217 MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0);
218 MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4);
219 MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8);
220 MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12);
221
222 mbedtls_aesce_gcm_mult(output, x, h);
223 return;
224 }
225#endif
226
Paul Bakker89e80c92012-03-20 13:50:09 +0000227 lo = x[15] & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000228
229 zh = ctx->HH[lo];
230 zl = ctx->HL[lo];
231
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 for (i = 15; i >= 0; i--) {
Paul Bakker89e80c92012-03-20 13:50:09 +0000233 lo = x[i] & 0xf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 hi = (x[i] >> 4) & 0xf;
Paul Bakker89e80c92012-03-20 13:50:09 +0000235
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 if (i != 15) {
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000237 rem = (unsigned char) zl & 0xf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 zl = (zh << 60) | (zl >> 4);
239 zh = (zh >> 4);
Paul Bakker89e80c92012-03-20 13:50:09 +0000240 zh ^= (uint64_t) last4[rem] << 48;
241 zh ^= ctx->HH[lo];
242 zl ^= ctx->HL[lo];
243
244 }
245
Paul Bakker4a2bd0d2012-11-02 11:06:08 +0000246 rem = (unsigned char) zl & 0xf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 zl = (zh << 60) | (zl >> 4);
248 zh = (zh >> 4);
Paul Bakker89e80c92012-03-20 13:50:09 +0000249 zh ^= (uint64_t) last4[rem] << 48;
250 zh ^= ctx->HH[hi];
251 zl ^= ctx->HL[hi];
252 }
253
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 MBEDTLS_PUT_UINT32_BE(zh >> 32, output, 0);
255 MBEDTLS_PUT_UINT32_BE(zh, output, 4);
256 MBEDTLS_PUT_UINT32_BE(zl >> 32, output, 8);
257 MBEDTLS_PUT_UINT32_BE(zl, output, 12);
Paul Bakker89e80c92012-03-20 13:50:09 +0000258}
259
Gilles Peskine449bd832023-01-11 14:50:10 +0100260int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
261 int mode,
262 const unsigned char *iv, size_t iv_len)
Paul Bakker89e80c92012-03-20 13:50:09 +0000263{
Janos Follath24eed8d2019-11-22 13:21:35 +0000264 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000265 unsigned char work_buf[16];
Paul Bakker89e80c92012-03-20 13:50:09 +0000266 const unsigned char *p;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200267 size_t use_len, olen = 0;
openluopworldeab65ac2021-09-22 23:59:42 +0800268 uint64_t iv_bits;
Paul Bakker89e80c92012-03-20 13:50:09 +0000269
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200270 /* IV is limited to 2^64 bits, so 2^61 bytes */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200271 /* IV is not allowed to be zero length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100272 if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) {
273 return MBEDTLS_ERR_GCM_BAD_INPUT;
274 }
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200275
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 memset(ctx->y, 0x00, sizeof(ctx->y));
277 memset(ctx->buf, 0x00, sizeof(ctx->buf));
Paul Bakker52cf16c2013-07-26 13:55:38 +0200278
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200279 ctx->mode = mode;
Paul Bakker52cf16c2013-07-26 13:55:38 +0200280 ctx->len = 0;
281 ctx->add_len = 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000282
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 if (iv_len == 12) {
284 memcpy(ctx->y, iv, iv_len);
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200285 ctx->y[15] = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 } else {
287 memset(work_buf, 0x00, 16);
288 iv_bits = (uint64_t) iv_len * 8;
289 MBEDTLS_PUT_UINT64_BE(iv_bits, work_buf, 8);
Paul Bakker89e80c92012-03-20 13:50:09 +0000290
291 p = iv;
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 while (iv_len > 0) {
293 use_len = (iv_len < 16) ? iv_len : 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000294
Gilles Peskine449bd832023-01-11 14:50:10 +0100295 mbedtls_xor(ctx->y, ctx->y, p, use_len);
Paul Bakker169b7f42013-06-25 14:58:00 +0200296
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 gcm_mult(ctx, ctx->y, ctx->y);
Paul Bakker89e80c92012-03-20 13:50:09 +0000298
299 iv_len -= use_len;
300 p += use_len;
301 }
302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 mbedtls_xor(ctx->y, ctx->y, work_buf, 16);
Paul Bakker89e80c92012-03-20 13:50:09 +0000304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 gcm_mult(ctx, ctx->y, ctx->y);
Paul Bakker89e80c92012-03-20 13:50:09 +0000306 }
307
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16,
309 ctx->base_ectr, &olen)) != 0) {
310 return ret;
Paul Bakker43aff2a2013-09-09 00:10:27 +0200311 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000312
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 return 0;
Gilles Peskine295fc132021-04-15 18:32:23 +0200314}
315
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200316/**
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200317 * mbedtls_gcm_context::buf contains the partial state of the computation of
318 * the authentication tag.
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200319 * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate
320 * different stages of the computation:
Mateusz Starzyk3d0bbee2021-06-15 14:26:53 +0200321 * * len == 0 && add_len == 0: initial state
322 * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have
323 * a partial block of AD that has been
324 * xored in but not yet multiplied in.
325 * * len == 0 && add_len % 16 == 0: the authentication tag is correct if
326 * the data ends now.
327 * * len % 16 != 0: the first `len % 16` bytes have
328 * a partial block of ciphertext that has
329 * been xored in but not yet multiplied in.
330 * * len > 0 && len % 16 == 0: the authentication tag is correct if
331 * the data ends now.
Mateusz Starzykb45b57e2021-06-07 15:44:18 +0200332 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100333int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx,
334 const unsigned char *add, size_t add_len)
Gilles Peskine295fc132021-04-15 18:32:23 +0200335{
336 const unsigned char *p;
Dave Rodgmand22fb732022-11-22 16:53:25 +0000337 size_t use_len, offset;
Gilles Peskine295fc132021-04-15 18:32:23 +0200338
Mateusz Starzyk939a54c2021-06-22 11:12:28 +0200339 /* IV is limited to 2^64 bits, so 2^61 bytes */
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 if ((uint64_t) add_len >> 61 != 0) {
341 return MBEDTLS_ERR_GCM_BAD_INPUT;
342 }
Gilles Peskine295fc132021-04-15 18:32:23 +0200343
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200344 offset = ctx->add_len % 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000345 p = add;
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 if (offset != 0) {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200348 use_len = 16 - offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 if (use_len > add_len) {
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200350 use_len = add_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 }
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200352
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200354
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 if (offset + use_len == 16) {
356 gcm_mult(ctx, ctx->buf, ctx->buf);
357 }
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200358
359 ctx->add_len += use_len;
360 add_len -= use_len;
361 p += use_len;
362 }
363
364 ctx->add_len += add_len;
365
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 while (add_len >= 16) {
367 mbedtls_xor(ctx->buf, ctx->buf, p, 16);
Paul Bakker169b7f42013-06-25 14:58:00 +0200368
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 gcm_mult(ctx, ctx->buf, ctx->buf);
Paul Bakker89e80c92012-03-20 13:50:09 +0000370
Mateusz Starzyk25a571e2021-06-15 13:22:42 +0200371 add_len -= 16;
372 p += 16;
Paul Bakker89e80c92012-03-20 13:50:09 +0000373 }
374
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 if (add_len > 0) {
376 mbedtls_xor(ctx->buf, ctx->buf, p, add_len);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200377 }
378
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200380}
381
Gilles Peskine58fc2722021-04-13 15:58:27 +0200382/* Increment the counter. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100383static void gcm_incr(unsigned char y[16])
Gilles Peskine58fc2722021-04-13 15:58:27 +0200384{
385 size_t i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 for (i = 16; i > 12; i--) {
387 if (++y[i - 1] != 0) {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200388 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 }
390 }
Gilles Peskine58fc2722021-04-13 15:58:27 +0200391}
392
393/* Calculate and apply the encryption mask. Process use_len bytes of data,
394 * starting at position offset in the mask block. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100395static int gcm_mask(mbedtls_gcm_context *ctx,
396 unsigned char ectr[16],
397 size_t offset, size_t use_len,
398 const unsigned char *input,
399 unsigned char *output)
Gilles Peskine58fc2722021-04-13 15:58:27 +0200400{
Gilles Peskine58fc2722021-04-13 15:58:27 +0200401 size_t olen = 0;
402 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
403
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr,
405 &olen)) != 0) {
406 mbedtls_platform_zeroize(ectr, 16);
407 return ret;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200408 }
409
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 if (ctx->mode == MBEDTLS_GCM_DECRYPT) {
411 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len);
412 }
413 mbedtls_xor(output, ectr + offset, input, use_len);
414 if (ctx->mode == MBEDTLS_GCM_ENCRYPT) {
415 mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len);
416 }
Dave Rodgmand22fb732022-11-22 16:53:25 +0000417
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 return 0;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200419}
420
Gilles Peskine449bd832023-01-11 14:50:10 +0100421int mbedtls_gcm_update(mbedtls_gcm_context *ctx,
422 const unsigned char *input, size_t input_length,
423 unsigned char *output, size_t output_size,
424 size_t *output_length)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200425{
Janos Follath24eed8d2019-11-22 13:21:35 +0000426 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200427 const unsigned char *p = input;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200428 unsigned char *out_p = output;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200429 size_t offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 unsigned char ectr[16] = { 0 };
Gilles Peskine58fc2722021-04-13 15:58:27 +0200431
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 if (output_size < input_length) {
433 return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL;
434 }
Gilles Peskinea56c4482021-04-15 17:22:35 +0200435 *output_length = input_length;
436
437 /* Exit early if input_length==0 so that we don't do any pointer arithmetic
Mateusz Starzyk3443bd22021-06-07 16:03:27 +0200438 * on a potentially null pointer.
439 * Returning early also means that the last partial block of AD remains
440 * untouched for mbedtls_gcm_finish */
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 if (input_length == 0) {
442 return 0;
443 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200444
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 if (output > input && (size_t) (output - input) < input_length) {
446 return MBEDTLS_ERR_GCM_BAD_INPUT;
447 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200448
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200449 /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
450 * Also check for possible overflow */
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 if (ctx->len + input_length < ctx->len ||
452 (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) {
453 return MBEDTLS_ERR_GCM_BAD_INPUT;
Manuel Pégourié-Gonnardb46e6ad2014-06-18 11:29:30 +0200454 }
455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 if (ctx->len == 0 && ctx->add_len % 16 != 0) {
457 gcm_mult(ctx, ctx->buf, ctx->buf);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200458 }
459
Gilles Peskine58fc2722021-04-13 15:58:27 +0200460 offset = ctx->len % 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 if (offset != 0) {
Gilles Peskine58fc2722021-04-13 15:58:27 +0200462 size_t use_len = 16 - offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 if (use_len > input_length) {
Gilles Peskinea56c4482021-04-15 17:22:35 +0200464 use_len = input_length;
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000466
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) {
468 return ret;
469 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000470
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 if (offset + use_len == 16) {
472 gcm_mult(ctx, ctx->buf, ctx->buf);
473 }
Paul Bakker169b7f42013-06-25 14:58:00 +0200474
Gilles Peskine58fc2722021-04-13 15:58:27 +0200475 ctx->len += use_len;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200476 input_length -= use_len;
Paul Bakker89e80c92012-03-20 13:50:09 +0000477 p += use_len;
478 out_p += use_len;
479 }
480
Gilles Peskinea56c4482021-04-15 17:22:35 +0200481 ctx->len += input_length;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200482
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 while (input_length >= 16) {
484 gcm_incr(ctx->y);
485 if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) {
486 return ret;
487 }
Gilles Peskine58fc2722021-04-13 15:58:27 +0200488
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 gcm_mult(ctx, ctx->buf, ctx->buf);
Gilles Peskine58fc2722021-04-13 15:58:27 +0200490
Gilles Peskinea56c4482021-04-15 17:22:35 +0200491 input_length -= 16;
Gilles Peskine58fc2722021-04-13 15:58:27 +0200492 p += 16;
493 out_p += 16;
494 }
495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 if (input_length > 0) {
497 gcm_incr(ctx->y);
498 if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) {
499 return ret;
500 }
Gilles Peskine58fc2722021-04-13 15:58:27 +0200501 }
502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 mbedtls_platform_zeroize(ectr, sizeof(ectr));
504 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200505}
506
Gilles Peskine449bd832023-01-11 14:50:10 +0100507int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
508 unsigned char *output, size_t output_size,
509 size_t *output_length,
510 unsigned char *tag, size_t tag_len)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200511{
512 unsigned char work_buf[16];
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100513 uint64_t orig_len;
514 uint64_t orig_add_len;
515
Gilles Peskine9461e452021-04-15 16:48:32 +0200516 /* We never pass any output in finish(). The output parameter exists only
517 * for the sake of alternative implementations. */
518 (void) output;
Gilles Peskineb7bb06872021-05-18 22:31:53 +0200519 (void) output_size;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200520 *output_length = 0;
Gilles Peskine9461e452021-04-15 16:48:32 +0200521
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100522 orig_len = ctx->len * 8;
523 orig_add_len = ctx->add_len * 8;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200524
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 if (ctx->len == 0 && ctx->add_len % 16 != 0) {
526 gcm_mult(ctx, ctx->buf, ctx->buf);
Mateusz Starzykbd513bb2021-05-26 14:25:39 +0200527 }
528
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 if (tag_len > 16 || tag_len < 4) {
530 return MBEDTLS_ERR_GCM_BAD_INPUT;
Paul Bakker89e80c92012-03-20 13:50:09 +0000531 }
532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 if (ctx->len % 16 != 0) {
534 gcm_mult(ctx, ctx->buf, ctx->buf);
535 }
536
537 memcpy(tag, ctx->base_ectr, tag_len);
538
539 if (orig_len || orig_add_len) {
540 memset(work_buf, 0x00, 16);
541
542 MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0);
543 MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4);
544 MBEDTLS_PUT_UINT32_BE((orig_len >> 32), work_buf, 8);
545 MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12);
546
547 mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16);
548
549 gcm_mult(ctx, ctx->buf, ctx->buf);
550
551 mbedtls_xor(tag, tag, ctx->buf, tag_len);
552 }
553
554 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000555}
556
Gilles Peskine449bd832023-01-11 14:50:10 +0100557int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
558 int mode,
559 size_t length,
560 const unsigned char *iv,
561 size_t iv_len,
562 const unsigned char *add,
563 size_t add_len,
564 const unsigned char *input,
565 unsigned char *output,
566 size_t tag_len,
567 unsigned char *tag)
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200568{
Janos Follath24eed8d2019-11-22 13:21:35 +0000569 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200570 size_t olen;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200571
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) {
573 return ret;
574 }
Gilles Peskine295fc132021-04-15 18:32:23 +0200575
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) {
577 return ret;
578 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200579
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 if ((ret = mbedtls_gcm_update(ctx, input, length,
581 output, length, &olen)) != 0) {
582 return ret;
583 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200584
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) {
586 return ret;
587 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200588
Gilles Peskine449bd832023-01-11 14:50:10 +0100589 return 0;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200590}
591
Gilles Peskine449bd832023-01-11 14:50:10 +0100592int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
593 size_t length,
594 const unsigned char *iv,
595 size_t iv_len,
596 const unsigned char *add,
597 size_t add_len,
598 const unsigned char *tag,
599 size_t tag_len,
600 const unsigned char *input,
601 unsigned char *output)
Paul Bakker89e80c92012-03-20 13:50:09 +0000602{
Janos Follath24eed8d2019-11-22 13:21:35 +0000603 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker89e80c92012-03-20 13:50:09 +0000604 unsigned char check_tag[16];
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200605 int diff;
Paul Bakker89e80c92012-03-20 13:50:09 +0000606
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
608 iv, iv_len, add, add_len,
609 input, output, tag_len, check_tag)) != 0) {
610 return ret;
Manuel Pégourié-Gonnard073f0fa2014-01-18 18:49:32 +0100611 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000612
Manuel Pégourié-Gonnard20d6a172013-08-31 16:37:46 +0200613 /* Check tag in "constant-time" */
Dave Rodgmand26a3d62023-09-11 18:25:16 +0100614 diff = mbedtls_ct_memcmp(tag, check_tag, tag_len);
Paul Bakker89e80c92012-03-20 13:50:09 +0000615
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 if (diff != 0) {
617 mbedtls_platform_zeroize(output, length);
618 return MBEDTLS_ERR_GCM_AUTH_FAILED;
619 }
620
621 return 0;
Paul Bakker89e80c92012-03-20 13:50:09 +0000622}
623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200625{
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 if (ctx == NULL) {
k-stachowiak8ffc92a2018-12-12 14:21:59 +0100627 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 }
629 mbedtls_cipher_free(&ctx->cipher_ctx);
630 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200631}
632
Jaeden Amero15263302017-09-21 12:53:48 +0100633#endif /* !MBEDTLS_GCM_ALT */
634
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200635#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
Paul Bakker89e80c92012-03-20 13:50:09 +0000636/*
Manuel Pégourié-Gonnarddae70932013-10-24 15:06:33 +0200637 * AES-GCM test vectors from:
Paul Bakker89e80c92012-03-20 13:50:09 +0000638 *
639 * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
640 */
641#define MAX_TESTS 6
642
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100643static const int key_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100644{ 0, 0, 1, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000645
Yanray Wang93533b52023-05-11 16:45:59 +0800646static const unsigned char key_test_data[][32] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000647{
648 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
652 { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
653 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
654 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200655 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000656};
657
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100658static const size_t iv_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100659{ 12, 12, 12, 12, 8, 60 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000660
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100661static const int iv_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100662{ 0, 0, 1, 1, 1, 2 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000663
Yanray Wang93533b52023-05-11 16:45:59 +0800664static const unsigned char iv_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000665{
666 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
667 0x00, 0x00, 0x00, 0x00 },
668 { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
669 0xde, 0xca, 0xf8, 0x88 },
670 { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
Paul Bakker169b7f42013-06-25 14:58:00 +0200671 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
Paul Bakker89e80c92012-03-20 13:50:09 +0000672 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200673 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
Paul Bakker89e80c92012-03-20 13:50:09 +0000674 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
Paul Bakker169b7f42013-06-25 14:58:00 +0200675 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
Paul Bakker89e80c92012-03-20 13:50:09 +0000676 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
Paul Bakker169b7f42013-06-25 14:58:00 +0200677 0xa6, 0x37, 0xb3, 0x9b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000678};
679
Michał Janiszewski9aeea932018-10-30 23:00:15 +0100680static const size_t add_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100681{ 0, 0, 0, 20, 20, 20 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000682
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100683static const int add_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100684{ 0, 0, 0, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000685
Yanray Wang93533b52023-05-11 16:45:59 +0800686static const unsigned char additional_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000687{
688 { 0x00 },
689 { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200690 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
Paul Bakker89e80c92012-03-20 13:50:09 +0000691 0xab, 0xad, 0xda, 0xd2 },
692};
693
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100694static const size_t pt_len_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100695{ 0, 16, 64, 60, 60, 60 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000696
Michał Janiszewskic79e92b2018-10-31 20:43:05 +0100697static const int pt_index_test_data[MAX_TESTS] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100698{ 0, 0, 1, 1, 1, 1 };
Paul Bakker89e80c92012-03-20 13:50:09 +0000699
Yanray Wang93533b52023-05-11 16:45:59 +0800700static const unsigned char pt_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000701{
702 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
704 { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
705 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
706 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
707 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
708 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
709 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
710 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
711 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
712};
713
Yanray Wangd329c692023-05-11 16:40:57 +0800714static const unsigned char ct_test_data[][64] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000715{
716 { 0x00 },
717 { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
718 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
719 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200720 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000721 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200722 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000723 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200724 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000725 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
726 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
727 { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200728 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000729 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200730 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
Paul Bakker89e80c92012-03-20 13:50:09 +0000731 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200732 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
Paul Bakker89e80c92012-03-20 13:50:09 +0000733 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
734 0x3d, 0x58, 0xe0, 0x91 },
735 { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
Paul Bakker169b7f42013-06-25 14:58:00 +0200736 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
Paul Bakker89e80c92012-03-20 13:50:09 +0000737 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200738 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
Paul Bakker89e80c92012-03-20 13:50:09 +0000739 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
Paul Bakker169b7f42013-06-25 14:58:00 +0200740 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
Paul Bakker89e80c92012-03-20 13:50:09 +0000741 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
742 0xc2, 0x3f, 0x45, 0x98 },
743 { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200744 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
Paul Bakker89e80c92012-03-20 13:50:09 +0000745 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
Paul Bakker169b7f42013-06-25 14:58:00 +0200746 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
Paul Bakker89e80c92012-03-20 13:50:09 +0000747 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
Paul Bakker169b7f42013-06-25 14:58:00 +0200748 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
Paul Bakker89e80c92012-03-20 13:50:09 +0000749 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
750 0x4c, 0x34, 0xae, 0xe5 },
Yanray Wangd329c692023-05-11 16:40:57 +0800751#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker89e80c92012-03-20 13:50:09 +0000752 { 0x00 },
753 { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200754 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000755 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200756 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000757 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200758 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
Paul Bakker89e80c92012-03-20 13:50:09 +0000759 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
Paul Bakker169b7f42013-06-25 14:58:00 +0200760 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000761 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
762 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
763 { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
Paul Bakker169b7f42013-06-25 14:58:00 +0200764 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000765 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
Paul Bakker169b7f42013-06-25 14:58:00 +0200766 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
767 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
768 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
Paul Bakker89e80c92012-03-20 13:50:09 +0000769 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200770 0xcc, 0xda, 0x27, 0x10 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000771 { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
Paul Bakker169b7f42013-06-25 14:58:00 +0200772 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
Paul Bakker89e80c92012-03-20 13:50:09 +0000773 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200774 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
Paul Bakker89e80c92012-03-20 13:50:09 +0000775 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
Paul Bakker169b7f42013-06-25 14:58:00 +0200776 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
Paul Bakker89e80c92012-03-20 13:50:09 +0000777 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200778 0xa0, 0xf0, 0x62, 0xf7 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000779 { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
Paul Bakker169b7f42013-06-25 14:58:00 +0200780 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
Paul Bakker89e80c92012-03-20 13:50:09 +0000781 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
Paul Bakker169b7f42013-06-25 14:58:00 +0200782 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
Paul Bakker89e80c92012-03-20 13:50:09 +0000783 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200784 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
Paul Bakker89e80c92012-03-20 13:50:09 +0000785 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
Paul Bakker169b7f42013-06-25 14:58:00 +0200786 0xe9, 0xb7, 0x37, 0x3b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000787 { 0x00 },
Paul Bakker169b7f42013-06-25 14:58:00 +0200788 { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
789 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
790 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
791 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
792 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
793 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
794 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
795 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
796 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
797 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
798 { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
799 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
800 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
801 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
802 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
803 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
804 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
805 0xbc, 0xc9, 0xf6, 0x62 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000806 { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
Paul Bakker169b7f42013-06-25 14:58:00 +0200807 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
Paul Bakker89e80c92012-03-20 13:50:09 +0000808 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
Paul Bakker169b7f42013-06-25 14:58:00 +0200809 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
Paul Bakker89e80c92012-03-20 13:50:09 +0000810 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200811 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
Paul Bakker89e80c92012-03-20 13:50:09 +0000812 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
Paul Bakker169b7f42013-06-25 14:58:00 +0200813 0xf4, 0x7c, 0x9b, 0x1f },
Paul Bakker89e80c92012-03-20 13:50:09 +0000814 { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
Paul Bakker169b7f42013-06-25 14:58:00 +0200815 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
Paul Bakker89e80c92012-03-20 13:50:09 +0000816 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
Paul Bakker169b7f42013-06-25 14:58:00 +0200817 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
Paul Bakker89e80c92012-03-20 13:50:09 +0000818 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
Paul Bakker169b7f42013-06-25 14:58:00 +0200819 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
Paul Bakker89e80c92012-03-20 13:50:09 +0000820 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
Paul Bakker169b7f42013-06-25 14:58:00 +0200821 0x44, 0xae, 0x7e, 0x3f },
Yanray Wangd329c692023-05-11 16:40:57 +0800822#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker89e80c92012-03-20 13:50:09 +0000823};
824
Yanray Wangd329c692023-05-11 16:40:57 +0800825static const unsigned char tag_test_data[][16] =
Paul Bakker89e80c92012-03-20 13:50:09 +0000826{
827 { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
828 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
829 { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
830 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
831 { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
Paul Bakker169b7f42013-06-25 14:58:00 +0200832 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000833 { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
834 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
835 { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
836 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
837 { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
838 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
Yanray Wangd329c692023-05-11 16:40:57 +0800839#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker89e80c92012-03-20 13:50:09 +0000840 { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
841 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
842 { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
Paul Bakker169b7f42013-06-25 14:58:00 +0200843 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
Paul Bakker89e80c92012-03-20 13:50:09 +0000844 { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
845 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
846 { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
Paul Bakker169b7f42013-06-25 14:58:00 +0200847 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000848 { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
Paul Bakker169b7f42013-06-25 14:58:00 +0200849 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000850 { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
Paul Bakker169b7f42013-06-25 14:58:00 +0200851 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000852 { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
Paul Bakker169b7f42013-06-25 14:58:00 +0200853 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000854 { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200855 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000856 { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
Paul Bakker169b7f42013-06-25 14:58:00 +0200857 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
Paul Bakker89e80c92012-03-20 13:50:09 +0000858 { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
Paul Bakker169b7f42013-06-25 14:58:00 +0200859 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
Paul Bakker89e80c92012-03-20 13:50:09 +0000860 { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
Paul Bakker169b7f42013-06-25 14:58:00 +0200861 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
Paul Bakker89e80c92012-03-20 13:50:09 +0000862 { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
Paul Bakker169b7f42013-06-25 14:58:00 +0200863 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
Yanray Wangd329c692023-05-11 16:40:57 +0800864#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker89e80c92012-03-20 13:50:09 +0000865};
866
Gilles Peskine449bd832023-01-11 14:50:10 +0100867int mbedtls_gcm_self_test(int verbose)
Paul Bakker89e80c92012-03-20 13:50:09 +0000868{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000870 unsigned char buf[64];
871 unsigned char tag_buf[16];
872 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
Gilles Peskinea56c4482021-04-15 17:22:35 +0200874 size_t olen;
Paul Bakker89e80c92012-03-20 13:50:09 +0000875
Gilles Peskine0cd9ab72023-03-16 13:06:14 +0100876 if (verbose != 0) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +0100877#if defined(MBEDTLS_GCM_ALT)
878 mbedtls_printf(" GCM note: alternative implementation.\n");
879#else /* MBEDTLS_GCM_ALT */
880#if defined(MBEDTLS_AESNI_HAVE_CODE)
881 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
882 mbedtls_printf(" GCM note: using AESNI.\n");
883 } else
884#endif
Jerry Yu2f26a592023-03-31 15:06:33 +0800885
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800886#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100887 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2f26a592023-03-31 15:06:33 +0800888 mbedtls_printf(" GCM note: using AESCE.\n");
889 } else
890#endif
891
Gilles Peskine7e67bd52023-03-10 22:35:24 +0100892 mbedtls_printf(" GCM note: built-in implementation.\n");
893#endif /* MBEDTLS_GCM_ALT */
894 }
895
Yanray Wangd329c692023-05-11 16:40:57 +0800896 static const int loop_limit =
897 (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS;
898
899 for (j = 0; j < loop_limit; j++) {
Paul Bakker89e80c92012-03-20 13:50:09 +0000900 int key_len = 128 + 64 * j;
901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 for (i = 0; i < MAX_TESTS; i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 if (verbose != 0) {
904 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
905 key_len, i, "enc");
906 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200907
Arto Kinnunen0f066182023-04-20 10:02:46 +0800908 mbedtls_gcm_init(&ctx);
909
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 ret = mbedtls_gcm_setkey(&ctx, cipher,
911 key_test_data[key_index_test_data[i]],
912 key_len);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +0100913 /*
914 * AES-192 is an optional feature that may be unavailable when
915 * there is an alternative underlying implementation i.e. when
916 * MBEDTLS_AES_ALT is defined.
917 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) {
919 mbedtls_printf("skipped\n");
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100920 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 } else if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100922 goto exit;
923 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000924
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT,
926 pt_len_test_data[i],
927 iv_test_data[iv_index_test_data[i]],
928 iv_len_test_data[i],
929 additional_test_data[add_index_test_data[i]],
930 add_len_test_data[i],
931 pt_test_data[pt_index_test_data[i]],
932 buf, 16, tag_buf);
Steven Cooreman2222d682021-01-11 18:45:22 +0100933#if defined(MBEDTLS_GCM_ALT)
934 /* Allow alternative implementations to only support 12-byte nonces. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
936 iv_len_test_data[i] != 12) {
937 mbedtls_printf("skipped\n");
Steven Cooreman2222d682021-01-11 18:45:22 +0100938 break;
939 }
940#endif /* defined(MBEDTLS_GCM_ALT) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100942 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000944
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 if (memcmp(buf, ct_test_data[j * 6 + i],
946 pt_len_test_data[i]) != 0 ||
947 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100948 ret = 1;
949 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000950 }
951
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200953
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 if (verbose != 0) {
955 mbedtls_printf("passed\n");
956 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100959
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 if (verbose != 0) {
961 mbedtls_printf(" AES-GCM-%3d #%d (%s): ",
962 key_len, i, "dec");
963 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200964
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 ret = mbedtls_gcm_setkey(&ctx, cipher,
966 key_test_data[key_index_test_data[i]],
967 key_len);
968 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 ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT,
973 pt_len_test_data[i],
974 iv_test_data[iv_index_test_data[i]],
975 iv_len_test_data[i],
976 additional_test_data[add_index_test_data[i]],
977 add_len_test_data[i],
978 ct_test_data[j * 6 + i], buf, 16, tag_buf);
Paul Bakker89e80c92012-03-20 13:50:09 +0000979
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100981 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
985 pt_len_test_data[i]) != 0 ||
986 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100987 ret = 1;
988 goto exit;
Paul Bakker89e80c92012-03-20 13:50:09 +0000989 }
990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200992
Gilles Peskine449bd832023-01-11 14:50:10 +0100993 if (verbose != 0) {
994 mbedtls_printf("passed\n");
995 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +0200996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +0100998
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 if (verbose != 0) {
1000 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1001 key_len, i, "enc");
1002 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001003
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 ret = mbedtls_gcm_setkey(&ctx, cipher,
1005 key_test_data[key_index_test_data[i]],
1006 key_len);
1007 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001008 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001010
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT,
1012 iv_test_data[iv_index_test_data[i]],
1013 iv_len_test_data[i]);
1014 if (ret != 0) {
Gilles Peskine295fc132021-04-15 18:32:23 +02001015 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001016 }
Gilles Peskine295fc132021-04-15 18:32:23 +02001017
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 ret = mbedtls_gcm_update_ad(&ctx,
1019 additional_test_data[add_index_test_data[i]],
1020 add_len_test_data[i]);
1021 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001022 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001024
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 if (pt_len_test_data[i] > 32) {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001026 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 ret = mbedtls_gcm_update(&ctx,
1028 pt_test_data[pt_index_test_data[i]],
1029 32,
1030 buf, sizeof(buf), &olen);
1031 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001032 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 }
1034 if (olen != 32) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001035 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_update(&ctx,
1039 pt_test_data[pt_index_test_data[i]] + 32,
1040 rest_len,
1041 buf + 32, sizeof(buf) - 32, &olen);
1042 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001043 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 }
1045 if (olen != rest_len) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001046 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 }
1048 } else {
1049 ret = mbedtls_gcm_update(&ctx,
1050 pt_test_data[pt_index_test_data[i]],
1051 pt_len_test_data[i],
1052 buf, sizeof(buf), &olen);
1053 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001054 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 }
1056 if (olen != pt_len_test_data[i]) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001057 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001059 }
1060
Gilles Peskine449bd832023-01-11 14:50:10 +01001061 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1062 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001063 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001065
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 if (memcmp(buf, ct_test_data[j * 6 + i],
1067 pt_len_test_data[i]) != 0 ||
1068 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001069 ret = 1;
1070 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001071 }
1072
Gilles Peskine449bd832023-01-11 14:50:10 +01001073 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001074
Gilles Peskine449bd832023-01-11 14:50:10 +01001075 if (verbose != 0) {
1076 mbedtls_printf("passed\n");
1077 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001078
Gilles Peskine449bd832023-01-11 14:50:10 +01001079 mbedtls_gcm_init(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001080
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 if (verbose != 0) {
1082 mbedtls_printf(" AES-GCM-%3d #%d split (%s): ",
1083 key_len, i, "dec");
1084 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001085
Gilles Peskine449bd832023-01-11 14:50:10 +01001086 ret = mbedtls_gcm_setkey(&ctx, cipher,
1087 key_test_data[key_index_test_data[i]],
1088 key_len);
1089 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001090 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001091 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001092
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT,
1094 iv_test_data[iv_index_test_data[i]],
1095 iv_len_test_data[i]);
1096 if (ret != 0) {
Gilles Peskine295fc132021-04-15 18:32:23 +02001097 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001098 }
1099 ret = mbedtls_gcm_update_ad(&ctx,
1100 additional_test_data[add_index_test_data[i]],
1101 add_len_test_data[i]);
1102 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001103 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001104 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001105
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 if (pt_len_test_data[i] > 32) {
Michał Janiszewskic79e92b2018-10-31 20:43:05 +01001107 size_t rest_len = pt_len_test_data[i] - 32;
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 ret = mbedtls_gcm_update(&ctx,
1109 ct_test_data[j * 6 + i], 32,
1110 buf, sizeof(buf), &olen);
1111 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001112 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001113 }
1114 if (olen != 32) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001115 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001116 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001117
Gilles Peskine449bd832023-01-11 14:50:10 +01001118 ret = mbedtls_gcm_update(&ctx,
1119 ct_test_data[j * 6 + i] + 32,
1120 rest_len,
1121 buf + 32, sizeof(buf) - 32, &olen);
1122 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001123 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001124 }
1125 if (olen != rest_len) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001126 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001127 }
1128 } else {
1129 ret = mbedtls_gcm_update(&ctx,
1130 ct_test_data[j * 6 + i],
1131 pt_len_test_data[i],
1132 buf, sizeof(buf), &olen);
1133 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001134 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001135 }
1136 if (olen != pt_len_test_data[i]) {
Gilles Peskinea56c4482021-04-15 17:22:35 +02001137 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001138 }
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001139 }
1140
Gilles Peskine449bd832023-01-11 14:50:10 +01001141 ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16);
1142 if (ret != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001143 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001144 }
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001145
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 if (memcmp(buf, pt_test_data[pt_index_test_data[i]],
1147 pt_len_test_data[i]) != 0 ||
1148 memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) {
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001149 ret = 1;
1150 goto exit;
Paul Bakkerb9d3cfa2013-06-26 15:07:16 +02001151 }
1152
Gilles Peskine449bd832023-01-11 14:50:10 +01001153 mbedtls_gcm_free(&ctx);
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +02001154
Gilles Peskine449bd832023-01-11 14:50:10 +01001155 if (verbose != 0) {
1156 mbedtls_printf("passed\n");
1157 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001158 }
1159 }
Paul Bakker169b7f42013-06-25 14:58:00 +02001160
Gilles Peskine449bd832023-01-11 14:50:10 +01001161 if (verbose != 0) {
1162 mbedtls_printf("\n");
1163 }
Paul Bakker89e80c92012-03-20 13:50:09 +00001164
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001165 ret = 0;
1166
1167exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001168 if (ret != 0) {
1169 if (verbose != 0) {
1170 mbedtls_printf("failed\n");
1171 }
1172 mbedtls_gcm_free(&ctx);
Andres Amaya Garcia2a078da2017-06-15 11:30:51 +01001173 }
1174
Gilles Peskine449bd832023-01-11 14:50:10 +01001175 return ret;
Paul Bakker89e80c92012-03-20 13:50:09 +00001176}
1177
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001178#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
Paul Bakker89e80c92012-03-20 13:50:09 +00001179
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001180#endif /* MBEDTLS_GCM_C */