blob: dac2a5df2c185e38a93a32940ad9c915742f5cfb [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/gcm.h"
Gilles Peskine36dd93e2021-04-13 13:02:03 +02003
4/* Use the multipart interface to process the encrypted data in two parts
5 * and check that the output matches the expected output.
6 * The context must have been set up with the key. */
Gilles Peskine449bd832023-01-11 14:50:10 +01007static int check_multipart(mbedtls_gcm_context *ctx,
8 int mode,
9 const data_t *iv,
10 const data_t *add,
11 const data_t *input,
12 const data_t *expected_output,
13 const data_t *tag,
14 size_t n1,
15 size_t n1_add)
Gilles Peskine36dd93e2021-04-13 13:02:03 +020016{
17 int ok = 0;
18 uint8_t *output = NULL;
19 size_t n2 = input->len - n1;
Mateusz Starzyk658f4fd2021-05-26 14:26:48 +020020 size_t n2_add = add->len - n1_add;
Gilles Peskinea56c4482021-04-15 17:22:35 +020021 size_t olen;
Gilles Peskine36dd93e2021-04-13 13:02:03 +020022
23 /* Sanity checks on the test data */
Gilles Peskine449bd832023-01-11 14:50:10 +010024 TEST_ASSERT(n1 <= input->len);
25 TEST_ASSERT(n1_add <= add->len);
26 TEST_EQUAL(input->len, expected_output->len);
Gilles Peskine36dd93e2021-04-13 13:02:03 +020027
Gilles Peskine449bd832023-01-11 14:50:10 +010028 TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode,
29 iv->x, iv->len));
30 TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, add->x, n1_add));
31 TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, add->x + n1_add, n2_add));
Gilles Peskine36dd93e2021-04-13 13:02:03 +020032
33 /* Allocate a tight buffer for each update call. This way, if the function
34 * tries to write beyond the advertised required buffer size, this will
35 * count as an overflow for memory sanitizers and static checkers. */
Tom Cosgrove05b2a872023-07-21 11:31:13 +010036 TEST_CALLOC(output, n1);
Gilles Peskinea56c4482021-04-15 17:22:35 +020037 olen = 0xdeadbeef;
Gilles Peskine449bd832023-01-11 14:50:10 +010038 TEST_EQUAL(0, mbedtls_gcm_update(ctx, input->x, n1, output, n1, &olen));
39 TEST_EQUAL(n1, olen);
Tom Cosgrovee4e9e7d2023-07-21 11:40:20 +010040 TEST_MEMORY_COMPARE(output, olen, expected_output->x, n1);
Gilles Peskine449bd832023-01-11 14:50:10 +010041 mbedtls_free(output);
Gilles Peskine36dd93e2021-04-13 13:02:03 +020042 output = NULL;
43
Tom Cosgrove05b2a872023-07-21 11:31:13 +010044 TEST_CALLOC(output, n2);
Gilles Peskinea56c4482021-04-15 17:22:35 +020045 olen = 0xdeadbeef;
Gilles Peskine449bd832023-01-11 14:50:10 +010046 TEST_EQUAL(0, mbedtls_gcm_update(ctx, input->x + n1, n2, output, n2, &olen));
47 TEST_EQUAL(n2, olen);
Tom Cosgrovee4e9e7d2023-07-21 11:40:20 +010048 TEST_MEMORY_COMPARE(output, olen, expected_output->x + n1, n2);
Gilles Peskine449bd832023-01-11 14:50:10 +010049 mbedtls_free(output);
Gilles Peskine36dd93e2021-04-13 13:02:03 +020050 output = NULL;
51
Tom Cosgrove05b2a872023-07-21 11:31:13 +010052 TEST_CALLOC(output, tag->len);
Gilles Peskine449bd832023-01-11 14:50:10 +010053 TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len));
54 TEST_EQUAL(0, olen);
Tom Cosgrovee4e9e7d2023-07-21 11:40:20 +010055 TEST_MEMORY_COMPARE(output, tag->len, tag->x, tag->len);
Gilles Peskine449bd832023-01-11 14:50:10 +010056 mbedtls_free(output);
Gilles Peskine36dd93e2021-04-13 13:02:03 +020057 output = NULL;
58
59 ok = 1;
60exit:
Gilles Peskine449bd832023-01-11 14:50:10 +010061 mbedtls_free(output);
62 return ok;
Gilles Peskine36dd93e2021-04-13 13:02:03 +020063}
64
Gilles Peskine449bd832023-01-11 14:50:10 +010065static void check_cipher_with_empty_ad(mbedtls_gcm_context *ctx,
66 int mode,
67 const data_t *iv,
68 const data_t *input,
69 const data_t *expected_output,
70 const data_t *tag,
71 size_t ad_update_count)
Mateusz Starzykfc606222021-06-16 11:04:07 +020072{
73 size_t n;
74 uint8_t *output = NULL;
75 size_t olen;
76
77 /* Sanity checks on the test data */
Gilles Peskine449bd832023-01-11 14:50:10 +010078 TEST_EQUAL(input->len, expected_output->len);
Mateusz Starzykfc606222021-06-16 11:04:07 +020079
Gilles Peskine449bd832023-01-11 14:50:10 +010080 TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode,
81 iv->x, iv->len));
Mateusz Starzykfc606222021-06-16 11:04:07 +020082
Gilles Peskine449bd832023-01-11 14:50:10 +010083 for (n = 0; n < ad_update_count; n++) {
84 TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, NULL, 0));
Mateusz Starzykfc606222021-06-16 11:04:07 +020085 }
86
87 /* Allocate a tight buffer for each update call. This way, if the function
88 * tries to write beyond the advertised required buffer size, this will
89 * count as an overflow for memory sanitizers and static checkers. */
Tom Cosgrove05b2a872023-07-21 11:31:13 +010090 TEST_CALLOC(output, input->len);
Mateusz Starzykfc606222021-06-16 11:04:07 +020091 olen = 0xdeadbeef;
Gilles Peskine449bd832023-01-11 14:50:10 +010092 TEST_EQUAL(0, mbedtls_gcm_update(ctx, input->x, input->len, output, input->len, &olen));
93 TEST_EQUAL(input->len, olen);
Tom Cosgrovee4e9e7d2023-07-21 11:40:20 +010094 TEST_MEMORY_COMPARE(output, olen, expected_output->x, input->len);
Gilles Peskine449bd832023-01-11 14:50:10 +010095 mbedtls_free(output);
Mateusz Starzykfc606222021-06-16 11:04:07 +020096 output = NULL;
97
Tom Cosgrove05b2a872023-07-21 11:31:13 +010098 TEST_CALLOC(output, tag->len);
Gilles Peskine449bd832023-01-11 14:50:10 +010099 TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len));
100 TEST_EQUAL(0, olen);
Tom Cosgrovee4e9e7d2023-07-21 11:40:20 +0100101 TEST_MEMORY_COMPARE(output, tag->len, tag->x, tag->len);
Mateusz Starzykfc606222021-06-16 11:04:07 +0200102
103exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100104 mbedtls_free(output);
Mateusz Starzykfc606222021-06-16 11:04:07 +0200105}
106
Gilles Peskine449bd832023-01-11 14:50:10 +0100107static void check_empty_cipher_with_ad(mbedtls_gcm_context *ctx,
Mateusz Starzykfc606222021-06-16 11:04:07 +0200108 int mode,
109 const data_t *iv,
110 const data_t *add,
111 const data_t *tag,
112 size_t cipher_update_count)
113{
114 size_t olen;
115 size_t n;
Gilles Peskine449bd832023-01-11 14:50:10 +0100116 uint8_t *output_tag = NULL;
Mateusz Starzykfc606222021-06-16 11:04:07 +0200117
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode, iv->x, iv->len));
119 TEST_EQUAL(0, mbedtls_gcm_update_ad(ctx, add->x, add->len));
Mateusz Starzykfc606222021-06-16 11:04:07 +0200120
Gilles Peskine449bd832023-01-11 14:50:10 +0100121 for (n = 0; n < cipher_update_count; n++) {
Mateusz Starzykfc606222021-06-16 11:04:07 +0200122 olen = 0xdeadbeef;
Gilles Peskine449bd832023-01-11 14:50:10 +0100123 TEST_EQUAL(0, mbedtls_gcm_update(ctx, NULL, 0, NULL, 0, &olen));
124 TEST_EQUAL(0, olen);
Mateusz Starzykfc606222021-06-16 11:04:07 +0200125 }
126
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100127 TEST_CALLOC(output_tag, tag->len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100128 TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen,
129 output_tag, tag->len));
130 TEST_EQUAL(0, olen);
Tom Cosgrovee4e9e7d2023-07-21 11:40:20 +0100131 TEST_MEMORY_COMPARE(output_tag, tag->len, tag->x, tag->len);
Mateusz Starzykfc606222021-06-16 11:04:07 +0200132
133exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 mbedtls_free(output_tag);
Mateusz Starzykfc606222021-06-16 11:04:07 +0200135}
136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137static void check_no_cipher_no_ad(mbedtls_gcm_context *ctx,
138 int mode,
139 const data_t *iv,
140 const data_t *tag)
Mateusz Starzyk469c9f32021-06-18 00:06:52 +0200141{
142 uint8_t *output = NULL;
Gilles Peskine5a7be102021-06-23 21:51:32 +0200143 size_t olen = 0;
Mateusz Starzyk469c9f32021-06-18 00:06:52 +0200144
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 TEST_EQUAL(0, mbedtls_gcm_starts(ctx, mode,
146 iv->x, iv->len));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100147 TEST_CALLOC(output, tag->len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 TEST_EQUAL(0, mbedtls_gcm_finish(ctx, NULL, 0, &olen, output, tag->len));
149 TEST_EQUAL(0, olen);
Tom Cosgrovee4e9e7d2023-07-21 11:40:20 +0100150 TEST_MEMORY_COMPARE(output, tag->len, tag->x, tag->len);
Mateusz Starzyk469c9f32021-06-18 00:06:52 +0200151
152exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 mbedtls_free(output);
Mateusz Starzyk469c9f32021-06-18 00:06:52 +0200154}
155
Chien Wong99ff1f52024-01-24 20:44:01 +0800156static void gcm_reset_ctx(mbedtls_gcm_context *ctx, const uint8_t *key,
157 size_t key_bits, const uint8_t *iv, size_t iv_len,
158 int starts_ret)
159{
160 int mode = MBEDTLS_GCM_ENCRYPT;
161 mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES;
162
163 mbedtls_gcm_init(ctx);
164 TEST_EQUAL(mbedtls_gcm_setkey(ctx, valid_cipher, key, key_bits), 0);
165 TEST_EQUAL(starts_ret, mbedtls_gcm_starts(ctx, mode, iv, iv_len));
166exit:
167 /* empty */
168}
169
Paul Bakker33b43f12013-08-20 11:48:36 +0200170/* END_HEADER */
Paul Bakker89e80c92012-03-20 13:50:09 +0000171
Paul Bakker33b43f12013-08-20 11:48:36 +0200172/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173 * depends_on:MBEDTLS_GCM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200174 * END_DEPENDENCIES
175 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000176
Paul Bakker33b43f12013-08-20 11:48:36 +0200177/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100178void gcm_bad_parameters(int cipher_id, int direction,
179 data_t *key_str, data_t *src_str,
180 data_t *iv_str, data_t *add_str,
181 int tag_len_bits, int gcm_result)
Ron Eldor5a21fd62016-12-16 16:15:56 +0200182{
Ron Eldor5a21fd62016-12-16 16:15:56 +0200183 unsigned char output[128];
184 unsigned char tag_output[16];
185 mbedtls_gcm_context ctx;
Azim Khan317efe82017-08-02 17:33:54 +0100186 size_t tag_len = tag_len_bits / 8;
Ron Eldor5a21fd62016-12-16 16:15:56 +0200187
Valerio Setti10e9aa22023-12-12 11:54:20 +0100188 BLOCK_CIPHER_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 mbedtls_gcm_init(&ctx);
Ron Eldor5a21fd62016-12-16 16:15:56 +0200190
Gilles Peskine449bd832023-01-11 14:50:10 +0100191 memset(output, 0x00, sizeof(output));
192 memset(tag_output, 0x00, sizeof(tag_output));
Darryl Green11999bb2018-03-13 15:22:58 +0000193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
195 TEST_ASSERT(mbedtls_gcm_crypt_and_tag(&ctx, direction, src_str->len, iv_str->x, iv_str->len,
196 add_str->x, add_str->len, src_str->x, output, tag_len,
197 tag_output) == gcm_result);
Ron Eldor5a21fd62016-12-16 16:15:56 +0200198
199exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 mbedtls_gcm_free(&ctx);
Valerio Setti10e9aa22023-12-12 11:54:20 +0100201 BLOCK_CIPHER_PSA_DONE();
Ron Eldor5a21fd62016-12-16 16:15:56 +0200202}
203/* END_CASE */
204
205/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100206void gcm_encrypt_and_tag(int cipher_id, data_t *key_str,
207 data_t *src_str, data_t *iv_str,
208 data_t *add_str, data_t *dst,
209 int tag_len_bits, data_t *tag,
210 int init_result)
Paul Bakker89e80c92012-03-20 13:50:09 +0000211{
Paul Bakker89e80c92012-03-20 13:50:09 +0000212 unsigned char output[128];
213 unsigned char tag_output[16];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200214 mbedtls_gcm_context ctx;
Azim Khanf1aaec92017-05-30 14:23:15 +0100215 size_t tag_len = tag_len_bits / 8;
Gilles Peskine36dd93e2021-04-13 13:02:03 +0200216 size_t n1;
Mateusz Starzykaf4ecdd2021-06-15 15:29:48 +0200217 size_t n1_add;
Paul Bakker89e80c92012-03-20 13:50:09 +0000218
Valerio Setti10e9aa22023-12-12 11:54:20 +0100219 BLOCK_CIPHER_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 mbedtls_gcm_init(&ctx);
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200221
Paul Bakker89e80c92012-03-20 13:50:09 +0000222 memset(output, 0x00, 128);
223 memset(tag_output, 0x00, 16);
224
Paul Bakker89e80c92012-03-20 13:50:09 +0000225
Gilles Peskine449bd832023-01-11 14:50:10 +0100226 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result);
227 if (init_result == 0) {
228 TEST_ASSERT(mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, src_str->len, iv_str->x,
229 iv_str->len, add_str->x, add_str->len, src_str->x,
230 output, tag_len, tag_output) == 0);
Paul Bakker89e80c92012-03-20 13:50:09 +0000231
Tom Cosgrovee4e9e7d2023-07-21 11:40:20 +0100232 TEST_MEMORY_COMPARE(output, src_str->len, dst->x, dst->len);
233 TEST_MEMORY_COMPARE(tag_output, tag_len, tag->x, tag->len);
Gilles Peskine36dd93e2021-04-13 13:02:03 +0200234
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 for (n1 = 0; n1 <= src_str->len; n1 += 1) {
236 for (n1_add = 0; n1_add <= add_str->len; n1_add += 1) {
237 mbedtls_test_set_step(n1 * 10000 + n1_add);
238 if (!check_multipart(&ctx, MBEDTLS_GCM_ENCRYPT,
239 iv_str, add_str, src_str,
240 dst, tag,
241 n1, n1_add)) {
Mateusz Starzykaf4ecdd2021-06-15 15:29:48 +0200242 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100243 }
Mateusz Starzykaf4ecdd2021-06-15 15:29:48 +0200244 }
Gilles Peskine36dd93e2021-04-13 13:02:03 +0200245 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000246 }
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200247
Paul Bakkerbd51b262014-07-10 15:26:12 +0200248exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 mbedtls_gcm_free(&ctx);
Valerio Setti10e9aa22023-12-12 11:54:20 +0100250 BLOCK_CIPHER_PSA_DONE();
Paul Bakker89e80c92012-03-20 13:50:09 +0000251}
Paul Bakker33b43f12013-08-20 11:48:36 +0200252/* END_CASE */
Paul Bakker89e80c92012-03-20 13:50:09 +0000253
Paul Bakker33b43f12013-08-20 11:48:36 +0200254/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100255void gcm_decrypt_and_verify(int cipher_id, data_t *key_str,
256 data_t *src_str, data_t *iv_str,
257 data_t *add_str, int tag_len_bits,
258 data_t *tag_str, char *result,
259 data_t *pt_result, int init_result)
Paul Bakker89e80c92012-03-20 13:50:09 +0000260{
Paul Bakker89e80c92012-03-20 13:50:09 +0000261 unsigned char output[128];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000263 int ret;
Azim Khanf1aaec92017-05-30 14:23:15 +0100264 size_t tag_len = tag_len_bits / 8;
Gilles Peskine36dd93e2021-04-13 13:02:03 +0200265 size_t n1;
Mateusz Starzykaf4ecdd2021-06-15 15:29:48 +0200266 size_t n1_add;
Paul Bakker89e80c92012-03-20 13:50:09 +0000267
Valerio Setti10e9aa22023-12-12 11:54:20 +0100268 BLOCK_CIPHER_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 mbedtls_gcm_init(&ctx);
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200270
Paul Bakker89e80c92012-03-20 13:50:09 +0000271 memset(output, 0x00, 128);
272
Paul Bakker89e80c92012-03-20 13:50:09 +0000273
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result);
275 if (init_result == 0) {
276 ret = mbedtls_gcm_auth_decrypt(&ctx,
277 src_str->len,
278 iv_str->x,
279 iv_str->len,
280 add_str->x,
281 add_str->len,
282 tag_str->x,
283 tag_len,
284 src_str->x,
285 output);
Paul Bakker89e80c92012-03-20 13:50:09 +0000286
Gilles Peskine449bd832023-01-11 14:50:10 +0100287 if (strcmp("FAIL", result) == 0) {
288 TEST_ASSERT(ret == MBEDTLS_ERR_GCM_AUTH_FAILED);
289 } else {
290 TEST_ASSERT(ret == 0);
Tom Cosgrovee4e9e7d2023-07-21 11:40:20 +0100291 TEST_MEMORY_COMPARE(output, src_str->len, pt_result->x, pt_result->len);
Paul Bakker89e80c92012-03-20 13:50:09 +0000292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 for (n1 = 0; n1 <= src_str->len; n1 += 1) {
294 for (n1_add = 0; n1_add <= add_str->len; n1_add += 1) {
295 mbedtls_test_set_step(n1 * 10000 + n1_add);
296 if (!check_multipart(&ctx, MBEDTLS_GCM_DECRYPT,
297 iv_str, add_str, src_str,
298 pt_result, tag_str,
299 n1, n1_add)) {
Mateusz Starzykaf4ecdd2021-06-15 15:29:48 +0200300 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 }
Mateusz Starzykaf4ecdd2021-06-15 15:29:48 +0200302 }
Gilles Peskine36dd93e2021-04-13 13:02:03 +0200303 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000304 }
305 }
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200306
Paul Bakkerbd51b262014-07-10 15:26:12 +0200307exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 mbedtls_gcm_free(&ctx);
Valerio Setti10e9aa22023-12-12 11:54:20 +0100309 BLOCK_CIPHER_PSA_DONE();
Paul Bakker89e80c92012-03-20 13:50:09 +0000310}
Paul Bakker33b43f12013-08-20 11:48:36 +0200311/* END_CASE */
Paul Bakker89e80c92012-03-20 13:50:09 +0000312
Mateusz Starzykfc606222021-06-16 11:04:07 +0200313/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100314void gcm_decrypt_and_verify_empty_cipher(int cipher_id,
315 data_t *key_str,
316 data_t *iv_str,
317 data_t *add_str,
318 data_t *tag_str,
319 int cipher_update_calls)
Mateusz Starzykfc606222021-06-16 11:04:07 +0200320{
321 mbedtls_gcm_context ctx;
322
Valerio Setti10e9aa22023-12-12 11:54:20 +0100323 BLOCK_CIPHER_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 mbedtls_gcm_init(&ctx);
Mateusz Starzykfc606222021-06-16 11:04:07 +0200325
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
327 check_empty_cipher_with_ad(&ctx, MBEDTLS_GCM_DECRYPT,
328 iv_str, add_str, tag_str,
329 cipher_update_calls);
Mateusz Starzykfc606222021-06-16 11:04:07 +0200330
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 mbedtls_gcm_free(&ctx);
Valerio Setti10e9aa22023-12-12 11:54:20 +0100332 BLOCK_CIPHER_PSA_DONE();
Mateusz Starzykfc606222021-06-16 11:04:07 +0200333}
334/* END_CASE */
335
336/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100337void gcm_decrypt_and_verify_empty_ad(int cipher_id,
338 data_t *key_str,
339 data_t *iv_str,
340 data_t *src_str,
341 data_t *tag_str,
342 data_t *pt_result,
343 int ad_update_calls)
Mateusz Starzykfc606222021-06-16 11:04:07 +0200344{
345 mbedtls_gcm_context ctx;
346
Valerio Setti10e9aa22023-12-12 11:54:20 +0100347 BLOCK_CIPHER_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 mbedtls_gcm_init(&ctx);
Mateusz Starzykfc606222021-06-16 11:04:07 +0200349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
351 check_cipher_with_empty_ad(&ctx, MBEDTLS_GCM_DECRYPT,
352 iv_str, src_str, pt_result, tag_str,
353 ad_update_calls);
Mateusz Starzykfc606222021-06-16 11:04:07 +0200354
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 mbedtls_gcm_free(&ctx);
Valerio Setti10e9aa22023-12-12 11:54:20 +0100356 BLOCK_CIPHER_PSA_DONE();
Mateusz Starzykfc606222021-06-16 11:04:07 +0200357}
358/* END_CASE */
359
360/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100361void gcm_decrypt_and_verify_no_ad_no_cipher(int cipher_id,
362 data_t *key_str,
363 data_t *iv_str,
364 data_t *tag_str)
Mateusz Starzyk469c9f32021-06-18 00:06:52 +0200365{
366 mbedtls_gcm_context ctx;
367
Valerio Setti10e9aa22023-12-12 11:54:20 +0100368 BLOCK_CIPHER_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 mbedtls_gcm_init(&ctx);
Mateusz Starzyk469c9f32021-06-18 00:06:52 +0200370
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
372 check_no_cipher_no_ad(&ctx, MBEDTLS_GCM_DECRYPT,
373 iv_str, tag_str);
Mateusz Starzyk469c9f32021-06-18 00:06:52 +0200374
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 mbedtls_gcm_free(&ctx);
Valerio Setti10e9aa22023-12-12 11:54:20 +0100376 BLOCK_CIPHER_PSA_DONE();
Mateusz Starzyk469c9f32021-06-18 00:06:52 +0200377}
378/* END_CASE */
379
380/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100381void gcm_encrypt_and_tag_empty_cipher(int cipher_id,
382 data_t *key_str,
383 data_t *iv_str,
384 data_t *add_str,
385 data_t *tag_str,
386 int cipher_update_calls)
Mateusz Starzykfc606222021-06-16 11:04:07 +0200387{
388 mbedtls_gcm_context ctx;
389
Valerio Setti10e9aa22023-12-12 11:54:20 +0100390 BLOCK_CIPHER_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 mbedtls_gcm_init(&ctx);
Mateusz Starzykfc606222021-06-16 11:04:07 +0200392
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
394 check_empty_cipher_with_ad(&ctx, MBEDTLS_GCM_ENCRYPT,
395 iv_str, add_str, tag_str,
396 cipher_update_calls);
Mateusz Starzykfc606222021-06-16 11:04:07 +0200397
398exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 mbedtls_gcm_free(&ctx);
Valerio Setti10e9aa22023-12-12 11:54:20 +0100400 BLOCK_CIPHER_PSA_DONE();
Mateusz Starzykfc606222021-06-16 11:04:07 +0200401}
402/* END_CASE */
403
404/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100405void gcm_encrypt_and_tag_empty_ad(int cipher_id,
406 data_t *key_str,
407 data_t *iv_str,
408 data_t *src_str,
409 data_t *dst,
410 data_t *tag_str,
411 int ad_update_calls)
Mateusz Starzykfc606222021-06-16 11:04:07 +0200412{
413 mbedtls_gcm_context ctx;
414
Valerio Setti10e9aa22023-12-12 11:54:20 +0100415 BLOCK_CIPHER_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 mbedtls_gcm_init(&ctx);
Mateusz Starzykfc606222021-06-16 11:04:07 +0200417
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
419 check_cipher_with_empty_ad(&ctx, MBEDTLS_GCM_ENCRYPT,
420 iv_str, src_str, dst, tag_str,
421 ad_update_calls);
Mateusz Starzykfc606222021-06-16 11:04:07 +0200422
423exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 mbedtls_gcm_free(&ctx);
Valerio Setti10e9aa22023-12-12 11:54:20 +0100425 BLOCK_CIPHER_PSA_DONE();
Mateusz Starzykfc606222021-06-16 11:04:07 +0200426}
427/* END_CASE */
428
Mateusz Starzyk469c9f32021-06-18 00:06:52 +0200429/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100430void gcm_encrypt_and_verify_no_ad_no_cipher(int cipher_id,
431 data_t *key_str,
432 data_t *iv_str,
433 data_t *tag_str)
Mateusz Starzyk469c9f32021-06-18 00:06:52 +0200434{
435 mbedtls_gcm_context ctx;
436
Valerio Setti10e9aa22023-12-12 11:54:20 +0100437 BLOCK_CIPHER_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 mbedtls_gcm_init(&ctx);
Mateusz Starzyk469c9f32021-06-18 00:06:52 +0200439
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == 0);
441 check_no_cipher_no_ad(&ctx, MBEDTLS_GCM_ENCRYPT,
442 iv_str, tag_str);
Mateusz Starzyk469c9f32021-06-18 00:06:52 +0200443
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 mbedtls_gcm_free(&ctx);
Valerio Setti10e9aa22023-12-12 11:54:20 +0100445 BLOCK_CIPHER_PSA_DONE();
Mateusz Starzyk469c9f32021-06-18 00:06:52 +0200446}
447/* END_CASE */
448
Tuvshinzaya Erdenekhuu104eb7f2022-07-29 14:48:21 +0100449/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100450void gcm_invalid_param()
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500451{
452 mbedtls_gcm_context ctx;
453 unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
454 mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES;
Ronald Cron875b5fb2021-05-21 08:50:00 +0200455 int invalid_bitlen = 1;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500456
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 mbedtls_gcm_init(&ctx);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500458
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500459 /* mbedtls_gcm_setkey */
Ronald Cron875b5fb2021-05-21 08:50:00 +0200460 TEST_EQUAL(
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500461 MBEDTLS_ERR_GCM_BAD_INPUT,
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 mbedtls_gcm_setkey(&ctx, valid_cipher, valid_buffer, invalid_bitlen));
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500463
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500464exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 mbedtls_gcm_free(&ctx);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500466}
467/* END_CASE */
468
Mateusz Starzykc48f43b2021-10-04 13:46:38 +0200469/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100470void gcm_update_output_buffer_too_small(int cipher_id, int mode,
471 data_t *key_str, const data_t *input,
472 const data_t *iv)
Mateusz Starzykc48f43b2021-10-04 13:46:38 +0200473{
474 mbedtls_gcm_context ctx;
475 uint8_t *output = NULL;
Mateusz Starzyk33d01ff2021-10-21 14:55:59 +0200476 size_t olen = 0;
Mateusz Starzykc48f43b2021-10-04 13:46:38 +0200477 size_t output_len = input->len - 1;
478
Valerio Setti10e9aa22023-12-12 11:54:20 +0100479 BLOCK_CIPHER_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 mbedtls_gcm_init(&ctx);
481 TEST_EQUAL(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8), 0);
482 TEST_EQUAL(0, mbedtls_gcm_starts(&ctx, mode, iv->x, iv->len));
Mateusz Starzykc48f43b2021-10-04 13:46:38 +0200483
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100484 TEST_CALLOC(output, output_len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 TEST_EQUAL(MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL,
486 mbedtls_gcm_update(&ctx, input->x, input->len, output, output_len, &olen));
Mateusz Starzykc48f43b2021-10-04 13:46:38 +0200487
488exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 mbedtls_free(output);
490 mbedtls_gcm_free(&ctx);
Valerio Setti10e9aa22023-12-12 11:54:20 +0100491 BLOCK_CIPHER_PSA_DONE();
Mateusz Starzykc48f43b2021-10-04 13:46:38 +0200492}
493/* END_CASE */
494
Chien Wong99ff1f52024-01-24 20:44:01 +0800495/* BEGIN_CASE */
Chien Wong92c17c42024-01-25 19:11:03 +0800496/* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of IV should
497 * satisfy 1 <= bit_len(IV) <= 2^64 - 1. */
Chien Wong99ff1f52024-01-24 20:44:01 +0800498void gcm_invalid_iv_len(void)
499{
500 mbedtls_gcm_context ctx;
501 uint8_t b16[16] = { 0 };
502
Chien Wong92c17c42024-01-25 19:11:03 +0800503 // Invalid IV length 0
Chien Wong99ff1f52024-01-24 20:44:01 +0800504 gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, 0, MBEDTLS_ERR_GCM_BAD_INPUT);
505 mbedtls_gcm_free(&ctx);
506
Chien Wong92c17c42024-01-25 19:11:03 +0800507 // Only testable on platforms where sizeof(size_t) >= 8.
Chien Wong99ff1f52024-01-24 20:44:01 +0800508#if SIZE_MAX >= UINT64_MAX
Chien Wong92c17c42024-01-25 19:11:03 +0800509 // Invalid IV length 2^61
Chien Wong99ff1f52024-01-24 20:44:01 +0800510 gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, 1ULL << 61, MBEDTLS_ERR_GCM_BAD_INPUT);
511 mbedtls_gcm_free(&ctx);
512#endif
513
514 goto exit; /* To suppress error that exit is defined but not used */
515exit:
516 /* empty */
517}
518/* END_CASE */
519
520/* BEGIN_CASE */
Chien Wong99ff1f52024-01-24 20:44:01 +0800521void gcm_add_len_too_long(void)
522{
Chien Wong92c17c42024-01-25 19:11:03 +0800523 // Only testable on platforms where sizeof(size_t) >= 8.
Chien Wong99ff1f52024-01-24 20:44:01 +0800524#if SIZE_MAX >= UINT64_MAX
525 mbedtls_gcm_context ctx;
526 uint8_t b16[16] = { 0 };
Chien Wong92c17c42024-01-25 19:11:03 +0800527 /* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of AD should
528 * be <= 2^64 - 1, ie < 2^64. This is the minimum invalid length in bytes. */
529 uint64_t len_max = 1ULL << 61;
Chien Wong99ff1f52024-01-24 20:44:01 +0800530
531 gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0);
Chien Wong92c17c42024-01-25 19:11:03 +0800532 // Feed AD that just exceeds the length limit
533 TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, len_max),
Chien Wong99ff1f52024-01-24 20:44:01 +0800534 MBEDTLS_ERR_GCM_BAD_INPUT);
535 mbedtls_gcm_free(&ctx);
536
537 gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0);
Chien Wong92c17c42024-01-25 19:11:03 +0800538 // Feed AD that just exceeds the length limit in two calls
Chien Wong99ff1f52024-01-24 20:44:01 +0800539 TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, 1), 0);
Chien Wong92c17c42024-01-25 19:11:03 +0800540 TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, len_max - 1),
Chien Wong99ff1f52024-01-24 20:44:01 +0800541 MBEDTLS_ERR_GCM_BAD_INPUT);
542 mbedtls_gcm_free(&ctx);
543
544 gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0);
Chien Wong92c17c42024-01-25 19:11:03 +0800545 // Test if potential total AD length overflow is handled properly
Chien Wong99ff1f52024-01-24 20:44:01 +0800546 TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, 1), 0);
547 TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, UINT64_MAX), MBEDTLS_ERR_GCM_BAD_INPUT);
548
549exit:
550 mbedtls_gcm_free(&ctx);
551#endif
552}
553/* END_CASE */
554
555/* BEGIN_CASE */
Chien Wong99ff1f52024-01-24 20:44:01 +0800556void gcm_input_len_too_long(void)
557{
Chien Wong92c17c42024-01-25 19:11:03 +0800558 // Only testable on platforms where sizeof(size_t) >= 8
Chien Wong99ff1f52024-01-24 20:44:01 +0800559#if SIZE_MAX >= UINT64_MAX
560 mbedtls_gcm_context ctx;
561 uint8_t b16[16] = { 0 };
Chien Wong92c17c42024-01-25 19:11:03 +0800562 uint8_t out[1];
Chien Wong99ff1f52024-01-24 20:44:01 +0800563 size_t out_len;
Chien Wong92c17c42024-01-25 19:11:03 +0800564 /* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of input should
565 * be <= 2^39 - 256. This is the maximum valid length in bytes. */
Chien Wong99ff1f52024-01-24 20:44:01 +0800566 uint64_t len_max = (1ULL << 36) - 32;
567
568 gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0);
Chien Wong92c17c42024-01-25 19:11:03 +0800569 // Feed input that just exceeds the length limit
570 TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, len_max + 1, out, len_max + 1,
Chien Wong99ff1f52024-01-24 20:44:01 +0800571 &out_len),
572 MBEDTLS_ERR_GCM_BAD_INPUT);
573 mbedtls_gcm_free(&ctx);
574
575 gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0);
Chien Wong92c17c42024-01-25 19:11:03 +0800576 // Feed input that just exceeds the length limit in two calls
577 TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, 1, out, 1, &out_len), 0);
Chien Wongef567952024-01-25 19:22:50 +0800578 TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, len_max, out, len_max, &out_len),
Chien Wong99ff1f52024-01-24 20:44:01 +0800579 MBEDTLS_ERR_GCM_BAD_INPUT);
580 mbedtls_gcm_free(&ctx);
581
582 gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0);
Chien Wong92c17c42024-01-25 19:11:03 +0800583 // Test if potential total input length overflow is handled properly
584 TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, 1, out, 1, &out_len), 0);
585 TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, UINT64_MAX, out, UINT64_MAX,
Chien Wong99ff1f52024-01-24 20:44:01 +0800586 &out_len),
587 MBEDTLS_ERR_GCM_BAD_INPUT);
588
589exit:
590 mbedtls_gcm_free(&ctx);
591#endif
592}
593/* END_CASE */
594
Valerio Setti689c0f72023-12-20 09:53:39 +0100595/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST:MBEDTLS_CCM_GCM_CAN_AES */
Gilles Peskine449bd832023-01-11 14:50:10 +0100596void gcm_selftest()
Paul Bakker89e80c92012-03-20 13:50:09 +0000597{
Valerio Setti10e9aa22023-12-12 11:54:20 +0100598 BLOCK_CIPHER_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 TEST_ASSERT(mbedtls_gcm_self_test(1) == 0);
Valerio Setti10e9aa22023-12-12 11:54:20 +0100600 BLOCK_CIPHER_PSA_DONE();
Paul Bakker89e80c92012-03-20 13:50:09 +0000601}
Paul Bakker33b43f12013-08-20 11:48:36 +0200602/* END_CASE */