/* BEGIN_HEADER */
#include "mbedtls/ccm.h"

/* Use the multipart interface to process the encrypted data in two parts
 * and check that the output matches the expected output.
 * The context must have been set up with the key. */
static int check_multipart( mbedtls_ccm_context *ctx,
                            int mode,
                            const data_t *iv,
                            const data_t *add,
                            const data_t *input,
                            const data_t *expected_output,
                            const data_t *tag,
                            size_t n1,
                            size_t n1_add)
{
    int ok = 0;
    uint8_t *output = NULL;
    size_t n2 = input->len - n1;
    size_t n2_add = add->len - n1_add;
    size_t olen;

    /* Sanity checks on the test data */
    TEST_ASSERT( n1 <= input->len );
    TEST_ASSERT( n1_add <= add->len );
    TEST_EQUAL( input->len, expected_output->len );
    TEST_EQUAL( 0, mbedtls_ccm_starts( ctx, mode, iv->x, iv->len ) );
    TEST_EQUAL( 0, mbedtls_ccm_set_lengths( ctx, add->len, input->len, tag->len ) );
    TEST_EQUAL( 0, mbedtls_ccm_update_ad( ctx, add->x, n1_add) );
    TEST_EQUAL( 0, mbedtls_ccm_update_ad( ctx, add->x + n1_add, n2_add ) );

    /* Allocate a tight buffer for each update call. This way, if the function
     * tries to write beyond the advertised required buffer size, this will
     * count as an overflow for memory sanitizers and static checkers. */
    ASSERT_ALLOC( output, n1 );
    olen = 0xdeadbeef;
    TEST_EQUAL( 0, mbedtls_ccm_update( ctx, input->x, n1, output, n1, &olen ) );
    TEST_EQUAL( n1, olen );
    ASSERT_COMPARE( output, olen, expected_output->x, n1 );
    mbedtls_free( output );
    output = NULL;

    ASSERT_ALLOC( output, n2 );
    olen = 0xdeadbeef;
    TEST_EQUAL( 0, mbedtls_ccm_update( ctx, input->x + n1, n2, output, n2, &olen ) );
    TEST_EQUAL( n2, olen );
    ASSERT_COMPARE( output, olen, expected_output->x + n1, n2 );
    mbedtls_free( output );
    output = NULL;

    if( tag->len == 0 )
        ASSERT_ALLOC( output, 16 );
    else
        ASSERT_ALLOC( output, tag->len );
    TEST_EQUAL( 0, mbedtls_ccm_finish( ctx, output, tag->len ) );
    ASSERT_COMPARE( output, tag->len, tag->x, tag->len );
    mbedtls_free( output );
    output = NULL;

    ok = 1;
exit:
    mbedtls_free( output );
    return( ok );
}
/* 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 n1, n1_add;
    uint8_t* io_msg_buf = NULL;
    uint8_t* tag_buf = NULL;
    const size_t expected_tag_len = result->len - msg->len;
    const uint8_t* expected_tag = result->x + msg->len;

    /* Prepare input/output message buffer */
    ASSERT_ALLOC( io_msg_buf, msg->len );
    if( msg->len != 0 )
        memcpy( io_msg_buf, msg->x, msg->len );

    /* Prepare tag buffer */
    ASSERT_ALLOC( tag_buf, expected_tag_len );

    mbedtls_ccm_init( &ctx );
    TEST_EQUAL( mbedtls_ccm_setkey( &ctx, cipher_id, key->x, key->len * 8 ), 0 );
    /* Test with input == output */
    TEST_EQUAL( mbedtls_ccm_encrypt_and_tag( &ctx, msg->len, iv->x, iv->len, add->x, add->len,
                io_msg_buf, io_msg_buf, tag_buf, expected_tag_len ), 0);

    ASSERT_COMPARE( io_msg_buf, msg->len, result->x, msg->len );
    ASSERT_COMPARE( tag_buf, expected_tag_len, expected_tag, expected_tag_len );

    /* Prepare data_t structers for multipart testing */
    const data_t encrypted_expected = { .x = result->x,
                                        .len = msg->len };
    const data_t tag_expected = { .x = (uint8_t*) expected_tag, /* cast to conform with data_t x type */
                                  .len = expected_tag_len };

    for( n1 = 0; n1 <= msg->len; n1 += 1 )
    {
        for( n1_add = 0; n1_add <= add->len; n1_add += 1 )
        {
            mbedtls_test_set_step( n1 * 10000 + n1_add );
            if( !check_multipart( &ctx, MBEDTLS_CCM_ENCRYPT,
                                  iv, add, msg,
                                  &encrypted_expected,
                                  &tag_expected,
                                  n1, n1_add ) )
                goto exit;
        }
    }

