diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 479da96008..2ec0381a49 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -76,6 +76,7 @@ set(src_crypto psa_crypto_mac.c psa_crypto_pake.c psa_crypto_rsa.c + psa_crypto_random.c psa_crypto_se.c psa_crypto_slot_management.c psa_crypto_storage.c diff --git a/library/Makefile b/library/Makefile index 6692a81f61..4e368efb86 100644 --- a/library/Makefile +++ b/library/Makefile @@ -167,6 +167,7 @@ OBJS_CRYPTO= \ psa_crypto_hash.o \ psa_crypto_mac.o \ psa_crypto_pake.o \ + psa_crypto_random.o \ psa_crypto_rsa.o \ psa_crypto_se.o \ psa_crypto_slot_management.o \ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 9e17e27f2d..ec6b685dd3 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -37,6 +37,7 @@ * stored keys. */ #include "psa_crypto_storage.h" +#include "psa_crypto_random.h" #include "psa_crypto_random_impl.h" #include @@ -4412,25 +4413,8 @@ static psa_status_t psa_generate_random_internal(uint8_t *output, return PSA_SUCCESS; #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - - while (output_size > 0) { - int ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; - size_t request_size = - (output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ? - MBEDTLS_PSA_RANDOM_MAX_REQUEST : - output_size); -#if defined(MBEDTLS_CTR_DRBG_C) - ret = mbedtls_ctr_drbg_random(&global_data.rng.drbg, output, request_size); -#elif defined(MBEDTLS_HMAC_DRBG_C) - ret = mbedtls_hmac_drbg_random(&global_data.rng.drbg, output, request_size); -#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */ - if (ret != 0) { - return mbedtls_to_psa_error(ret); - } - output_size -= request_size; - output += request_size; - } - return PSA_SUCCESS; + return psa_random_internal_generate(&global_data.rng, + output, output_size); #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ } @@ -7986,28 +7970,7 @@ static void mbedtls_psa_random_init(mbedtls_psa_random_context_t *rng) #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) memset(rng, 0, sizeof(*rng)); #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - - /* Set default configuration if - * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */ - if (rng->entropy_init == NULL) { - rng->entropy_init = mbedtls_entropy_init; - } - if (rng->entropy_free == NULL) { - rng->entropy_free = mbedtls_entropy_free; - } - - rng->entropy_init(&rng->entropy); -#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ - defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) - /* The PSA entropy injection feature depends on using NV seed as an entropy - * source. Add NV seed as an entropy source for PSA entropy injection. */ - mbedtls_entropy_add_source(&rng->entropy, - mbedtls_nv_seed_poll, NULL, - MBEDTLS_ENTROPY_BLOCK_SIZE, - MBEDTLS_ENTROPY_SOURCE_STRONG); -#endif - - mbedtls_psa_drbg_init(&rng->drbg); + psa_random_internal_init(rng); #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ } @@ -8021,8 +7984,7 @@ static void mbedtls_psa_random_free(mbedtls_psa_random_context_t *rng) #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) memset(rng, 0, sizeof(*rng)); #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - mbedtls_psa_drbg_free(&rng->drbg); - rng->entropy_free(&rng->entropy); + psa_random_internal_free(rng); #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ } @@ -8035,10 +7997,7 @@ static psa_status_t mbedtls_psa_random_seed(mbedtls_psa_random_context_t *rng) (void) rng; return PSA_SUCCESS; #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - const unsigned char drbg_seed[] = "PSA"; - int ret = mbedtls_psa_drbg_seed(&rng->drbg, &rng->entropy, - drbg_seed, sizeof(drbg_seed) - 1); - return mbedtls_to_psa_error(ret); + return psa_random_internal_seed(rng); #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ } diff --git a/library/psa_crypto_random.c b/library/psa_crypto_random.c new file mode 100644 index 0000000000..f5eb658ab6 --- /dev/null +++ b/library/psa_crypto_random.c @@ -0,0 +1,82 @@ +/* + * PSA crypto random generator. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "common.h" + +#if defined(MBEDTLS_PSA_CRYPTO_C) && !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) + +#include "psa_crypto_core.h" +#include "psa_crypto_random.h" +#include "psa_crypto_random_impl.h" + +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) +#include "entropy_poll.h" +#endif + +void psa_random_internal_init(mbedtls_psa_random_context_t *rng) +{ + /* Set default configuration if + * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */ + if (rng->entropy_init == NULL) { + rng->entropy_init = mbedtls_entropy_init; + } + if (rng->entropy_free == NULL) { + rng->entropy_free = mbedtls_entropy_free; + } + + rng->entropy_init(&rng->entropy); +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ + defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) + /* The PSA entropy injection feature depends on using NV seed as an entropy + * source. Add NV seed as an entropy source for PSA entropy injection. */ + mbedtls_entropy_add_source(&rng->entropy, + mbedtls_nv_seed_poll, NULL, + MBEDTLS_ENTROPY_BLOCK_SIZE, + MBEDTLS_ENTROPY_SOURCE_STRONG); +#endif + + mbedtls_psa_drbg_init(&rng->drbg); +} + +void psa_random_internal_free(mbedtls_psa_random_context_t *rng) +{ + mbedtls_psa_drbg_free(&rng->drbg); + rng->entropy_free(&rng->entropy); +} +psa_status_t psa_random_internal_seed(mbedtls_psa_random_context_t *rng) +{ + const unsigned char drbg_seed[] = "PSA"; + int ret = mbedtls_psa_drbg_seed(&rng->drbg, &rng->entropy, + drbg_seed, sizeof(drbg_seed) - 1); + return mbedtls_to_psa_error(ret); +} + +psa_status_t psa_random_internal_generate( + mbedtls_psa_random_context_t *rng, + uint8_t *output, size_t output_size) +{ + while (output_size > 0) { + size_t request_size = + (output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ? + MBEDTLS_PSA_RANDOM_MAX_REQUEST : + output_size); +#if defined(MBEDTLS_CTR_DRBG_C) + int ret = mbedtls_ctr_drbg_random(&rng->drbg, output, request_size); +#elif defined(MBEDTLS_HMAC_DRBG_C) + int ret = mbedtls_hmac_drbg_random(&rng->drbg, output, request_size); +#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */ + if (ret != 0) { + return mbedtls_to_psa_error(ret); + } + output_size -= request_size; + output += request_size; + } + return PSA_SUCCESS; +} + +#endif /* MBEDTLS_PSA_CRYPTO_C && !MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ diff --git a/library/psa_crypto_random.h b/library/psa_crypto_random.h new file mode 100644 index 0000000000..167bb235b3 --- /dev/null +++ b/library/psa_crypto_random.h @@ -0,0 +1,72 @@ +/* + * PSA crypto random generator internal functions. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef PSA_CRYPTO_RANDOM_H +#define PSA_CRYPTO_RANDOM_H + +#include "common.h" + +#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) + +#include +#include "psa_crypto_random_impl.h" + +/** Initialize the PSA random generator. + * + * \param[out] rng The random generator context to initialize. + */ +void psa_random_internal_init(mbedtls_psa_random_context_t *rng); + +/** Deinitialize the PSA random generator. + * + * \param[in,out] rng The random generator context to deinitialize. + */ +void psa_random_internal_free(mbedtls_psa_random_context_t *rng); + +/** Seed the PSA random generator. + * + * \note This function is not thread-safe. + * + * \param[in,out] rng The random generator context to seed. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * The entropy source failed. + */ +psa_status_t psa_random_internal_seed(mbedtls_psa_random_context_t *rng); + +/** + * \brief Generate random bytes. Like psa_generate_random(), but for use + * inside the library. + * + * This function is thread-safe. + * + * \warning This function **can** fail! Callers MUST check the return status + * and MUST NOT use the content of the output buffer if the return + * status is not #PSA_SUCCESS. + * + * \param[in,out] rng The random generator context to seed. + * \param[out] output Output buffer for the generated data. + * \param output_size Number of bytes to generate and output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * The random generator needed to reseed, and the entropy + * source failed. + * \retval #PSA_ERROR_HARDWARE_FAILURE + * A hardware accelerator failed. + */ +psa_status_t psa_random_internal_generate( + mbedtls_psa_random_context_t *rng, + uint8_t *output, size_t output_size); + +#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */ + +#endif /* PSA_CRYPTO_RANDOM_H */