/* BEGIN_HEADER */
#include <polarssl/ctr_drbg.h>

#include <string.h>

int test_offset_idx;
int entropy_func( void *data, unsigned char *buf, size_t len )
{
    const unsigned char *p = (unsigned char *) data;
    memcpy( buf, p + test_offset_idx, len );
    test_offset_idx += len;
    return( 0 );
}
/* END_HEADER */

/* BEGIN_DEPENDENCIES
 * depends_on:POLARSSL_CTR_DRBG_C
 * END_DEPENDENCIES
 */

/* BEGIN_CASE */
void ctr_drbg_validate_pr( char *add_init_string, char *entropy_string,
                           char *add1_string, char *add2_string,
                           char *result_str )
{
    unsigned char entropy[512];
    unsigned char add_init[512];
    unsigned char add1[512];
    unsigned char add2[512];
    ctr_drbg_context ctx;
    unsigned char buf[512];
    unsigned char output_str[512];
    int add_init_len, add1_len, add2_len;

    memset( output_str, 0, 512 );

    unhexify( entropy, entropy_string );
    add_init_len = unhexify( add_init, add_init_string );
    add1_len = unhexify( add1, add1_string );
    add2_len = unhexify( add2, add2_string );

    test_offset_idx = 0;
    TEST_ASSERT( ctr_drbg_init_entropy_len( &ctx, entropy_func, entropy, add_init, add_init_len, 32 ) == 0 );
    ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON );

    TEST_ASSERT( ctr_drbg_random_with_add( &ctx, buf, 16, add1, add1_len ) == 0 );
    TEST_ASSERT( ctr_drbg_random_with_add( &ctx, buf, 16, add2, add2_len ) == 0 );
    hexify( output_str, buf, 16 );
    TEST_ASSERT( strcmp( (char *) output_str, result_str ) == 0 );

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

/* BEGIN_CASE */
void ctr_drbg_validate_nopr( char *add_init_string, char *entropy_string,
                             char *add1_string, char *add_reseed_string,
                             char *add2_string, char *result_str )
{
    unsigned char entropy[512];
    unsigned char add_init[512];
    unsigned char add1[512];
    unsigned char add_reseed[512];
    unsigned char add2[512];
    ctr_drbg_context ctx;
    unsigned char buf[512];
    unsigned char output_str[512];
    int add_init_len, add1_len, add_reseed_len, add2_len;

    memset( output_str, 0, 512 );

    unhexify( entropy, entropy_string );
    add_init_len = unhexify( add_init, add_init_string );
    add1_len = unhexify( add1, add1_string );
    add_reseed_len = unhexify( add_reseed, add_reseed_string );
    add2_len = unhexify( add2, add2_string );

    test_offset_idx = 0;
    TEST_ASSERT( ctr_drbg_init_entropy_len( &ctx, entropy_func, entropy, add_init, add_init_len, 32 ) == 0 );

    TEST_ASSERT( ctr_drbg_random_with_add( &ctx, buf, 16, add1, add1_len ) == 0 );
    TEST_ASSERT( ctr_drbg_reseed( &ctx, add_reseed, add_reseed_len ) == 0 );
    TEST_ASSERT( ctr_drbg_random_with_add( &ctx, buf, 16, add2, add2_len ) == 0 );
    hexify( output_str, buf, 16 );
    TEST_ASSERT( strcmp( (char *) output_str, result_str ) == 0 );

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

/* BEGIN_CASE */
void ctr_drbg_entropy_usage( )
{
    unsigned char out[16];
    unsigned char add[16];
    unsigned char entropy[1024];
    ctr_drbg_context ctx;
    size_t i, reps = 10;
    int last_idx;

    test_offset_idx = 0;
    memset( entropy, 0, sizeof( entropy ) );
    memset( out, 0, sizeof( out ) );
    memset( add, 0, sizeof( add ) );

    /* Init must use entropy */
    last_idx = test_offset_idx;
    TEST_ASSERT( ctr_drbg_init( &ctx, entropy_func, entropy, NULL, 0 ) == 0 );
    TEST_ASSERT( last_idx < test_offset_idx );

    /* By default, PR is off and reseed_interval is large,
     * so the next few calls should not use entropy */
    last_idx = test_offset_idx;
    for( i = 0; i < reps; i++ )
    {
        TEST_ASSERT( ctr_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 );
        TEST_ASSERT( ctr_drbg_random_with_add( &ctx, out, sizeof( out ) - 4,
                                                add, sizeof( add ) ) == 0 );
    }
    TEST_ASSERT( last_idx == test_offset_idx );

    /* While at it, make sure we didn't write past the requested length */
    TEST_ASSERT( out[sizeof( out ) - 4] == 0 );
    TEST_ASSERT( out[sizeof( out ) - 3] == 0 );
    TEST_ASSERT( out[sizeof( out ) - 2] == 0 );
    TEST_ASSERT( out[sizeof( out ) - 1] == 0 );

    /* Set reseed_interval to the number of calls done,
     * so the next call should reseed */
    ctr_drbg_set_reseed_interval( &ctx, 2 * reps );
    TEST_ASSERT( ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
    TEST_ASSERT( last_idx < test_offset_idx );

    /* The new few calls should not reseed */
    last_idx = test_offset_idx;
    for( i = 0; i < reps / 2; i++ )
    {
        TEST_ASSERT( ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
        TEST_ASSERT( ctr_drbg_random_with_add( &ctx, out, sizeof( out ) ,
                                                add, sizeof( add ) ) == 0 );
    }
    TEST_ASSERT( last_idx == test_offset_idx );

    /* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT)
     * (just make sure it doesn't cause memory corruption) */
    ctr_drbg_update( &ctx, entropy, sizeof( entropy ) );

    /* Now enable PR, so the next few calls should all reseed */
    ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON );
    TEST_ASSERT( ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
    TEST_ASSERT( last_idx < test_offset_idx );

    /* Finally, check setting entropy_len */
    ctr_drbg_set_entropy_len( &ctx, 42 );
    last_idx = test_offset_idx;
    TEST_ASSERT( ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
    TEST_ASSERT( test_offset_idx - last_idx == 42 );

    ctr_drbg_set_entropy_len( &ctx, 13 );
    last_idx = test_offset_idx;
    TEST_ASSERT( ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
    TEST_ASSERT( test_offset_idx - last_idx == 13 );

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

/* BEGIN_CASE depends_on:POLARSSL_FS_IO */
void ctr_drbg_seed_file( char *path, int ret )
{
    ctr_drbg_context ctx;

    TEST_ASSERT( ctr_drbg_init( &ctx, rnd_std_rand, NULL, NULL, 0 ) == 0 );
    TEST_ASSERT( ctr_drbg_write_seed_file( &ctx, path ) == ret );
    TEST_ASSERT( ctr_drbg_update_seed_file( &ctx, path ) == ret );

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

/* BEGIN_CASE depends_on:POLARSSL_SELF_TEST */
void ctr_drbg_selftest( )
{
    TEST_ASSERT( ctr_drbg_self_test( 0 ) == 0 );
}
/* END_CASE */
