From 8b4f7578b703cdf157c8bb68a4754f38aafdc6fe Mon Sep 17 00:00:00 2001 From: Francois Beerten Date: Mon, 28 Feb 2022 14:37:14 +0100 Subject: [PATCH] psa: entropy: add entropy source using PSA entropy collection entry points MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drivers can have entry points to collect entropy. The automatically generated PSA driver wrapper code will call each driver entry point. An entropy source inside Mbed TLS will use psa_driver_collect_entropy(). Signed-off-by: François Beerten Signed-off-by: Francois Beerten --- include/mbedtls/mbedtls_config.h | 11 ++++ library/entropy.c | 5 ++ library/entropy_poll.c | 66 +++++++++++++++++++ library/entropy_poll.h | 9 +++ library/psa_crypto_driver_wrappers.h | 20 ++++++ .../psa_crypto_driver_wrappers.c.jinja | 28 ++++++++ tests/suites/helpers.function | 1 + 7 files changed, 140 insertions(+) diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index e96a7973312..659c8739c6d 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -1191,6 +1191,17 @@ */ //#define MBEDTLS_PSA_CRYPTO_DRIVERS +/** \def MBEDTLS_ENTROPY_PSA + * + * Enable support for entropy collection via the PSA crypto driver interface. + * + * Requires: MBEDTLS_PSA_CRYPTO_DRIVERS + * + * \warning This interface is experimental and may change or be removed + * without notice. + */ +//#define MBEDTLS_ENTROPY_PSA + /** \def MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG * * Make the PSA Crypto module use an external random generator provided diff --git a/library/entropy.c b/library/entropy.c index 08c5bd7d16d..d9719b0ae11 100644 --- a/library/entropy.c +++ b/library/entropy.c @@ -78,6 +78,11 @@ void mbedtls_entropy_init( mbedtls_entropy_context *ctx ) MBEDTLS_ENTROPY_MIN_HARDWARE, MBEDTLS_ENTROPY_SOURCE_STRONG ); #endif +#if defined(MBEDTLS_ENTROPY_PSA) + mbedtls_entropy_add_source( ctx, mbedtls_psa_entropy_poll, NULL, + 0, + MBEDTLS_ENTROPY_SOURCE_STRONG ); +#endif #if defined(MBEDTLS_ENTROPY_NV_SEED) mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL, MBEDTLS_ENTROPY_BLOCK_SIZE, diff --git a/library/entropy_poll.c b/library/entropy_poll.c index 2ae57fdc09a..81f785113c4 100644 --- a/library/entropy_poll.c +++ b/library/entropy_poll.c @@ -38,6 +38,10 @@ #if defined(MBEDTLS_ENTROPY_NV_SEED) || !defined(HAVE_SYSCTL_ARND) #include "mbedtls/platform.h" #endif +#if defined(MBEDTLS_ENTROPY_PSA) +#include "psa_crypto_core.h" +#include "psa_crypto_driver_wrappers.h" +#endif #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) @@ -214,6 +218,68 @@ int mbedtls_platform_entropy_poll( void *data, #endif /* _WIN32 && !EFIX64 && !EFI32 */ #endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */ +#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) && defined(MBEDTLS_ENTROPY_PSA) +psa_status_t mbedtls_accumulate_psa_entropy(struct psa_entropy_acc *acc, + size_t estimate_bits, uint8_t *p) +{ + int ret; + +#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) + ret = mbedtls_sha512_update( &acc->hashctxt, p, MBEDTLS_ENTROPY_BLOCK_SIZE ); +#else + ret = mbedtls_sha256_update( &acc->hashctxt, p, MBEDTLS_ENTROPY_BLOCK_SIZE ); +#endif + acc->estimate_bits += estimate_bits; + + return mbedtls_to_psa_error( ret ); +} + +int mbedtls_psa_entropy_poll( void *data, unsigned char *output, size_t len, + size_t *olen ) +{ + struct psa_entropy_acc acc; + int ret; + uint8_t buf[MBEDTLS_ENTROPY_MAX_GATHER]; + + ((void) data); + *olen = 0; + + acc.estimate_bits = 0; +#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) + ret = mbedtls_sha512_starts( &acc.hashctxt, 0 ); +#else + ret = mbedtls_sha256_starts( &acc.hashctxt, 0 ); +#endif + if( ret ) + goto cleanup; + + ret = psa_driver_collect_entropy( MBEDTLS_ENTROPY_BLOCK_SIZE, buf, &acc ); + if( ret != PSA_SUCCESS ) { + ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; + goto cleanup; + } + +#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) + ret = mbedtls_sha512_finish( &acc.hashctxt, buf ); +#else + ret = mbedtls_sha256_finish( &acc.hashctxt, buf ); +#endif + if( ret ) + goto cleanup; + + *olen = acc.estimate_bits / 8; + if ( *olen > len ) + *olen = len; + memcpy(output, buf, *olen); + +cleanup: + mbedtls_platform_zeroize( buf, sizeof( buf ) ); + mbedtls_platform_zeroize( &acc.hashctxt, sizeof( acc.hashctxt ) ); + + return ret; +} +#endif /* MBEDTLS_ENTROPY_PSA */ + #if defined(MBEDTLS_ENTROPY_NV_SEED) int mbedtls_nv_seed_poll( void *data, unsigned char *output, size_t len, size_t *olen ) diff --git a/library/entropy_poll.h b/library/entropy_poll.h index aef1a0977d4..85a38d1ef74 100644 --- a/library/entropy_poll.h +++ b/library/entropy_poll.h @@ -59,6 +59,15 @@ int mbedtls_hardware_poll( void *data, unsigned char *output, size_t len, size_t *olen ); #endif + +#if defined(MBEDTLS_ENTROPY_PSA) +/** + * \brief Entropy poll callback for a PSA crypto driver sources + */ +int mbedtls_psa_entropy_poll( void *data, unsigned char *output, size_t len, + size_t *olen ); +#endif + #if defined(MBEDTLS_ENTROPY_NV_SEED) /** * \brief Entropy poll callback for a non-volatile seed file diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h index 12c649da37f..06745ffc9c1 100644 --- a/library/psa_crypto_driver_wrappers.h +++ b/library/psa_crypto_driver_wrappers.h @@ -361,6 +361,26 @@ psa_status_t psa_driver_wrapper_asymmetric_decrypt( size_t output_size, size_t *output_length ); +/* + * Entropy entry points + */ +struct psa_entropy_acc { + unsigned int estimate_bits; +#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) + mbedtls_sha512_context hashctxt; +#elif defined(MBEDTLS_ENTROPY_SHA256_ACCUMULATOR) + mbedtls_sha256_context hashctxt; +#endif +}; + +psa_status_t mbedtls_accumulate_psa_entropy(struct psa_entropy_acc *acc, + size_t estimate_bits, uint8_t *p); + +psa_status_t psa_driver_collect_entropy( + size_t sz, + uint8_t *buf, + struct psa_entropy_acc *acc ); + #endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */ /* End of automatically generated file. */ diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja index a5ae6a29e46..aa5c7ae5ffe 100644 --- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja +++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja @@ -2468,4 +2468,32 @@ psa_status_t psa_driver_wrapper_asymmetric_decrypt( } } +/* + * Entropy collection + */ +struct psa_entropy_acc; + +psa_status_t psa_driver_collect_entropy( size_t sz, uint8_t *buf, struct psa_entropy_acc *acc ) +{ + size_t estimate_bits = 0; + psa_status_t status = PSA_SUCCESS; + +{% if not entropydrivers %} + (void)sz; + (void)buf; + (void)acc; + (void)estimate_bits; +{% endif %} +{% for driver in entropydrivers %} + status = $driver(PSA_DRIVER_GET_ENTROPY_BLOCK, &estimate_bits, buf, sz); + if( status ) + return status; + status = mbedtls_accumulate_psa_entropy(acc, estimate_bits, buf); + if( status ) + return status; +{% endfor %} + + return status; +} + #endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function index a620178f616..d6756eea54b 100644 --- a/tests/suites/helpers.function +++ b/tests/suites/helpers.function @@ -87,6 +87,7 @@ typedef struct data_tag #if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) && \ ( !defined(MBEDTLS_NO_PLATFORM_ENTROPY) || \ defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \ + defined(MBEDTLS_ENTROPY_PSA) || \ defined(ENTROPY_NV_SEED) ) #define ENTROPY_HAVE_STRONG #endif