/* 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[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_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_ccm_free( &ctx );
}
/* END_CASE */

/* BEGIN_CASE */
void mbedtls_ccm_encrypt_and_tag( int cipher_id,
                          char *key_hex, char *msg_hex,
                          char *iv_hex, char *add_hex,
                          char *result_hex )
{
    unsigned char key[32];
    unsigned char msg[50];
    unsigned char iv[13];
    unsigned char add[32];
    unsigned char result[50];
    mbedtls_ccm_context ctx;
    size_t key_len, msg_len, iv_len, add_len, tag_len, result_len;

    mbedtls_ccm_init( &ctx );

    memset( key, 0x00, sizeof( key ) );
    memset( msg, 0x00, sizeof( msg ) );
    memset( iv, 0x00, sizeof( iv ) );
    memset( add, 0x00, sizeof( add ) );
    memset( result, 0x00, sizeof( result ) );

    key_len = unhexify( key, key_hex );
    msg_len = unhexify( msg, msg_hex );
    iv_len = unhexify( iv, iv_hex );
    add_len = unhexify( add, add_hex );
    result_len = unhexify( result, result_hex );
    tag_len = result_len - msg_len;

    TEST_ASSERT( mbedtls_ccm_setkey( &ctx, cipher_id, key, key_len * 8 ) == 0 );

    /* Test with input == output */
    TEST_ASSERT( mbedtls_ccm_encrypt_and_tag( &ctx, msg_len, iv, iv_len, add, add_len,
                 msg, msg, msg + msg_len, tag_len ) == 0 );

    TEST_ASSERT( memcmp( msg, result, result_len ) == 0 );

    /* Check we didn't write past the end */
    TEST_ASSERT( msg[result_len] == 0 && msg[result_len + 1] == 0 );

exit:
    mbedtls_ccm_free( &ctx );
}
/* END_CASE */

/* BEGIN_CASE */
void mbedtls_ccm_auth_decrypt( int cipher_id,
                       char *key_hex, char *msg_hex,
                       char *iv_hex, char *add_hex,
                       int tag_len, char *result_hex )
{
    unsigned char key[32];
    unsigned char msg[50];
    unsigned char iv[13];
    unsigned char add[32];
    unsigned char tag[16];
    unsigned char result[50];
    mbedtls_ccm_context ctx;
    size_t key_len, msg_len, iv_len, add_len, result_len;
    int ret;

    mbedtls_ccm_init( &ctx );

    memset( key, 0x00, sizeof( key ) );
    memset( msg, 0x00, sizeof( msg ) );
    memset( iv, 0x00, sizeof( iv ) );
    memset( add, 0x00, sizeof( add ) );
    memset( tag, 0x00, sizeof( tag ) );
    memset( result, 0x00, sizeof( result ) );

    key_len = unhexify( key, key_hex );
    msg_len = unhexify( msg, msg_hex );
    iv_len = unhexify( iv, iv_hex );
    add_len = unhexify( add, add_hex );
    msg_len -= tag_len;
    memcpy( tag, msg + msg_len, tag_len );

    if( strcmp( "FAIL", result_hex ) == 0 )
    {
        ret = MBEDTLS_ERR_CCM_AUTH_FAILED;
        result_len = -1;
    }
    else
    {
        ret = 0;
        result_len = unhexify( result, result_hex );
    }

    TEST_ASSERT( mbedtls_ccm_setkey( &ctx, cipher_id, key, key_len * 8 ) == 0 );

    /* Test with input == output */
    TEST_ASSERT( mbedtls_ccm_auth_decrypt( &ctx, msg_len, iv, iv_len, add, add_len,
                 msg, msg, msg + msg_len, tag_len ) == ret );

    if( ret == 0 )
    {
        TEST_ASSERT( memcmp( msg, result, result_len ) == 0 );
    }
    else
    {
        size_t i;

        for( i = 0; i < msg_len; i++ )
            TEST_ASSERT( msg[i] == 0 );
    }

    /* Check we didn't write past the end (where the original tag is) */
    TEST_ASSERT( memcmp( msg + msg_len, tag, tag_len ) == 0 );

exit:
    mbedtls_ccm_free( &ctx );
}
/* END_CASE */
