blob: 610f2ba467f8cd708f7c39b95c55c7f9794f9647 [file] [log] [blame]
Manuel Pégourié-Gonnarda6916fa2014-05-02 15:17:29 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/ccm.h"
Mateusz Starzyk25a3dfe2021-07-12 14:53:45 +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_ccm_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)
Mateusz Starzyk25a3dfe2021-07-12 14:53:45 +020016{
17 int ok = 0;
18 uint8_t *output = NULL;
19 size_t n2 = input->len - n1;
20 size_t n2_add = add->len - n1_add;
21 size_t olen;
22
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);
27 TEST_EQUAL(0, mbedtls_ccm_starts(ctx, mode, iv->x, iv->len));
28 TEST_EQUAL(0, mbedtls_ccm_set_lengths(ctx, add->len, input->len, tag->len));
29 TEST_EQUAL(0, mbedtls_ccm_update_ad(ctx, add->x, n1_add));
30 TEST_EQUAL(0, mbedtls_ccm_update_ad(ctx, add->x + n1_add, n2_add));
Mateusz Starzyk25a3dfe2021-07-12 14:53:45 +020031
32 /* Allocate a tight buffer for each update call. This way, if the function
33 * tries to write beyond the advertised required buffer size, this will
34 * count as an overflow for memory sanitizers and static checkers. */
Tom Cosgrovef9ffd112023-07-20 16:48:18 +010035 TEST_CALLOC_OR_FAIL(output, n1);
Mateusz Starzyk25a3dfe2021-07-12 14:53:45 +020036 olen = 0xdeadbeef;
Gilles Peskine449bd832023-01-11 14:50:10 +010037 TEST_EQUAL(0, mbedtls_ccm_update(ctx, input->x, n1, output, n1, &olen));
38 TEST_EQUAL(n1, olen);
Tom Cosgrove65cd8512023-07-20 16:46:01 +010039 TEST_BUFFERS_EQUAL(output, olen, expected_output->x, n1);
Gilles Peskine449bd832023-01-11 14:50:10 +010040 mbedtls_free(output);
Mateusz Starzyk25a3dfe2021-07-12 14:53:45 +020041 output = NULL;
42
Tom Cosgrovef9ffd112023-07-20 16:48:18 +010043 TEST_CALLOC_OR_FAIL(output, n2);
Mateusz Starzyk25a3dfe2021-07-12 14:53:45 +020044 olen = 0xdeadbeef;
Gilles Peskine449bd832023-01-11 14:50:10 +010045 TEST_EQUAL(0, mbedtls_ccm_update(ctx, input->x + n1, n2, output, n2, &olen));
46 TEST_EQUAL(n2, olen);
Tom Cosgrove65cd8512023-07-20 16:46:01 +010047 TEST_BUFFERS_EQUAL(output, olen, expected_output->x + n1, n2);
Gilles Peskine449bd832023-01-11 14:50:10 +010048 mbedtls_free(output);
Mateusz Starzyk25a3dfe2021-07-12 14:53:45 +020049 output = NULL;
50
Tom Cosgrovef9ffd112023-07-20 16:48:18 +010051 TEST_CALLOC_OR_FAIL(output, tag->len);
Gilles Peskine449bd832023-01-11 14:50:10 +010052 TEST_EQUAL(0, mbedtls_ccm_finish(ctx, output, tag->len));
Tom Cosgrove65cd8512023-07-20 16:46:01 +010053 TEST_BUFFERS_EQUAL(output, tag->len, tag->x, tag->len);
Gilles Peskine449bd832023-01-11 14:50:10 +010054 mbedtls_free(output);
Mateusz Starzyk25a3dfe2021-07-12 14:53:45 +020055 output = NULL;
56
57 ok = 1;
58exit:
Gilles Peskine449bd832023-01-11 14:50:10 +010059 mbedtls_free(output);
60 return ok;
Mateusz Starzyk25a3dfe2021-07-12 14:53:45 +020061}
Manuel Pégourié-Gonnarda6916fa2014-05-02 15:17:29 +020062/* END_HEADER */
63
64/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065 * depends_on:MBEDTLS_CCM_C
Manuel Pégourié-Gonnarda6916fa2014-05-02 15:17:29 +020066 * END_DEPENDENCIES
67 */
68
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST:MBEDTLS_AES_C */
Gilles Peskine449bd832023-01-11 14:50:10 +010070void mbedtls_ccm_self_test()
Manuel Pégourié-Gonnarda6916fa2014-05-02 15:17:29 +020071{
Gilles Peskine449bd832023-01-11 14:50:10 +010072 TEST_ASSERT(mbedtls_ccm_self_test(1) == 0);
Manuel Pégourié-Gonnarda6916fa2014-05-02 15:17:29 +020073}
74/* END_CASE */
Manuel Pégourié-Gonnard9fe0d132014-05-06 12:12:45 +020075
76/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +010077void mbedtls_ccm_setkey(int cipher_id, int key_size, int result)
Manuel Pégourié-Gonnard9fe0d132014-05-06 12:12:45 +020078{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079 mbedtls_ccm_context ctx;
Manuel Pégourié-Gonnard9fe0d132014-05-06 12:12:45 +020080 unsigned char key[32];
81 int ret;
82
Gilles Peskine449bd832023-01-11 14:50:10 +010083 mbedtls_ccm_init(&ctx);
Manuel Pégourié-Gonnard6963ff02015-04-28 18:02:54 +020084
Gilles Peskine449bd832023-01-11 14:50:10 +010085 memset(key, 0x2A, sizeof(key));
86 TEST_ASSERT((unsigned) key_size <= 8 * sizeof(key));
Manuel Pégourié-Gonnard9fe0d132014-05-06 12:12:45 +020087
Gilles Peskine449bd832023-01-11 14:50:10 +010088 ret = mbedtls_ccm_setkey(&ctx, cipher_id, key, key_size);
89 TEST_ASSERT(ret == result);
Manuel Pégourié-Gonnard9fe0d132014-05-06 12:12:45 +020090
Paul Bakkerbd51b262014-07-10 15:26:12 +020091exit:
Gilles Peskine449bd832023-01-11 14:50:10 +010092 mbedtls_ccm_free(&ctx);
Manuel Pégourié-Gonnard9fe0d132014-05-06 12:12:45 +020093}
94/* END_CASE */
Manuel Pégourié-Gonnard637eb3d2014-05-06 12:13:09 +020095
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020096/* BEGIN_CASE depends_on:MBEDTLS_AES_C */
Gilles Peskine449bd832023-01-11 14:50:10 +010097void ccm_lengths(int msg_len, int iv_len, int add_len, int tag_len, int res)
Manuel Pégourié-Gonnard87df5ba2014-05-06 18:07:24 +020098{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099 mbedtls_ccm_context ctx;
Manuel Pégourié-Gonnard87df5ba2014-05-06 18:07:24 +0200100 unsigned char key[16];
101 unsigned char msg[10];
102 unsigned char iv[14];
Dave Rodgman2e680342020-10-15 14:00:40 +0100103 unsigned char *add = NULL;
Manuel Pégourié-Gonnard87df5ba2014-05-06 18:07:24 +0200104 unsigned char out[10];
105 unsigned char tag[18];
106 int decrypt_ret;
107
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 mbedtls_ccm_init(&ctx);
Manuel Pégourié-Gonnard6963ff02015-04-28 18:02:54 +0200109
Tom Cosgrove412a8132023-07-20 16:55:14 +0100110 TEST_CALLOC_OR_SKIP(add, add_len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100111 memset(key, 0, sizeof(key));
112 memset(msg, 0, sizeof(msg));
113 memset(iv, 0, sizeof(iv));
114 memset(out, 0, sizeof(out));
115 memset(tag, 0, sizeof(tag));
Manuel Pégourié-Gonnard87df5ba2014-05-06 18:07:24 +0200116
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 TEST_ASSERT(mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
118 key, 8 * sizeof(key)) == 0);
Manuel Pégourié-Gonnard87df5ba2014-05-06 18:07:24 +0200119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 TEST_ASSERT(mbedtls_ccm_encrypt_and_tag(&ctx, msg_len, iv, iv_len, add, add_len,
121 msg, out, tag, tag_len) == res);
Manuel Pégourié-Gonnard87df5ba2014-05-06 18:07:24 +0200122
Gilles Peskine449bd832023-01-11 14:50:10 +0100123 decrypt_ret = mbedtls_ccm_auth_decrypt(&ctx, msg_len, iv, iv_len, add, add_len,
124 msg, out, tag, tag_len);
Manuel Pégourié-Gonnard87df5ba2014-05-06 18:07:24 +0200125
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 if (res == 0) {
127 TEST_ASSERT(decrypt_ret == MBEDTLS_ERR_CCM_AUTH_FAILED);
128 } else {
129 TEST_ASSERT(decrypt_ret == res);
130 }
Manuel Pégourié-Gonnard87df5ba2014-05-06 18:07:24 +0200131
Paul Bakkerbd51b262014-07-10 15:26:12 +0200132exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 mbedtls_free(add);
134 mbedtls_ccm_free(&ctx);
Manuel Pégourié-Gonnard87df5ba2014-05-06 18:07:24 +0200135}
136/* END_CASE */
137
Janos Follath95ab93d2018-05-14 14:32:41 +0100138/* BEGIN_CASE depends_on:MBEDTLS_AES_C */
Gilles Peskine449bd832023-01-11 14:50:10 +0100139void ccm_star_lengths(int msg_len, int iv_len, int add_len, int tag_len,
140 int res)
Janos Follath95ab93d2018-05-14 14:32:41 +0100141{
142 mbedtls_ccm_context ctx;
143 unsigned char key[16];
144 unsigned char msg[10];
145 unsigned char iv[14];
146 unsigned char add[10];
147 unsigned char out[10];
148 unsigned char tag[18];
149 int decrypt_ret;
150
Gilles Peskine449bd832023-01-11 14:50:10 +0100151 mbedtls_ccm_init(&ctx);
Janos Follath95ab93d2018-05-14 14:32:41 +0100152
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 memset(key, 0, sizeof(key));
154 memset(msg, 0, sizeof(msg));
155 memset(iv, 0, sizeof(iv));
156 memset(add, 0, sizeof(add));
157 memset(out, 0, sizeof(out));
158 memset(tag, 0, sizeof(tag));
Janos Follath95ab93d2018-05-14 14:32:41 +0100159
Gilles Peskine449bd832023-01-11 14:50:10 +0100160 TEST_ASSERT(mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
161 key, 8 * sizeof(key)) == 0);
Janos Follath95ab93d2018-05-14 14:32:41 +0100162
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 TEST_ASSERT(mbedtls_ccm_star_encrypt_and_tag(&ctx, msg_len, iv, iv_len,
164 add, add_len, msg, out, tag, tag_len) == res);
Janos Follath95ab93d2018-05-14 14:32:41 +0100165
Gilles Peskine449bd832023-01-11 14:50:10 +0100166 decrypt_ret = mbedtls_ccm_star_auth_decrypt(&ctx, msg_len, iv, iv_len, add,
167 add_len, msg, out, tag, tag_len);
Janos Follath95ab93d2018-05-14 14:32:41 +0100168
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 if (res == 0 && tag_len != 0) {
170 TEST_ASSERT(decrypt_ret == MBEDTLS_ERR_CCM_AUTH_FAILED);
171 } else {
172 TEST_ASSERT(decrypt_ret == res);
173 }
Janos Follath95ab93d2018-05-14 14:32:41 +0100174
175exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100176 mbedtls_ccm_free(&ctx);
Janos Follath95ab93d2018-05-14 14:32:41 +0100177}
178/* END_CASE */
179
Manuel Pégourié-Gonnard637eb3d2014-05-06 12:13:09 +0200180/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100181void mbedtls_ccm_encrypt_and_tag(int cipher_id, data_t *key,
182 data_t *msg, data_t *iv,
183 data_t *add, data_t *result)
Manuel Pégourié-Gonnard637eb3d2014-05-06 12:13:09 +0200184{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200185 mbedtls_ccm_context ctx;
Mateusz Starzyk25a3dfe2021-07-12 14:53:45 +0200186 size_t n1, n1_add;
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 uint8_t *io_msg_buf = NULL;
188 uint8_t *tag_buf = NULL;
Mateusz Starzyk27a1bef2021-07-13 15:33:19 +0200189 const size_t expected_tag_len = result->len - msg->len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 const uint8_t *expected_tag = result->x + msg->len;
Mateusz Starzyk27a1bef2021-07-13 15:33:19 +0200191
192 /* Prepare input/output message buffer */
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100193 TEST_CALLOC_OR_FAIL(io_msg_buf, msg->len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 if (msg->len != 0) {
195 memcpy(io_msg_buf, msg->x, msg->len);
196 }
Mateusz Starzyk27a1bef2021-07-13 15:33:19 +0200197
198 /* Prepare tag buffer */
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100199 TEST_CALLOC_OR_FAIL(tag_buf, expected_tag_len);
Manuel Pégourié-Gonnard637eb3d2014-05-06 12:13:09 +0200200
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 mbedtls_ccm_init(&ctx);
202 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
Manuel Pégourié-Gonnard0f6b66d2014-05-07 14:43:46 +0200203 /* Test with input == output */
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 TEST_EQUAL(mbedtls_ccm_encrypt_and_tag(&ctx, msg->len, iv->x, iv->len, add->x, add->len,
205 io_msg_buf, io_msg_buf, tag_buf, expected_tag_len), 0);
Manuel Pégourié-Gonnard637eb3d2014-05-06 12:13:09 +0200206
Tom Cosgrove65cd8512023-07-20 16:46:01 +0100207 TEST_BUFFERS_EQUAL(io_msg_buf, msg->len, result->x, msg->len);
208 TEST_BUFFERS_EQUAL(tag_buf, expected_tag_len, expected_tag, expected_tag_len);
Manuel Pégourié-Gonnard637eb3d2014-05-06 12:13:09 +0200209
Mateusz Starzykceb5bc62021-07-30 14:36:22 +0200210 /* Prepare data_t structures for multipart testing */
Mateusz Starzyk25a3dfe2021-07-12 14:53:45 +0200211 const data_t encrypted_expected = { .x = result->x,
212 .len = msg->len };
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 const data_t tag_expected = { .x = (uint8_t *) expected_tag, /* cast to conform with data_t x type */
Mateusz Starzyk27a1bef2021-07-13 15:33:19 +0200214 .len = expected_tag_len };
Mateusz Starzyk25a3dfe2021-07-12 14:53:45 +0200215
Gilles Peskine449bd832023-01-11 14:50:10 +0100216 for (n1 = 0; n1 <= msg->len; n1 += 1) {
217 for (n1_add = 0; n1_add <= add->len; n1_add += 1) {
218 mbedtls_test_set_step(n1 * 10000 + n1_add);
219 if (!check_multipart(&ctx, MBEDTLS_CCM_ENCRYPT,
220 iv, add, msg,
221 &encrypted_expected,
222 &tag_expected,
223 n1, n1_add)) {
Mateusz Starzyk25a3dfe2021-07-12 14:53:45 +0200224 goto exit;
Mateusz Starzyk29ec75b2021-07-13 12:26:17 +0200225 }
226 }
227 }
228
Darryl Green0daf4ca2018-05-29 14:12:26 +0100229exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 mbedtls_ccm_free(&ctx);
231 mbedtls_free(io_msg_buf);
232 mbedtls_free(tag_buf);
Darryl Green0daf4ca2018-05-29 14:12:26 +0100233}
234/* END_CASE */
235
236/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100237void mbedtls_ccm_star_no_tag(int cipher_id, int mode, data_t *key,
238 data_t *msg, data_t *iv, data_t *result)
239{
240 mbedtls_ccm_context ctx;
241 uint8_t *output = NULL;
242 size_t olen;
243
244 mbedtls_ccm_init(&ctx);
245 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
246 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
247 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, 0, msg->len, 0));
248
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100249 TEST_CALLOC_OR_FAIL(output, msg->len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 TEST_EQUAL(0, mbedtls_ccm_update(&ctx, msg->x, msg->len, output, msg->len, &olen));
251 TEST_EQUAL(result->len, olen);
Tom Cosgrove65cd8512023-07-20 16:46:01 +0100252 TEST_BUFFERS_EQUAL(output, olen, result->x, result->len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100253
254 TEST_EQUAL(0, mbedtls_ccm_finish(&ctx, NULL, 0));
255exit:
256 mbedtls_free(output);
257 mbedtls_ccm_free(&ctx);
258}
259/* END_CASE */
260
261/* BEGIN_CASE */
262void mbedtls_ccm_auth_decrypt(int cipher_id, data_t *key,
263 data_t *msg, data_t *iv,
264 data_t *add, int expected_tag_len, int result,
265 data_t *expected_msg)
266{
267 mbedtls_ccm_context ctx;
268 size_t n1, n1_add;
269
270 const size_t expected_msg_len = msg->len - expected_tag_len;
271 const uint8_t *expected_tag = msg->x + expected_msg_len;
272
273 /* Prepare input/output message buffer */
274 uint8_t *io_msg_buf = NULL;
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100275 TEST_CALLOC_OR_FAIL(io_msg_buf, expected_msg_len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 if (expected_msg_len) {
277 memcpy(io_msg_buf, msg->x, expected_msg_len);
278 }
279
280 mbedtls_ccm_init(&ctx);
281 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
282 /* Test with input == output */
283 TEST_EQUAL(mbedtls_ccm_auth_decrypt(&ctx, expected_msg_len, iv->x, iv->len, add->x, add->len,
284 io_msg_buf, io_msg_buf, expected_tag, expected_tag_len),
285 result);
286
287 if (result == 0) {
Tom Cosgrove65cd8512023-07-20 16:46:01 +0100288 TEST_BUFFERS_EQUAL(io_msg_buf, expected_msg_len, expected_msg->x, expected_msg_len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100289
290 /* Prepare data_t structures for multipart testing */
291 const data_t encrypted = { .x = msg->x,
292 .len = expected_msg_len };
293
294 const data_t tag_expected = { .x = (uint8_t *) expected_tag,
295 .len = expected_tag_len };
296
297 for (n1 = 0; n1 <= expected_msg_len; n1 += 1) {
298 for (n1_add = 0; n1_add <= add->len; n1_add += 1) {
299 mbedtls_test_set_step(n1 * 10000 + n1_add);
300 if (!check_multipart(&ctx, MBEDTLS_CCM_DECRYPT,
301 iv, add, &encrypted,
302 expected_msg,
303 &tag_expected,
304 n1, n1_add)) {
305 goto exit;
306 }
307 }
308 }
309 } else {
310 size_t i;
311
312 for (i = 0; i < expected_msg_len; i++) {
313 TEST_EQUAL(io_msg_buf[i], 0);
314 }
315 }
316
317exit:
318 mbedtls_free(io_msg_buf);
319 mbedtls_ccm_free(&ctx);
320}
321/* END_CASE */
322
323/* BEGIN_CASE */
324void mbedtls_ccm_star_encrypt_and_tag(int cipher_id,
325 data_t *key, data_t *msg,
326 data_t *source_address, data_t *frame_counter,
327 int sec_level, data_t *add,
328 data_t *expected_result, int output_ret)
329{
330 unsigned char iv[13];
331 mbedtls_ccm_context ctx;
332 size_t iv_len, expected_tag_len;
333 size_t n1, n1_add;
334 uint8_t *io_msg_buf = NULL;
335 uint8_t *tag_buf = NULL;
336
337 const uint8_t *expected_tag = expected_result->x + msg->len;
338
339 /* Calculate tag length */
340 if (sec_level % 4 == 0) {
341 expected_tag_len = 0;
342 } else {
343 expected_tag_len = 1 << (sec_level % 4 + 1);
344 }
345
346 /* Prepare input/output message buffer */
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100347 TEST_CALLOC_OR_FAIL(io_msg_buf, msg->len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 if (msg->len) {
349 memcpy(io_msg_buf, msg->x, msg->len);
350 }
351
352 /* Prepare tag buffer */
353 if (expected_tag_len == 0) {
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100354 TEST_CALLOC_OR_FAIL(tag_buf, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 } else {
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100356 TEST_CALLOC_OR_FAIL(tag_buf, expected_tag_len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 }
358
359 /* Calculate iv */
360 TEST_ASSERT(source_address->len == 8);
361 TEST_ASSERT(frame_counter->len == 4);
362 memcpy(iv, source_address->x, source_address->len);
363 memcpy(iv + source_address->len, frame_counter->x, frame_counter->len);
364 iv[source_address->len + frame_counter->len] = sec_level;
365 iv_len = sizeof(iv);
366
367 mbedtls_ccm_init(&ctx);
368 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id,
369 key->x, key->len * 8), 0);
370 /* Test with input == output */
371 TEST_EQUAL(mbedtls_ccm_star_encrypt_and_tag(&ctx, msg->len, iv, iv_len,
372 add->x, add->len, io_msg_buf,
373 io_msg_buf, tag_buf, expected_tag_len), output_ret);
374
Tom Cosgrove65cd8512023-07-20 16:46:01 +0100375 TEST_BUFFERS_EQUAL(io_msg_buf, msg->len, expected_result->x, msg->len);
376 TEST_BUFFERS_EQUAL(tag_buf, expected_tag_len, expected_tag, expected_tag_len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100377
378 if (output_ret == 0) {
379 const data_t iv_data = { .x = iv,
380 .len = iv_len };
381
382 const data_t encrypted_expected = { .x = expected_result->x,
383 .len = msg->len };
384 const data_t tag_expected = { .x = (uint8_t *) expected_tag,
385 .len = expected_tag_len };
386
387 for (n1 = 0; n1 <= msg->len; n1 += 1) {
388 for (n1_add = 0; n1_add <= add->len; n1_add += 1) {
389 mbedtls_test_set_step(n1 * 10000 + n1_add);
390 if (!check_multipart(&ctx, MBEDTLS_CCM_STAR_ENCRYPT,
391 &iv_data, add, msg,
392 &encrypted_expected,
393 &tag_expected,
394 n1, n1_add)) {
395 goto exit;
396 }
397 }
398 }
399 }
400
401exit:
402 mbedtls_ccm_free(&ctx);
403 mbedtls_free(io_msg_buf);
404 mbedtls_free(tag_buf);
405}
406/* END_CASE */
407
408/* BEGIN_CASE */
409void mbedtls_ccm_star_auth_decrypt(int cipher_id,
410 data_t *key, data_t *msg,
411 data_t *source_address, data_t *frame_counter,
412 int sec_level, data_t *add,
413 data_t *expected_result, int output_ret)
Darryl Green0daf4ca2018-05-29 14:12:26 +0100414{
Darryl Green0daf4ca2018-05-29 14:12:26 +0100415 unsigned char iv[13];
Darryl Green0daf4ca2018-05-29 14:12:26 +0100416 mbedtls_ccm_context ctx;
Mateusz Starzyk27a1bef2021-07-13 15:33:19 +0200417 size_t iv_len, expected_tag_len;
Mateusz Starzyk29ec75b2021-07-13 12:26:17 +0200418 size_t n1, n1_add;
Darryl Green0daf4ca2018-05-29 14:12:26 +0100419
Mateusz Starzyk27a1bef2021-07-13 15:33:19 +0200420 /* Calculate tag length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 if (sec_level % 4 == 0) {
Mateusz Starzyk27a1bef2021-07-13 15:33:19 +0200422 expected_tag_len = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 } else {
424 expected_tag_len = 1 << (sec_level % 4 + 1);
425 }
Darryl Green0daf4ca2018-05-29 14:12:26 +0100426
Mateusz Starzyk27a1bef2021-07-13 15:33:19 +0200427 const size_t expected_msg_len = msg->len - expected_tag_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 const uint8_t *expected_tag = msg->x + expected_msg_len;
Mateusz Starzyk27a1bef2021-07-13 15:33:19 +0200429
430 /* Prepare input/output message buffer */
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 uint8_t *io_msg_buf = NULL;
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100432 TEST_CALLOC_OR_FAIL(io_msg_buf, expected_msg_len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 if (expected_msg_len) {
434 memcpy(io_msg_buf, msg->x, expected_msg_len);
435 }
Mateusz Starzyk27a1bef2021-07-13 15:33:19 +0200436
437 /* Calculate iv */
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 memset(iv, 0x00, sizeof(iv));
439 TEST_ASSERT(source_address->len == 8);
440 TEST_ASSERT(frame_counter->len == 4);
441 memcpy(iv, source_address->x, source_address->len);
442 memcpy(iv + source_address->len, frame_counter->x, frame_counter->len);
Ronald Cron9ed40732020-06-25 09:03:34 +0200443 iv[source_address->len + frame_counter->len] = sec_level;
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 iv_len = sizeof(iv);
Darryl Green0daf4ca2018-05-29 14:12:26 +0100445
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 mbedtls_ccm_init(&ctx);
447 TEST_ASSERT(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8) == 0);
Mateusz Starzyk27a1bef2021-07-13 15:33:19 +0200448 /* Test with input == output */
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 TEST_EQUAL(mbedtls_ccm_star_auth_decrypt(&ctx, expected_msg_len, iv, iv_len,
450 add->x, add->len, io_msg_buf, io_msg_buf,
451 expected_tag, expected_tag_len), output_ret);
Darryl Green0daf4ca2018-05-29 14:12:26 +0100452
Tom Cosgrove65cd8512023-07-20 16:46:01 +0100453 TEST_BUFFERS_EQUAL(io_msg_buf, expected_msg_len, expected_result->x, expected_msg_len);
Darryl Green0daf4ca2018-05-29 14:12:26 +0100454
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 if (output_ret == 0) {
Mateusz Starzyk29ec75b2021-07-13 12:26:17 +0200456 const data_t iv_data = { .x = iv,
457 .len = iv_len };
458
Mateusz Starzyk27a1bef2021-07-13 15:33:19 +0200459 const data_t encrypted = { .x = msg->x,
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 .len = expected_msg_len };
Mateusz Starzyk29ec75b2021-07-13 12:26:17 +0200461
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 const data_t tag_expected = { .x = (uint8_t *) expected_tag,
Mateusz Starzyk27a1bef2021-07-13 15:33:19 +0200463 .len = expected_tag_len };
464
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 for (n1 = 0; n1 <= expected_msg_len; n1 += 1) {
466 for (n1_add = 0; n1_add <= add->len; n1_add += 1) {
467 mbedtls_test_set_step(n1 * 10000 + n1_add);
468 if (!check_multipart(&ctx, MBEDTLS_CCM_STAR_DECRYPT,
469 &iv_data, add, &encrypted,
470 expected_result,
471 &tag_expected,
472 n1, n1_add)) {
Mateusz Starzyk29ec75b2021-07-13 12:26:17 +0200473 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 }
475 }
Mateusz Starzyk29ec75b2021-07-13 12:26:17 +0200476 }
477 }
478
Darryl Green0daf4ca2018-05-29 14:12:26 +0100479exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 mbedtls_ccm_free(&ctx);
481 mbedtls_free(io_msg_buf);
Darryl Green0daf4ca2018-05-29 14:12:26 +0100482}
483/* END_CASE */
Mateusz Starzyk87889062021-07-29 14:08:18 +0200484
Mateusz Starzyk8fb17542021-08-10 13:45:19 +0200485/* Skip auth data, provide full text */
Mateusz Starzyk87889062021-07-29 14:08:18 +0200486/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100487void mbedtls_ccm_skip_ad(int cipher_id, int mode,
488 data_t *key, data_t *msg, data_t *iv,
489 data_t *result, data_t *tag)
Mateusz Starzyk87889062021-07-29 14:08:18 +0200490{
491 mbedtls_ccm_context ctx;
492 uint8_t *output = NULL;
493 size_t olen;
494
495 /* Sanity checks on the test data */
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 TEST_EQUAL(msg->len, result->len);
Mateusz Starzyk87889062021-07-29 14:08:18 +0200497
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 mbedtls_ccm_init(&ctx);
499 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
500 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
501 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, 0, msg->len, tag->len));
Mateusz Starzyk87889062021-07-29 14:08:18 +0200502
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100503 TEST_CALLOC_OR_FAIL(output, result->len);
Mateusz Starzyk87889062021-07-29 14:08:18 +0200504 olen = 0xdeadbeef;
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 TEST_EQUAL(0, mbedtls_ccm_update(&ctx, msg->x, msg->len, output, result->len, &olen));
506 TEST_EQUAL(result->len, olen);
Tom Cosgrove65cd8512023-07-20 16:46:01 +0100507 TEST_BUFFERS_EQUAL(output, olen, result->x, result->len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 mbedtls_free(output);
Mateusz Starzyk87889062021-07-29 14:08:18 +0200509 output = NULL;
510
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100511 TEST_CALLOC_OR_FAIL(output, tag->len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 TEST_EQUAL(0, mbedtls_ccm_finish(&ctx, output, tag->len));
Tom Cosgrove65cd8512023-07-20 16:46:01 +0100513 TEST_BUFFERS_EQUAL(output, tag->len, tag->x, tag->len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 mbedtls_free(output);
Mateusz Starzyk87889062021-07-29 14:08:18 +0200515 output = NULL;
516
517exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 mbedtls_free(output);
519 mbedtls_ccm_free(&ctx);
Mateusz Starzyk87889062021-07-29 14:08:18 +0200520}
521/* END_CASE */
522
Mateusz Starzyk8fb17542021-08-10 13:45:19 +0200523/* Provide auth data, skip full text */
Mateusz Starzyk87889062021-07-29 14:08:18 +0200524/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100525void mbedtls_ccm_skip_update(int cipher_id, int mode,
526 data_t *key, data_t *iv, data_t *add,
527 data_t *tag)
Mateusz Starzyk87889062021-07-29 14:08:18 +0200528{
529 mbedtls_ccm_context ctx;
530 uint8_t *output = NULL;
531
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 mbedtls_ccm_init(&ctx);
533 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
534 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
535 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, 0, tag->len));
Mateusz Starzyk87889062021-07-29 14:08:18 +0200536
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
Mateusz Starzyk87889062021-07-29 14:08:18 +0200538
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100539 TEST_CALLOC_OR_FAIL(output, tag->len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 TEST_EQUAL(0, mbedtls_ccm_finish(&ctx, output, tag->len));
Tom Cosgrove65cd8512023-07-20 16:46:01 +0100541 TEST_BUFFERS_EQUAL(output, tag->len, tag->x, tag->len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 mbedtls_free(output);
Mateusz Starzyk87889062021-07-29 14:08:18 +0200543 output = NULL;
544
545exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 mbedtls_free(output);
547 mbedtls_ccm_free(&ctx);
Mateusz Starzyk87889062021-07-29 14:08:18 +0200548}
549/* END_CASE */
550
Mateusz Starzyk8fb17542021-08-10 13:45:19 +0200551/* Provide too much auth data */
Mateusz Starzyk87889062021-07-29 14:08:18 +0200552/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100553void mbedtls_ccm_overflow_ad(int cipher_id, int mode,
554 data_t *key, data_t *iv,
555 data_t *add)
Mateusz Starzyk87889062021-07-29 14:08:18 +0200556{
557 mbedtls_ccm_context ctx;
558
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 mbedtls_ccm_init(&ctx);
560 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
561 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
Mateusz Starzyk87889062021-07-29 14:08:18 +0200562 // use hardcoded values for msg length and tag length. They are not a part of this test
Mateusz Starzyk3050f052021-09-02 12:38:51 +0200563 // subtract 1 from configured auth data length to provoke an overflow
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len - 1, 16, 16));
Mateusz Starzyk87889062021-07-29 14:08:18 +0200565
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
Mateusz Starzyk87889062021-07-29 14:08:18 +0200567exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 mbedtls_ccm_free(&ctx);
Mateusz Starzyk87889062021-07-29 14:08:18 +0200569}
570/* END_CASE */
571
Mateusz Starzyk83e4c122021-09-03 14:07:21 +0200572/* Provide unexpected auth data */
573/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100574void mbedtls_ccm_unexpected_ad(int cipher_id, int mode,
575 data_t *key, data_t *iv,
576 data_t *add)
Mateusz Starzyk83e4c122021-09-03 14:07:21 +0200577{
578 mbedtls_ccm_context ctx;
579
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 mbedtls_ccm_init(&ctx);
581 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
582 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
Mateusz Starzyk83e4c122021-09-03 14:07:21 +0200583 // use hardcoded values for msg length and tag length. They are not a part of this test
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, 0, 16, 16));
Mateusz Starzyk83e4c122021-09-03 14:07:21 +0200585
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
Mateusz Starzyk83e4c122021-09-03 14:07:21 +0200587exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 mbedtls_ccm_free(&ctx);
Mateusz Starzyk83e4c122021-09-03 14:07:21 +0200589}
590/* END_CASE */
591
592/* Provide unexpected plaintext/ciphertext data */
593/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100594void mbedtls_ccm_unexpected_text(int cipher_id, int mode,
595 data_t *key, data_t *msg, data_t *iv,
596 data_t *add)
Mateusz Starzyk83e4c122021-09-03 14:07:21 +0200597{
598 mbedtls_ccm_context ctx;
599 uint8_t *output = NULL;
600 size_t olen;
601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 mbedtls_ccm_init(&ctx);
603 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
604 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
Mateusz Starzyk83e4c122021-09-03 14:07:21 +0200605 // use hardcoded value for tag length. It is not a part of this test
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, 0, 16));
Mateusz Starzyk83e4c122021-09-03 14:07:21 +0200607
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
Mateusz Starzyk83e4c122021-09-03 14:07:21 +0200609
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100610 TEST_CALLOC_OR_FAIL(output, msg->len);
Mateusz Starzyk83e4c122021-09-03 14:07:21 +0200611 olen = 0xdeadbeef;
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT,
613 mbedtls_ccm_update(&ctx, msg->x, msg->len, output, msg->len, &olen));
Mateusz Starzyk83e4c122021-09-03 14:07:21 +0200614exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 mbedtls_free(output);
616 mbedtls_ccm_free(&ctx);
Mateusz Starzyk83e4c122021-09-03 14:07:21 +0200617}
618/* END_CASE */
619
Mateusz Starzyk8fb17542021-08-10 13:45:19 +0200620/* Provide incomplete auth data and finish */
Mateusz Starzyk87889062021-07-29 14:08:18 +0200621/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100622void mbedtls_ccm_incomplete_ad(int cipher_id, int mode,
623 data_t *key, data_t *iv, data_t *add)
Mateusz Starzykf442de62021-08-10 13:36:43 +0200624{
625 mbedtls_ccm_context ctx;
626 uint8_t *output = NULL;
627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 mbedtls_ccm_init(&ctx);
629 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
630 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200631 // use hardcoded values for msg length and tag length. They are not a part of this test
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, 0, 16));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len - 1));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200635
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100636 TEST_CALLOC_OR_FAIL(output, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_finish(&ctx, output, 16));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200638
639exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 mbedtls_free(output);
641 mbedtls_ccm_free(&ctx);
Mateusz Starzykf442de62021-08-10 13:36:43 +0200642}
643/* END_CASE */
644
Mateusz Starzyk8fb17542021-08-10 13:45:19 +0200645/* Provide complete auth data on first update_ad.
646 * Provide unexpected auth data on second update_ad */
Mateusz Starzykf442de62021-08-10 13:36:43 +0200647/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100648void mbedtls_ccm_full_ad_and_overflow(int cipher_id, int mode,
649 data_t *key, data_t *iv,
650 data_t *add)
Mateusz Starzykf442de62021-08-10 13:36:43 +0200651{
652 mbedtls_ccm_context ctx;
653
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 mbedtls_ccm_init(&ctx);
655 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
656 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200657 // use hardcoded values for msg length and tag length. They are not a part of this test
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, 16, 16));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200659
660 // pass full auth data
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200662 // pass 1 extra byte
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_update_ad(&ctx, add->x, 1));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200664exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 mbedtls_ccm_free(&ctx);
Mateusz Starzykf442de62021-08-10 13:36:43 +0200666}
667/* END_CASE */
668
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200669/* Provide incomplete auth data on first update_ad.
670 * Provide too much auth data on second update_ad */
671/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100672void mbedtls_ccm_incomplete_ad_and_overflow(int cipher_id, int mode,
673 data_t *key, data_t *iv,
674 data_t *add)
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200675{
676 mbedtls_ccm_context ctx;
Ronald Cron133740b2021-09-17 09:38:07 +0200677 uint8_t add_second_buffer[2];
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200678
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 add_second_buffer[0] = add->x[add->len - 1];
Ronald Cron133740b2021-09-17 09:38:07 +0200680 add_second_buffer[1] = 0xAB; // some magic value
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 mbedtls_ccm_init(&ctx);
683 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
684 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200685 // use hardcoded values for msg length and tag length. They are not a part of this test
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, 16, 16));
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200687
688 // pass incomplete auth data
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len - 1));
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200690 // pass 2 extra bytes (1 missing byte from previous incomplete pass, and 1 unexpected byte)
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_update_ad(&ctx, add_second_buffer, 2));
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200692exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 mbedtls_ccm_free(&ctx);
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200694}
695/* END_CASE */
696
Mateusz Starzyk8fb17542021-08-10 13:45:19 +0200697/* Provide too much plaintext/ciphertext */
Mateusz Starzykf442de62021-08-10 13:36:43 +0200698/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100699void mbedtls_ccm_overflow_update(int cipher_id, int mode,
700 data_t *key, data_t *msg, data_t *iv,
701 data_t *add)
Mateusz Starzyk87889062021-07-29 14:08:18 +0200702{
703 mbedtls_ccm_context ctx;
704 uint8_t *output = NULL;
705 size_t olen;
706
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 mbedtls_ccm_init(&ctx);
708 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
709 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
Mateusz Starzyk87889062021-07-29 14:08:18 +0200710 // use hardcoded value for tag length. It is a not a part of this test
Mateusz Starzyk3050f052021-09-02 12:38:51 +0200711 // subtract 1 from configured msg length to provoke an overflow
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, msg->len - 1, 16));
Mateusz Starzyk87889062021-07-29 14:08:18 +0200713
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
Mateusz Starzyk87889062021-07-29 14:08:18 +0200715
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100716 TEST_CALLOC_OR_FAIL(output, msg->len);
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, \
718 mbedtls_ccm_update(&ctx, msg->x, msg->len, output, msg->len, &olen));
Mateusz Starzyk87889062021-07-29 14:08:18 +0200719exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 mbedtls_free(output);
721 mbedtls_ccm_free(&ctx);
Mateusz Starzyk87889062021-07-29 14:08:18 +0200722}
723/* END_CASE */
Mateusz Starzykf442de62021-08-10 13:36:43 +0200724
Mateusz Starzyk8fb17542021-08-10 13:45:19 +0200725/* Provide incomplete plaintext/ciphertext and finish */
Mateusz Starzykf442de62021-08-10 13:36:43 +0200726/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100727void mbedtls_ccm_incomplete_update(int cipher_id, int mode,
728 data_t *key, data_t *msg, data_t *iv,
729 data_t *add)
Mateusz Starzykf442de62021-08-10 13:36:43 +0200730{
731 mbedtls_ccm_context ctx;
732 uint8_t *output = NULL;
733 size_t olen;
734
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 mbedtls_ccm_init(&ctx);
736 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
737 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200738 // use hardcoded value for tag length. It is not a part of this test
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, msg->len, 16));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200740
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200742
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100743 TEST_CALLOC_OR_FAIL(output, msg->len);
Mateusz Starzykf442de62021-08-10 13:36:43 +0200744 olen = 0xdeadbeef;
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 TEST_EQUAL(0, mbedtls_ccm_update(&ctx, msg->x, msg->len - 1, output, msg->len, &olen));
746 mbedtls_free(output);
Mateusz Starzykf442de62021-08-10 13:36:43 +0200747 output = NULL;
748
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100749 TEST_CALLOC_OR_FAIL(output, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_finish(&ctx, output, 16));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200751
752exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 mbedtls_free(output);
754 mbedtls_ccm_free(&ctx);
Mateusz Starzykf442de62021-08-10 13:36:43 +0200755}
756/* END_CASE */
757
Mateusz Starzyk8fb17542021-08-10 13:45:19 +0200758/* Provide full plaintext/ciphertext of first update
759 * Provide unexpected plaintext/ciphertext on second update */
Mateusz Starzykf442de62021-08-10 13:36:43 +0200760/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100761void mbedtls_ccm_full_update_and_overflow(int cipher_id, int mode,
762 data_t *key, data_t *msg, data_t *iv,
763 data_t *add)
Mateusz Starzykf442de62021-08-10 13:36:43 +0200764{
765 mbedtls_ccm_context ctx;
766 uint8_t *output = NULL;
767 size_t olen;
768
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 mbedtls_ccm_init(&ctx);
770 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
771 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200772 // use hardcoded value for tag length. It is a not a part of this test
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, msg->len, 16));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200774
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200776
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100777 TEST_CALLOC_OR_FAIL(output, msg->len);
Mateusz Starzykf442de62021-08-10 13:36:43 +0200778 // pass full text
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 TEST_EQUAL(0, mbedtls_ccm_update(&ctx, msg->x, msg->len, output, msg->len, &olen));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200780 // pass 1 extra byte
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, \
782 mbedtls_ccm_update(&ctx, msg->x, 1, output, 1, &olen));
Mateusz Starzykf442de62021-08-10 13:36:43 +0200783exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 mbedtls_free(output);
785 mbedtls_ccm_free(&ctx);
Mateusz Starzykf442de62021-08-10 13:36:43 +0200786}
787/* END_CASE */
Mateusz Starzyke0f52272021-08-10 13:55:47 +0200788
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200789/* Provide incomplete plaintext/ciphertext of first update
790 * Provide too much plaintext/ciphertext on second update */
791/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100792void mbedtls_ccm_incomplete_update_overflow(int cipher_id, int mode,
793 data_t *key, data_t *msg, data_t *iv,
794 data_t *add)
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200795{
796 mbedtls_ccm_context ctx;
797 uint8_t *output = NULL;
798 size_t olen;
Ronald Cron133740b2021-09-17 09:38:07 +0200799 uint8_t msg_second_buffer[2];
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200800
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 msg_second_buffer[0] = msg->x[msg->len - 1];
Ronald Cron133740b2021-09-17 09:38:07 +0200802 msg_second_buffer[1] = 0xAB; // some magic value
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200803
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 mbedtls_ccm_init(&ctx);
805 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
806 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200807 // use hardcoded value for tag length. It is a not a part of this test
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, msg->len, 16));
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200809
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200811
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100812 TEST_CALLOC_OR_FAIL(output, msg->len + 1);
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200813 // pass incomplete text
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 TEST_EQUAL(0, mbedtls_ccm_update(&ctx, msg->x, msg->len - 1, output, msg->len + 1, &olen));
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200815 // pass 2 extra bytes (1 missing byte from previous incomplete pass, and 1 unexpected byte)
Gilles Peskine449bd832023-01-11 14:50:10 +0100816 TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, \
817 mbedtls_ccm_update(&ctx, msg_second_buffer, 2, output + msg->len - 1, 2, &olen));
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200818exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 mbedtls_free(output);
820 mbedtls_ccm_free(&ctx);
Mateusz Starzykcd975e42021-09-02 13:25:19 +0200821}
822/* END_CASE */
823
Mateusz Starzyke0f52272021-08-10 13:55:47 +0200824/* Finish without passing any auth data or plaintext/ciphertext input */
825/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100826void mbedtls_ccm_instant_finish(int cipher_id, int mode,
827 data_t *key, data_t *iv)
Mateusz Starzyke0f52272021-08-10 13:55:47 +0200828{
829 mbedtls_ccm_context ctx;
830 uint8_t *output = NULL;
831
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 mbedtls_ccm_init(&ctx);
833 TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
834 TEST_EQUAL(0, mbedtls_ccm_starts(&ctx, mode, iv->x, iv->len));
Mateusz Starzyke0f52272021-08-10 13:55:47 +0200835 // use hardcoded values for add length, msg length and tag length.
836 // They are not a part of this test
Gilles Peskine449bd832023-01-11 14:50:10 +0100837 TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, 16, 16, 16));
Mateusz Starzyke0f52272021-08-10 13:55:47 +0200838
Tom Cosgrovef9ffd112023-07-20 16:48:18 +0100839 TEST_CALLOC_OR_FAIL(output, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_finish(&ctx, output, 16));
Mateusz Starzyke0f52272021-08-10 13:55:47 +0200841
842exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 mbedtls_free(output);
844 mbedtls_ccm_free(&ctx);
Mateusz Starzyke0f52272021-08-10 13:55:47 +0200845}
846/* END_CASE */