/* BEGIN_HEADER */ #include "mbedtls/ccm.h" /* END_HEADER */ /* BEGIN_DEPENDENCIES * depends_on:MBEDTLS_CCM_C * END_DEPENDENCIES */ /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST:MBEDTLS_AES_C */ void mbedtls_ccm_self_test() { TEST_ASSERT(mbedtls_ccm_self_test(1) == 0); } /* END_CASE */ /* BEGIN_CASE */ void mbedtls_ccm_setkey(int cipher_id, int key_size, int result) { mbedtls_ccm_context ctx; unsigned char key[32]; int ret; mbedtls_ccm_init(&ctx); memset(key, 0x2A, sizeof(key)); TEST_ASSERT((unsigned) key_size <= 8 * sizeof(key)); ret = mbedtls_ccm_setkey(&ctx, cipher_id, key, key_size); TEST_ASSERT(ret == result); exit: mbedtls_ccm_free(&ctx); } /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_AES_C */ void ccm_lengths(int msg_len, int iv_len, int add_len, int tag_len, int res) { mbedtls_ccm_context ctx; unsigned char key[16]; unsigned char msg[10]; unsigned char iv[14]; unsigned char *add = NULL; unsigned char out[10]; unsigned char tag[18]; int decrypt_ret; mbedtls_ccm_init(&ctx); TEST_CALLOC_OR_SKIP(add, add_len); memset(key, 0, sizeof(key)); memset(msg, 0, sizeof(msg)); memset(iv, 0, sizeof(iv)); memset(out, 0, sizeof(out)); memset(tag, 0, sizeof(tag)); TEST_ASSERT(mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof(key)) == 0); TEST_ASSERT(mbedtls_ccm_encrypt_and_tag(&ctx, msg_len, iv, iv_len, add, add_len, msg, out, tag, tag_len) == res); decrypt_ret = mbedtls_ccm_auth_decrypt(&ctx, msg_len, iv, iv_len, add, add_len, msg, out, tag, tag_len); if (res == 0) { TEST_ASSERT(decrypt_ret == MBEDTLS_ERR_CCM_AUTH_FAILED); } else { TEST_ASSERT(decrypt_ret == res); } exit: mbedtls_free(add); mbedtls_ccm_free(&ctx); } /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_AES_C */ void ccm_star_lengths(int msg_len, int iv_len, int add_len, int tag_len, int res) { mbedtls_ccm_context ctx; unsigned char key[16]; unsigned char msg[10]; unsigned char iv[14]; unsigned char add[10]; unsigned char out[10]; unsigned char tag[18]; int decrypt_ret; mbedtls_ccm_init(&ctx); memset(key, 0, sizeof(key)); memset(msg, 0, sizeof(msg)); memset(iv, 0, sizeof(iv)); memset(add, 0, sizeof(add)); memset(out, 0, sizeof(out)); memset(tag, 0, sizeof(tag)); TEST_ASSERT(mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof(key)) == 0); TEST_ASSERT(mbedtls_ccm_star_encrypt_and_tag(&ctx, msg_len, iv, iv_len, add, add_len, msg, out, tag, tag_len) == res); decrypt_ret = mbedtls_ccm_star_auth_decrypt(&ctx, msg_len, iv, iv_len, add, add_len, msg, out, tag, tag_len); if (res == 0 && tag_len != 0) { TEST_ASSERT(decrypt_ret == MBEDTLS_ERR_CCM_AUTH_FAILED); } else { TEST_ASSERT(decrypt_ret == res); } exit: mbedtls_ccm_free(&ctx); } /* END_CASE */ /* BEGIN_CASE */ void mbedtls_ccm_encrypt_and_tag(int cipher_id, data_t *key, data_t *msg, data_t *iv, data_t *add, data_t *result) { mbedtls_ccm_context ctx; size_t tag_len; uint8_t *msg_n_tag = (uint8_t *) malloc(result->len + 2); mbedtls_ccm_init(&ctx); memset(msg_n_tag, 0, result->len + 2); memcpy(msg_n_tag, msg->x, msg->len); tag_len = result->len - msg->len; TEST_ASSERT(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8) == 0); /* Test with input == output */ TEST_ASSERT(mbedtls_ccm_encrypt_and_tag(&ctx, msg->len, iv->x, iv->len, add->x, add->len, msg_n_tag, msg_n_tag, msg_n_tag + msg->len, tag_len) == 0); TEST_ASSERT(memcmp(msg_n_tag, result->x, result->len) == 0); /* Check we didn't write past the end */ TEST_ASSERT(msg_n_tag[result->len] == 0 && msg_n_tag[result->len + 1] == 0); exit: mbedtls_ccm_free(&ctx); free(msg_n_tag); } /* END_CASE */ /* BEGIN_CASE */ void mbedtls_ccm_auth_decrypt(int cipher_id, data_t *key, data_t *msg, data_t *iv, data_t *add, int tag_len, int result, data_t *expected_msg) { unsigned char tag[16]; mbedtls_ccm_context ctx; mbedtls_ccm_init(&ctx); memset(tag, 0x00, sizeof(tag)); msg->len -= tag_len; memcpy(tag, msg->x + msg->len, tag_len); TEST_ASSERT(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8) == 0); /* Test with input == output */ TEST_ASSERT(mbedtls_ccm_auth_decrypt(&ctx, msg->len, iv->x, iv->len, add->x, add->len, msg->x, msg->x, msg->x + msg->len, tag_len) == result); if (result == 0) { TEST_ASSERT(memcmp(msg->x, expected_msg->x, expected_msg->len) == 0); } else { size_t i; for (i = 0; i < msg->len; i++) { TEST_ASSERT(msg->x[i] == 0); } } /* Check we didn't write past the end (where the original tag is) */ TEST_ASSERT(memcmp(msg->x + msg->len, tag, tag_len) == 0); exit: mbedtls_ccm_free(&ctx); } /* END_CASE */ /* BEGIN_CASE */ void mbedtls_ccm_star_encrypt_and_tag(int cipher_id, data_t *key, data_t *msg, data_t *source_address, data_t *frame_counter, int sec_level, data_t *add, data_t *expected_result, int output_ret) { unsigned char iv[13]; unsigned char result[50]; mbedtls_ccm_context ctx; size_t iv_len, tag_len; int ret; mbedtls_ccm_init(&ctx); memset(result, 0x00, sizeof(result)); if (sec_level % 4 == 0) { tag_len = 0; } else { tag_len = 1 << (sec_level % 4 + 1); } TEST_ASSERT(source_address->len == 8); TEST_ASSERT(frame_counter->len == 4); memcpy(iv, source_address->x, source_address->len); memcpy(iv + source_address->len, frame_counter->x, frame_counter->len); iv[source_address->len + frame_counter->len] = sec_level; iv_len = sizeof(iv); TEST_ASSERT(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8) == 0); ret = mbedtls_ccm_star_encrypt_and_tag(&ctx, msg->len, iv, iv_len, add->x, add->len, msg->x, result, result + msg->len, tag_len); TEST_ASSERT(ret == output_ret); TEST_ASSERT(memcmp(result, expected_result->x, expected_result->len) == 0); /* Check we didn't write past the end */ TEST_ASSERT(result[expected_result->len] == 0 && result[expected_result->len + 1] == 0); exit: mbedtls_ccm_free(&ctx); } /* END_CASE */ /* BEGIN_CASE */ void mbedtls_ccm_star_auth_decrypt(int cipher_id, data_t *key, data_t *msg, data_t *source_address, data_t *frame_counter, int sec_level, data_t *add, data_t *expected_result, int output_ret) { unsigned char iv[13]; unsigned char result[50]; mbedtls_ccm_context ctx; size_t iv_len, tag_len; int ret; mbedtls_ccm_init(&ctx); memset(iv, 0x00, sizeof(iv)); memset(result, '+', sizeof(result)); if (sec_level % 4 == 0) { tag_len = 0; } else { tag_len = 1 << (sec_level % 4 + 1); } TEST_ASSERT(source_address->len == 8); TEST_ASSERT(frame_counter->len == 4); memcpy(iv, source_address->x, source_address->len); memcpy(iv + source_address->len, frame_counter->x, frame_counter->len); iv[source_address->len + frame_counter->len] = sec_level; iv_len = sizeof(iv); TEST_ASSERT(mbedtls_ccm_setkey(&ctx, cipher_id, key->x, key->len * 8) == 0); ret = mbedtls_ccm_star_auth_decrypt(&ctx, msg->len - tag_len, iv, iv_len, add->x, add->len, msg->x, result, msg->x + msg->len - tag_len, tag_len); TEST_ASSERT(ret == output_ret); TEST_ASSERT(memcmp(result, expected_result->x, expected_result->len) == 0); /* Check we didn't write past the end (where the original tag is) */ TEST_ASSERT((msg->len + 2) <= sizeof(result)); TEST_EQUAL(result[msg->len], '+'); TEST_EQUAL(result[msg->len + 1], '+'); exit: mbedtls_ccm_free(&ctx); } /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */ void ccm_invalid_param() { struct mbedtls_ccm_context ctx; unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES; int valid_len = sizeof(valid_buffer); int valid_bitlen = valid_len * 8; mbedtls_ccm_init(&ctx); /* mbedtls_ccm_init() */ TEST_INVALID_PARAM(mbedtls_ccm_init(NULL)); /* mbedtls_ccm_setkey() */ TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_setkey(NULL, valid_cipher, valid_buffer, valid_bitlen)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_setkey(&ctx, valid_cipher, NULL, valid_bitlen)); /* mbedtls_ccm_encrypt_and_tag() */ TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_encrypt_and_tag(NULL, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, valid_buffer, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_encrypt_and_tag(&ctx, valid_len, NULL, valid_len, valid_buffer, valid_len, valid_buffer, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_encrypt_and_tag(&ctx, valid_len, valid_buffer, valid_len, NULL, valid_len, valid_buffer, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_encrypt_and_tag(&ctx, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, NULL, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_encrypt_and_tag(&ctx, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, valid_buffer, NULL, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_encrypt_and_tag(&ctx, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, valid_buffer, valid_buffer, NULL, valid_len)); /* mbedtls_ccm_star_encrypt_and_tag() */ TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_star_encrypt_and_tag(NULL, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, valid_buffer, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_star_encrypt_and_tag(&ctx, valid_len, NULL, valid_len, valid_buffer, valid_len, valid_buffer, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_star_encrypt_and_tag(&ctx, valid_len, valid_buffer, valid_len, NULL, valid_len, valid_buffer, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_star_encrypt_and_tag(&ctx, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, NULL, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_star_encrypt_and_tag(&ctx, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, valid_buffer, NULL, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_star_encrypt_and_tag(&ctx, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, valid_buffer, valid_buffer, NULL, valid_len)); /* mbedtls_ccm_auth_decrypt() */ TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_auth_decrypt(NULL, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, valid_buffer, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_auth_decrypt(&ctx, valid_len, NULL, valid_len, valid_buffer, valid_len, valid_buffer, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_auth_decrypt(&ctx, valid_len, valid_buffer, valid_len, NULL, valid_len, valid_buffer, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_auth_decrypt(&ctx, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, NULL, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_auth_decrypt(&ctx, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, valid_buffer, NULL, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_auth_decrypt(&ctx, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, valid_buffer, valid_buffer, NULL, valid_len)); /* mbedtls_ccm_star_auth_decrypt() */ TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_star_auth_decrypt(NULL, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, valid_buffer, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_star_auth_decrypt(&ctx, valid_len, NULL, valid_len, valid_buffer, valid_len, valid_buffer, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_star_auth_decrypt(&ctx, valid_len, valid_buffer, valid_len, NULL, valid_len, valid_buffer, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_star_auth_decrypt(&ctx, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, NULL, valid_buffer, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_star_auth_decrypt(&ctx, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, valid_buffer, NULL, valid_buffer, valid_len)); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CCM_BAD_INPUT, mbedtls_ccm_star_auth_decrypt(&ctx, valid_len, valid_buffer, valid_len, valid_buffer, valid_len, valid_buffer, valid_buffer, NULL, valid_len)); exit: mbedtls_ccm_free(&ctx); return; } /* END_CASE */ /* BEGIN_CASE */ void ccm_valid_param() { TEST_VALID_PARAM(mbedtls_ccm_free(NULL)); exit: return; } /* END_CASE */