diff --git a/src/crypto/crypto_mbedtls_alt.c b/src/crypto/crypto_mbedtls_alt.c index f533a1246..806d448dc 100644 --- a/src/crypto/crypto_mbedtls_alt.c +++ b/src/crypto/crypto_mbedtls_alt.c @@ -10,8 +10,6 @@ #ifndef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE #include -#include -#include #include /* mbedtls_platform_zeroize() */ #include #include @@ -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 +/* 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 +#include 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 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); @@ -186,13 +200,16 @@ __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 @@ -200,6 +217,7 @@ __attribute_cold__ void crypto_unload(void) } } +#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) */ @@ -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 @@ -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 @@ -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; @@ -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); @@ -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; @@ -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; } @@ -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; @@ -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; } @@ -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; @@ -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); @@ -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; } @@ -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; @@ -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; } @@ -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 diff --git a/src/crypto/tls_mbedtls_alt.c b/src/crypto/tls_mbedtls_alt.c index 85f99b7df..f23ed9d81 100644 --- a/src/crypto/tls_mbedtls_alt.c +++ b/src/crypto/tls_mbedtls_alt.c @@ -59,6 +59,9 @@ #include #include +extern int (*hostap_rng_fn)(void*, unsigned char*, size_t); +extern void* hostap_rng_ctx; + #ifdef MBEDTLS_DEBUG_C #define DEBUG_THRESHOLD 4 #include @@ -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); @@ -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) { @@ -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 */ @@ -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);