Skip to content

Commit

Permalink
[noup] zephyr: Update to support MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
Browse files Browse the repository at this point in the history
-This commit add support for MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
 which adds support for PRNG (seeded by TRNG) without using
 the legacy Mbed TLS APIs in ctr_drbg.c and entropy.c. When the
 configuration MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled there
 is a new function available in the system that is used to override
 this behavior. This function is called mbedtls_psa_external_get_random
 but for compatibility with the f_rng/p_rng signature the
 function mbedtls_psa_get_random (found in mbedtls/psa_util.h) is
 used directly in code.
-Added a function pointer called hostap_rng_fn which is set
 to mbedtls_psa_get_random if MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is
 enabled, otherwise it is set to the legacy API mbedtls_ctr_drbg_random.
-Added a context pointer called hostap_rng_ctx that is set to
 MBEDTLS_PSA_RANDOM_STATE (NULL) if MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
 is set, otherwise it points to the existing ctr_drbg context.
-Updated all calls using legacy APIs making use of the f_rng/p_rng
 pattern to use hostap_rng_fn and hostap_rng_ctx in crypto_mbedtls_alt
-Added forward declaration of hostap_rng_fn and hostap_rng_ctx in
 tls_mbedtls_alt.c and changed every API-call making use of the
 f_rng/p_rng pattern.

Signed-off-by: Frank Audun Kvamtrø <[email protected]>
  • Loading branch information
frkv committed Jan 24, 2025
1 parent 4957416 commit 95a6692
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 25 deletions.
56 changes: 34 additions & 22 deletions src/crypto/crypto_mbedtls_alt.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

#ifndef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE
#include <mbedtls/version.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/platform_util.h> /* mbedtls_platform_zeroize() */
#include <mbedtls/asn1.h>
#include <mbedtls/asn1write.h>
Expand Down Expand Up @@ -146,17 +144,33 @@
#if defined(CRYPTO_RSA_OAEP_SHA256)
#define CRYPTO_MBEDTLS_CRYPTO_RSA
#endif

#endif /* crypto_rsa_*() */



#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
#include <mbedtls/psa_util.h>
/* Setting ctr_drbg_init_state to 1 to allow unload_crypto to run */
static int ctr_drbg_init_state = 1;
int (*hostap_rng_fn)(void*, unsigned char*, size_t) = mbedtls_psa_get_random;
void *hostap_rng_ctx = MBEDTLS_PSA_RANDOM_STATE;
#else
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
static int ctr_drbg_init_state;
static mbedtls_ctr_drbg_context ctr_drbg;
static mbedtls_entropy_context entropy;
int(*hostap_rng_fn)(void*, unsigned char*, size_t) = mbedtls_ctr_drbg_random;
void *hostap_rng_ctx = &ctr_drbg;
#endif

#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM
#include <mbedtls/bignum.h>
static mbedtls_mpi mpi_sw_A;
#endif

#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
static int wm_wrap_entropy_poll(void *data, unsigned char *output, size_t len, size_t *olen)
{
((void)data);
Expand Down Expand Up @@ -186,20 +200,24 @@ __attribute_cold__ __attribute_noinline__ static mbedtls_ctr_drbg_context *ctr_d

return &ctr_drbg;
}
#endif

__attribute_cold__ void crypto_unload(void)
{
if (ctr_drbg_init_state)
{
#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
#endif
#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM
mbedtls_mpi_free(&mpi_sw_A);
#endif
ctr_drbg_init_state = 0;
}
}

#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
/* init ctr_drbg on first use
* crypto_global_init() and crypto_global_deinit() are not available here
* (available only when CONFIG_TLS=internal, which is not CONFIG_TLS=mbedtls) */
Expand All @@ -208,6 +226,7 @@ inline mbedtls_ctr_drbg_context *crypto_mbedtls_ctr_drbg(void)
{
return ctr_drbg_init_state ? &ctr_drbg : ctr_drbg_init();
}
#endif

