psa: let mbedtls_psa_get_random() always use psa_generate_random()

It means that mbedtls_psa_get_random() goes through the PSA interface
all the times. Fallbacks to CTR_DRBG or HMAC_DRBG are still possible,
but that depends on how the crypto provider is built.

Signed-off-by: Valerio Setti <valerio.setti@nordicsemi.no>
This commit is contained in:
Valerio Setti 2024-02-26 12:03:59 +01:00
parent bb91bcda0e
commit a53e7a5cb5
4 changed files with 37 additions and 116 deletions

View File

@ -23,42 +23,22 @@
#if defined(MBEDTLS_PSA_CRYPTO_C)
/* Expose whatever RNG the PSA subsystem uses to applications using the
* mbedtls_xxx API. The declarations and definitions here need to be
* consistent with the implementation in library/psa_crypto_random_impl.h.
* See that file for implementation documentation. */
/* The type of a `f_rng` random generator function that many library functions
* take.
*
* This type name is not part of the Mbed TLS stable API. It may be renamed
* or moved without warning.
*/
typedef int mbedtls_f_rng_t(void *p_rng, unsigned char *output, size_t output_size);
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
/** The random generator function for the PSA subsystem.
*
* This function is suitable as the `f_rng` random generator function
* parameter of many `mbedtls_xxx` functions. Use #MBEDTLS_PSA_RANDOM_STATE
* to obtain the \p p_rng parameter.
* parameter of many `mbedtls_xxx` functions.
*
* The implementation of this function depends on the configuration of the
* library.
*
* \note Depending on the configuration, this may be a function or
* a pointer to a function.
*
* \note This function may only be used if the PSA crypto subsystem is active.
* This means that you must call psa_crypto_init() before any call to
* this function, and you must not call this function after calling
* mbedtls_psa_crypto_free().
*
* \param p_rng The random generator context. This must be
* #MBEDTLS_PSA_RANDOM_STATE. No other state is
* supported.
* \param p_rng This parameter is only kept for backward compatibility
* reasons with legacy `f_rng` functions and it's ignored.
* Set to #MBEDTLS_PSA_RANDOM_STATE or NULL.
* \param output The buffer to fill. It must have room for
* \c output_size bytes.
* \param output_size The number of bytes to write to \p output.
@ -80,32 +60,11 @@ int mbedtls_psa_get_random(void *p_rng,
/** The random generator state for the PSA subsystem.
*
* This macro expands to an expression which is suitable as the `p_rng`
* random generator state parameter of many `mbedtls_xxx` functions.
* It must be used in combination with the random generator function
* mbedtls_psa_get_random().
*
* The implementation of this macro depends on the configuration of the
* library. Do not make any assumption on its nature.
* This macro always expands to NULL because the `p_rng` parameter is unused
* in mbedtls_psa_get_random(), but it's kept for interface's backward
* compatibility.
*/
#define MBEDTLS_PSA_RANDOM_STATE NULL
#else /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
#if defined(MBEDTLS_CTR_DRBG_C)
#include "mbedtls/ctr_drbg.h"
typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t;
static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_ctr_drbg_random;
#elif defined(MBEDTLS_HMAC_DRBG_C)
#include "mbedtls/hmac_drbg.h"
typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t;
static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_hmac_drbg_random;
#endif
extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
#define MBEDTLS_PSA_RANDOM_STATE mbedtls_psa_random_state
#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
#define MBEDTLS_PSA_RANDOM_STATE NULL
/** \defgroup psa_tls_helpers TLS helper functions
* @{

View File

@ -102,7 +102,7 @@ typedef struct {
static psa_global_data_t global_data;
#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state =
mbedtls_psa_drbg_context_t *const mbedtls_psa_drbg_ctx =
&global_data.rng.drbg;
#endif
@ -7322,7 +7322,7 @@ static void mbedtls_psa_random_init(mbedtls_psa_random_context_t *rng)
MBEDTLS_ENTROPY_SOURCE_STRONG);
#endif
mbedtls_psa_drbg_init(MBEDTLS_PSA_RANDOM_STATE);
mbedtls_psa_drbg_init(MBEDTLS_PSA_DRBG_CTX);
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
}
@ -7333,7 +7333,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(MBEDTLS_PSA_RANDOM_STATE);
mbedtls_psa_drbg_free(MBEDTLS_PSA_DRBG_CTX);
rng->entropy_free(&rng->entropy);
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
}
@ -7382,8 +7382,8 @@ psa_status_t psa_generate_random(uint8_t *output,
(output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ?
MBEDTLS_PSA_RANDOM_MAX_REQUEST :
output_size);
int ret = mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE,
output, request_size);
int ret = mbedtls_psa_legacy_get_random(MBEDTLS_PSA_DRBG_CTX,
output, request_size);
if (ret != 0) {
return mbedtls_to_psa_error(ret);
}

View File

@ -20,23 +20,9 @@
#include "psa_util_internal.h"
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
#include <string.h>
#include <mbedtls/entropy.h> // only for error codes
#include <psa/crypto.h>
typedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t;
/* Trivial wrapper around psa_generate_random(). */
int mbedtls_psa_get_random(void *p_rng,
unsigned char *output,
size_t output_size);
/* The PSA RNG API doesn't need any externally maintained state. */
#define MBEDTLS_PSA_RANDOM_STATE NULL
#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
#include "mbedtls/entropy.h"
/* Choose a DRBG based on configuration and availability */
#if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
@ -67,11 +53,23 @@ int mbedtls_psa_get_random(void *p_rng,
#error "No hash algorithm available for HMAC_DBRG."
#endif
#else
#else /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
#error "No DRBG module available for the psa_crypto module."
#endif
#endif /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
#include "mbedtls/entropy.h"
#if defined(MBEDTLS_CTR_DRBG_C)
#include "mbedtls/ctr_drbg.h"
#elif defined(MBEDTLS_HMAC_DRBG_C)
#include "mbedtls/hmac_drbg.h"
#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
#if defined(MBEDTLS_CTR_DRBG_C)
#define mbedtls_psa_legacy_get_random mbedtls_ctr_drbg_random
typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t;
#elif defined(MBEDTLS_HMAC_DRBG_C)
#define mbedtls_psa_legacy_get_random mbedtls_hmac_drbg_random
typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t;
#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
/** Initialize the PSA DRBG.
*
@ -111,20 +109,6 @@ typedef struct {
mbedtls_psa_drbg_context_t drbg;
} mbedtls_psa_random_context_t;
/* Defined in include/psa_util_internal.h so that it's visible to
* application code. The declaration here is redundant, but included
* as a safety net to make it more likely that a future change that
* accidentally causes the implementation to diverge from the interface
* will be noticed. */
/* Do not include the declaration under MSVC because it doesn't accept it
* ("error C2370: 'mbedtls_psa_get_random' : redefinition; different storage class").
* Observed with Visual Studio 2013. A known bug apparently:
* https://stackoverflow.com/questions/8146541/duplicate-external-static-declarations-not-allowed-in-visual-studio
*/
#if !defined(_MSC_VER)
static mbedtls_f_rng_t *const mbedtls_psa_get_random;
#endif
/** The maximum number of bytes that mbedtls_psa_get_random() is expected to
* return.
*/
@ -134,27 +118,13 @@ static mbedtls_f_rng_t *const mbedtls_psa_get_random;
#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
#endif
/** A pointer to the PSA DRBG state.
/** A pointer to the PSA DRBG context.
*
* This variable is only intended to be used through the macro
* #MBEDTLS_PSA_RANDOM_STATE.
* #MBEDTLS_PSA_DRBG_CTX.
*/
/* psa_crypto.c sets this variable to a pointer to the DRBG state in the
* global PSA crypto state. */
/* The type `mbedtls_psa_drbg_context_t` is defined in
* include/psa_util_internal.h so that `mbedtls_psa_random_state` can be
* declared there and be visible to application code. */
extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
/** A pointer to the PSA DRBG state.
*
* This macro expands to an expression that is suitable as the \c p_rng
* parameter to pass to mbedtls_psa_get_random().
*
* This macro exists in all configurations where the psa_crypto module is
* enabled. Its expansion depends on the configuration.
*/
#define MBEDTLS_PSA_RANDOM_STATE mbedtls_psa_random_state
extern mbedtls_psa_drbg_context_t *const mbedtls_psa_drbg_ctx;
#define MBEDTLS_PSA_DRBG_CTX mbedtls_psa_drbg_ctx
/** Seed the PSA DRBG.
*
@ -172,14 +142,14 @@ static inline int mbedtls_psa_drbg_seed(
const unsigned char *custom, size_t len)
{
#if defined(MBEDTLS_CTR_DRBG_C)
return mbedtls_ctr_drbg_seed(MBEDTLS_PSA_RANDOM_STATE,
return mbedtls_ctr_drbg_seed(MBEDTLS_PSA_DRBG_CTX,
mbedtls_entropy_func,
entropy,
custom, len);
#elif defined(MBEDTLS_HMAC_DRBG_C)
const mbedtls_md_info_t *md_info =
mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE);
return mbedtls_hmac_drbg_seed(MBEDTLS_PSA_RANDOM_STATE,
return mbedtls_hmac_drbg_seed(MBEDTLS_PSA_DRBG_CTX,
md_info,
mbedtls_entropy_func,
entropy,

View File

@ -46,6 +46,7 @@
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
#include <mbedtls/cipher.h>
#endif
#include <mbedtls/entropy.h>
/* PSA_SUCCESS is kept at the top of each error table since
* it's the most common status when everything functions properly. */
@ -343,15 +344,7 @@ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
* `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
* `psa_generate_random(...)`. The state parameter is ignored since the
* PSA API doesn't support passing an explicit state.
*
* In the non-external case, psa_generate_random() calls an
* `mbedtls_xxx_drbg_random` function which has exactly the same signature
* and semantics as mbedtls_psa_get_random(). As an optimization,
* instead of doing this back-and-forth between the PSA API and the
* classic API, psa_crypto_random_impl.h defines `mbedtls_psa_get_random`
* as a constant function pointer to `mbedtls_xxx_drbg_random`.
*/
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
int mbedtls_psa_get_random(void *p_rng,
unsigned char *output,
size_t output_size)
@ -369,7 +362,6 @@ int mbedtls_psa_get_random(void *p_rng,
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
}
}
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
#endif /* MBEDTLS_PSA_CRYPTO_C */