/* BEGIN_HEADER */
#include <stdint.h>
#include <string.h>

#include <psa/crypto.h>

#include "mbedtls/entropy.h"
#include "entropy_poll.h"

/* Calculating the minimum allowed entropy size in bytes */
#define MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)

#if defined(MBEDTLS_PSA_INJECT_ENTROPY)

#if defined(MBEDTLS_PSA_ITS_FILE_C)
#include <stdio.h>
#else
#include <psa/internal_trusted_storage.h>
#endif

/* Remove the entropy seed file. Since the library does not expose a way
 * to do this (it would be a security risk if such a function was ever
 * accessible in production), implement this functionality in a white-box
 * manner. */
psa_status_t remove_seed_file( void )
{
#if defined(MBEDTLS_PSA_ITS_FILE_C)
    if( remove( "00000000ffffff52.psa_its" ) == 0 )
        return( PSA_SUCCESS );
    else
        return( PSA_ERROR_DOES_NOT_EXIST );
#else
    return( psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID ) );
#endif
}

#endif /* MBEDTLS_PSA_INJECT_ENTROPY */

/* END_HEADER */

/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
void external_rng_failure_generate( )
{
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
    psa_set_key_bits( &attributes, 128 );
    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
    uint8_t output[1];

    PSA_ASSERT( psa_crypto_init( ) );

    PSA_ASSERT( psa_generate_random( output, sizeof( output ) ) );
    PSA_ASSERT( psa_generate_key( &attributes, &key ) );
    PSA_ASSERT( psa_destroy_key( key ) );

    mbedtls_test_disable_insecure_external_rng( );
    TEST_EQUAL( PSA_ERROR_INSUFFICIENT_ENTROPY,
                psa_generate_random( output, sizeof( output ) ) );
    TEST_EQUAL( PSA_ERROR_INSUFFICIENT_ENTROPY,
                psa_generate_key( &attributes, &key ) );

exit:
    psa_destroy_key( key );
    PSA_DONE( );
}
/* END_CASE */

/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
void external_rng_failure_sign( int key_type, data_t *key_data, int alg,
                                int input_size_arg )
{
    /* This test case is only expected to pass if the signature mechanism
     * requires randomness, either because it is a randomized signature
     * or because the implementation uses blinding. */

    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_set_key_type( &attributes, key_type );
    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
    psa_set_key_algorithm( &attributes, alg );
    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
    size_t input_size = input_size_arg;
    uint8_t *input = NULL;
    uint8_t *signature = NULL;
    size_t signature_size = PSA_SIGNATURE_MAX_SIZE;
    size_t signature_length;

    ASSERT_ALLOC( input, input_size );
    ASSERT_ALLOC( signature, signature_size );

    PSA_ASSERT( psa_crypto_init( ) );
    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                &key ) );
    PSA_ASSERT( psa_sign_hash( key, alg,
                               input, input_size,
                               signature, signature_size,
                               &signature_length ) );
    PSA_ASSERT( psa_destroy_key( key ) );

    mbedtls_test_disable_insecure_external_rng( );
    /* Import the key again, because for RSA Mbed TLS caches blinding values
     * in the key object and this could perturb the test. */
    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                &key ) );
    TEST_EQUAL( PSA_ERROR_INSUFFICIENT_ENTROPY,
                psa_sign_hash( key, alg,
                               input, input_size,
                               signature, signature_size,
                               &signature_length ) );
    PSA_ASSERT( psa_destroy_key( key ) );

exit:
    psa_destroy_key( key );
    PSA_DONE( );
    mbedtls_free( input );
    mbedtls_free( signature );
}
/* END_CASE */

/* BEGIN_CASE depends_on:MBEDTLS_PSA_INJECT_ENTROPY */
void validate_entropy_seed_injection( int seed_length_a,
                                      int expected_status_a,
                                      int seed_length_b,
                                      int expected_status_b )
{
    psa_status_t status;
    uint8_t output[32] = { 0 };
    uint8_t zeros[32] = { 0 };
    uint8_t *seed = NULL;
    int i;
    int seed_size;
    if( seed_length_a > seed_length_b )
    {
        seed_size = seed_length_a;
    }
    else
    {
        seed_size = seed_length_b;
    }
    ASSERT_ALLOC( seed, seed_size );
    /* fill seed with some data */
    for( i = 0; i < seed_size; ++i )
    {
        seed[i] = i;
    }
    status =  remove_seed_file( );
    TEST_ASSERT( ( status == PSA_SUCCESS ) ||
                 ( status == PSA_ERROR_DOES_NOT_EXIST ) );
    status = mbedtls_psa_inject_entropy( seed, seed_length_a );
    TEST_EQUAL( status, expected_status_a );
    status = mbedtls_psa_inject_entropy( seed, seed_length_b );
    TEST_EQUAL( status, expected_status_b );
    PSA_ASSERT( psa_crypto_init( ) );
    PSA_ASSERT( psa_generate_random( output,
                                     sizeof( output ) ) );
    TEST_ASSERT( memcmp( output, zeros, sizeof( output ) ) != 0 );
exit:
    mbedtls_free( seed );
    remove_seed_file( );
    PSA_DONE( );
}
/* END_CASE */

/* BEGIN_CASE depends_on:MBEDTLS_PSA_INJECT_ENTROPY */
void run_entropy_inject_with_crypto_init( )
{
    psa_status_t status;
    size_t i;
    uint8_t seed[MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE] = { 0 };
    /* fill seed with some data */
    for( i = 0; i < sizeof( seed ); ++i )
    {
        seed[i] = i;
    }
    status =  remove_seed_file( );
    TEST_ASSERT( ( status == PSA_SUCCESS ) ||
                 ( status == PSA_ERROR_DOES_NOT_EXIST ) );
    status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) );
    PSA_ASSERT( status );
    status =  remove_seed_file( );
    TEST_EQUAL( status, PSA_SUCCESS );
    status = psa_crypto_init( );
    TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_ENTROPY );
    status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) );
    PSA_ASSERT( status );
    status = psa_crypto_init( );
    PSA_ASSERT( status );
    PSA_DONE( );
    /* The seed is written by nv_seed callback functions therefore the injection will fail */
    status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) );
    TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
exit:
    remove_seed_file( );
    PSA_DONE( );
}
/* END_CASE */