/* tradeoff: slightly smaller code size here at cost of slight increase
* in instructions and function calls at runtime versus the expanded
Expand Down Expand Up @@ -1194,8 +1213,7 @@ int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)

/*assert(r != m);*/ /* r must not be same as m for mbedtls_mpi_random()*/
#if MBEDTLS_VERSION_NUMBER >= 0x021B0000 /* mbedtls 2.27.0 */
return mbedtls_mpi_random((mbedtls_mpi *)r, 0, (mbedtls_mpi *)m, mbedtls_ctr_drbg_random,
crypto_mbedtls_ctr_drbg()) ?
return mbedtls_mpi_random((mbedtls_mpi *)r, 0, (mbedtls_mpi *)m, hostap_rng_fn, hostap_rng_ctx) ?
-1 :
0;
#else
Expand Down Expand Up @@ -1423,8 +1441,7 @@ __attribute_noinline__ static int crypto_mbedtls_dh_init_public(
mbedtls_dhm_context *ctx, u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, u8 *pubkey)
{
if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len) ||
mbedtls_dhm_make_public(ctx, (int)prime_len, pubkey, prime_len, mbedtls_ctr_drbg_random,
crypto_mbedtls_ctr_drbg()))
mbedtls_dhm_make_public(ctx, (int)prime_len, pubkey, prime_len, hostap_rng_fn, hostap_rng_ctx))
return -1;

return mbedtls_mpi_write_binary(&ctx->MBEDTLS_PRIVATE(X), privkey, prime_len) ? -1 : 0;
Expand Down Expand Up @@ -1489,7 +1506,7 @@ int crypto_dh_derive_secret(u8 generator,
int ret =
mbedtls_dhm_read_params(&ctx, &p, p + 2 + prime_len + 5 + pubkey_len) ||
mbedtls_mpi_read_binary(&ctx.MBEDTLS_PRIVATE(X), privkey, privkey_len) ||
mbedtls_dhm_calc_secret(&ctx, secret, *len, len, mbedtls_ctr_drbg_random, crypto_mbedtls_ctr_drbg()) ?
mbedtls_dhm_calc_secret(&ctx, secret, *len, len, hostap_rng_fn, hostap_rng_ctx) ?
-1 :
0;
mbedtls_dhm_free(&ctx);
Expand Down Expand Up @@ -1581,8 +1598,7 @@ struct wpabuf *dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, co
if (buf == NULL)
return NULL;
if (mbedtls_dhm_read_public((mbedtls_dhm_context *)ctx, wpabuf_head(peer_public), wpabuf_len(peer_public)) == 0 &&
mbedtls_dhm_calc_secret(ctx, wpabuf_mhead(buf), olen, &olen, mbedtls_ctr_drbg_random,
crypto_mbedtls_ctr_drbg()) == 0)
mbedtls_dhm_calc_secret(ctx, wpabuf_mhead(buf), olen, &olen, hostap_rng_fn, hostap_rng_ctx) == 0)
{
wpabuf_put(buf, olen);
return buf;
Expand Down Expand Up @@ -1732,7 +1748,7 @@ static int crypto_mbedtls_keypair_gen(int group, mbedtls_pk_context *pk)
if (pk_info == NULL)
return -1;
return mbedtls_pk_setup(pk, pk_info) ||
mbedtls_ecp_gen_key(grp_id, mbedtls_pk_ec(*pk), mbedtls_ctr_drbg_random, crypto_mbedtls_ctr_drbg()) ?
mbedtls_ecp_gen_key(grp_id, mbedtls_pk_ec(*pk), hostap_rng_fn, hostap_rng_ctx) ?
-1 :
0;
}
Expand Down Expand Up @@ -1940,8 +1956,7 @@ struct wpabuf *crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, cons
if (buf == NULL)
return NULL;