exit:
    mbedtls_ccm_free( &ctx );
    mbedtls_free( io_msg_buf );
    mbedtls_free( tag_buf );
}
/* 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 expected_tag_len, int result,
                               data_t * expected_msg )
{
    mbedtls_ccm_context ctx;
    size_t n1, n1_add;

    const size_t expected_msg_len = msg->len - expected_tag_len;
    const uint8_t* expected_tag = msg->x + expected_msg_len;

    /* Prepare input/output message buffer */
    uint8_t* io_msg_buf = NULL;
    ASSERT_ALLOC( io_msg_buf, expected_msg_len );
    if( expected_msg_len )
        memcpy( io_msg_buf, msg->x, expected_msg_len );

    mbedtls_ccm_init( &ctx );
    TEST_EQUAL( mbedtls_ccm_setkey( &ctx, cipher_id, key->x, key->len * 8 ), 0 );
    /* Test with input == output */
    TEST_EQUAL( mbedtls_ccm_auth_decrypt( &ctx, expected_msg_len, iv->x, iv->len, add->x, add->len,
                io_msg_buf, io_msg_buf, expected_tag, expected_tag_len ), result );

    if( result == 0 )
    {
        ASSERT_COMPARE( io_msg_buf, expected_msg_len, expected_msg->x, expected_msg_len );

         /* Prepare data_t structers for multipart testing */
        const data_t encrypted = { .x = msg->x,
                                   .len = expected_msg_len };

        const data_t tag_expected = { .x = (uint8_t*) expected_tag,
                                      .len = expected_tag_len };

        for( n1 = 0; n1 <= expected_msg_len; n1 += 1 )
        {
            for( n1_add = 0; n1_add <= add->len; n1_add += 1 )
            {
                mbedtls_test_set_step( n1 * 10000 + n1_add );
                if( !check_multipart( &ctx, MBEDTLS_CCM_DECRYPT,
                                iv, add, &encrypted,
                                expected_msg,
                                &tag_expected,
                                n1, n1_add ) )
                    goto exit;
           }
        }
    }
    else
    {
        size_t i;

        for( i = 0; i < expected_msg_len; i++ )
            TEST_EQUAL( io_msg_buf[i], 0 );
    }

