blob: c61288aa792521a972cddb79752891be3c16a0ab [file] [log] [blame]
/* 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);
ASSERT_ALLOC_WEAK(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 */