if (mbedtls_ecdh_calc_secret(&ecdh->ctx, &len, wpabuf_mhead(buf), len, mbedtls_ctr_drbg_random,
crypto_mbedtls_ctr_drbg()) == 0)
if (mbedtls_ecdh_calc_secret(&ecdh->ctx, &len, wpabuf_mhead(buf), len, hostap_rng_fn, hostap_rng_ctx) == 0)
{
wpabuf_put(buf, len);
return buf;
Expand Down Expand Up @@ -2240,7 +2255,7 @@ int crypto_ec_point_mul(struct crypto_ec *e,
return -1;

return mbedtls_ecp_mul((mbedtls_ecp_group *)e, (mbedtls_ecp_point *)res, (const mbedtls_mpi *)b,
(const mbedtls_ecp_point *)p, mbedtls_ctr_drbg_random, crypto_mbedtls_ctr_drbg()) ?
(const mbedtls_ecp_point *)p, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE) ?
-1 :
0;
}
Expand Down Expand Up @@ -2361,7 +2376,7 @@ struct crypto_ec_key *crypto_ec_key_parse_priv(const u8 *der, size_t der_len)
#if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */
if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0) == 0)
#else
if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0, mbedtls_ctr_drbg_random, crypto_mbedtls_ctr_drbg()) == 0)
if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0, hostap_rng_fn, hostap_rng_ctx) == 0)
#endif
return (struct crypto_ec_key *)ctx;