exit:
    mbedtls_free(io_msg_buf);
    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];
    mbedtls_ccm_context ctx;
    size_t iv_len, expected_tag_len;
    size_t n1, n1_add;
    uint8_t* io_msg_buf = NULL;
    uint8_t* tag_buf = NULL;

    const uint8_t* expected_tag = expected_result->x + msg->len;

    /* Calculate tag length */
    if( sec_level % 4 == 0)
        expected_tag_len = 0;
    else
        expected_tag_len = 1 << ( sec_level % 4 + 1);

    /* Prepare input/output message buffer */
    ASSERT_ALLOC( io_msg_buf, msg->len );
    if( msg->len )
        memcpy( io_msg_buf, msg->x, msg->len );

    /* Prepare tag buffer */
    if( expected_tag_len == 0 )
        ASSERT_ALLOC( tag_buf, 16 );
    else
        ASSERT_ALLOC( tag_buf, expected_tag_len );

    /* Calculate iv */
    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 );

    mbedtls_ccm_init( &ctx );
    TEST_EQUAL( mbedtls_ccm_setkey( &ctx, cipher_id,
                                     key->x, key->len * 8 ), 0 );
    /* Test with input == output */
    TEST_EQUAL( mbedtls_ccm_star_encrypt_and_tag( &ctx, msg->len, iv, iv_len,
                                            add->x, add->len, io_msg_buf,
                                            io_msg_buf, tag_buf, expected_tag_len), output_ret );

    ASSERT_COMPARE( io_msg_buf, msg->len, expected_result->x, msg->len );
    ASSERT_COMPARE( tag_buf, expected_tag_len, expected_tag, expected_tag_len );

    if( output_ret == 0 )
    {
        const data_t iv_data = { .x = iv,
                                 .len = iv_len };

        const data_t encrypted_expected = { .x = expected_result->x,
                                            .len = msg->len };
        const data_t tag_expected = { .x = (uint8_t*)expected_tag,
                                      .len = expected_tag_len };

        for( n1 = 0; n1 <= msg->len; n1 += 1 )
        {
            for( n1_add = 0; n1_add <= add->len; n1_add += 1 )
            {
                mbedtls_test_set_step( n1 * 10000 + n1_add );
                if( !check_multipart( &ctx, MBEDTLS_CCM_STAR_ENCRYPT,
                                      &iv_data, add, msg,
                                      &encrypted_expected,
                                      &tag_expected,
                                      n1, n1_add ) )
                    goto exit;
            }
        }
    }

exit:
    mbedtls_ccm_free( &ctx );
    mbedtls_free( io_msg_buf );
    mbedtls_free( tag_buf );
}
/* 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];
    mbedtls_ccm_context ctx;
    size_t iv_len, expected_tag_len;
    size_t n1, n1_add;

    /* Calculate tag length */
    if( sec_level % 4 == 0)
        expected_tag_len = 0;
    else
        expected_tag_len = 1 << ( sec_level % 4 + 1);

    const size_t expected_msg_len = msg->len - expected_tag_len;
    const uint8_t* expected_tag = msg->x + expected_msg_len;

    /* Prepare input/output message buffer */
    uint8_t* io_msg_buf = NULL;
    ASSERT_ALLOC( io_msg_buf, expected_msg_len );
    if( expected_msg_len )
        memcpy( io_msg_buf, msg->x, expected_msg_len );

    /* Calculate iv */
    memset( iv, 0x00, sizeof( iv ) );
    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 );

    mbedtls_ccm_init( &ctx );
    TEST_ASSERT( mbedtls_ccm_setkey( &ctx, cipher_id, key->x, key->len * 8 ) == 0 );
    /* Test with input == output */
    TEST_EQUAL( mbedtls_ccm_star_auth_decrypt( &ctx, expected_msg_len, iv, iv_len,
                                         add->x, add->len, io_msg_buf, io_msg_buf,
                                         expected_tag, expected_tag_len ), output_ret );

    ASSERT_COMPARE( io_msg_buf, expected_msg_len, expected_result->x, expected_msg_len );

    if( output_ret == 0 )
    {
        const data_t iv_data = { .x = iv,
                                 .len = iv_len };

        const data_t encrypted = { .x = msg->x,
                                   .len = expected_msg_len} ;

        const data_t tag_expected = { .x = (uint8_t*) expected_tag,
                                      .len = expected_tag_len };

        for( n1 = 0; n1 <= expected_msg_len; n1 += 1 )
        {
            for( n1_add = 0; n1_add <= add->len; n1_add += 1 )
            {
                mbedtls_test_set_step( n1 * 10000 + n1_add );
                if( !check_multipart( &ctx, MBEDTLS_CCM_STAR_DECRYPT,
                                &iv_data, add, &encrypted,
                                expected_result,
                                &tag_expected,
                                n1, n1_add ) )
                    goto exit;
           }
        }
    }

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