• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* BEGIN_HEADER */
2#include "mbedtls/ccm.h"
3
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. */
7static 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)
16{
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 */
24    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));
31
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. */
35    ASSERT_ALLOC(output, n1);
36    olen = 0xdeadbeef;
37    TEST_EQUAL(0, mbedtls_ccm_update(ctx, input->x, n1, output, n1, &olen));
38    TEST_EQUAL(n1, olen);
39    ASSERT_COMPARE(output, olen, expected_output->x, n1);
40    mbedtls_free(output);
41    output = NULL;
42
43    ASSERT_ALLOC(output, n2);
44    olen = 0xdeadbeef;
45    TEST_EQUAL(0, mbedtls_ccm_update(ctx, input->x + n1, n2, output, n2, &olen));
46    TEST_EQUAL(n2, olen);
47    ASSERT_COMPARE(output, olen, expected_output->x + n1, n2);
48    mbedtls_free(output);
49    output = NULL;
50
51    ASSERT_ALLOC(output, tag->len);
52    TEST_EQUAL(0, mbedtls_ccm_finish(ctx, output, tag->len));
53    ASSERT_COMPARE(output, tag->len, tag->x, tag->len);
54    mbedtls_free(output);
55    output = NULL;
56
57    ok = 1;
58exit:
59    mbedtls_free(output);
60    return ok;
61}
62/* END_HEADER */
63
64/* BEGIN_DEPENDENCIES
65 * depends_on:MBEDTLS_CCM_C
66 * END_DEPENDENCIES
67 */
68
69/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST:MBEDTLS_AES_C */
70void mbedtls_ccm_self_test()
71{
72    TEST_ASSERT(mbedtls_ccm_self_test(1) == 0);
73}
74/* END_CASE */
75
76/* BEGIN_CASE */
77void mbedtls_ccm_setkey(int cipher_id, int key_size, int result)
78{
79    mbedtls_ccm_context ctx;
80    unsigned char key[32];
81    int ret;
82
83    mbedtls_ccm_init(&ctx);
84
85    memset(key, 0x2A, sizeof(key));
86    TEST_ASSERT((unsigned) key_size <= 8 * sizeof(key));
87
88    ret = mbedtls_ccm_setkey(&ctx, cipher_id, key, key_size);
89    TEST_ASSERT(ret == result);
90
91exit:
92    mbedtls_ccm_free(&ctx);
93}
94/* END_CASE */
95
96/* BEGIN_CASE depends_on:MBEDTLS_AES_C */
97void ccm_lengths(int msg_len, int iv_len, int add_len, int tag_len, int res)
98{
99    mbedtls_ccm_context ctx;
100    unsigned char key[16];
101    unsigned char msg[10];
102    unsigned char iv[14];
103    unsigned char *add = NULL;
104    unsigned char out[10];
105    unsigned char tag[18];
106    int decrypt_ret;
107
108    mbedtls_ccm_init(&ctx);
109
110    ASSERT_ALLOC_WEAK(add, add_len);
111    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));
116
117    TEST_ASSERT(mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
118                                   key, 8 * sizeof(key)) == 0);
119
120    TEST_ASSERT(mbedtls_ccm_encrypt_and_tag(&ctx, msg_len, iv, iv_len, add, add_len,
121                                            msg, out, tag, tag_len) == res);
122
123    decrypt_ret = mbedtls_ccm_auth_decrypt(&ctx, msg_len, iv, iv_len, add, add_len,
124                                           msg, out, tag, tag_len);
125
126    if (res == 0) {
127        TEST_ASSERT(decrypt_ret == MBEDTLS_ERR_CCM_AUTH_FAILED);
128    } else {
129        TEST_ASSERT(decrypt_ret == res);
130    }
131
132exit:
133    mbedtls_free(add);
134    mbedtls_ccm_free(&ctx);
135}
136/* END_CASE */
137
138/* BEGIN_CASE depends_on:MBEDTLS_AES_C */
139void ccm_star_lengths(int msg_len, int iv_len, int add_len, int tag_len,
140                      int res)
141{
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
151    mbedtls_ccm_init(&ctx);
152
153    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));
159
160    TEST_ASSERT(mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
161                                   key, 8 * sizeof(key)) == 0);
162
163    TEST_ASSERT(mbedtls_ccm_star_encrypt_and_tag(&ctx, msg_len, iv, iv_len,
164                                                 add, add_len, msg, out, tag, tag_len) == res);
165
166    decrypt_ret = mbedtls_ccm_star_auth_decrypt(&ctx, msg_len, iv, iv_len, add,
167                                                add_len, msg, out, tag, tag_len);
168
169    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    }
174
175exit:
176    mbedtls_ccm_free(&ctx);
177}
178/* END_CASE */
179
180/* BEGIN_CASE */
181void 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)
184{
185    mbedtls_ccm_context ctx;
186    size_t n1, n1_add;
187    uint8_t *io_msg_buf = NULL;
188    uint8_t *tag_buf = NULL;
189    const size_t expected_tag_len = result->len - msg->len;
190    const uint8_t *expected_tag = result->x + msg->len;
191
192    /* Prepare input/output message buffer */
193    ASSERT_ALLOC(io_msg_buf, msg->len);
194    if (msg->len != 0) {
195        memcpy(io_msg_buf, msg->x, msg->len);
196    }
197
198    /* Prepare tag buffer */
199    ASSERT_ALLOC(tag_buf, expected_tag_len);
200
201    mbedtls_ccm_init(&ctx);
202    TEST_EQUAL(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8), 0);
203    /* Test with input == output */
204    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);
206
207    ASSERT_COMPARE(io_msg_buf, msg->len, result->x, msg->len);
208    ASSERT_COMPARE(tag_buf, expected_tag_len, expected_tag, expected_tag_len);
209
210    /* Prepare data_t structures for multipart testing */
211    const data_t encrypted_expected = { .x = result->x,
212                                        .len = msg->len };
213    const data_t tag_expected = { .x = (uint8_t *) expected_tag, /* cast to conform with data_t x type */
214                                  .len = expected_tag_len };
215
216    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)) {
224                goto exit;
225            }
226        }
227    }
228
229exit:
230    mbedtls_ccm_free(&ctx);
231    mbedtls_free(io_msg_buf);
232    mbedtls_free(tag_buf);
233}
234/* END_CASE */
235
236/* BEGIN_CASE */
237void 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
249    ASSERT_ALLOC(output, msg->len);
250    TEST_EQUAL(0, mbedtls_ccm_update(&ctx, msg->x, msg->len, output, msg->len, &olen));
251    TEST_EQUAL(result->len, olen);
252    ASSERT_COMPARE(output, olen, result->x, result->len);
253
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;
275    ASSERT_ALLOC(io_msg_buf, expected_msg_len);
276    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) {
288        ASSERT_COMPARE(io_msg_buf, expected_msg_len, expected_msg->x, expected_msg_len);
289
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 */
347    ASSERT_ALLOC(io_msg_buf, msg->len);
348    if (msg->len) {
349        memcpy(io_msg_buf, msg->x, msg->len);
350    }
351
352    /* Prepare tag buffer */
353    if (expected_tag_len == 0) {
354        ASSERT_ALLOC(tag_buf, 16);
355    } else {
356        ASSERT_ALLOC(tag_buf, expected_tag_len);
357    }
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
375    ASSERT_COMPARE(io_msg_buf, msg->len, expected_result->x, msg->len);
376    ASSERT_COMPARE(tag_buf, expected_tag_len, expected_tag, expected_tag_len);
377
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)
414{
415    unsigned char iv[13];
416    mbedtls_ccm_context ctx;
417    size_t iv_len, expected_tag_len;
418    size_t n1, n1_add;
419
420    /* Calculate tag length */
421    if (sec_level % 4 == 0) {
422        expected_tag_len = 0;
423    } else {
424        expected_tag_len = 1 << (sec_level % 4 + 1);
425    }
426
427    const size_t expected_msg_len = msg->len - expected_tag_len;
428    const uint8_t *expected_tag = msg->x + expected_msg_len;
429
430    /* Prepare input/output message buffer */
431    uint8_t *io_msg_buf = NULL;
432    ASSERT_ALLOC(io_msg_buf, expected_msg_len);
433    if (expected_msg_len) {
434        memcpy(io_msg_buf, msg->x, expected_msg_len);
435    }
436
437    /* Calculate iv */
438    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);
443    iv[source_address->len + frame_counter->len] = sec_level;
444    iv_len = sizeof(iv);
445
446    mbedtls_ccm_init(&ctx);
447    TEST_ASSERT(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8) == 0);
448    /* Test with input == output */
449    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);
452
453    ASSERT_COMPARE(io_msg_buf, expected_msg_len, expected_result->x, expected_msg_len);
454
455    if (output_ret == 0) {
456        const data_t iv_data = { .x = iv,
457                                 .len = iv_len };
458
459        const data_t encrypted = { .x = msg->x,
460                                   .len = expected_msg_len };
461
462        const data_t tag_expected = { .x = (uint8_t *) expected_tag,
463                                      .len = expected_tag_len };
464
465        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)) {
473                    goto exit;
474                }
475            }
476        }
477    }
478
479exit:
480    mbedtls_ccm_free(&ctx);
481    mbedtls_free(io_msg_buf);
482}
483/* END_CASE */
484
485/* Skip auth data, provide full text */
486/* BEGIN_CASE */
487void 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)
490{
491    mbedtls_ccm_context ctx;
492    uint8_t *output = NULL;
493    size_t olen;
494
495    /* Sanity checks on the test data */
496    TEST_EQUAL(msg->len, result->len);
497
498    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));
502
503    ASSERT_ALLOC(output, result->len);
504    olen = 0xdeadbeef;
505    TEST_EQUAL(0, mbedtls_ccm_update(&ctx, msg->x, msg->len, output, result->len, &olen));
506    TEST_EQUAL(result->len, olen);
507    ASSERT_COMPARE(output, olen, result->x, result->len);
508    mbedtls_free(output);
509    output = NULL;
510
511    ASSERT_ALLOC(output, tag->len);
512    TEST_EQUAL(0, mbedtls_ccm_finish(&ctx, output, tag->len));
513    ASSERT_COMPARE(output, tag->len, tag->x, tag->len);
514    mbedtls_free(output);
515    output = NULL;
516
517exit:
518    mbedtls_free(output);
519    mbedtls_ccm_free(&ctx);
520}
521/* END_CASE */
522
523/* Provide auth data, skip full text */
524/* BEGIN_CASE */
525void mbedtls_ccm_skip_update(int cipher_id, int mode,
526                             data_t *key, data_t *iv, data_t *add,
527                             data_t *tag)
528{
529    mbedtls_ccm_context ctx;
530    uint8_t *output = NULL;
531
532    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));
536
537    TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
538
539    ASSERT_ALLOC(output, tag->len);
540    TEST_EQUAL(0, mbedtls_ccm_finish(&ctx, output, tag->len));
541    ASSERT_COMPARE(output, tag->len, tag->x, tag->len);
542    mbedtls_free(output);
543    output = NULL;
544
545exit:
546    mbedtls_free(output);
547    mbedtls_ccm_free(&ctx);
548}
549/* END_CASE */
550
551/* Provide too much auth data */
552/* BEGIN_CASE */
553void mbedtls_ccm_overflow_ad(int cipher_id, int mode,
554                             data_t *key, data_t *iv,
555                             data_t *add)
556{
557    mbedtls_ccm_context ctx;
558
559    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));
562    // use hardcoded values for msg length and tag length. They are not a part of this test
563    // subtract 1 from configured auth data length to provoke an overflow
564    TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len - 1, 16, 16));
565
566    TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
567exit:
568    mbedtls_ccm_free(&ctx);
569}
570/* END_CASE */
571
572/* Provide unexpected auth data */
573/* BEGIN_CASE */
574void mbedtls_ccm_unexpected_ad(int cipher_id, int mode,
575                               data_t *key, data_t *iv,
576                               data_t *add)
577{
578    mbedtls_ccm_context ctx;
579
580    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));
583    // use hardcoded values for msg length and tag length. They are not a part of this test
584    TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, 0, 16, 16));
585
586    TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
587exit:
588    mbedtls_ccm_free(&ctx);
589}
590/* END_CASE */
591
592/* Provide unexpected plaintext/ciphertext data */
593/* BEGIN_CASE */
594void mbedtls_ccm_unexpected_text(int cipher_id, int mode,
595                                 data_t *key, data_t *msg, data_t *iv,
596                                 data_t *add)
597{
598    mbedtls_ccm_context ctx;
599    uint8_t *output = NULL;
600    size_t olen;
601
602    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));
605    // use hardcoded value for tag length. It is not a part of this test
606    TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, 0, 16));
607
608    TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
609
610    ASSERT_ALLOC(output, msg->len);
611    olen = 0xdeadbeef;
612    TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT,
613               mbedtls_ccm_update(&ctx, msg->x, msg->len, output, msg->len, &olen));
614exit:
615    mbedtls_free(output);
616    mbedtls_ccm_free(&ctx);
617}
618/* END_CASE */
619
620/* Provide incomplete auth data and finish */
621/* BEGIN_CASE */
622void mbedtls_ccm_incomplete_ad(int cipher_id, int mode,
623                               data_t *key, data_t *iv, data_t *add)
624{
625    mbedtls_ccm_context ctx;
626    uint8_t *output = NULL;
627
628    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));
631    // use hardcoded values for msg length and tag length. They are not a part of this test
632    TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, 0, 16));
633
634    TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len - 1));
635
636    ASSERT_ALLOC(output, 16);
637    TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_finish(&ctx, output, 16));
638
639exit:
640    mbedtls_free(output);
641    mbedtls_ccm_free(&ctx);
642}
643/* END_CASE */
644
645/* Provide complete auth data on first update_ad.
646 * Provide unexpected auth data on second update_ad */
647/* BEGIN_CASE */
648void mbedtls_ccm_full_ad_and_overflow(int cipher_id, int mode,
649                                      data_t *key, data_t *iv,
650                                      data_t *add)
651{
652    mbedtls_ccm_context ctx;
653
654    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));
657    // use hardcoded values for msg length and tag length. They are not a part of this test
658    TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, 16, 16));
659
660    // pass full auth data
661    TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
662    // pass 1 extra byte
663    TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_update_ad(&ctx, add->x, 1));
664exit:
665    mbedtls_ccm_free(&ctx);
666}
667/* END_CASE */
668
669/* Provide incomplete auth data on first update_ad.
670 * Provide too much auth data on second update_ad */
671/* BEGIN_CASE */
672void mbedtls_ccm_incomplete_ad_and_overflow(int cipher_id, int mode,
673                                            data_t *key, data_t *iv,
674                                            data_t *add)
675{
676    mbedtls_ccm_context ctx;
677    uint8_t add_second_buffer[2];
678
679    add_second_buffer[0] = add->x[add->len - 1];
680    add_second_buffer[1] = 0xAB; // some magic value
681
682    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));
685    // use hardcoded values for msg length and tag length. They are not a part of this test
686    TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, 16, 16));
687
688    // pass incomplete auth data
689    TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len - 1));
690    // pass 2 extra bytes (1 missing byte from previous incomplete pass, and 1 unexpected byte)
691    TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_update_ad(&ctx, add_second_buffer, 2));
692exit:
693    mbedtls_ccm_free(&ctx);
694}
695/* END_CASE */
696
697/* Provide too much plaintext/ciphertext */
698/* BEGIN_CASE */
699void mbedtls_ccm_overflow_update(int cipher_id, int mode,
700                                 data_t *key, data_t *msg, data_t *iv,
701                                 data_t *add)
702{
703    mbedtls_ccm_context ctx;
704    uint8_t *output = NULL;
705    size_t olen;
706
707    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));
710    // use hardcoded value for tag length. It is a not a part of this test
711    // subtract 1 from configured msg length to provoke an overflow
712    TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, msg->len - 1, 16));
713
714    TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
715
716    ASSERT_ALLOC(output, msg->len);
717    TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, \
718               mbedtls_ccm_update(&ctx, msg->x, msg->len, output, msg->len, &olen));
719exit:
720    mbedtls_free(output);
721    mbedtls_ccm_free(&ctx);
722}
723/* END_CASE */
724
725/* Provide incomplete plaintext/ciphertext and finish */
726/* BEGIN_CASE */
727void mbedtls_ccm_incomplete_update(int cipher_id, int mode,
728                                   data_t *key, data_t *msg, data_t *iv,
729                                   data_t *add)
730{
731    mbedtls_ccm_context ctx;
732    uint8_t *output = NULL;
733    size_t olen;
734
735    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));
738    // use hardcoded value for tag length. It is not a part of this test
739    TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, msg->len, 16));
740
741    TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
742
743    ASSERT_ALLOC(output, msg->len);
744    olen = 0xdeadbeef;
745    TEST_EQUAL(0, mbedtls_ccm_update(&ctx, msg->x, msg->len - 1, output, msg->len, &olen));
746    mbedtls_free(output);
747    output = NULL;
748
749    ASSERT_ALLOC(output, 16);
750    TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_finish(&ctx, output, 16));
751
752exit:
753    mbedtls_free(output);
754    mbedtls_ccm_free(&ctx);
755}
756/* END_CASE */
757
758/* Provide full plaintext/ciphertext of first update
759 * Provide unexpected plaintext/ciphertext on second update */
760/* BEGIN_CASE */
761void 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)
764{
765    mbedtls_ccm_context ctx;
766    uint8_t *output = NULL;
767    size_t olen;
768
769    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));
772    // use hardcoded value for tag length. It is a not a part of this test
773    TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, msg->len, 16));
774
775    TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
776
777    ASSERT_ALLOC(output, msg->len);
778    // pass full text
779    TEST_EQUAL(0, mbedtls_ccm_update(&ctx, msg->x, msg->len, output, msg->len, &olen));
780    // pass 1 extra byte
781    TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, \
782               mbedtls_ccm_update(&ctx, msg->x, 1, output, 1, &olen));
783exit:
784    mbedtls_free(output);
785    mbedtls_ccm_free(&ctx);
786}
787/* END_CASE */
788
789/* Provide incomplete plaintext/ciphertext of first update
790 * Provide too much plaintext/ciphertext on second update */
791/* BEGIN_CASE */
792void mbedtls_ccm_incomplete_update_overflow(int cipher_id, int mode,
793                                            data_t *key, data_t *msg, data_t *iv,
794                                            data_t *add)
795{
796    mbedtls_ccm_context ctx;
797    uint8_t *output = NULL;
798    size_t olen;
799    uint8_t msg_second_buffer[2];
800
801    msg_second_buffer[0] = msg->x[msg->len - 1];
802    msg_second_buffer[1] = 0xAB; // some magic value
803
804    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));
807    // use hardcoded value for tag length. It is a not a part of this test
808    TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, add->len, msg->len, 16));
809
810    TEST_EQUAL(0, mbedtls_ccm_update_ad(&ctx, add->x, add->len));
811
812    ASSERT_ALLOC(output, msg->len + 1);
813    // pass incomplete text
814    TEST_EQUAL(0, mbedtls_ccm_update(&ctx, msg->x, msg->len - 1, output, msg->len + 1, &olen));
815    // pass 2 extra bytes (1 missing byte from previous incomplete pass, and 1 unexpected byte)
816    TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, \
817               mbedtls_ccm_update(&ctx, msg_second_buffer, 2, output +  msg->len - 1, 2, &olen));
818exit:
819    mbedtls_free(output);
820    mbedtls_ccm_free(&ctx);
821}
822/* END_CASE */
823
824/* Finish without passing any auth data or plaintext/ciphertext input */
825/* BEGIN_CASE */
826void mbedtls_ccm_instant_finish(int cipher_id, int mode,
827                                data_t *key, data_t *iv)
828{
829    mbedtls_ccm_context ctx;
830    uint8_t *output = NULL;
831
832    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));
835    // use hardcoded values for add length, msg length and tag length.
836    // They are not a part of this test
837    TEST_EQUAL(0, mbedtls_ccm_set_lengths(&ctx, 16, 16, 16));
838
839    ASSERT_ALLOC(output, 16);
840    TEST_EQUAL(MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_finish(&ctx, output, 16));
841
842exit:
843    mbedtls_free(output);
844    mbedtls_ccm_free(&ctx);
845}
846/* END_CASE */
847