Expand Down Expand Up @@ -2521,9 +2536,7 @@ static struct crypto_ec_key *crypto_ec_key_set_pub_point_for_group(mbedtls_ecp_g
{
/* (Is private key generation necessary for callers?)
* alt: gen key then overwrite Q
* mbedtls_ecp_gen_key(grp_id, ecp_kp,
* mbedtls_ctr_drbg_random,
* crypto_mbedtls_ctr_drbg()) == 0
* mbedtls_ecp_gen_key(grp_id, ecp_kp, hostap_rng_fn, hostap_rng_ctx) == 0
*/
mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx);
mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp);
Expand All @@ -2532,7 +2545,7 @@ static struct crypto_ec_key *crypto_ec_key_set_pub_point_for_group(mbedtls_ecp_g
if (mbedtls_ecp_group_load(ecp_kp_grp, grp_id) == 0 &&
(pub ? mbedtls_ecp_copy(ecp_kp_Q, pub) == 0 :
mbedtls_ecp_point_read_binary(ecp_kp_grp, ecp_kp_Q, buf, len) == 0) &&
mbedtls_ecp_gen_privkey(ecp_kp_grp, ecp_kp_d, mbedtls_ctr_drbg_random, crypto_mbedtls_ctr_drbg()) == 0)
mbedtls_ecp_gen_privkey(ecp_kp_grp, ecp_kp_d, hostap_rng_fn, hostap_rng_ctx) == 0)
{
return (struct crypto_ec_key *)ctx;
}
Expand Down Expand Up @@ -2802,7 +2815,7 @@ struct wpabuf *crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data, siz
#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
sig_len,
#endif
&sig_len, mbedtls_ctr_drbg_random, crypto_mbedtls_ctr_drbg()) == 0)
&sig_len, hostap_rng_fn, hostap_rng_ctx) == 0)
{
wpabuf_put(buf, sig_len);
return buf;
Expand All @@ -2825,7 +2838,7 @@ struct wpabuf *crypto_ec_key_sign_r_s(struct crypto_ec_key *key, const u8 *data,
#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
sig_len,
#endif
&sig_len, mbedtls_ctr_drbg_random, crypto_mbedtls_ctr_drbg()))
&sig_len, hostap_rng_fn, hostap_rng_ctx))
{
return NULL;
}
Expand Down Expand Up @@ -3191,8 +3204,7 @@ struct wpabuf *crypto_csr_sign(struct crypto_csr *csr, struct crypto_ec_key *key
mbedtls_x509write_csr_set_md_alg((mbedtls_x509write_csr *)csr, sig_md);

unsigned char buf[4096]; /* XXX: large enough? too large? */
int len = mbedtls_x509write_csr_der((mbedtls_x509write_csr *)csr, buf, sizeof(buf), mbedtls_ctr_drbg_random,
crypto_mbedtls_ctr_drbg());
int len = mbedtls_x509write_csr_der((mbedtls_x509write_csr *)csr, buf, sizeof(buf), hostap_rng_fn, hostap_rng_ctx);
if (len < 0)
return NULL;
/* Note: data is written at the end of the buffer! Use the
Expand Down
13 changes: 10 additions & 3 deletions src/crypto/tls_mbedtls_alt.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
#include <mbedtls/x509.h>
#include <mbedtls/x509_crt.h>

extern int (*hostap_rng_fn)(void*, unsigned char*, size_t);
extern void* hostap_rng_ctx;

#ifdef MBEDTLS_DEBUG_C
#define DEBUG_THRESHOLD 4
#include <mbedtls/debug.h>
Expand Down Expand Up @@ -345,7 +348,7 @@ struct tls_conf *tls_conf_init(void *tls_ctx)
tls_conf->refcnt = 1;

mbedtls_ssl_config_init(&tls_conf->conf);
mbedtls_ssl_conf_rng(&tls_conf->conf, mbedtls_ctr_drbg_random, tls_ctx_global.ctr_drbg);
mbedtls_ssl_conf_rng(&tls_conf->conf, hostap_rng_fn, hostap_rng_ctx);
mbedtls_x509_crt_init(&tls_conf->ca_cert);
mbedtls_x509_crt_init(&tls_conf->client_cert);
mbedtls_pk_init(&tls_conf->private_key);
Expand Down Expand Up @@ -383,7 +386,9 @@ struct tls_conf *tls_conf_deinit(struct tls_conf *tls_conf)
return NULL;
}

#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
mbedtls_ctr_drbg_context *crypto_mbedtls_ctr_drbg(void); /*(not in header)*/
#endif

__attribute_cold__ void *tls_init(const struct tls_config *conf)
{
Expand All @@ -392,10 +397,12 @@ __attribute_cold__ void *tls_init(const struct tls_config *conf)
if (++tls_ctx_global.refcnt > 1)
return &tls_ctx_global;

#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
tls_ctx_global.ctr_drbg = crypto_mbedtls_ctr_drbg();
#endif
#ifdef MBEDTLS_SSL_SESSION_TICKETS
mbedtls_ssl_ticket_init(&tls_ctx_global.ticket_ctx);
mbedtls_ssl_ticket_setup(&tls_ctx_global.ticket_ctx, mbedtls_ctr_drbg_random, tls_ctx_global.ctr_drbg,
mbedtls_ssl_ticket_setup(&tls_ctx_global.ticket_ctx, hostap_rng_fn, hostap_rng_ctx,
MBEDTLS_CIPHER_AES_256_GCM, 43200); /* ticket timeout: 12 hours */
#endif
/* copy struct for future use */
Expand Down Expand Up @@ -1608,7 +1615,7 @@ static int tls_mbedtls_set_certs(struct tls_conf *tls_conf, const struct tls_con
const char *pwd = params->private_key_passwd;
#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
ret = mbedtls_pk_parse_key(&tls_conf->private_key, data, len, (const unsigned char *)pwd,
pwd ? os_strlen(pwd) : 0, mbedtls_ctr_drbg_random, tls_ctx_global.ctr_drbg);
pwd ? os_strlen(pwd) : 0, hostap_rng_fn, hostap_rng_ctx);
#else
ret = mbedtls_pk_parse_key(&tls_conf->private_key, data, len, (const unsigned char *)pwd,
pwd ? os_strlen(pwd) : 0);
Expand Down

0 comments on commit 95a6692

Please sign in to comment.