Merge pull request #10179 from gilles-peskine-arm/union-initialization-gcc15-driver-checks-3.6

Backport 3.6: Check union initialization portably
diff --git a/ChangeLog.d/move-crypto-struct-inclusion.txt b/ChangeLog.d/move-crypto-struct-inclusion.txt
new file mode 100644
index 0000000..c5f6d2b
--- /dev/null
+++ b/ChangeLog.d/move-crypto-struct-inclusion.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Resolved build issue with C++ projects using TF-PSA-Crypto when compiling
+     with the MSVC toolset v142 and earlier. Fixes mbedtls issue #7087.
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 8367cd3..1e1c063 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -12,6 +12,7 @@
 #include "mbedtls/private_access.h"
 
 #include "mbedtls/build_info.h"
+#include "mbedtls/platform_util.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -928,7 +929,7 @@
  *                 be relevant in applications like deterministic ECDSA.
  */
 int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /** Generate a random number uniformly in a range.
@@ -966,7 +967,7 @@
 int mbedtls_mpi_random(mbedtls_mpi *X,
                        mbedtls_mpi_sint min,
                        const mbedtls_mpi *N,
-                       int (*f_rng)(void *, unsigned char *, size_t),
+                       mbedtls_f_rng_t *f_rng,
                        void *p_rng);
 
 /**
@@ -1030,7 +1031,7 @@
  * \return         Another negative error code on other kinds of failure.
  */
 int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds,
-                             int (*f_rng)(void *, unsigned char *, size_t),
+                             mbedtls_f_rng_t *f_rng,
                              void *p_rng);
 /**
  * \brief Flags for mbedtls_mpi_gen_prime()
@@ -1063,7 +1064,7 @@
  *                 \c 3 and #MBEDTLS_MPI_MAX_BITS.
  */
 int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags,
-                          int (*f_rng)(void *, unsigned char *, size_t),
+                          mbedtls_f_rng_t *f_rng,
                           void *p_rng);
 
 #if defined(MBEDTLS_SELF_TEST)
diff --git a/include/mbedtls/dhm.h b/include/mbedtls/dhm.h
index fcba3d2..bbfe6ea 100644
--- a/include/mbedtls/dhm.h
+++ b/include/mbedtls/dhm.h
@@ -183,7 +183,7 @@
  */
 int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size,
                             unsigned char *output, size_t *olen,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /**
@@ -250,7 +250,7 @@
  */
 int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size,
                             unsigned char *output, size_t olen,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /**
@@ -281,7 +281,7 @@
  */
 int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx,
                             unsigned char *output, size_t output_size, size_t *olen,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /**
diff --git a/include/mbedtls/ecdh.h b/include/mbedtls/ecdh.h
index a6a5069..a919ad2 100644
--- a/include/mbedtls/ecdh.h
+++ b/include/mbedtls/ecdh.h
@@ -189,7 +189,7 @@
  *                  \c MBEDTLS_MPI_XXX error code on failure.
  */
 int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /**
@@ -225,7 +225,7 @@
  */
 int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z,
                                 const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
-                                int (*f_rng)(void *, unsigned char *, size_t),
+                                mbedtls_f_rng_t *f_rng,
                                 void *p_rng);
 
 /**
@@ -290,7 +290,7 @@
  */
 int mbedtls_ecdh_make_params(mbedtls_ecdh_context *ctx, size_t *olen,
                              unsigned char *buf, size_t blen,
-                             int (*f_rng)(void *, unsigned char *, size_t),
+                             mbedtls_f_rng_t *f_rng,
                              void *p_rng);
 
 /**
@@ -372,7 +372,7 @@
  */
 int mbedtls_ecdh_make_public(mbedtls_ecdh_context *ctx, size_t *olen,
                              unsigned char *buf, size_t blen,
-                             int (*f_rng)(void *, unsigned char *, size_t),
+                             mbedtls_f_rng_t *f_rng,
                              void *p_rng);
 
 /**
@@ -428,7 +428,7 @@
  */
 int mbedtls_ecdh_calc_secret(mbedtls_ecdh_context *ctx, size_t *olen,
                              unsigned char *buf, size_t blen,
-                             int (*f_rng)(void *, unsigned char *, size_t),
+                             mbedtls_f_rng_t *f_rng,
                              void *p_rng);
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h
index 2ecf349..c161661 100644
--- a/include/mbedtls/ecdsa.h
+++ b/include/mbedtls/ecdsa.h
@@ -150,7 +150,8 @@
  *                  buffer of length \p blen Bytes. It may be \c NULL if
  *                  \p blen is zero.
  * \param blen      The length of \p buf in Bytes.
