From 2bcd312cda2f1eafaf827ae389963f2591d8f043 Mon Sep 17 00:00:00 2001 From: Netanel Gonen Date: Mon, 19 Nov 2018 11:53:02 +0200 Subject: [PATCH] Add entropy injection function to psa cripto APIs --- include/psa/crypto_extra.h | 27 +++++++++++++++++++++++++++ library/psa_crypto.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 2d03f7311..f39f33963 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -34,6 +34,9 @@ extern "C" { #endif +/* UID for secure storage seed */ +#define MBED_RANDOM_SEED_ITS_UID 0xFFFFFF52 + /** * \brief Library deinitialization. * @@ -44,6 +47,30 @@ extern "C" { */ void mbedtls_psa_crypto_free( void ); + +#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) ) +/** + * \brief Inject initial entropy seed into persistent storage for random capabilities. + * + * \warning This function **can** fail! Callers MUST check the return status. + * + * \note To use this function both mbedtls_nv_seed_read and mbedtls_nv_seed_write + * must be defined. + * + * \param seed[in] Buffer storing the seed value to inject. + * \param seed_size[in] Size of the \p seed buffer. The minimum size of the seed is MBEDTLS_ENTROPY_MIN_PLATFORM + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_BAD_STATE + */ +psa_status_t mbedtls_psa_inject_entropy(const unsigned char *seed, + size_t seed_size); + +#endif + #ifdef __cplusplus } #endif diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 58cb73830..77314f2dd 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -69,6 +69,7 @@ #include "mbedtls/ecdh.h" #include "mbedtls/ecp.h" #include "mbedtls/entropy.h" +#include "mbedtls/entropy_poll.h" #include "mbedtls/error.h" #include "mbedtls/gcm.h" #include "mbedtls/md2.h" @@ -85,7 +86,9 @@ #include "mbedtls/sha512.h" #include "mbedtls/xtea.h" - +#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) ) +#include "psa_prot_internal_storage.h" +#endif #define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) ) @@ -4223,6 +4226,30 @@ psa_status_t psa_generate_random( uint8_t *output, return( mbedtls_to_psa_error( ret ) ); } +#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) ) +psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed, + size_t seed_size ) +{ + psa_status_t status; + struct psa_its_info_t p_info; + if( global_data.initialized ) + return( PSA_ERROR_NOT_PERMITTED ); + if( ( seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM ) || ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) ) + return( PSA_ERROR_INVALID_ARGUMENT ); + status = psa_its_get_info( MBED_RANDOM_SEED_ITS_UID, &p_info ); + if( PSA_ITS_ERROR_KEY_NOT_FOUND == status ) /* No seed exists */ + { + status = psa_its_set( MBED_RANDOM_SEED_ITS_UID, seed_size, seed, 0 ); + } + else if( PSA_ITS_SUCCESS == status ) + { + /* You should not be here. Seed needs to be injected only once */ + status = PSA_ERROR_NOT_PERMITTED; + } + return( status ); +} +#endif + psa_status_t psa_generate_key( psa_key_slot_t key, psa_key_type_t type, size_t bits,