/* BEGIN_HEADER */
#include "mbedtls/chacha20.h"
/* END_HEADER */

/* BEGIN_DEPENDENCIES
 * depends_on:MBEDTLS_CHACHA20_C
 * END_DEPENDENCIES
 */

/* BEGIN_CASE */
void chacha20_crypt( char *hex_key_string,
                     char *hex_nonce_string,
                     int counter,
                     char *hex_src_string,
                     char *hex_dst_string )
{
    unsigned char key_str[32]; /* size set by the standard */
    unsigned char nonce_str[12]; /* size set by the standard */
    unsigned char src_str[375]; /* max size of binary input */
    unsigned char dst_str[751]; /* hex expansion of the above */
    unsigned char output[751];
    size_t key_len;
    size_t nonce_len;
    size_t src_len;
    size_t dst_len;
    mbedtls_chacha20_context ctx;

    memset( key_str,    0x00, sizeof( key_str ) );
    memset( nonce_str,  0x00, sizeof( nonce_str ) );
    memset( src_str,    0x00, sizeof( src_str ) );
    memset( dst_str,    0x00, sizeof( dst_str ) );
    memset( output,     0x00, sizeof( output ) );

    key_len   = unhexify( key_str, hex_key_string );
    nonce_len = unhexify( nonce_str, hex_nonce_string );
    src_len   = unhexify( src_str, hex_src_string );
    dst_len   = unhexify( dst_str, hex_dst_string );

    TEST_ASSERT( src_len   == dst_len );
    TEST_ASSERT( key_len   == 32U );
    TEST_ASSERT( nonce_len == 12U );

    /*
     * Test the integrated API
     */
    TEST_ASSERT( mbedtls_chacha20_crypt( key_str, nonce_str, counter, src_len, src_str, output ) == 0 );

    hexify( dst_str, output, src_len );
    TEST_ASSERT( strcmp( (char*) dst_str, hex_dst_string ) == 0 );

    /*
     * Test the streaming API
     */
    mbedtls_chacha20_init( &ctx );

    TEST_ASSERT( mbedtls_chacha20_setkey( &ctx, key_str ) == 0 );

    TEST_ASSERT( mbedtls_chacha20_starts( &ctx, nonce_str, counter ) == 0 );

    memset( output, 0x00, sizeof( output ) );
    TEST_ASSERT( mbedtls_chacha20_update( &ctx, src_len, src_str, output ) == 0 );

    hexify( dst_str, output, src_len );
    TEST_ASSERT( strcmp( (char*) dst_str, hex_dst_string ) == 0 );

    /*
     * Test the streaming API again, piecewise
     */

    /* Don't free/init the context nor set the key again,
     * in order to test that starts() does the right thing. */
    TEST_ASSERT( mbedtls_chacha20_starts( &ctx, nonce_str, counter ) == 0 );

    memset( output, 0x00, sizeof( output ) );
    TEST_ASSERT( mbedtls_chacha20_update( &ctx, 1, src_str, output ) == 0 );
    TEST_ASSERT( mbedtls_chacha20_update( &ctx, src_len - 1, src_str + 1, output + 1 ) == 0 );

    hexify( dst_str, output, src_len );
    TEST_ASSERT( strcmp( (char*) dst_str, hex_dst_string ) == 0 );

    mbedtls_chacha20_free( &ctx );
}
/* END_CASE */

/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
void chacha20_bad_params()
{
    unsigned char key[32];
    unsigned char nonce[12];
    unsigned char src[1];
    unsigned char dst[1];
    uint32_t counter = 0;
    size_t len = sizeof( src );
    mbedtls_chacha20_context ctx;

    TEST_INVALID_PARAM( mbedtls_chacha20_init( NULL ) );
    TEST_VALID_PARAM( mbedtls_chacha20_free( NULL ) );

    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
                            mbedtls_chacha20_setkey( NULL, key ) );
    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
                            mbedtls_chacha20_setkey( &ctx, NULL ) );

    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
                            mbedtls_chacha20_starts( NULL, nonce, counter ) );
    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
                            mbedtls_chacha20_starts( &ctx, NULL, counter ) );

    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
                            mbedtls_chacha20_update( NULL, 0, src, dst ) );
    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
                            mbedtls_chacha20_update( &ctx, len, NULL, dst ) );
    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
                            mbedtls_chacha20_update( &ctx, len, src, NULL ) );

    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
                            mbedtls_chacha20_crypt( NULL, nonce, counter, 0, src, dst ) );
    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
                            mbedtls_chacha20_crypt( key, NULL, counter, 0, src, dst ) );
    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
                            mbedtls_chacha20_crypt( key, nonce, counter, len, NULL, dst ) );
    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA,
                            mbedtls_chacha20_crypt( key, nonce, counter, len, src, NULL ) );

exit:
    return;

}
/* END_CASE */

/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void chacha20_self_test()
{
    TEST_ASSERT( mbedtls_chacha20_self_test( 1 ) == 0 );
}
/* END_CASE */