- * \param f_rng     The RNG function. This must not be \c NULL.
+ * \param f_rng     The RNG function, used both to generate the ECDSA nonce
+ *                  and for blinding. This must not be \c NULL.
  * \param p_rng     The RNG context to be passed to \p f_rng. This may be
  *                  \c NULL if \p f_rng doesn't need a context parameter.
  *
@@ -160,7 +161,7 @@
  */
 int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
                        const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
-                       int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                       mbedtls_f_rng_t *f_rng, void *p_rng);
 
 #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
 /**
@@ -207,7 +208,7 @@
                                mbedtls_mpi *s, const mbedtls_mpi *d,
                                const unsigned char *buf, size_t blen,
                                mbedtls_md_type_t md_alg,
-                               int (*f_rng_blind)(void *, unsigned char *, size_t),
+                               mbedtls_f_rng_t *f_rng_blind,
                                void *p_rng_blind);
 #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
 
@@ -247,7 +248,8 @@
  *                      buffer of length \p blen Bytes. It may be \c NULL if
  *                      \p blen is zero.
  * \param blen          The length of \p buf in Bytes.
- * \param f_rng         The RNG function. This must not be \c NULL.
+ * \param f_rng         The RNG function used to generate the ECDSA nonce.
+ *                      This must not be \c NULL.
  * \param p_rng         The RNG context to be passed to \p f_rng. This may be
  *                      \c NULL if \p f_rng doesn't need a context parameter.
  * \param f_rng_blind   The RNG function used for blinding. This must not be
@@ -271,9 +273,9 @@
     mbedtls_mpi *r, mbedtls_mpi *s,
     const mbedtls_mpi *d,
     const unsigned char *buf, size_t blen,
-    int (*f_rng)(void *, unsigned char *, size_t),
+    mbedtls_f_rng_t *f_rng,
     void *p_rng,
-    int (*f_rng_blind)(void *, unsigned char *, size_t),
+    mbedtls_f_rng_t *f_rng_blind,
     void *p_rng_blind,
     mbedtls_ecdsa_restart_ctx *rs_ctx);
 
@@ -334,7 +336,7 @@
     mbedtls_mpi *r, mbedtls_mpi *s,
     const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
     mbedtls_md_type_t md_alg,
-    int (*f_rng_blind)(void *, unsigned char *, size_t),
+    mbedtls_f_rng_t *f_rng_blind,
     void *p_rng_blind,
     mbedtls_ecdsa_restart_ctx *rs_ctx);
 
@@ -458,10 +460,10 @@
  * \param sig_size  The size of the \p sig buffer in bytes.
  * \param slen      The address at which to store the actual length of
  *                  the signature written. Must not be \c NULL.
- * \param f_rng     The RNG function. This must not be \c NULL if
- *                  #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
- *                  it is used only for blinding and may be set to \c NULL, but
- *                  doing so is DEPRECATED.
+ * \param f_rng     The RNG function. This is used for blinding.
+ *                  If #MBEDTLS_ECDSA_DETERMINISTIC is unset, this is also
+ *                  used to generate the ECDSA nonce.
+ *                  This must not be \c NULL.
  * \param p_rng     The RNG context to be passed to \p f_rng. This may be
  *                  \c NULL if \p f_rng is \c NULL or doesn't use a context.
  *
@@ -473,7 +475,7 @@
                                   mbedtls_md_type_t md_alg,
                                   const unsigned char *hash, size_t hlen,
                                   unsigned char *sig, size_t sig_size, size_t *slen,
-                                  int (*f_rng)(void *, unsigned char *, size_t),
+                                  mbedtls_f_rng_t *f_rng,
                                   void *p_rng);
 
 /**
@@ -501,9 +503,10 @@
  * \param sig_size  The size of the \p sig buffer in bytes.
  * \param slen      The address at which to store the actual length of
  *                  the signature written. Must not be \c NULL.
- * \param f_rng     The RNG function. This must not be \c NULL if
- *                  #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
- *                  it is unused and may be set to \c NULL.
+ * \param f_rng     The RNG function. This is used for blinding.
+ *                  If #MBEDTLS_ECDSA_DETERMINISTIC is unset, this is also
+ *                  used to generate the ECDSA nonce.
+ *                  This must not be \c NULL.
  * \param p_rng     The RNG context to be passed to \p f_rng. This may be
  *                  \c NULL if \p f_rng is \c NULL or doesn't use a context.
  * \param rs_ctx    The restart context to use. This may be \c NULL to disable
@@ -520,7 +523,7 @@
                                               mbedtls_md_type_t md_alg,
                                               const unsigned char *hash, size_t hlen,
                                               unsigned char *sig, size_t sig_size, size_t *slen,
-                                              int (*f_rng)(void *, unsigned char *, size_t),
+                                              mbedtls_f_rng_t *f_rng,
                                               void *p_rng,
                                               mbedtls_ecdsa_restart_ctx *rs_ctx);
 
@@ -608,7 +611,7 @@
  * \return         An \c MBEDTLS_ERR_ECP_XXX code on failure.
  */
 int mbedtls_ecdsa_genkey(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
-                         int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                         mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /**
  * \brief           This function sets up an ECDSA context from an EC key pair.
diff --git a/include/mbedtls/ecjpake.h b/include/mbedtls/ecjpake.h
index c2148a2..7da8cb4 100644
--- a/include/mbedtls/ecjpake.h
+++ b/include/mbedtls/ecjpake.h
@@ -162,7 +162,7 @@
  */
 int mbedtls_ecjpake_write_round_one(mbedtls_ecjpake_context *ctx,
                                     unsigned char *buf, size_t len, size_t *olen,
-                                    int (*f_rng)(void *, unsigned char *, size_t),
+                                    mbedtls_f_rng_t *f_rng,
                                     void *p_rng);
 
 /**
@@ -203,7 +203,7 @@
  */
 int mbedtls_ecjpake_write_round_two(mbedtls_ecjpake_context *ctx,
                                     unsigned char *buf, size_t len, size_t *olen,
-                                    int (*f_rng)(void *, unsigned char *, size_t),
+                                    mbedtls_f_rng_t *f_rng,
                                     void *p_rng);
 
 /**
@@ -243,7 +243,7 @@
  */
 int mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx,
                                   unsigned char *buf, size_t len, size_t *olen,
-                                  int (*f_rng)(void *, unsigned char *, size_t),
+                                  mbedtls_f_rng_t *f_rng,
                                   void *p_rng);
 
 /**
@@ -266,7 +266,7 @@
  */
 int mbedtls_ecjpake_write_shared_key(mbedtls_ecjpake_context *ctx,
                                      unsigned char *buf, size_t len, size_t *olen,
-                                     int (*f_rng)(void *, unsigned char *, size_t),
+                                     mbedtls_f_rng_t *f_rng,
                                      void *p_rng);
 
 /**
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 623910b..5cc0271 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -966,7 +966,7 @@
  */
 int mbedtls_ecp_mul(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
                     const mbedtls_mpi *m, const mbedtls_ecp_point *P,
-                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                    mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /**
  * \brief           This function performs multiplication of a point by
@@ -1000,7 +1000,7 @@
  */
 int mbedtls_ecp_mul_restartable(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
                                 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
-                                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                                mbedtls_f_rng_t *f_rng, void *p_rng,
                                 mbedtls_ecp_restart_ctx *rs_ctx);
 
 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
@@ -1179,7 +1179,7 @@
  */
 int mbedtls_ecp_gen_privkey(const mbedtls_ecp_group *grp,
                             mbedtls_mpi *d,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /**
@@ -1212,7 +1212,7 @@
 int mbedtls_ecp_gen_keypair_base(mbedtls_ecp_group *grp,
                                  const mbedtls_ecp_point *G,
                                  mbedtls_mpi *d, mbedtls_ecp_point *Q,
-                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 mbedtls_f_rng_t *f_rng,
                                  void *p_rng);
 
 /**
@@ -1240,7 +1240,7 @@
  */
 int mbedtls_ecp_gen_keypair(mbedtls_ecp_group *grp, mbedtls_mpi *d,
                             mbedtls_ecp_point *Q,
-                            int (*f_rng)(void *, unsigned char *, size_t),
+                            mbedtls_f_rng_t *f_rng,
                             void *p_rng);
 
 /**
@@ -1257,7 +1257,7 @@
  *                  on failure.
  */
 int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
-                        int (*f_rng)(void *, unsigned char *, size_t),
+                        mbedtls_f_rng_t *f_rng,
                         void *p_rng);
 
 /** \brief          Set the public key in a key pair object.
@@ -1451,7 +1451,7 @@
  */
 int mbedtls_ecp_check_pub_priv(
     const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv,
-    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+    mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /** \brief          Calculate the public key from a private key in a key pair.
  *
@@ -1468,7 +1468,7 @@
  */
 int mbedtls_ecp_keypair_calc_public(
     mbedtls_ecp_keypair *key,
-    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+    mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /** \brief          Query the group that a key pair belongs to.
  *
diff --git a/include/mbedtls/lms.h b/include/mbedtls/lms.h
index 95fce21..2f29791 100644
--- a/include/mbedtls/lms.h
+++ b/include/mbedtls/lms.h
@@ -364,7 +364,7 @@
 int mbedtls_lms_generate_private_key(mbedtls_lms_private_t *ctx,
                                      mbedtls_lms_algorithm_type_t type,
                                      mbedtls_lmots_algorithm_type_t otstype,
-                                     int (*f_rng)(void *, unsigned char *, size_t),
+                                     mbedtls_f_rng_t *f_rng,
                                      void *p_rng, const unsigned char *seed,
                                      size_t seed_size);
 
@@ -427,7 +427,7 @@
  * \return         A non-zero error code on failure.
  */
 int mbedtls_lms_sign(mbedtls_lms_private_t *ctx,
-                     int (*f_rng)(void *, unsigned char *, size_t),
+                     mbedtls_f_rng_t *f_rng,
                      void *p_rng, const unsigned char *msg,
                      unsigned int msg_size, unsigned char *sig, size_t sig_size,
                      size_t *sig_len);
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index 52f4cc6..2b7f34b 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -285,7 +285,7 @@
                                                const unsigned char *input, unsigned char *output,
                                                size_t output_max_len);
 typedef int (*mbedtls_pk_rsa_alt_sign_func)(void *ctx,
-                                            int (*f_rng)(void *, unsigned char *, size_t),
+                                            mbedtls_f_rng_t *f_rng,
                                             void *p_rng,
                                             mbedtls_md_type_t md_alg, unsigned int hashlen,
                                             const unsigned char *hash, unsigned char *sig);
@@ -849,7 +849,7 @@
 int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
                     const unsigned char *hash, size_t hash_len,
                     unsigned char *sig, size_t sig_size, size_t *sig_len,
-                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                    mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /**
  * \brief           Make signature given a signature type.
@@ -885,7 +885,7 @@
                         mbedtls_md_type_t md_alg,
                         const unsigned char *hash, size_t hash_len,
                         unsigned char *sig, size_t sig_size, size_t *sig_len,
-                        int (*f_rng)(void *, unsigned char *, size_t),
+                        mbedtls_f_rng_t *f_rng,
                         void *p_rng);
 
 /**
@@ -921,7 +921,7 @@
                                 mbedtls_md_type_t md_alg,
                                 const unsigned char *hash, size_t hash_len,
                                 unsigned char *sig, size_t sig_size, size_t *sig_len,
-                                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                                mbedtls_f_rng_t *f_rng, void *p_rng,
                                 mbedtls_pk_restart_ctx *rs_ctx);
 
 /**
@@ -947,7 +947,7 @@
 int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
                        const unsigned char *input, size_t ilen,
                        unsigned char *output, size_t *olen, size_t osize,
-                       int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                       mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /**
  * \brief           Encrypt message (including padding if relevant).
@@ -973,7 +973,7 @@
 int mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
                        const unsigned char *input, size_t ilen,
                        unsigned char *output, size_t *olen, size_t osize,
-                       int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                       mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /**
  * \brief           Check if a public-private pair of keys matches.
@@ -991,7 +991,7 @@
  */
 int mbedtls_pk_check_pair(const mbedtls_pk_context *pub,
                           const mbedtls_pk_context *prv,
-                          int (*f_rng)(void *, unsigned char *, size_t),
+                          mbedtls_f_rng_t *f_rng,
                           void *p_rng);
 
 /**
@@ -1109,7 +1109,7 @@
 int mbedtls_pk_parse_key(mbedtls_pk_context *ctx,
                          const unsigned char *key, size_t keylen,
                          const unsigned char *pwd, size_t pwdlen,
-                         int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                         mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /** \ingroup pk_module */
 /**
@@ -1173,7 +1173,7 @@
  */
 int mbedtls_pk_parse_keyfile(mbedtls_pk_context *ctx,
                              const char *path, const char *password,
-                             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
+                             mbedtls_f_rng_t *f_rng, void *p_rng);
 
 /** \ingroup pk_module */
 /**
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index 1b371ef..adad6bc 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -159,6 +159,56 @@
 void mbedtls_platform_zeroize(void *buf, size_t len);
 #endif
 
+/** \brief              The type of custom random generator (RNG) callbacks.
+ *
+ *                      Many Mbed TLS functions take two parameters
+ *                      `mbedtls_f_rng_t *f_rng, void *p_rng`. The
+ *                      library will call \c f_rng to generate
+ *                      random values.
+ *
+ * \note                This is typically one of the following:
+ *                      - mbedtls_ctr_drbg_random() with \c p_rng
+ *                        pointing to a #mbedtls_ctr_drbg_context;
+ *                      - mbedtls_hmac_drbg_random() with \c p_rng
+ *                        pointing to a #mbedtls_hmac_drbg_context;
+ *                      - mbedtls_psa_get_random() with
+ *                        `prng = MBEDTLS_PSA_RANDOM_STATE`.
+ *
+ * \note                Generally, given a call
+ *                      `mbedtls_foo(f_rng, p_rng, ....)`, the RNG callback
+ *                      and the context only need to remain valid until
+ *                      the call to `mbedtls_foo` returns. However, there
+ *                      are a few exceptions where the callback is stored
+ *                      in for future use. Check the documentation of
+ *                      the calling function.
+ *
+ * \warning             In a multithreaded environment, calling the
+ *                      function should be thread-safe. The standard
+ *                      functions provided by the library are thread-safe
+ *                      when #MBEDTLS_THREADING_C is enabled.
+ *
+ * \warning             This function must either provide as many
+ *                      bytes as requested of **cryptographic quality**
+ *                      random data, or return a negative error code.
+ *
+ * \param p_rng         The \c p_rng argument that was passed along \c f_rng.
+ *                      The library always passes \c p_rng unchanged.
+ *                      This is typically a pointer to the random generator
+ *                      state, or \c NULL if the custom random generator
+ *                      doesn't need a context-specific state.
+ * \param[out] output   On success, this must be filled with \p output_size
+ *                      bytes of cryptographic-quality random data.
+ * \param output_size   The number of bytes to output.
+ *
+ * \return              \c 0 on success, or a negative error code on failure.
+ *                      Library functions will generally propagate this
+ *                      error code, so \c MBEDTLS_ERR_xxx values are
+ *                      recommended. #MBEDTLS_ERR_ENTROPY_SOURCE_FAILED is
+ *                      typically sensible for RNG failures.
+ */
+typedef int mbedtls_f_rng_t(void *p_rng,
+                            unsigned char *output, size_t output_size);
+
 #if defined(MBEDTLS_HAVE_TIME_DATE)
 /**
  * \brief      Platform-specific implementation of gmtime_r()
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index c1e76b3..3f0881a 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -465,7 +465,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx,
-                        int (*f_rng)(void *, unsigned char *, size_t),
+                        mbedtls_f_rng_t *f_rng,
                         void *p_rng,
                         unsigned int nbits, int exponent);
 
@@ -590,7 +590,7 @@
  *
  */
 int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
-                        int (*f_rng)(void *, unsigned char *, size_t),
+                        mbedtls_f_rng_t *f_rng,
                         void *p_rng,
                         const unsigned char *input,
                         unsigned char *output);
@@ -619,7 +619,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_encrypt(mbedtls_rsa_context *ctx,
-                              int (*f_rng)(void *, unsigned char *, size_t),
+                              mbedtls_f_rng_t *f_rng,
                               void *p_rng,
                               size_t ilen,
                               const unsigned char *input,
@@ -646,7 +646,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_rsa_context *ctx,
-                                        int (*f_rng)(void *, unsigned char *, size_t),
+                                        mbedtls_f_rng_t *f_rng,
                                         void *p_rng,
                                         size_t ilen,
                                         const unsigned char *input,
@@ -680,7 +680,7 @@
  * \return           An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx,
-                                   int (*f_rng)(void *, unsigned char *, size_t),
+                                   mbedtls_f_rng_t *f_rng,
                                    void *p_rng,
                                    const unsigned char *label, size_t label_len,
                                    size_t ilen,
@@ -723,7 +723,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx,
-                              int (*f_rng)(void *, unsigned char *, size_t),
+                              mbedtls_f_rng_t *f_rng,
                               void *p_rng,
                               size_t *olen,
                               const unsigned char *input,
@@ -765,7 +765,7 @@
  *
  */
 int mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_rsa_context *ctx,
-                                        int (*f_rng)(void *, unsigned char *, size_t),
+                                        mbedtls_f_rng_t *f_rng,
                                         void *p_rng,
                                         size_t *olen,
                                         const unsigned char *input,
@@ -806,7 +806,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx,
-                                   int (*f_rng)(void *, unsigned char *, size_t),
+                                   mbedtls_f_rng_t *f_rng,
                                    void *p_rng,
                                    const unsigned char *label, size_t label_len,
                                    size_t *olen,
@@ -849,7 +849,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_pkcs1_sign(mbedtls_rsa_context *ctx,
-                           int (*f_rng)(void *, unsigned char *, size_t),
+                           mbedtls_f_rng_t *f_rng,
                            void *p_rng,
                            mbedtls_md_type_t md_alg,
                            unsigned int hashlen,
@@ -881,7 +881,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context *ctx,
-                                      int (*f_rng)(void *, unsigned char *, size_t),
+                                      mbedtls_f_rng_t *f_rng,
                                       void *p_rng,
                                       mbedtls_md_type_t md_alg,
                                       unsigned int hashlen,
@@ -933,7 +933,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pss_sign_ext(mbedtls_rsa_context *ctx,
-                                    int (*f_rng)(void *, unsigned char *, size_t),
+                                    mbedtls_f_rng_t *f_rng,
                                     void *p_rng,
                                     mbedtls_md_type_t md_alg,
                                     unsigned int hashlen,
@@ -983,7 +983,7 @@
  * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
  */
 int mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
-                                int (*f_rng)(void *, unsigned char *, size_t),
+                                mbedtls_f_rng_t *f_rng,
                                 void *p_rng,
                                 mbedtls_md_type_t md_alg,
                                 unsigned int hashlen,
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index cc9da34..3cdddf7 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -2255,12 +2255,16 @@
 /**
  * \brief          Set the random number generator callback
  *
+ * \note           The callback with its parameter must remain valid as
+ *                 long as there is an SSL context that uses the
+ *                 SSL configuration.
+ *
  * \param conf     SSL configuration
  * \param f_rng    RNG function (mandatory)
  * \param p_rng    RNG parameter
  */
 void mbedtls_ssl_conf_rng(mbedtls_ssl_config *conf,
-                          int (*f_rng)(void *, unsigned char *, size_t),
+                          mbedtls_f_rng_t *f_rng,
                           void *p_rng);
 
 /**
diff --git a/include/mbedtls/ssl_cookie.h b/include/mbedtls/ssl_cookie.h
index 71c258e..0f211e6 100644
--- a/include/mbedtls/ssl_cookie.h
+++ b/include/mbedtls/ssl_cookie.h
@@ -70,7 +70,7 @@
  * \brief          Setup cookie context (generate keys)
  */
 int mbedtls_ssl_cookie_setup(mbedtls_ssl_cookie_ctx *ctx,
-                             int (*f_rng)(void *, unsigned char *, size_t),
+                             mbedtls_f_rng_t *f_rng,
                              void *p_rng);
 
 /**
diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h
index 2ee1400..9f7e440 100644
--- a/include/mbedtls/ssl_ticket.h
+++ b/include/mbedtls/ssl_ticket.h
@@ -98,7 +98,9 @@
  *
  * \param ctx       Context to be set up
  * \param f_rng     RNG callback function (mandatory)
- * \param p_rng     RNG callback context
+ * \param p_rng     RNG callback context.
+ *                  Note that the RNG callback must remain valid
+ *                  until the ticket context is freed.
  * \param cipher    AEAD cipher to use for ticket protection.
  *                  Recommended value: MBEDTLS_CIPHER_AES_256_GCM.
  * \param lifetime  Tickets lifetime in seconds
@@ -122,7 +124,7 @@
  *                  or a specific MBEDTLS_ERR_XXX error code
  */
 int mbedtls_ssl_ticket_setup(mbedtls_ssl_ticket_context *ctx,
-                             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                             mbedtls_f_rng_t *f_rng, void *p_rng,
                              mbedtls_cipher_type_t cipher,
                              uint32_t lifetime);
 
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 1ce0d23..6b96039 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -1176,7 +1176,7 @@
  * \note            \p f_rng is used for the signature operation.
  */
 int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
-                              int (*f_rng)(void *, unsigned char *, size_t),
+                              mbedtls_f_rng_t *f_rng,
                               void *p_rng);
 
 #if defined(MBEDTLS_PEM_WRITE_C)
@@ -1194,7 +1194,7 @@
  * \note            \p f_rng is used for the signature operation.
  */
 int mbedtls_x509write_crt_pem(mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
-                              int (*f_rng)(void *, unsigned char *, size_t),
+                              mbedtls_f_rng_t *f_rng,
                               void *p_rng);
 #endif /* MBEDTLS_PEM_WRITE_C */
 #endif /* MBEDTLS_X509_CRT_WRITE_C */
diff --git a/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h
index 8c31c09..c4bd7f1 100644
--- a/include/mbedtls/x509_csr.h
+++ b/include/mbedtls/x509_csr.h
@@ -349,7 +349,7 @@
  * \note            \p f_rng is used for the signature operation.
  */
 int mbedtls_x509write_csr_der(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
-                              int (*f_rng)(void *, unsigned char *, size_t),
+                              mbedtls_f_rng_t *f_rng,
                               void *p_rng);
 
 #if defined(MBEDTLS_PEM_WRITE_C)
@@ -368,7 +368,7 @@
  * \note            \p f_rng is used for the signature operation.
  */
 int mbedtls_x509write_csr_pem(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
-                              int (*f_rng)(void *, unsigned char *, size_t),
+                              mbedtls_f_rng_t *f_rng,
                               void *p_rng);
 #endif /* MBEDTLS_PEM_WRITE_C */
 #endif /* MBEDTLS_X509_CSR_WRITE_C */
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 2bbcea3..2fe9f35 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -59,6 +59,18 @@
  * of integral types defined in "crypto_types.h". */
 #include "crypto_values.h"
 
+/* The file "crypto_sizes.h" contains definitions for size calculation
+ * macros whose definitions are implementation-specific. */
+#include "crypto_sizes.h"
+
+/* The file "crypto_struct.h" contains definitions for
+ * implementation-specific structs that are declared above. */
+#if defined(MBEDTLS_PSA_CRYPTO_STRUCT_FILE)
+#include MBEDTLS_PSA_CRYPTO_STRUCT_FILE
+#else
+#include "crypto_struct.h"
+#endif
+
 /** \defgroup initialization Library initialization
  * @{
  */
@@ -4958,18 +4970,6 @@
 }
 #endif
 
-/* The file "crypto_sizes.h" contains definitions for size calculation
- * macros whose definitions are implementation-specific. */
-#include "crypto_sizes.h"
-
-/* The file "crypto_struct.h" contains definitions for
- * implementation-specific structs that are declared above. */
-#if defined(MBEDTLS_PSA_CRYPTO_STRUCT_FILE)
-#include MBEDTLS_PSA_CRYPTO_STRUCT_FILE
-#else
-#include "crypto_struct.h"
-#endif
-
 /* The file "crypto_extra.h" contains vendor-specific definitions. This
  * can include vendor-defined algorithms, extra functions, etc. */
 #include "crypto_extra.h"