Merge pull request #4588 from TRodziewicz/remove_MD2_MD4_RC4_Blowfish_and_XTEA

Remove MD2, MD4, RC4, Blowfish and XTEA
diff --git a/ChangeLog.d/issue4083.txt b/ChangeLog.d/issue4083.txt
new file mode 100644
index 0000000..8457337
--- /dev/null
+++ b/ChangeLog.d/issue4083.txt
@@ -0,0 +1,4 @@
+Removals
+    * Remove the following functions: mbedtls_timing_self_test(),
+      mbedtls_hardclock_poll(), mbedtls_timing_hardclock() and
+      mbedtls_set_alarm(). Fixes #4083.
diff --git a/ChangeLog.d/mandatory-rng-param.txt b/ChangeLog.d/mandatory-rng-param.txt
new file mode 100644
index 0000000..39ee335
--- /dev/null
+++ b/ChangeLog.d/mandatory-rng-param.txt
@@ -0,0 +1,14 @@
+API changes
+   * For all functions that take a random number generator (RNG) as a
+     parameter, this parameter is now mandatory (that is, NULL is not an
+     acceptable value). Functions which previously accepted NULL and now
+     reject it are: the X.509 CRT and CSR writing functions; the PK and RSA
+     sign and decrypt function; mbedtls_rsa_private(); the functions
+     in DHM and ECDH that compute the shared secret; the scalar multiplication
+     functions in ECP.
+   * The following functions now require an RNG parameter:
+     mbedtls_ecp_check_pub_priv(), mbedtls_pk_check_pair(),
+     mbedtls_pk_parse_key(), mbedtls_pk_parse_keyfile().
+Removals
+   * The configuration option MBEDTLS_ECP_NO_INTERNAL_RNG has been removed as
+     it no longer had any effect.
diff --git a/ChangeLog.d/psa_key_derivation-bad_workflow.txt b/ChangeLog.d/psa_key_derivation-bad_workflow.txt
new file mode 100644
index 0000000..7fd03e6
--- /dev/null
+++ b/ChangeLog.d/psa_key_derivation-bad_workflow.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix PSA_ALG_TLS12_PRF and PSA_ALG_TLS12_PSK_TO_MS being too permissive
+     about missing inputs.
diff --git a/ChangeLog.d/remove-rsa-mode-parameter.txt b/ChangeLog.d/remove-rsa-mode-parameter.txt
index 854dda3..2590d3a 100644
--- a/ChangeLog.d/remove-rsa-mode-parameter.txt
+++ b/ChangeLog.d/remove-rsa-mode-parameter.txt
@@ -6,4 +6,3 @@
      decryption functions now always use the private key and verification and
      encryption use the public key. Verification functions also no longer have
      RNG parameters.
-   * The RNG is now mandatory for all private-key RSA operations.
diff --git a/docs/3.0-migration-guide.d/mandatory-rng-param.md b/docs/3.0-migration-guide.d/mandatory-rng-param.md
new file mode 100644
index 0000000..f6aba08
--- /dev/null
+++ b/docs/3.0-migration-guide.d/mandatory-rng-param.md
@@ -0,0 +1,40 @@
+The RNG parameter is now mandatory for all functions that accept one
+--------------------------------------------------------------------
+
+This change affects all users who called a function accepting a `f_rng`
+parameter with `NULL` as the value of this argument; this is no longer
+supported.
+
+The changed functions are: the X.509 CRT and CSR writing functions; the PK and
+RSA sign and decrypt functions; `mbedtls_rsa_private()`; the functions in DHM
+and ECDH that compute the shared secret; the scalar multiplication functions in
+ECP.
+
+You now need to pass a properly seeded, cryptographically secure RNG to all
+functions that accept a `f_rng` parameter. It is of course still possible to
+pass `NULL` as the context pointer `p_rng` if your RNG function doesn't need a
+context.
+
+Alternative implementations of a module (enabled with the `MBEDTLS_module_ALT`
+configuration options) may have their own internal and are free to ignore the
+`f_rng` argument but must allow users to pass one anyway.
+
+Some functions gained an RNG parameter
+--------------------------------------
+
+This affects users of the following functions: `mbedtls_ecp_check_pub_priv()`,
+`mbedtls_pk_check_pair()`, `mbedtls_pk_parse_key()`, and
+`mbedtls_pk_parse_keyfile()`.
+
+You now need to pass a properly seeded, cryptographically secure RNG when
+calling these functions. It is used for blinding, a counter-measure against
+side-channel attacks.
+
+The configuration option `MBEDTLS_ECP_NO_INTERNAL_RNG` was removed
+------------------------------------------------------------------
+
+This doesn't affect users of the default configuration; it only affects people
+who were explicitly setting this option.
+
+This was a trade-off between code size and counter-measures; it is no longer
+relevant as the counter-measure is now always on at no cost in code size.
diff --git a/docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md b/docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md
new file mode 100644
index 0000000..fa61e27
--- /dev/null
+++ b/docs/3.0-migration-guide.d/move_part_of_timing_module_out_of_the_library.md
@@ -0,0 +1,9 @@
+Move part of timing module out of the library
+--
+
+The change affects users who use any of the following functions:
+`mbedtls_timing_self_test()`, `mbedtls_hardclock_poll()`,
+`mbedtls_timing_hardclock()` and `mbedtls_set_alarm()`.
+
+If you were relying on these functions, you'll now need to change to using your
+platform's corresponding functions directly.
diff --git a/docs/3.0-migration-guide.d/remove-rsa-mode-parameter.md b/docs/3.0-migration-guide.d/remove-rsa-mode-parameter.md
index e400650..d21d5ed 100644
--- a/docs/3.0-migration-guide.d/remove-rsa-mode-parameter.md
+++ b/docs/3.0-migration-guide.d/remove-rsa-mode-parameter.md
@@ -19,11 +19,3 @@
 was only needed when using a private key). This affects all applications using
 the RSA verify functions.
 
-RNG is now mandatory in all RSA private key operations
-------------------------------------------------------
-
-The random generator is now mandatory for blinding in all RSA private-key
-operations (`mbedtls_rsa_private`, `mbedtls_rsa_xxx_sign`,
-`mbedtls_rsa_xxx_decrypt`) as well as for encryption
-(`mbedtls_rsa_xxx_encrypt`). This means that passing a null `f_rng` is no longer
-supported.
diff --git a/docs/3.0-migration-guide.d/remove-ssl-get-session_pointer.md b/docs/3.0-migration-guide.d/remove-ssl-get-session_pointer.md
new file mode 100644
index 0000000..a4a4895
--- /dev/null
+++ b/docs/3.0-migration-guide.d/remove-ssl-get-session_pointer.md
@@ -0,0 +1,23 @@
+Remove the SSL API mbedtls_ssl_get_session_pointer()
+-----------------------------------------------------------------
+
+This affects two classes of users:
+
+1. Users who manually inspect parts of the current session through
+   direct structure field access.
+
+2. Users of session resumption who query the current session
+   via `mbedtls_ssl_get_session_pointer()` prior to saving or exporting
+   it via `mbedtls_ssl_session_copy()` or `mbedtls_ssl_session_save()`,
+   respectively.
+
+Migration paths:
+
+1. Mbed TLS 3.0 does not offer a migration path for the usecase 1: Like many
+   other Mbed TLS structures, the structure of `mbedtls_ssl_session` is no
+   longer part of the public API in Mbed TLS 3.0, and direct structure field
+   access is no longer supported. Please see the corresponding migration guide.
+
+2. Users should replace calls to `mbedtls_ssl_get_session_pointer()` by
+   calls to `mbedtls_ssl_get_session()` as demonstrated in the example
+   program `programs/ssl/ssl_client2.c`.
diff --git a/docs/3.0-migration-guide.d/ssl-ticket-api.md b/docs/3.0-migration-guide.d/ssl-ticket-api.md
new file mode 100644
index 0000000..23c53d6
--- /dev/null
+++ b/docs/3.0-migration-guide.d/ssl-ticket-api.md
@@ -0,0 +1,30 @@
+Modified semantics of mbedtls_ssl_{get,set}_session()
+-----------------------------------------------------------------
+
+This affects users who call `mbedtls_ssl_get_session()` or
+`mbedtls_ssl_set_session()` multiple times on the same SSL context
+representing an established TLS 1.2 connection.
+Those users will now observe the second call to fail with
+`MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE`.
+
+Migration path:
+- Exporting the same TLS 1.2 connection multiple times via
+  `mbedtls_ssl_get_session()` leads to multiple copies of
+  the same session. This use of `mbedtls_ssl_get_session()`
+  is discouraged, and the following should be considered:
+  * If the various session copies are later loaded into
+    fresh SSL contexts via `mbedtls_ssl_set_session()`,
+    export via `mbedtls_ssl_get_session()` only once and
+    load the same session into different contexts via
+    `mbedtls_ssl_set_session()`. Since `mbedtls_ssl_set_session()`
+    makes a copy of the session that's being loaded, this
+    is functionally equivalent.
+  * If the various session copies are later serialized
+    via `mbedtls_ssl_session_save()`, export and serialize
+    the session only once via `mbedtls_ssl_get_session()` and
+    `mbedtls_ssl_session_save()` and make copies of the raw
+    data instead.
+- Calling `mbedtls_ssl_set_session()` multiple times in Mbed TLS 2.x
+  is not useful since subsequent calls overwrite the effect of previous
+  calls. Applications achieve equivalent functional behaviour by
+  issuing only the very last call to `mbedtls_ssl_set_session()`.
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 90dee6c..85f7efd 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -150,14 +150,6 @@
 #error "MBEDTLS_ECP_C defined, but not all prerequisites"
 #endif
 
-#if defined(MBEDTLS_ECP_C) && !(            \
-    defined(MBEDTLS_ECP_ALT) ||             \
-    defined(MBEDTLS_CTR_DRBG_C) ||          \
-    defined(MBEDTLS_HMAC_DRBG_C) ||         \
-    defined(MBEDTLS_ECP_NO_INTERNAL_RNG))
-#error "MBEDTLS_ECP_C requires a DRBG module unless MBEDTLS_ECP_NO_INTERNAL_RNG is defined or an alternative implementation is used"
-#endif
-
 #if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
 #error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites"
 #endif
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index e8e2b1b..16f93f9 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -47,7 +47,6 @@
  *
  * Used in:
  *      library/aria.c
- *      library/timing.c
  *      library/bn_mul.h
  *
  * Required by:
@@ -268,7 +267,7 @@
 /**
  * \def MBEDTLS_TIMING_ALT
  *
- * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(),
+ * Uncomment to provide your own alternate implementation for
  * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay()
  *
  * Only works if you have MBEDTLS_TIMING_C enabled.
@@ -645,28 +644,6 @@
 #define MBEDTLS_ECP_NIST_OPTIM
 
 /**
- * \def MBEDTLS_ECP_NO_INTERNAL_RNG
- *
- * When this option is disabled, mbedtls_ecp_mul() will make use of an
- * internal RNG when called with a NULL \c f_rng argument, in order to protect
- * against some side-channel attacks.
- *
- * This protection introduces a dependency of the ECP module on one of the
- * DRBG modules. For very constrained implementations that don't require this
- * protection (for example, because you're only doing signature verification,
- * so not manipulating any secret, or because local/physical side-channel
- * attacks are outside your threat model), it might be desirable to get rid of
- * that dependency.
- *
- * \warning Enabling this option makes some uses of ECP vulnerable to some
- * side-channel attacks. Only enable it if you know that's not a problem for
- * your use case.
- *
- * Uncomment this macro to disable some counter-measures in ECP.
- */
-//#define MBEDTLS_ECP_NO_INTERNAL_RNG
-
-/**
  * \def MBEDTLS_ECP_RESTARTABLE
  *
  * Enable "non-blocking" ECC operations that can return early and be resumed.
@@ -1007,8 +984,7 @@
 /**
  * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
  *
- * Do not add default entropy sources. These are the platform specific
- * or mbedtls_timing_hardclock poll function.
+ * Do not add default entropy sources in mbedtls_entropy_init().
  *
  * This is useful to have more control over the added entropy sources in an
  * application.
diff --git a/include/mbedtls/dhm.h b/include/mbedtls/dhm.h
index e8c8a82..850813e 100644
--- a/include/mbedtls/dhm.h
+++ b/include/mbedtls/dhm.h
@@ -279,10 +279,10 @@
  * \param output_size   The size of the destination buffer. This must be at
  *                      least the size of \c ctx->len (the size of \c P).
  * \param olen          On exit, holds the actual number of Bytes written.
- * \param f_rng         The RNG function, for blinding purposes. This may
- *                      b \c NULL if blinding isn't needed.
- * \param p_rng         The RNG context. This may be \c NULL if \p f_rng
- *                      doesn't need a context argument.
+ * \param f_rng         The RNG function. Must not be \c NULL. Used for
+ *                      blinding.
+ * \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.
  *
  * \return              \c 0 on success.
  * \return              An \c MBEDTLS_ERR_DHM_XXX error code on failure.
diff --git a/include/mbedtls/ecdh.h b/include/mbedtls/ecdh.h
index 2a0980b..587035a 100644
--- a/include/mbedtls/ecdh.h
+++ b/include/mbedtls/ecdh.h
@@ -222,10 +222,7 @@
  *                  This must be initialized.
  * \param d         Our secret exponent (private key).
  *                  This must be initialized.
- * \param f_rng     The RNG function. This may be \c NULL if randomization
- *                  of intermediate results during the ECP computations is
- *                  not needed (discouraged). See the documentation of
- *                  mbedtls_ecp_mul() for more.
+ * \param f_rng     The RNG function to use. 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 need a
  *                  context argument.
@@ -428,8 +425,7 @@
  * \param buf       The buffer to write the generated shared key to. This
  *                  must be a writable buffer of size \p blen Bytes.
  * \param blen      The length of the destination buffer \p buf in Bytes.
- * \param f_rng     The RNG function, for blinding purposes. This may
- *                  b \c NULL if blinding isn't needed.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
  * \param p_rng     The RNG context. This may be \c NULL if \p f_rng
  *                  doesn't need a context argument.
  *
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 49e85d9..75ad808 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -911,15 +911,8 @@
  * \note            To prevent timing attacks, this function
  *                  executes the exact same sequence of base-field
  *                  operations for any valid \p m. It avoids any if-branch or
- *                  array index depending on the value of \p m.
- *
- * \note            If \p f_rng is not NULL, it is used to randomize
- *                  intermediate results to prevent potential timing attacks
- *                  targeting these results. We recommend always providing
- *                  a non-NULL \p f_rng. The overhead is negligible.
- *                  Note: unless #MBEDTLS_ECP_NO_INTERNAL_RNG is defined, when
- *                  \p f_rng is NULL, an internal RNG (seeded from the value
- *                  of \p m) will be used instead.
+ *                  array index depending on the value of \p m. If also uses
+ *                  \p f_rng to randomize some intermediate results.
  *
  * \param grp       The ECP group to use.
  *                  This must be initialized and have group parameters
@@ -928,9 +921,9 @@
  *                  This must be initialized.
  * \param m         The integer by which to multiply. This must be initialized.
  * \param P         The point to multiply. This must be initialized.
- * \param f_rng     The RNG function. This may be \c NULL if randomization
- *                  of intermediate results isn't desired (discouraged).
- * \param p_rng     The RNG context to be passed to \p p_rng.
+ * \param f_rng     The RNG function. 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.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private
@@ -959,9 +952,9 @@
  *                  This must be initialized.
  * \param m         The integer by which to multiply. This must be initialized.
  * \param P         The point to multiply. This must be initialized.
- * \param f_rng     The RNG function. This may be \c NULL if randomization
- *                  of intermediate results isn't desired (discouraged).
- * \param p_rng     The RNG context to be passed to \p p_rng.
+ * \param f_rng     The RNG function. 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.
  * \param rs_ctx    The restart context (NULL disables restart).
  *
  * \return          \c 0 on success.
@@ -1265,14 +1258,18 @@
  *                  part is ignored.
  * \param prv       The keypair structure holding the full keypair.
  *                  This must be initialized.
+ * \param f_rng     The RNG function. 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.
  *
  * \return          \c 0 on success, meaning that the keys are valid and match.
  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the keys are invalid or do not match.
  * \return          An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX
  *                  error code on calculation failure.
  */
-int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub,
-                                const mbedtls_ecp_keypair *prv );
+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 );
 
 #if defined(MBEDTLS_SELF_TEST)
 
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index 85bf7c9..dec5111 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -498,7 +498,7 @@
  *                  given the key type.
  * \param sig_len   On successful return,
  *                  the number of bytes written to \p sig.
- * \param f_rng     RNG function
+ * \param f_rng     RNG function, must not be \c NULL.
  * \param p_rng     RNG parameter
  *
  * \return          0 on success, or a specific error code.
@@ -538,7 +538,7 @@
  *                  given the key type.
  * \param sig_len   On successful return,
  *                  the number of bytes written to \p sig.
- * \param f_rng     RNG function
+ * \param f_rng     RNG function, must not be \c NULL.
  * \param p_rng     RNG parameter
  * \param rs_ctx    Restart context (NULL to disable restart)
  *
@@ -563,7 +563,7 @@
  * \param output    Decrypted output
  * \param olen      Decrypted message length
  * \param osize     Size of the output buffer
- * \param f_rng     RNG function
+ * \param f_rng     RNG function, must not be \c NULL.
  * \param p_rng     RNG parameter
  *
  * \note            For RSA keys, the default padding type is PKCS#1 v1.5.
@@ -584,9 +584,11 @@
  * \param output    Encrypted output
  * \param olen      Encrypted output length
  * \param osize     Size of the output buffer
- * \param f_rng     RNG function
+ * \param f_rng     RNG function, must not be \c NULL.
  * \param p_rng     RNG parameter
  *
+ * \note            \p f_rng is used for padding generation.
+ *
  * \note            For RSA keys, the default padding type is PKCS#1 v1.5.
  *
  * \return          0 on success, or a specific error code.
@@ -601,6 +603,8 @@
  *
  * \param pub       Context holding a public key.
  * \param prv       Context holding a private (and public) key.
+ * \param f_rng     RNG function, must not be \c NULL.
+ * \param p_rng     RNG parameter
  *
  * \return          \c 0 on success (keys were checked and match each other).
  * \return          #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the keys could not
@@ -608,7 +612,10 @@
  * \return          #MBEDTLS_ERR_PK_BAD_INPUT_DATA if a context is invalid.
  * \return          Another non-zero value if the keys do not match.
  */
-int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv );
+int mbedtls_pk_check_pair( const mbedtls_pk_context *pub,
+                           const mbedtls_pk_context *prv,
+                           int (*f_rng)(void *, unsigned char *, size_t),
+                           void *p_rng );
 
 /**
  * \brief           Export debug information
@@ -660,6 +667,8 @@
  *                  The empty password is not supported.
  * \param pwdlen    Size of the password in bytes.
  *                  Ignored if \p pwd is \c NULL.
+ * \param f_rng     RNG function, must not be \c NULL. Used for blinding.
+ * \param p_rng     RNG parameter
  *
  * \note            On entry, ctx must be empty, either freshly initialised
  *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@@ -670,8 +679,9 @@
  * \return          0 if successful, or a specific PK or PEM error code
  */
 int mbedtls_pk_parse_key( mbedtls_pk_context *ctx,
-                  const unsigned char *key, size_t keylen,
-                  const unsigned char *pwd, size_t pwdlen );
+              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 );
 
 /** \ingroup pk_module */
 /**
@@ -711,6 +721,8 @@
  *                  Pass a null-terminated string if expecting an encrypted
  *                  key; a non-encrypted key will also be accepted.
  *                  The empty password is not supported.
+ * \param f_rng     RNG function, must not be \c NULL. Used for blinding.
+ * \param p_rng     RNG parameter
  *
  * \note            On entry, ctx must be empty, either freshly initialised
  *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
@@ -721,7 +733,8 @@
  * \return          0 if successful, or a specific PK or PEM error code
  */
 int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
-                      const char *path, const char *password );
+                  const char *path, const char *password,
+                  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
 
 /** \ingroup pk_module */
 /**
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index b2f5c67..603615b 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -933,6 +933,8 @@
     unsigned char MBEDTLS_PRIVATE(id)[32];       /*!< session identifier */
     unsigned char MBEDTLS_PRIVATE(master)[48];   /*!< the master secret  */
 
+    unsigned char exported;
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
     mbedtls_x509_crt *MBEDTLS_PRIVATE(peer_cert);       /*!< peer X.509 cert chain */
@@ -1535,7 +1537,7 @@
  * \brief          Set the random number generator callback
  *
  * \param conf     SSL configuration
- * \param f_rng    RNG function
+ * \param f_rng    RNG function (mandatory)
  * \param p_rng    RNG parameter
  */
 void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf,
@@ -2391,18 +2393,49 @@
 
 #if defined(MBEDTLS_SSL_CLI_C)
 /**
- * \brief          Request resumption of session (client-side only)
- *                 Session data is copied from presented session structure.
+ * \brief          Load a session for session resumption.
  *
- * \param ssl      SSL context
- * \param session  session context
+ *                 Sessions loaded through this call will be considered
+ *                 for session resumption in the next handshake.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed,
- *                 MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or
- *                 arguments are otherwise invalid
+ * \note           Even if this call succeeds, it is not guaranteed that
+ *                 the next handshake will indeed be shortened through the
+ *                 use of session resumption: The server is always free
+ *                 to reject any attempt for resumption and fall back to
+ *                 a full handshake.
+ *
+ * \note           This function can handle a variety of mechanisms for session
+ *                 resumption: For TLS 1.2, both session ID-based resumption and
+ *                 ticket-based resumption will be considered. For TLS 1.3,
+ *                 once implemented, sessions equate to tickets, and loading
+ *                 one or more sessions via this call will lead to their
+ *                 corresponding tickets being advertised as resumption PSKs
+ *                 by the client.
+ *
+ * \note           Calling this function multiple times will only be useful
+ *                 once TLS 1.3 is supported. For TLS 1.2 connections, this
+ *                 function should be called at most once.
+ *
+ * \param ssl      The SSL context representing the connection which should
+ *                 be attempted to be setup using session resumption. This
+ *                 must be initialized via mbedtls_ssl_init() and bound to
+ *                 an SSL configuration via mbedtls_ssl_setup(), but
+ *                 the handshake must not yet have been started.
+ * \param session  The session to be considered for session resumption.
+ *                 This must be a session previously exported via
+ *                 mbedtls_ssl_get_session(), and potentially serialized and
+ *                 deserialized through mbedtls_ssl_session_save() and
+ *                 mbedtls_ssl_session_load() in the meantime.
+ *
+ * \return         \c 0 if successful.
+ * \return         \c MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if the session
+ *                 could not be loaded because of an implementation limitation.
+ *                 This error is non-fatal, and has no observable effect on
+ *                 the SSL context or the session that was attempted to be loaded.
+ * \return         Another negative error code on other kinds of failure.
  *
  * \sa             mbedtls_ssl_get_session()
+ * \sa             mbedtls_ssl_session_load()
  */
 int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session );
 #endif /* MBEDTLS_SSL_CLI_C */
@@ -2451,7 +2484,6 @@
  *                 of session cache or session tickets.
  *
  * \see            mbedtls_ssl_session_load()
- * \see            mbedtls_ssl_get_session_pointer()
  *
  * \param session  The session structure to be saved.
  * \param buf      The buffer to write the serialized data to. It must be a
@@ -2475,23 +2507,6 @@
                               size_t *olen );
 
 /**
- * \brief          Get a pointer to the current session structure, for example
- *                 to serialize it.
- *
- * \warning        Ownership of the session remains with the SSL context, and
- *                 the returned pointer is only guaranteed to be valid until
- *                 the next API call operating on the same \p ssl context.
- *
- * \see            mbedtls_ssl_session_save()
- *
- * \param ssl      The SSL context.
- *
- * \return         A pointer to the current session if successful.
- * \return         \c NULL if no session is active.
- */
-const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_context *ssl );
-
-/**
  * \brief               Set the list of allowed ciphersuites and the preference
  *                      order. First in the list has the highest preference.
  *                      (Overrides all version-specific lists)
@@ -3642,32 +3657,41 @@
 
 #if defined(MBEDTLS_SSL_CLI_C)
 /**
- * \brief          Save session in order to resume it later (client-side only)
- *                 Session data is copied to presented session structure.
+ * \brief          Export a session in order to resume it later.
  *
+ * \param ssl      The SSL context representing the connection for which to
+ *                 to export a session structure for later resumption.
+ * \param session  The target structure in which to store the exported session.
+ *                 This must have been initialized with mbedtls_ssl_init_session()
+ *                 but otherwise be unused.
  *
- * \param ssl      SSL context
- * \param session  session context
+ * \note           This function can handle a variety of mechanisms for session
+ *                 resumption: For TLS 1.2, both session ID-based resumption and
+ *                 ticket-based resumption will be considered. For TLS 1.3,
+ *                 once implemented, sessions equate to tickets, and calling
+ *                 this function multiple times will export the available
+ *                 tickets one a time until no further tickets are available,
+ *                 in which case MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE will
+ *                 be returned.
  *
- * \return         0 if successful,
- *                 MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed,
- *                 MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or
- *                 arguments are otherwise invalid.
+ * \note           Calling this function multiple times will only be useful
+ *                 once TLS 1.3 is supported. For TLS 1.2 connections, this
+ *                 function should be called at most once.
  *
- * \note           Only the server certificate is copied, and not the full chain,
- *                 so you should not attempt to validate the certificate again
- *                 by calling \c mbedtls_x509_crt_verify() on it.
- *                 Instead, you should use the results from the verification
- *                 in the original handshake by calling \c mbedtls_ssl_get_verify_result()
- *                 after loading the session again into a new SSL context
- *                 using \c mbedtls_ssl_set_session().
- *
- * \note           Once the session object is not needed anymore, you should
- *                 free it by calling \c mbedtls_ssl_session_free().
+ * \return         \c 0 if successful. In this case, \p session can be used for
+ *                 session resumption by passing it to mbedtls_ssl_set_session(),
+ *                 and serialized for storage via mbedtls_ssl_session_save().
+ * \return         #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if no further session
+ *                 is available for export.
+ *                 This error is a non-fatal, and has no observable effect on
+ *                 the SSL context or the destination session.
+ * \return         Another negative error code on other kinds of failure.
  *
  * \sa             mbedtls_ssl_set_session()
+ * \sa             mbedtls_ssl_session_save()
  */
-int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *session );
+int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl,
+                             mbedtls_ssl_session *session );
 #endif /* MBEDTLS_SSL_CLI_C */
 
 /**
diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h
index 871eec3..1047dbb 100644
--- a/include/mbedtls/ssl_ticket.h
+++ b/include/mbedtls/ssl_ticket.h
@@ -90,7 +90,7 @@
  * \brief           Prepare context to be actually used
  *
  * \param ctx       Context to be set up
- * \param f_rng     RNG callback function
+ * \param f_rng     RNG callback function (mandatory)
  * \param p_rng     RNG callback context
  * \param cipher    AEAD cipher to use for ticket protection.
  *                  Recommended value: MBEDTLS_CIPHER_AES_256_GCM.
diff --git a/include/mbedtls/timing.h b/include/mbedtls/timing.h
index 7669bb9..6ffc812 100644
--- a/include/mbedtls/timing.h
+++ b/include/mbedtls/timing.h
@@ -61,52 +61,10 @@
 #include "timing_alt.h"
 #endif /* MBEDTLS_TIMING_ALT */
 
-extern volatile int mbedtls_timing_alarmed;
-
-/**
- * \brief          Return the CPU cycle counter value
- *
- * \warning        This is only a best effort! Do not rely on this!
- *                 In particular, it is known to be unreliable on virtual
- *                 machines.
- *
- * \note           This value starts at an unspecified origin and
- *                 may wrap around.
- */
-unsigned long mbedtls_timing_hardclock( void );
-
-/**
- * \brief          Return the elapsed time in milliseconds
- *
- * \param val      points to a timer structure
- * \param reset    If 0, query the elapsed time. Otherwise (re)start the timer.
- *
- * \return         Elapsed time since the previous reset in ms. When
- *                 restarting, this is always 0.
- *
- * \note           To initialize a timer, call this function with reset=1.
- *
- *                 Determining the elapsed time and resetting the timer is not
- *                 atomic on all platforms, so after the sequence
- *                 `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 =
- *                 get_timer(0) }` the value time1+time2 is only approximately
- *                 the delay since the first reset.
- */
+/* Internal use */
 unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset );
 
 /**
- * \brief          Setup an alarm clock
- *
- * \param seconds  delay before the "mbedtls_timing_alarmed" flag is set
- *                 (must be >=0)
- *
- * \warning        Only one alarm at a time  is supported. In a threaded
- *                 context, this means one for the whole process, not one per
- *                 thread.
- */
-void mbedtls_set_alarm( int seconds );
-
-/**
  * \brief          Set a pair of delays to watch
  *                 (See \c mbedtls_timing_get_delay().)
  *
@@ -136,15 +94,6 @@
  */
 int mbedtls_timing_get_delay( void *data );
 
-#if defined(MBEDTLS_SELF_TEST)
-/**
- * \brief          Checkup routine
- *
- * \return         0 if successful, or 1 if a test failed
- */
-int mbedtls_timing_self_test( int verbose );
-#endif
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index d383168..5c5509c 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -1108,16 +1108,13 @@
  * \param ctx       certificate to write away
  * \param buf       buffer to write to
  * \param size      size of the buffer
- * \param f_rng     RNG function (for signature, see note)
+ * \param f_rng     RNG function. This must not be \c NULL.
  * \param p_rng     RNG parameter
  *
  * \return          length of data written if successful, or a specific
  *                  error code
  *
- * \note            f_rng may be NULL if RSA is used for signature and the
- *                  signature is made offline (otherwise f_rng is desirable
- *                  for countermeasures against timing attacks).
- *                  ECDSA signatures always require a non-NULL f_rng.
+ * \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),
@@ -1130,15 +1127,12 @@
  * \param ctx       certificate to write away
  * \param buf       buffer to write to
  * \param size      size of the buffer
- * \param f_rng     RNG function (for signature, see note)
+ * \param f_rng     RNG function. This must not be \c NULL.
  * \param p_rng     RNG parameter
  *
  * \return          0 if successful, or a specific error code
  *
- * \note            f_rng may be NULL if RSA is used for signature and the
- *                  signature is made offline (otherwise f_rng is desirable
- *                  for countermeasures against timing attacks).
- *                  ECDSA signatures always require a non-NULL f_rng.
+ * \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),
diff --git a/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h
index 0a069df..a0f1278 100644
--- a/include/mbedtls/x509_csr.h
+++ b/include/mbedtls/x509_csr.h
@@ -264,16 +264,13 @@
  * \param ctx       CSR to write away
  * \param buf       buffer to write to
  * \param size      size of the buffer
- * \param f_rng     RNG function (for signature, see note)
+ * \param f_rng     RNG function. This must not be \c NULL.
  * \param p_rng     RNG parameter
  *
  * \return          length of data written if successful, or a specific
  *                  error code
  *
- * \note            f_rng may be NULL if RSA is used for signature and the
- *                  signature is made offline (otherwise f_rng is desirable
- *                  for countermeasures against timing attacks).
- *                  ECDSA signatures always require a non-NULL f_rng.
+ * \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),
@@ -287,15 +284,12 @@
  * \param ctx       CSR to write away
  * \param buf       buffer to write to
  * \param size      size of the buffer
- * \param f_rng     RNG function (for signature, see note)
+ * \param f_rng     RNG function. This must not be \c NULL.
  * \param p_rng     RNG parameter
  *
  * \return          0 if successful, or a specific error code
  *
- * \note            f_rng may be NULL if RSA is used for signature and the
- *                  signature is made offline (otherwise f_rng is desirable
- *                  for countermeasures against timing attacks).
- *                  ECDSA signatures always require a non-NULL f_rng.
+ * \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),
diff --git a/library/dhm.c b/library/dhm.c
index e88f3a2..29ce755 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -444,6 +444,9 @@
     DHM_VALIDATE_RET( output != NULL );
     DHM_VALIDATE_RET( olen != NULL );
 
+    if( f_rng == NULL )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
     if( output_size < mbedtls_dhm_get_len( ctx ) )
         return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
 
@@ -453,25 +456,17 @@
     mbedtls_mpi_init( &GYb );
 
     /* Blind peer's value */
-    if( f_rng != NULL )
-    {
-        MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
-    }
-    else
-        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) );
+    MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
 
     /* Do modular exponentiation */
     MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
                           &ctx->P, &ctx->RP ) );
 
     /* Unblind secret value */
-    if( f_rng != NULL )
-    {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
-    }
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
 
     /* Output the secret without any leading zero byte. This is mandatory
      * for TLS per RFC 5246 §8.1.2. */
diff --git a/library/ecjpake.c b/library/ecjpake.c
index de43ddb..d229311 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -962,6 +962,28 @@
     0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
 };
 
+/*
+ * PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!!
+ *
+ * This is the linear congruential generator from numerical recipes,
+ * except we only use the low byte as the output. See
+ * https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
+ */
+static int self_test_rng( void *ctx, unsigned char *out, size_t len )
+{
+    static uint32_t state = 42;
+
+    (void) ctx;
+
+    for( size_t i = 0; i < len; i++ )
+    {
+        state = state * 1664525u + 1013904223u;
+        out[i] = (unsigned char) state;
+    }
+
+    return( 0 );
+}
+
 /* Load my private keys and generate the corresponding public keys */
 static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
                               const unsigned char *xm1, size_t len1,
@@ -972,9 +994,9 @@
     MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) );
     MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) );
     MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1,
-                                      &ctx->grp.G, NULL, NULL ) );
+                                      &ctx->grp.G, self_test_rng, NULL ) );
     MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2,
-                                      &ctx->grp.G, NULL, NULL ) );
+                                      &ctx->grp.G, self_test_rng, NULL ) );
 
 cleanup:
     return( ret );
diff --git a/library/ecp.c b/library/ecp.c
index 044bbe1..8f6e988 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -101,16 +101,6 @@
 
 #include "ecp_internal_alt.h"
 
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-#if defined(MBEDTLS_HMAC_DRBG_C)
-#include "mbedtls/hmac_drbg.h"
-#elif defined(MBEDTLS_CTR_DRBG_C)
-#include "mbedtls/ctr_drbg.h"
-#else
-#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid."
-#endif
-#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */
-
 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
     !defined(inline) && !defined(__cplusplus)
 #define inline __inline
@@ -124,144 +114,6 @@
 static unsigned long add_count, dbl_count, mul_count;
 #endif
 
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-/*
- * Currently ecp_mul() takes a RNG function as an argument, used for
- * side-channel protection, but it can be NULL. The initial reasoning was
- * that people will pass non-NULL RNG when they care about side-channels, but
- * unfortunately we have some APIs that call ecp_mul() with a NULL RNG, with
- * no opportunity for the user to do anything about it.
- *
- * The obvious strategies for addressing that include:
- * - change those APIs so that they take RNG arguments;
- * - require a global RNG to be available to all crypto modules.
- *
- * Unfortunately those would break compatibility. So what we do instead is
- * have our own internal DRBG instance, seeded from the secret scalar.
- *
- * The following is a light-weight abstraction layer for doing that with
- * HMAC_DRBG (first choice) or CTR_DRBG.
- */
-
-#if defined(MBEDTLS_HMAC_DRBG_C)
-
-/* DRBG context type */
-typedef mbedtls_hmac_drbg_context ecp_drbg_context;
-
-/* DRBG context init */
-static inline void ecp_drbg_init( ecp_drbg_context *ctx )
-{
-    mbedtls_hmac_drbg_init( ctx );
-}
-
-/* DRBG context free */
-static inline void ecp_drbg_free( ecp_drbg_context *ctx )
-{
-    mbedtls_hmac_drbg_free( ctx );
-}
-
-/* DRBG function */
-static inline int ecp_drbg_random( void *p_rng,
-                                   unsigned char *output, size_t output_len )
-{
-    return( mbedtls_hmac_drbg_random( p_rng, output, output_len ) );
-}
-
-/* DRBG context seeding */
-static int ecp_drbg_seed( ecp_drbg_context *ctx,
-                   const mbedtls_mpi *secret, size_t secret_len )
-{
-    int ret;
-    unsigned char secret_bytes[MBEDTLS_ECP_MAX_BYTES];
-    /* The list starts with strong hashes */
-    const mbedtls_md_type_t md_type = mbedtls_md_list()[0];
-    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_type );
-
-    if( secret_len > MBEDTLS_ECP_MAX_BYTES )
-    {
-        ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
-        goto cleanup;
-    }
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( secret,
-                                               secret_bytes, secret_len ) );
-
-    ret = mbedtls_hmac_drbg_seed_buf( ctx, md_info, secret_bytes, secret_len );
-
-cleanup:
-    mbedtls_platform_zeroize( secret_bytes, secret_len );
-
-    return( ret );
-}
-
-#elif defined(MBEDTLS_CTR_DRBG_C)
-
-/* DRBG context type */
-typedef mbedtls_ctr_drbg_context ecp_drbg_context;
-
-/* DRBG context init */
-static inline void ecp_drbg_init( ecp_drbg_context *ctx )
-{
-    mbedtls_ctr_drbg_init( ctx );
-}
-
-/* DRBG context free */
-static inline void ecp_drbg_free( ecp_drbg_context *ctx )
-{
-    mbedtls_ctr_drbg_free( ctx );
-}
-
-/* DRBG function */
-static inline int ecp_drbg_random( void *p_rng,
-                                   unsigned char *output, size_t output_len )
-{
-    return( mbedtls_ctr_drbg_random( p_rng, output, output_len ) );
-}
-
-/*
- * Since CTR_DRBG doesn't have a seed_buf() function the way HMAC_DRBG does,
- * we need to pass an entropy function when seeding. So we use a dummy
- * function for that, and pass the actual entropy as customisation string.
- * (During seeding of CTR_DRBG the entropy input and customisation string are
- * concatenated before being used to update the secret state.)
- */
-static int ecp_ctr_drbg_null_entropy(void *ctx, unsigned char *out, size_t len)
-{
-    (void) ctx;
-    memset( out, 0, len );
-    return( 0 );
-}
-
-/* DRBG context seeding */
-static int ecp_drbg_seed( ecp_drbg_context *ctx,
-                   const mbedtls_mpi *secret, size_t secret_len )
-{
-    int ret;
-    unsigned char secret_bytes[MBEDTLS_ECP_MAX_BYTES];
-
-    if( secret_len > MBEDTLS_ECP_MAX_BYTES )
-    {
-        ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
-        goto cleanup;
-    }
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( secret,
-                                               secret_bytes, secret_len ) );
-
-    ret = mbedtls_ctr_drbg_seed( ctx, ecp_ctr_drbg_null_entropy, NULL,
-                                 secret_bytes, secret_len );
-
-cleanup:
-    mbedtls_platform_zeroize( secret_bytes, secret_len );
-
-    return( ret );
-}
-
-#else
-#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid."
-#endif /* DRBG modules */
-#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */
-
 #if defined(MBEDTLS_ECP_RESTARTABLE)
 /*
  * Maximum number of "basic operations" to be done in a row.
@@ -309,10 +161,6 @@
         ecp_rsm_comb_core,      /* ecp_mul_comb_core()                      */
         ecp_rsm_final_norm,     /* do the final normalization               */
     } state;
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_context drbg_ctx;
-    unsigned char drbg_seeded;
-#endif
 };
 
 /*
@@ -325,10 +173,6 @@
     ctx->T = NULL;
     ctx->T_size = 0;
     ctx->state = ecp_rsm_init;
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_init( &ctx->drbg_ctx );
-    ctx->drbg_seeded = 0;
-#endif
 }
 
 /*
@@ -350,10 +194,6 @@
         mbedtls_free( ctx->T );
     }
 
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_free( &ctx->drbg_ctx );
-#endif
-
     ecp_restart_rsm_init( ctx );
 }
 
@@ -2068,9 +1908,7 @@
         i = d;
         MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, T_size, x[i] ) );
         MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) );
-#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
         if( f_rng != 0 )
-#endif
             MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) );
     }
 
@@ -2204,9 +2042,7 @@
      *
      * Avoid the leak by randomizing coordinates before we normalize them.
      */
-#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
     if( f_rng != 0 )
-#endif
         MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) );
 
     MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) );
@@ -2286,42 +2122,9 @@
     size_t d;
     unsigned char T_size = 0, T_ok = 0;
     mbedtls_ecp_point *T = NULL;
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_context drbg_ctx;
-
-    ecp_drbg_init( &drbg_ctx );
-#endif
 
     ECP_RS_ENTER( rsm );
 
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    if( f_rng == NULL )
-    {
-        /* Adjust pointers */
-        f_rng = &ecp_drbg_random;
-#if defined(MBEDTLS_ECP_RESTARTABLE)
-        if( rs_ctx != NULL && rs_ctx->rsm != NULL )
-            p_rng = &rs_ctx->rsm->drbg_ctx;
-        else
-#endif
-            p_rng = &drbg_ctx;
-
-        /* Initialize internal DRBG if necessary */
-#if defined(MBEDTLS_ECP_RESTARTABLE)
-        if( rs_ctx == NULL || rs_ctx->rsm == NULL ||
-            rs_ctx->rsm->drbg_seeded == 0 )
-#endif
-        {
-            const size_t m_len = ( grp->nbits + 7 ) / 8;
-            MBEDTLS_MPI_CHK( ecp_drbg_seed( p_rng, m, m_len ) );
-        }
-#if defined(MBEDTLS_ECP_RESTARTABLE)
-        if( rs_ctx != NULL && rs_ctx->rsm != NULL )
-            rs_ctx->rsm->drbg_seeded = 1;
-#endif
-    }
-#endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */
-
     /* Is P the base point ? */
 #if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
     p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 &&
@@ -2393,10 +2196,6 @@
 
 cleanup:
 
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_free( &drbg_ctx );
-#endif
-
     /* does T belong to the group? */
     if( T == grp->T )
         T = NULL;
@@ -2583,22 +2382,10 @@
     unsigned char b;
     mbedtls_ecp_point RP;
     mbedtls_mpi PX;
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_context drbg_ctx;
-
-    ecp_drbg_init( &drbg_ctx );
-#endif
     mbedtls_ecp_point_init( &RP ); mbedtls_mpi_init( &PX );
 
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
     if( f_rng == NULL )
-    {
-        const size_t m_len = ( grp->nbits + 7 ) / 8;
-        MBEDTLS_MPI_CHK( ecp_drbg_seed( &drbg_ctx, m, m_len ) );
-        f_rng = &ecp_drbg_random;
-        p_rng = &drbg_ctx;
-    }
-#endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
 
     /* Save PX and read from P before writing to R, in case P == R */
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &PX, &P->X ) );
@@ -2613,10 +2400,7 @@
     MOD_ADD( RP.X );
 
     /* Randomize coordinates of the starting point */
-#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    if( f_rng != NULL )
-#endif
-        MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) );
 
     /* Loop invariant: R = result so far, RP = R + P */
     i = mbedtls_mpi_bitlen( m ); /* one past the (zero-based) most significant bit */
@@ -2648,18 +2432,10 @@
      *
      * Avoid the leak by randomizing coordinates before we normalize them.
      */
-#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    if( f_rng != NULL )
-#endif
-        MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) );
-
+    MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) );
     MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) );
 
 cleanup:
-#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
-    ecp_drbg_free( &drbg_ctx );
-#endif
-
     mbedtls_ecp_point_free( &RP ); mbedtls_mpi_free( &PX );
 
     return( ret );
@@ -2669,8 +2445,11 @@
 
 /*
  * Restartable multiplication R = m * P
+ *
+ * This internal function can be called without an RNG in case where we know
+ * the inputs are not sensitive.
  */
-int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+static int ecp_mul_restartable_internal( 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_ecp_restart_ctx *rs_ctx )
@@ -2679,10 +2458,6 @@
 #if defined(MBEDTLS_ECP_INTERNAL_ALT)
     char is_grp_capable = 0;
 #endif
-    ECP_VALIDATE_RET( grp != NULL );
-    ECP_VALIDATE_RET( R   != NULL );
-    ECP_VALIDATE_RET( m   != NULL );
-    ECP_VALIDATE_RET( P   != NULL );
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
     /* reset ops count for this call if top-level */
@@ -2736,6 +2511,25 @@
 }
 
 /*
+ * Restartable multiplication R = m * P
+ */
+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_ecp_restart_ctx *rs_ctx )
+{
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( R   != NULL );
+    ECP_VALIDATE_RET( m   != NULL );
+    ECP_VALIDATE_RET( P   != NULL );
+
+    if( f_rng == NULL )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    return( ecp_mul_restartable_internal( grp, R, m, P, f_rng, p_rng, rs_ctx ) );
+}
+
+/*
  * Multiplication R = m * P
  */
 int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
@@ -2828,8 +2622,8 @@
     }
     else
     {
-        MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, R, m, P,
-                                                      NULL, NULL, rs_ctx ) );
+        MBEDTLS_MPI_CHK( ecp_mul_restartable_internal( grp, R, m, P,
+                                                       NULL, NULL, rs_ctx ) );
     }
 
 cleanup:
@@ -3272,7 +3066,9 @@
 /*
  * Check a public-private key pair
  */
-int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv )
+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 )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     mbedtls_ecp_point Q;
@@ -3296,7 +3092,7 @@
     mbedtls_ecp_group_copy( &grp, &prv->grp );
 
     /* Also checks d is valid */
-    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, NULL, NULL ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, f_rng, p_rng ) );
 
     if( mbedtls_mpi_cmp_mpi( &Q.X, &prv->Q.X ) ||
         mbedtls_mpi_cmp_mpi( &Q.Y, &prv->Q.Y ) ||
@@ -3315,6 +3111,28 @@
 
 #if defined(MBEDTLS_SELF_TEST)
 
+/*
+ * PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!!
+ *
+ * This is the linear congruential generator from numerical recipes,
+ * except we only use the low byte as the output. See
+ * https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
+ */
+static int self_test_rng( void *ctx, unsigned char *out, size_t len )
+{
+    static uint32_t state = 42;
+
+    (void) ctx;
+
+    for( size_t i = 0; i < len; i++ )
+    {
+        state = state * 1664525u + 1013904223u;
+        out[i] = (unsigned char) state;
+    }
+
+    return( 0 );
+}
+
 /* Adjust the exponent to be a valid private point for the specified curve.
  * This is sometimes necessary because we use a single set of exponents
  * for all curves but the validity of values depends on the curve. */
@@ -3370,7 +3188,7 @@
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[0] ) );
     MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
-    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, self_test_rng, NULL ) );
 
     for( i = 1; i < n_exponents; i++ )
     {
@@ -3383,7 +3201,7 @@
 
         MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[i] ) );
         MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
-        MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
+        MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, self_test_rng, NULL ) );
 
         if( add_count != add_c_prev ||
             dbl_count != dbl_c_prev ||
@@ -3461,7 +3279,7 @@
         mbedtls_printf( "  ECP SW test #1 (constant op_count, base point G): " );
     /* Do a dummy multiplication first to trigger precomputation */
     MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) );
-    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, self_test_rng, NULL ) );
     ret = self_test_point( verbose,
                            &grp, &R, &m, &grp.G,
                            sw_exponents,
diff --git a/library/entropy.c b/library/entropy.c
index f12a239..9e31f84 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -73,11 +73,6 @@
                                 MBEDTLS_ENTROPY_MIN_PLATFORM,
                                 MBEDTLS_ENTROPY_SOURCE_STRONG );
 #endif
-#if defined(MBEDTLS_TIMING_C)
-    mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL,
-                                MBEDTLS_ENTROPY_MIN_HARDCLOCK,
-                                MBEDTLS_ENTROPY_SOURCE_WEAK );
-#endif
 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
     mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL,
                                 MBEDTLS_ENTROPY_MIN_HARDWARE,
diff --git a/library/entropy_poll.c b/library/entropy_poll.c
index e5d75c5..bccc034 100644
--- a/library/entropy_poll.c
+++ b/library/entropy_poll.c
@@ -211,24 +211,6 @@
 #endif /* _WIN32 && !EFIX64 && !EFI32 */
 #endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
 
-#if defined(MBEDTLS_TIMING_C)
-int mbedtls_hardclock_poll( void *data,
-                    unsigned char *output, size_t len, size_t *olen )
-{
-    unsigned long timer = mbedtls_timing_hardclock();
-    ((void) data);
-    *olen = 0;
-
-    if( len < sizeof(unsigned long) )
-        return( 0 );
-
-    memcpy( output, &timer, sizeof(unsigned long) );
-    *olen = sizeof(unsigned long);
-
-    return( 0 );
-}
-#endif /* MBEDTLS_TIMING_C */
-
 #if defined(MBEDTLS_ENTROPY_NV_SEED)
 int mbedtls_nv_seed_poll( void *data,
                           unsigned char *output, size_t len, size_t *olen )
diff --git a/library/entropy_poll.h b/library/entropy_poll.h
index 9120fe5..bf26889 100644
--- a/library/entropy_poll.h
+++ b/library/entropy_poll.h
@@ -38,7 +38,6 @@
  * Default thresholds for built-in sources, in bytes
  */
 #define MBEDTLS_ENTROPY_MIN_PLATFORM     32     /**< Minimum for platform source    */
-#define MBEDTLS_ENTROPY_MIN_HARDCLOCK     4     /**< Minimum for mbedtls_timing_hardclock()        */
 #if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE)
 #define MBEDTLS_ENTROPY_MIN_HARDWARE     32     /**< Minimum for the hardware source */
 #endif
@@ -51,14 +50,6 @@
                            unsigned char *output, size_t len, size_t *olen );
 #endif
 
-#if defined(MBEDTLS_TIMING_C)
-/**
- * \brief           mbedtls_timing_hardclock-based entropy poll callback
- */
-int mbedtls_hardclock_poll( void *data,
-                    unsigned char *output, size_t len, size_t *olen );
-#endif
-
 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
 /**
  * \brief           Entropy poll callback for a hardware source
diff --git a/library/pk.c b/library/pk.c
index 06021e2..275d34b 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -500,7 +500,10 @@
 /*
  * Check public-private key pair
  */
-int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
+int mbedtls_pk_check_pair( const mbedtls_pk_context *pub,
+                           const mbedtls_pk_context *prv,
+                           int (*f_rng)(void *, unsigned char *, size_t),
+                           void *p_rng )
 {
     PK_VALIDATE_RET( pub != NULL );
     PK_VALIDATE_RET( prv != NULL );
@@ -511,6 +514,9 @@
         return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
     }
 
+    if( f_rng == NULL )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
     if( prv->pk_info->check_pair_func == NULL )
         return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
 
@@ -525,7 +531,7 @@
             return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
     }
 
-    return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
+    return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx, f_rng, p_rng ) );
 }
 
 /*
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 7c317c5..864e495 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -154,8 +154,12 @@
                                        ilen, input, output ) );
 }
 
-static int rsa_check_pair_wrap( const void *pub, const void *prv )
+static int rsa_check_pair_wrap( const void *pub, const void *prv,
+                                int (*f_rng)(void *, unsigned char *, size_t),
+                                void *p_rng )
 {
+    (void) f_rng;
+    (void) p_rng;
     return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
                                 (const mbedtls_rsa_context *) prv ) );
 }
@@ -388,10 +392,13 @@
 #endif /* MBEDTLS_ECP_RESTARTABLE */
 #endif /* MBEDTLS_ECDSA_C */
 
-static int eckey_check_pair( const void *pub, const void *prv )
+static int eckey_check_pair( const void *pub, const void *prv,
+                             int (*f_rng)(void *, unsigned char *, size_t),
+                             void *p_rng )
 {
     return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
-                                (const mbedtls_ecp_keypair *) prv ) );
+                                (const mbedtls_ecp_keypair *) prv,
+                                f_rng, p_rng ) );
 }
 
 static void *eckey_alloc_wrap( void )
@@ -799,7 +806,9 @@
 }
 
 #if defined(MBEDTLS_RSA_C)
-static int rsa_alt_check_pair( const void *pub, const void *prv )
+static int rsa_alt_check_pair( const void *pub, const void *prv,
+                               int (*f_rng)(void *, unsigned char *, size_t),
+                               void *p_rng )
 {
     unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
     unsigned char hash[32];
@@ -813,7 +822,7 @@
 
     if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
                                    hash, sizeof( hash ),
-                                   sig, &sig_len, NULL, NULL ) ) != 0 )
+                                   sig, &sig_len, f_rng, p_rng ) ) != 0 )
     {
         return( ret );
     }
diff --git a/library/pk_wrap.h b/library/pk_wrap.h
index f7f938a..b2db637 100644
--- a/library/pk_wrap.h
+++ b/library/pk_wrap.h
@@ -85,7 +85,9 @@
                          void *p_rng );
 
     /** Check public-private key pair */
-    int (*check_pair_func)( const void *pub, const void *prv );
+    int (*check_pair_func)( const void *pub, const void *prv,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng );
 
     /** Allocate a new context */
     void * (*ctx_alloc_func)( void );
diff --git a/library/pkparse.c b/library/pkparse.c
index 52b9ecc..fe6aaca 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -123,7 +123,8 @@
  * Load and parse a private key
  */
 int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
-                      const char *path, const char *pwd )
+        const char *path, const char *pwd,
+        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t n;
@@ -136,10 +137,10 @@
         return( ret );
 
     if( pwd == NULL )
-        ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0 );
+        ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0, f_rng, p_rng );
     else
         ret = mbedtls_pk_parse_key( ctx, buf, n,
-                (const unsigned char *) pwd, strlen( pwd ) );
+                (const unsigned char *) pwd, strlen( pwd ), f_rng, p_rng );
 
     mbedtls_platform_zeroize( buf, n );
     mbedtls_free( buf );
@@ -859,8 +860,8 @@
  * Parse a SEC1 encoded private EC key
  */
 static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
-                                  const unsigned char *key,
-                                  size_t keylen )
+        const unsigned char *key, size_t keylen,
+        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     int version, pubkey_done;
@@ -967,7 +968,7 @@
 
     if( ! pubkey_done &&
         ( ret = mbedtls_ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G,
-                                                      NULL, NULL ) ) != 0 )
+                                 f_rng, p_rng ) ) != 0 )
     {
         mbedtls_ecp_keypair_free( eck );
         return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
@@ -997,9 +998,9 @@
  *
  */
 static int pk_parse_key_pkcs8_unencrypted_der(
-                                    mbedtls_pk_context *pk,
-                                    const unsigned char* key,
-                                    size_t keylen )
+        mbedtls_pk_context *pk,
+        const unsigned char* key, size_t keylen,
+        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret, version;
     size_t len;
@@ -1009,6 +1010,11 @@
     mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
     const mbedtls_pk_info_t *pk_info;
 
+#if !defined(MBEDTLS_ECP_C)
+    (void) f_rng;
+    (void) p_rng;
+#endif
+
     /*
      * This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208)
      *
@@ -1071,7 +1077,7 @@
     if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH )
     {
         if( ( ret = pk_use_ecparams( &params, &mbedtls_pk_ec( *pk )->grp ) ) != 0 ||
-            ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len )  ) != 0 )
+            ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len, f_rng, p_rng ) ) != 0 )
         {
             mbedtls_pk_free( pk );
             return( ret );
@@ -1094,9 +1100,10 @@
  */
 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
 static int pk_parse_key_pkcs8_encrypted_der(
-                                    mbedtls_pk_context *pk,
-                                    unsigned char *key, size_t keylen,
-                                    const unsigned char *pwd, size_t pwdlen )
+        mbedtls_pk_context *pk,
+        unsigned char *key, size_t keylen,
+        const unsigned char *pwd, size_t pwdlen,
+        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret, decrypted = 0;
     size_t len;
@@ -1188,7 +1195,7 @@
     if( decrypted == 0 )
         return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
 
-    return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
+    return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len, f_rng, p_rng ) );
 }
 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
 
@@ -1197,7 +1204,8 @@
  */
 int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
                   const unsigned char *key, size_t keylen,
-                  const unsigned char *pwd, size_t pwdlen )
+                  const unsigned char *pwd, size_t pwdlen,
+                  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     const mbedtls_pk_info_t *pk_info;
@@ -1260,7 +1268,8 @@
 
         if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
             ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
-                                           pem.buf, pem.buflen ) ) != 0 )
+                                           pem.buf, pem.buflen,
+                                           f_rng, p_rng ) ) != 0 )
         {
             mbedtls_pk_free( pk );
         }
@@ -1287,7 +1296,7 @@
     if( ret == 0 )
     {
         if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk,
-                                                pem.buf, pem.buflen ) ) != 0 )
+                        pem.buf, pem.buflen, f_rng, p_rng ) ) != 0 )
         {
             mbedtls_pk_free( pk );
         }
@@ -1309,9 +1318,8 @@
                                key, NULL, 0, &len );
     if( ret == 0 )
     {
-        if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
-                                                      pem.buf, pem.buflen,
-                                                      pwd, pwdlen ) ) != 0 )
+        if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, pem.buf, pem.buflen,
+                        pwd, pwdlen, f_rng, p_rng ) ) != 0 )
         {
             mbedtls_pk_free( pk );
         }
@@ -1344,7 +1352,7 @@
         memcpy( key_copy, key, keylen );
 
         ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen,
-                                                pwd, pwdlen );
+                                                pwd, pwdlen, f_rng, p_rng );
 
         mbedtls_platform_zeroize( key_copy, keylen );
         mbedtls_free( key_copy );
@@ -1362,8 +1370,11 @@
     }
 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
 
-    if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
+    if( ( ret = pk_parse_key_pkcs8_unencrypted_der(
+                    pk, key, keylen, f_rng, p_rng ) ) == 0 )
+    {
         return( 0 );
+    }
 
     mbedtls_pk_free( pk );
     mbedtls_pk_init( pk );
@@ -1385,7 +1396,7 @@
     pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
     if( mbedtls_pk_setup( pk, pk_info ) == 0 &&
         pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
-                               key, keylen ) == 0 )
+                               key, keylen, f_rng, p_rng ) == 0 )
     {
         return( 0 );
     }
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 8416aa7..a9caa18 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -3710,6 +3710,17 @@
     psa_status_t status;
     uint8_t offset, length;
 
+    switch( tls12_prf->state )
+    {
+        case PSA_TLS12_PRF_STATE_LABEL_SET:
+            tls12_prf->state = PSA_TLS12_PRF_STATE_OUTPUT;
+            break;
+        case PSA_TLS12_PRF_STATE_OUTPUT:
+            break;
+        default:
+            return( PSA_ERROR_BAD_STATE );
+    }
+
     while( output_length != 0 )
     {
         /* Check if we have fully processed the current block. */
diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c
index f2e9a1c..ef2adc1 100644
--- a/library/psa_crypto_rsa.c
+++ b/library/psa_crypto_rsa.c
@@ -108,7 +108,8 @@
     /* Parse the data. */
     if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
         status = mbedtls_to_psa_error(
-            mbedtls_pk_parse_key( &ctx, data, data_length, NULL, 0 ) );
+            mbedtls_pk_parse_key( &ctx, data, data_length, NULL, 0,
+                mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ) );
     else
         status = mbedtls_to_psa_error(
             mbedtls_pk_parse_public_key( &ctx, data, data_length ) );
diff --git a/library/rsa.c b/library/rsa.c
index f7274ea..d4e63b6 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -929,8 +929,11 @@
     RSA_VALIDATE_RET( input  != NULL );
     RSA_VALIDATE_RET( output != NULL );
 
-    if( rsa_check_context( ctx, 1             /* private key checks */,
-                                f_rng != NULL /* blinding y/n       */ ) != 0 )
+    if( f_rng == NULL )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    if( rsa_check_context( ctx, 1 /* private key checks */,
+                                1 /* blinding on        */ ) != 0 )
     {
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
     }
@@ -947,15 +950,12 @@
     mbedtls_mpi_init( &Q1 );
     mbedtls_mpi_init( &R );
 
-    if( f_rng != NULL )
-    {
 #if defined(MBEDTLS_RSA_NO_CRT)
-        mbedtls_mpi_init( &D_blind );
+    mbedtls_mpi_init( &D_blind );
 #else
-        mbedtls_mpi_init( &DP_blind );
-        mbedtls_mpi_init( &DQ_blind );
+    mbedtls_mpi_init( &DP_blind );
+    mbedtls_mpi_init( &DQ_blind );
 #endif
-    }
 
 #if !defined(MBEDTLS_RSA_NO_CRT)
     mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ );
@@ -975,57 +975,54 @@
 
     MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) );
 
-    if( f_rng != NULL )
-    {
-        /*
-         * Blinding
-         * T = T * Vi mod N
-         */
-        MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
+    /*
+     * Blinding
+     * T = T * Vi mod N
+     */
+    MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
 
-        /*
-         * Exponent blinding
-         */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
+    /*
+     * Exponent blinding
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
 
 #if defined(MBEDTLS_RSA_NO_CRT)
-        /*
-         * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
-         */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
-                         f_rng, p_rng ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
+    /*
+     * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
+                     f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
 
-        D = &D_blind;
+    D = &D_blind;
 #else
-        /*
-         * DP_blind = ( P - 1 ) * R + DP
-         */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
-                         f_rng, p_rng ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
-                    &ctx->DP ) );
+    /*
+     * DP_blind = ( P - 1 ) * R + DP
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
+                     f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
+                &ctx->DP ) );
 
-        DP = &DP_blind;
+    DP = &DP_blind;
 
-        /*
-         * DQ_blind = ( Q - 1 ) * R + DQ
-         */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
-                         f_rng, p_rng ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
-                    &ctx->DQ ) );
+    /*
+     * DQ_blind = ( Q - 1 ) * R + DQ
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
+                     f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
+                &ctx->DQ ) );
 
-        DQ = &DQ_blind;
+    DQ = &DQ_blind;
 #endif /* MBEDTLS_RSA_NO_CRT */
-    }
 
 #if defined(MBEDTLS_RSA_NO_CRT)
     MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
@@ -1054,15 +1051,12 @@
     MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) );
 #endif /* MBEDTLS_RSA_NO_CRT */
 
-    if( f_rng != NULL )
-    {
-        /*
-         * Unblind
-         * T = T * Vf mod N
-         */
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
-        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
-    }
+    /*
+     * Unblind
+     * T = T * Vf mod N
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
 
     /* Verify the result to prevent glitching attacks. */
     MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &C, &T, &ctx->E,
@@ -1086,15 +1080,12 @@
     mbedtls_mpi_free( &Q1 );
     mbedtls_mpi_free( &R );
 
-    if( f_rng != NULL )
-    {
 #if defined(MBEDTLS_RSA_NO_CRT)
-        mbedtls_mpi_free( &D_blind );
+    mbedtls_mpi_free( &D_blind );
 #else
-        mbedtls_mpi_free( &DP_blind );
-        mbedtls_mpi_free( &DQ_blind );
+    mbedtls_mpi_free( &DP_blind );
+    mbedtls_mpi_free( &DQ_blind );
 #endif
-    }
 
     mbedtls_mpi_free( &T );
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 5c1bc32..2961637 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3504,6 +3504,9 @@
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
+    if( ssl->handshake->resume == 1 )
+        return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+
     if( ( ret = mbedtls_ssl_session_copy( ssl->session_negotiate,
                                           session ) ) != 0 )
         return( ret );
@@ -4465,6 +4468,8 @@
 int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl,
                              mbedtls_ssl_session *dst )
 {
+    int ret;
+
     if( ssl == NULL ||
         dst == NULL ||
         ssl->session == NULL ||
@@ -4473,18 +4478,30 @@
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
-    return( mbedtls_ssl_session_copy( dst, ssl->session ) );
+    /* Since Mbed TLS 3.0, mbedtls_ssl_get_session() is no longer
+     * idempotent: Each session can only be exported once.
+     *
+     * (This is in preparation for TLS 1.3 support where we will
+     * need the ability to export multiple sessions (aka tickets),
+     * which will be achieved by calling mbedtls_ssl_get_session()
+     * multiple times until it fails.)
+     *
+     * Check whether we have already exported the current session,
+     * and fail if so.
+     */
+    if( ssl->session->exported == 1 )
+        return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+
+    ret = mbedtls_ssl_session_copy( dst, ssl->session );
+    if( ret != 0 )
+        return( ret );
+
+    /* Remember that we've exported the session. */
+    ssl->session->exported = 1;
+    return( 0 );
 }
 #endif /* MBEDTLS_SSL_CLI_C */
 
-const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_context *ssl )
-{
-    if( ssl == NULL )
-        return( NULL );
-
-    return( ssl->session );
-}
-
 /*
  * Define ticket header determining Mbed TLS version
  * and structure of the ticket.
diff --git a/library/timing.c b/library/timing.c
index 664fde0..a85ce67 100644
--- a/library/timing.c
+++ b/library/timing.c
@@ -19,13 +19,6 @@
 
 #include "common.h"
 
-#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#define mbedtls_printf     printf
-#endif
-
 #if defined(MBEDTLS_TIMING_C)
 
 #include "mbedtls/timing.h"
@@ -38,10 +31,6 @@
 #error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h"
 #endif
 
-#ifndef asm
-#define asm __asm
-#endif
-
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 
 #include <windows.h>
@@ -67,174 +56,25 @@
 
 #endif /* _WIN32 && !EFIX64 && !EFI32 */
 
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
-    ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__)
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long tsc;
-    __asm   rdtsc
-    __asm   mov  [tsc], eax
-    return( tsc );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */
-
-/* some versions of mingw-64 have 32-bit longs even on x84_64 */
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
-    defined(__GNUC__) && ( defined(__i386__) || (                       \
-    ( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) )
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long lo, hi;
-    asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
-    return( lo );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && __i386__ */
-
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
-    defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) )
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long lo, hi;
-    asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
-    return( lo | ( hi << 32 ) );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && ( __amd64__ || __x86_64__ ) */
-
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
-    defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) )
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long tbl, tbu0, tbu1;
-
-    do
-    {
-        asm volatile( "mftbu %0" : "=r" (tbu0) );
-        asm volatile( "mftb  %0" : "=r" (tbl ) );
-        asm volatile( "mftbu %0" : "=r" (tbu1) );
-    }
-    while( tbu0 != tbu1 );
-
-    return( tbl );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && ( __powerpc__ || __ppc__ ) */
-
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
-    defined(__GNUC__) && defined(__sparc64__)
-
-#if defined(__OpenBSD__)
-#warning OpenBSD does not allow access to tick register using software version instead
-#else
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long tick;
-    asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) );
-    return( tick );
-}
-#endif /* __OpenBSD__ */
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && __sparc64__ */
-
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
-    defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__)
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long tick;
-    asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" );
-    asm volatile( "mov   %%g1, %0" : "=r" (tick) );
-    return( tick );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && __sparc__ && !__sparc64__ */
-
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&      \
-    defined(__GNUC__) && defined(__alpha__)
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long cc;
-    asm volatile( "rpcc %0" : "=r" (cc) );
-    return( cc & 0xFFFFFFFF );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && __alpha__ */
-
-#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&      \
-    defined(__GNUC__) && defined(__ia64__)
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    unsigned long itc;
-    asm volatile( "mov %0 = ar.itc" : "=r" (itc) );
-    return( itc );
-}
-#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
-          __GNUC__ && __ia64__ */
-
-#if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \
-    !defined(EFIX64) && !defined(EFI32)
-
-#define HAVE_HARDCLOCK
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    LARGE_INTEGER offset;
-
-    QueryPerformanceCounter( &offset );
-
-    return( (unsigned long)( offset.QuadPart ) );
-}
-#endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */
-
-#if !defined(HAVE_HARDCLOCK)
-
-#define HAVE_HARDCLOCK
-
-static int hardclock_init = 0;
-static struct timeval tv_init;
-
-unsigned long mbedtls_timing_hardclock( void )
-{
-    struct timeval tv_cur;
-
-    if( hardclock_init == 0 )
-    {
-        gettimeofday( &tv_init, NULL );
-        hardclock_init = 1;
-    }
-
-    gettimeofday( &tv_cur, NULL );
-    return( ( tv_cur.tv_sec  - tv_init.tv_sec  ) * 1000000
-          + ( tv_cur.tv_usec - tv_init.tv_usec ) );
-}
-#endif /* !HAVE_HARDCLOCK */
-
-volatile int mbedtls_timing_alarmed = 0;
-
+/**
+ * \brief          Return the elapsed time in milliseconds
+ *
+ * \warning        May change without notice
+ *
+ * \param val      points to a timer structure
+ * \param reset    If 0, query the elapsed time. Otherwise (re)start the timer.
+ *
+ * \return         Elapsed time since the previous reset in ms. When
+ *                 restarting, this is always 0.
+ *
+ * \note           To initialize a timer, call this function with reset=1.
+ *
+ *                 Determining the elapsed time and resetting the timer is not
+ *                 atomic on all platforms, so after the sequence
+ *                 `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 =
+ *                 get_timer(0) }` the value time1+time2 is only approximately
+ *                 the delay since the first reset.
+ */
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 
 unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
@@ -258,33 +98,6 @@
     }
 }
 
-/* It's OK to use a global because alarm() is supposed to be global anyway */
-static DWORD alarmMs;
-
-static void TimerProc( void *TimerContext )
-{
-    (void) TimerContext;
-    Sleep( alarmMs );
-    mbedtls_timing_alarmed = 1;
-    /* _endthread will be called implicitly on return
-     * That ensures execution of thread funcition's epilogue */
-}
-
-void mbedtls_set_alarm( int seconds )
-{
-    if( seconds == 0 )
-    {
-        /* No need to create a thread for this simple case.
-         * Also, this shorcut is more reliable at least on MinGW32 */
-        mbedtls_timing_alarmed = 1;
-        return;
-    }
-
-    mbedtls_timing_alarmed = 0;
-    alarmMs = seconds * 1000;
-    (void) _beginthread( TimerProc, 0, NULL );
-}
-
 #else /* _WIN32 && !EFIX64 && !EFI32 */
 
 unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
@@ -307,25 +120,6 @@
     }
 }
 
-static void sighandler( int signum )
-{
-    mbedtls_timing_alarmed = 1;
-    signal( signum, sighandler );
-}
-
-void mbedtls_set_alarm( int seconds )
-{
-    mbedtls_timing_alarmed = 0;
-    signal( SIGALRM, sighandler );
-    alarm( seconds );
-    if( seconds == 0 )
-    {
-        /* alarm(0) cancelled any previous pending alarm, but the
-           handler won't fire, so raise the flag straight away. */
-        mbedtls_timing_alarmed = 1;
-    }
-}
-
 #endif /* _WIN32 && !EFIX64 && !EFI32 */
 
 /*
@@ -365,178 +159,4 @@
 }
 
 #endif /* !MBEDTLS_TIMING_ALT */
-
-#if defined(MBEDTLS_SELF_TEST)
-
-/*
- * Busy-waits for the given number of milliseconds.
- * Used for testing mbedtls_timing_hardclock.
- */
-static void busy_msleep( unsigned long msec )
-{
-    struct mbedtls_timing_hr_time hires;
-    unsigned long i = 0; /* for busy-waiting */
-    volatile unsigned long j; /* to prevent optimisation */
-
-    (void) mbedtls_timing_get_timer( &hires, 1 );
-
-    while( mbedtls_timing_get_timer( &hires, 0 ) < msec )
-        i++;
-
-    j = i;
-    (void) j;
-}
-
-static void print_timers( struct mbedtls_timing_hr_time *hires,
-                          mbedtls_timing_delay_context *ctx )
-{
-#if defined(MBEDTLS_TIMING_ALT)
-    mbedtls_printf( " elapsed(hires)=%lu elapsed(ctx)=?? status(ctx)=%d\n",
-                    mbedtls_timing_get_timer( hires, 0 ),
-                    mbedtls_timing_get_delay( ctx ) );
-#else
-    mbedtls_printf( " elapsed(hires)=%lu elapsed(ctx)=%lu status(ctx)=%d\n",
-                    mbedtls_timing_get_timer( hires, 0 ),
-                    mbedtls_timing_get_timer( &ctx->timer, 0 ),
-                    mbedtls_timing_get_delay( ctx ) );
-#endif
-}
-
-#define FAIL    do                                                      \
-    {                                                                   \
-        if( verbose != 0 )                                              \
-        {                                                               \
-            mbedtls_printf( "failed at line %d\n", __LINE__ );          \
-            mbedtls_printf( " cycles=%lu ratio=%lu millisecs=%lu secs=%lu hardfail=%d a=%lu b=%lu\n", \
-                            cycles, ratio, millisecs, secs, hardfail,   \
-                            (unsigned long) a, (unsigned long) b );     \
-            print_timers( &hires, &ctx );                               \
-        }                                                               \
-        return( 1 );                                                    \
-    } while( 0 )
-
-/*
- * Checkup routine
- *
- * Warning: this is work in progress, some tests may not be reliable enough
- * yet! False positives may happen.
- */
-int mbedtls_timing_self_test( int verbose )
-{
-    unsigned long cycles = 0, ratio = 0;
-    unsigned long millisecs = 0, secs = 0;
-    int hardfail = 0;
-    struct mbedtls_timing_hr_time hires;
-    uint32_t a = 0, b = 0;
-    mbedtls_timing_delay_context ctx;
-
-    if( verbose != 0 )
-        mbedtls_printf( "  TIMING tests note: will take some time!\n" );
-
-    if( verbose != 0 )
-        mbedtls_printf( "  TIMING test #1 (set_alarm / get_timer): " );
-
-    {
-        secs = 1;
-
-        (void) mbedtls_timing_get_timer( &hires, 1 );
-
-        mbedtls_set_alarm( (int) secs );
-        while( !mbedtls_timing_alarmed )
-            ;
-
-        millisecs = mbedtls_timing_get_timer( &hires, 0 );
-
-        /* For some reason on Windows it looks like alarm has an extra delay
-         * (maybe related to creating a new thread). Allow some room here. */
-        if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 )
-            FAIL;
-    }
-
-    if( verbose != 0 )
-        mbedtls_printf( "passed\n" );
-
-    if( verbose != 0 )
-        mbedtls_printf( "  TIMING test #2 (set/get_delay        ): " );
-
-    {
-        a = 800;
-        b = 400;
-        mbedtls_timing_set_delay( &ctx, a, a + b );          /* T = 0 */
-
-        busy_msleep( a - a / 4 );                      /* T = a - a/4 */
-        if( mbedtls_timing_get_delay( &ctx ) != 0 )
-            FAIL;
-
-        busy_msleep( a / 4 + b / 4 );                  /* T = a + b/4 */
-        if( mbedtls_timing_get_delay( &ctx ) != 1 )
-            FAIL;
-
-        busy_msleep( b );                          /* T = a + b + b/4 */
-        if( mbedtls_timing_get_delay( &ctx ) != 2 )
-            FAIL;
-    }
-
-    mbedtls_timing_set_delay( &ctx, 0, 0 );
-    busy_msleep( 200 );
-    if( mbedtls_timing_get_delay( &ctx ) != -1 )
-        FAIL;
-
-    if( verbose != 0 )
-        mbedtls_printf( "passed\n" );
-
-    if( verbose != 0 )
-        mbedtls_printf( "  TIMING test #3 (hardclock / get_timer): " );
-
-    /*
-     * Allow one failure for possible counter wrapping.
-     * On a 4Ghz 32-bit machine the cycle counter wraps about once per second;
-     * since the whole test is about 10ms, it shouldn't happen twice in a row.
-     */
-
-hard_test:
-    if( hardfail > 1 )
-    {
-        if( verbose != 0 )
-            mbedtls_printf( "failed (ignored)\n" );
-
-        goto hard_test_done;
-    }
-
-    /* Get a reference ratio cycles/ms */
-    millisecs = 1;
-    cycles = mbedtls_timing_hardclock();
-    busy_msleep( millisecs );
-    cycles = mbedtls_timing_hardclock() - cycles;
-    ratio = cycles / millisecs;
-
-    /* Check that the ratio is mostly constant */
-    for( millisecs = 2; millisecs <= 4; millisecs++ )
-    {
-        cycles = mbedtls_timing_hardclock();
-        busy_msleep( millisecs );
-        cycles = mbedtls_timing_hardclock() - cycles;
-
-        /* Allow variation up to 20% */
-        if( cycles / millisecs < ratio - ratio / 5 ||
-            cycles / millisecs > ratio + ratio / 5 )
-        {
-            hardfail++;
-            goto hard_test;
-        }
-    }
-
-    if( verbose != 0 )
-        mbedtls_printf( "passed\n" );
-
-hard_test_done:
-
-    if( verbose != 0 )
-        mbedtls_printf( "\n" );
-
-    return( 0 );
-}
-
-#endif /* MBEDTLS_SELF_TEST */
-
 #endif /* MBEDTLS_TIMING_C */
diff --git a/programs/aes/CMakeLists.txt b/programs/aes/CMakeLists.txt
index 62a54c7..85bcd5f 100644
--- a/programs/aes/CMakeLists.txt
+++ b/programs/aes/CMakeLists.txt
@@ -5,6 +5,7 @@
 foreach(exe IN LISTS executables)
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
     target_link_libraries(${exe} ${mbedcrypto_target})
+    target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
 endforeach()
 
 install(TARGETS ${executables}
diff --git a/programs/fuzz/CMakeLists.txt b/programs/fuzz/CMakeLists.txt
index 4f35d76..c7fcd35 100644
--- a/programs/fuzz/CMakeLists.txt
+++ b/programs/fuzz/CMakeLists.txt
@@ -8,7 +8,6 @@
 endif()
 
 set(executables_no_common_c
-    fuzz_privkey
     fuzz_pubkey
     fuzz_x509crl
     fuzz_x509crt
@@ -16,6 +15,7 @@
 )
 
 set(executables_with_common_c
+    fuzz_privkey
     fuzz_client
     fuzz_dtlsclient
     fuzz_dtlsserver
diff --git a/programs/fuzz/fuzz_dtlsserver.c b/programs/fuzz/fuzz_dtlsserver.c
index 34ff63e..9a6e894 100644
--- a/programs/fuzz/fuzz_dtlsserver.c
+++ b/programs/fuzz/fuzz_dtlsserver.c
@@ -55,7 +55,8 @@
                                    mbedtls_test_cas_pem_len ) != 0)
             return 1;
         if (mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_srv_key,
-                                 mbedtls_test_srv_key_len, NULL, 0 ) != 0)
+                                 mbedtls_test_srv_key_len, NULL, 0,
+                                 dummy_random, NULL ) != 0)
             return 1;
 #endif
         dummy_init();
diff --git a/programs/fuzz/fuzz_privkey.c b/programs/fuzz/fuzz_privkey.c
index f76afd1..b9a160e 100644
--- a/programs/fuzz/fuzz_privkey.c
+++ b/programs/fuzz/fuzz_privkey.c
@@ -3,6 +3,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include "mbedtls/pk.h"
+#include "common.h"
 
 //4 Kb should be enough for every bug ;-)
 #define MAX_LEN 0x1000
@@ -19,7 +20,8 @@
     }
 
     mbedtls_pk_init( &pk );
-    ret = mbedtls_pk_parse_key( &pk, Data, Size, NULL, 0 );
+    ret = mbedtls_pk_parse_key( &pk, Data, Size, NULL, 0,
+                                dummy_random, NULL );
     if (ret == 0) {
 #if defined(MBEDTLS_RSA_C)
         if( mbedtls_pk_get_type( &pk ) == MBEDTLS_PK_RSA )
diff --git a/programs/fuzz/fuzz_server.c b/programs/fuzz/fuzz_server.c
index 5480e3e..c35b425 100644
--- a/programs/fuzz/fuzz_server.c
+++ b/programs/fuzz/fuzz_server.c
@@ -56,6 +56,13 @@
     options = Data[Size - 1];
 
     if (initialized == 0) {
+        mbedtls_ctr_drbg_init( &ctr_drbg );
+        mbedtls_entropy_init( &entropy );
+
+        if( mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy, &entropy,
+                                  (const unsigned char *) pers, strlen( pers ) ) != 0 )
+            return 1;
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
         mbedtls_x509_crt_init( &srvcert );
         mbedtls_pk_init( &pkey );
@@ -66,7 +73,8 @@
                                    mbedtls_test_cas_pem_len ) != 0)
             return 1;
         if (mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_srv_key,
-                                 mbedtls_test_srv_key_len, NULL, 0 ) != 0)
+                                 mbedtls_test_srv_key_len, NULL, 0,
+                                 dummy_random, &ctr_drbg ) != 0)
             return 1;
 #endif
 
@@ -80,17 +88,10 @@
     }
     mbedtls_ssl_init( &ssl );
     mbedtls_ssl_config_init( &conf );
-    mbedtls_ctr_drbg_init( &ctr_drbg );
-    mbedtls_entropy_init( &entropy );
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
     mbedtls_ssl_ticket_init( &ticket_ctx );
 #endif
 
-    if( mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy, &entropy,
-                              (const unsigned char *) pers, strlen( pers ) ) != 0 )
-        goto exit;
-
-
     if( mbedtls_ssl_config_defaults( &conf,
                                     MBEDTLS_SSL_IS_SERVER,
                                     MBEDTLS_SSL_TRANSPORT_STREAM,
diff --git a/programs/hash/CMakeLists.txt b/programs/hash/CMakeLists.txt
index b2f2a1f..729474c 100644
--- a/programs/hash/CMakeLists.txt
+++ b/programs/hash/CMakeLists.txt
@@ -6,6 +6,7 @@
 foreach(exe IN LISTS executables)
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
     target_link_libraries(${exe} ${mbedcrypto_target})
+    target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
 endforeach()
 
 install(TARGETS ${executables}
diff --git a/programs/pkey/CMakeLists.txt b/programs/pkey/CMakeLists.txt
index 9c6fe7d..3ad5643 100644
--- a/programs/pkey/CMakeLists.txt
+++ b/programs/pkey/CMakeLists.txt
@@ -6,6 +6,7 @@
 foreach(exe IN LISTS executables_mbedtls)
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
     target_link_libraries(${exe} ${mbedtls_target})
+    target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
 endforeach()
 
 set(executables_mbedcrypto
@@ -32,6 +33,7 @@
 foreach(exe IN LISTS executables_mbedcrypto)
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
     target_link_libraries(${exe} ${mbedcrypto_target})
+    target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
 endforeach()
 
 install(TARGETS ${executables_mbedtls} ${executables_mbedcrypto}
diff --git a/programs/pkey/key_app.c b/programs/pkey/key_app.c
index 7bd93c7..2145e07 100644
--- a/programs/pkey/key_app.c
+++ b/programs/pkey/key_app.c
@@ -35,10 +35,13 @@
 #endif /* MBEDTLS_PLATFORM_C */
 
 #if defined(MBEDTLS_BIGNUM_C) && \
-    defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_FS_IO)
+    defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_FS_IO) && \
+    defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_CTR_DRBG_C)
 #include "mbedtls/error.h"
 #include "mbedtls/rsa.h"
 #include "mbedtls/pk.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
 
 #include <string.h>
 #endif
@@ -63,11 +66,13 @@
     "\n"
 
 #if !defined(MBEDTLS_BIGNUM_C) ||                                  \
-    !defined(MBEDTLS_PK_PARSE_C) || !defined(MBEDTLS_FS_IO)
+    !defined(MBEDTLS_PK_PARSE_C) || !defined(MBEDTLS_FS_IO) || \
+    !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C)
 int main( void )
 {
     mbedtls_printf("MBEDTLS_BIGNUM_C and/or "
-           "MBEDTLS_PK_PARSE_C and/or MBEDTLS_FS_IO not defined.\n");
+           "MBEDTLS_PK_PARSE_C and/or MBEDTLS_FS_IO and/or "
+           "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C not defined.\n");
     mbedtls_exit( 0 );
 }
 #else
@@ -92,12 +97,19 @@
     int i;
     char *p, *q;
 
+    const char *pers = "pkey/key_app";
+    mbedtls_entropy_context entropy;
+    mbedtls_ctr_drbg_context ctr_drbg;
+
     mbedtls_pk_context pk;
     mbedtls_mpi N, P, Q, D, E, DP, DQ, QP;
 
     /*
      * Set to sane values
      */
+    mbedtls_entropy_init( &entropy );
+    mbedtls_ctr_drbg_init( &ctr_drbg );
+
     mbedtls_pk_init( &pk );
     memset( buf, 0, sizeof(buf) );
 
@@ -181,7 +193,16 @@
         mbedtls_printf( "\n  . Loading the private key ..." );
         fflush( stdout );
 
-        ret = mbedtls_pk_parse_keyfile( &pk, opt.filename, opt.password );
+        if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
+                                   (const unsigned char *) pers,
+                                   strlen( pers ) ) ) != 0 )
+        {
+            mbedtls_printf( " failed\n  !  mbedtls_ctr_drbg_seed returned -0x%04x\n", (unsigned int) -ret );
+            goto cleanup;
+        }
+
+        ret = mbedtls_pk_parse_keyfile( &pk, opt.filename, opt.password,
+                                        mbedtls_ctr_drbg_random, &ctr_drbg );
 
         if( ret != 0 )
         {
@@ -299,6 +320,9 @@
     }
 #endif
 
+    mbedtls_ctr_drbg_free( &ctr_drbg );
+    mbedtls_entropy_free( &entropy );
+
     mbedtls_pk_free( &pk );
     mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q );
     mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP );
@@ -311,4 +335,5 @@
 
     mbedtls_exit( exit_code );
 }
-#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_PK_PARSE_C && MBEDTLS_FS_IO */
+#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_PK_PARSE_C && MBEDTLS_FS_IO &&
+          MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */
diff --git a/programs/pkey/key_app_writer.c b/programs/pkey/key_app_writer.c
index 4b65262..89c67ed 100644
--- a/programs/pkey/key_app_writer.c
+++ b/programs/pkey/key_app_writer.c
@@ -34,11 +34,16 @@
 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
 #endif /* MBEDTLS_PLATFORM_C */
 
-#if defined(MBEDTLS_PK_WRITE_C) && defined(MBEDTLS_FS_IO)
+#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_PK_WRITE_C) && \
+    defined(MBEDTLS_FS_IO) && \
+    defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_CTR_DRBG_C)
 #include "mbedtls/error.h"
 #include "mbedtls/pk.h"
 #include "mbedtls/error.h"
 
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+
 #include <stdio.h>
 #include <string.h>
 #endif
@@ -88,10 +93,14 @@
 
 #if !defined(MBEDTLS_PK_PARSE_C) || \
     !defined(MBEDTLS_PK_WRITE_C) || \
-    !defined(MBEDTLS_FS_IO)
+    !defined(MBEDTLS_FS_IO)      || \
+    !defined(MBEDTLS_ENTROPY_C)  || \
+    !defined(MBEDTLS_CTR_DRBG_C)
 int main( void )
 {
-    mbedtls_printf( "MBEDTLS_PK_PARSE_C and/or MBEDTLS_PK_WRITE_C and/or MBEDTLS_FS_IO not defined.\n" );
+    mbedtls_printf( "MBEDTLS_PK_PARSE_C and/or MBEDTLS_PK_WRITE_C and/or "
+                    "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
+                    "MBEDTLS_FS_IO not defined.\n" );
     mbedtls_exit( 0 );
 }
 #else
@@ -201,12 +210,19 @@
     int i;
     char *p, *q;
 
+    const char *pers = "pkey/key_app";
+    mbedtls_entropy_context entropy;
+    mbedtls_ctr_drbg_context ctr_drbg;
+
     mbedtls_pk_context key;
     mbedtls_mpi N, P, Q, D, E, DP, DQ, QP;
 
     /*
      * Set to sane values
      */
+    mbedtls_entropy_init( &entropy );
+    mbedtls_ctr_drbg_init( &ctr_drbg );
+
     mbedtls_pk_init( &key );
     memset( buf, 0, sizeof( buf ) );
 
@@ -292,8 +308,16 @@
         mbedtls_printf( "\n  . Loading the private key ..." );
         fflush( stdout );
 
-        ret = mbedtls_pk_parse_keyfile( &key, opt.filename, NULL );
+        if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
+                                   (const unsigned char *) pers,
+                                   strlen( pers ) ) ) != 0 )
+        {
+            mbedtls_printf( " failed\n  !  mbedtls_ctr_drbg_seed returned -0x%04x\n", (unsigned int) -ret );
+            goto exit;
+        }
 
+        ret = mbedtls_pk_parse_keyfile( &key, opt.filename, NULL,
+                                        mbedtls_ctr_drbg_random, &ctr_drbg );
         if( ret != 0 )
         {
             mbedtls_strerror( ret, (char *) buf, sizeof(buf) );
@@ -429,6 +453,9 @@
 
     mbedtls_pk_free( &key );
 
+    mbedtls_ctr_drbg_free( &ctr_drbg );
+    mbedtls_entropy_free( &entropy );
+
 #if defined(_WIN32)
     mbedtls_printf( "  + Press Enter to exit this program.\n" );
     fflush( stdout ); getchar();
@@ -436,4 +463,5 @@
 
     mbedtls_exit( exit_code );
 }
-#endif /* MBEDTLS_PK_PARSE_C && MBEDTLS_PK_WRITE_C && MBEDTLS_FS_IO */
+#endif /* MBEDTLS_PK_PARSE_C && MBEDTLS_PK_WRITE_C && MBEDTLS_FS_IO &&
+          MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */
diff --git a/programs/pkey/pk_decrypt.c b/programs/pkey/pk_decrypt.c
index 810d6fb..e01f5d5 100644
--- a/programs/pkey/pk_decrypt.c
+++ b/programs/pkey/pk_decrypt.c
@@ -106,7 +106,8 @@
     mbedtls_printf( "\n  . Reading private key from '%s'", argv[1] );
     fflush( stdout );
 
-    if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 )
+    if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "",
+                    mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! mbedtls_pk_parse_keyfile returned -0x%04x\n", (unsigned int) -ret );
         goto exit;
diff --git a/programs/pkey/pk_sign.c b/programs/pkey/pk_sign.c
index 451e3de..422fa25 100644
--- a/programs/pkey/pk_sign.c
+++ b/programs/pkey/pk_sign.c
@@ -101,7 +101,8 @@
     mbedtls_printf( "\n  . Reading private key from '%s'", argv[1] );
     fflush( stdout );
 
-    if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 )
+    if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "",
+                    mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! Could not parse '%s'\n", argv[1] );
         goto exit;
diff --git a/programs/pkey/rsa_sign_pss.c b/programs/pkey/rsa_sign_pss.c
index 26056dd..bbbe0a9 100644
--- a/programs/pkey/rsa_sign_pss.c
+++ b/programs/pkey/rsa_sign_pss.c
@@ -102,7 +102,8 @@
     mbedtls_printf( "\n  . Reading private key from '%s'", argv[1] );
     fflush( stdout );
 
-    if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 )
+    if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "",
+                    mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
     {
         mbedtls_printf( " failed\n  ! Could not read key from '%s'\n", argv[1] );
         mbedtls_printf( "  ! mbedtls_pk_parse_public_keyfile returned %d\n\n", ret );
diff --git a/programs/random/CMakeLists.txt b/programs/random/CMakeLists.txt
index f32dc31..e5edf7b 100644
--- a/programs/random/CMakeLists.txt
+++ b/programs/random/CMakeLists.txt
@@ -6,6 +6,7 @@
 foreach(exe IN LISTS executables)
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
     target_link_libraries(${exe} ${mbedcrypto_target})
+    target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
 endforeach()
 
 install(TARGETS ${executables}
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index de47aab..d2cc450 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -79,6 +79,7 @@
 #include "mbedtls/error.h"
 #include "mbedtls/debug.h"
 #include "mbedtls/timing.h"
+
 #include "test/certs.h"
 
 #if defined(MBEDTLS_SSL_CACHE_C)
@@ -138,7 +139,23 @@
 #endif
 
     /*
-     * 1. Load the certificates and private RSA key
+     * 1. Seed the RNG
+     */
+    printf( "  . Seeding the random number generator..." );
+    fflush( stdout );
+
+    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
+                               (const unsigned char *) pers,
+                               strlen( pers ) ) ) != 0 )
+    {
+        printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
+        goto exit;
+    }
+
+    printf( " ok\n" );
+
+    /*
+     * 2. Load the certificates and private RSA key
      */
     printf( "\n  . Loading the server cert. and key..." );
     fflush( stdout );
@@ -165,7 +182,7 @@
     }
 
     ret =  mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_srv_key,
-                         mbedtls_test_srv_key_len, NULL, 0 );
+                         mbedtls_test_srv_key_len, NULL, 0, mbedtls_ctr_drbg_random, &ctr_drbg );
     if( ret != 0 )
     {
         printf( " failed\n  !  mbedtls_pk_parse_key returned %d\n\n", ret );
@@ -175,7 +192,7 @@
     printf( " ok\n" );
 
     /*
-     * 2. Setup the "listening" UDP socket
+     * 3. Setup the "listening" UDP socket
      */
     printf( "  . Bind on udp/*/4433 ..." );
     fflush( stdout );
@@ -189,22 +206,6 @@
     printf( " ok\n" );
 
     /*
-     * 3. Seed the RNG
-     */
-    printf( "  . Seeding the random number generator..." );
-    fflush( stdout );
-
-    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
-                               (const unsigned char *) pers,
-                               strlen( pers ) ) ) != 0 )
-    {
-        printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
-        goto exit;
-    }
-
-    printf( " ok\n" );
-
-    /*
      * 4. Setup stuff
      */
     printf( "  . Setting up the DTLS data..." );
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 98a3048..322cef8 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -1548,12 +1548,12 @@
     else
 #if defined(MBEDTLS_FS_IO)
     if( strlen( opt.key_file ) )
-        ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file, opt.key_pwd );
+        ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file, opt.key_pwd, rng_get, &rng );
     else
 #endif
         ret = mbedtls_pk_parse_key( &pkey,
                 (const unsigned char *) mbedtls_test_cli_key,
-                mbedtls_test_cli_key_len, NULL, 0 );
+                mbedtls_test_cli_key_len, NULL, 0, rng_get, &rng );
     if( ret != 0 )
     {
         mbedtls_printf( " failed\n  !  mbedtls_pk_parse_key returned -0x%x\n\n",
@@ -2163,6 +2163,8 @@
 
         if( opt.reco_mode == 1 )
         {
+            mbedtls_ssl_session exported_session;
+
             /* free any previously saved data */
             if( session_data != NULL )
             {
@@ -2171,27 +2173,40 @@
                 session_data = NULL;
             }
 
+            mbedtls_ssl_session_init( &exported_session );
+            ret = mbedtls_ssl_get_session( &ssl, &exported_session );
+            if( ret != 0 )
+            {
+                mbedtls_printf(
+                    "failed\n  ! mbedtls_ssl_get_session() returned -%#02x\n",
+                    (unsigned) -ret );
+                goto exit;
+            }
+
             /* get size of the buffer needed */
-            mbedtls_ssl_session_save( mbedtls_ssl_get_session_pointer( &ssl ),
-                                      NULL, 0, &session_data_len );
+            mbedtls_ssl_session_save( &exported_session, NULL, 0, &session_data_len );
             session_data = mbedtls_calloc( 1, session_data_len );
             if( session_data == NULL )
             {
                 mbedtls_printf( " failed\n  ! alloc %u bytes for session data\n",
                                 (unsigned) session_data_len );
+                mbedtls_ssl_session_free( &exported_session );
                 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
                 goto exit;
             }
 
             /* actually save session data */
-            if( ( ret = mbedtls_ssl_session_save( mbedtls_ssl_get_session_pointer( &ssl ),
+            if( ( ret = mbedtls_ssl_session_save( &exported_session,
                                                   session_data, session_data_len,
                                                   &session_data_len ) ) != 0 )
             {
                 mbedtls_printf( " failed\n  ! mbedtls_ssl_session_saved returned -0x%04x\n\n",
                                 (unsigned int) -ret );
+                mbedtls_ssl_session_free( &exported_session );
                 goto exit;
             }
+
+            mbedtls_ssl_session_free( &exported_session );
         }
         else
         {
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index 5732108..7419010 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -166,7 +166,8 @@
     }
 
     ret =  mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_srv_key,
-                          mbedtls_test_srv_key_len, NULL, 0 );
+                          mbedtls_test_srv_key_len, NULL, 0,
+                          mbedtls_ctr_drbg_random, &ctr_drbg );
     if( ret != 0 )
     {
         mbedtls_printf( " failed!  mbedtls_pk_parse_key returned %d\n\n", ret );
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index 09bbc3d..f223977 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -556,12 +556,17 @@
 
 #if defined(MBEDTLS_FS_IO)
     if( strlen( opt.key_file ) )
-        ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file, "" );
+    {
+        ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file, "",
+                mbedtls_ctr_drbg_random, &ctr_drbg );
+    }
     else
 #endif
 #if defined(MBEDTLS_PEM_PARSE_C)
+    {
         ret = mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_cli_key,
-                mbedtls_test_cli_key_len, NULL, 0 );
+                mbedtls_test_cli_key_len, NULL, 0, mbedtls_ctr_drbg_random, &ctr_drbg );
+    }
 #else
     {
         mbedtls_printf("MBEDTLS_PEM_PARSE_C not defined.");
diff --git a/programs/ssl/ssl_pthread_server.c b/programs/ssl/ssl_pthread_server.c
index 93eab46..a083e4b 100644
--- a/programs/ssl/ssl_pthread_server.c
+++ b/programs/ssl/ssl_pthread_server.c
@@ -360,7 +360,23 @@
     mbedtls_entropy_init( &entropy );
 
     /*
-     * 1. Load the certificates and private RSA key
+     * 1a. Seed the random number generator
+     */
+    mbedtls_printf( "  . Seeding the random number generator..." );
+
+    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
+                               (const unsigned char *) pers,
+                               strlen( pers ) ) ) != 0 )
+    {
+        mbedtls_printf( " failed: mbedtls_ctr_drbg_seed returned -0x%04x\n",
+                ( unsigned int ) -ret );
+        goto exit;
+    }
+
+    mbedtls_printf( " ok\n" );
+
+    /*
+     * 1b. Load the certificates and private RSA key
      */
     mbedtls_printf( "\n  . Loading the server cert. and key..." );
     fflush( stdout );
@@ -388,7 +404,8 @@
 
     mbedtls_pk_init( &pkey );
     ret =  mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_srv_key,
-                         mbedtls_test_srv_key_len, NULL, 0 );
+                         mbedtls_test_srv_key_len, NULL, 0,
+                         mbedtls_ctr_drbg_random, &ctr_drbg );
     if( ret != 0 )
     {
         mbedtls_printf( " failed\n  !  mbedtls_pk_parse_key returned %d\n\n", ret );
@@ -398,22 +415,6 @@
     mbedtls_printf( " ok\n" );
 
     /*
-     * 1b. Seed the random number generator
-     */
-    mbedtls_printf( "  . Seeding the random number generator..." );
-
-    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
-                               (const unsigned char *) pers,
-                               strlen( pers ) ) ) != 0 )
-    {
-        mbedtls_printf( " failed: mbedtls_ctr_drbg_seed returned -0x%04x\n",
-                ( unsigned int ) -ret );
-        goto exit;
-    }
-
-    mbedtls_printf( " ok\n" );
-
-    /*
      * 1c. Prepare SSL configuration
      */
     mbedtls_printf( "  . Setting up the SSL data...." );
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index 42196ff..aaccb58 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -125,7 +125,23 @@
 #endif
 
     /*
-     * 1. Load the certificates and private RSA key
+     * 1. Seed the RNG
+     */
+    mbedtls_printf( "  . Seeding the random number generator..." );
+    fflush( stdout );
+
+    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
+                               (const unsigned char *) pers,
+                               strlen( pers ) ) ) != 0 )
+    {
+        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
+        goto exit;
+    }
+
+    mbedtls_printf( " ok\n" );
+
+    /*
+     * 2. Load the certificates and private RSA key
      */
     mbedtls_printf( "\n  . Loading the server cert. and key..." );
     fflush( stdout );
@@ -152,7 +168,8 @@
     }
 
     ret =  mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_srv_key,
-                         mbedtls_test_srv_key_len, NULL, 0 );
+                         mbedtls_test_srv_key_len, NULL, 0,
+                         mbedtls_ctr_drbg_random, &ctr_drbg );
     if( ret != 0 )
     {
         mbedtls_printf( " failed\n  !  mbedtls_pk_parse_key returned %d\n\n", ret );
@@ -162,7 +179,7 @@
     mbedtls_printf( " ok\n" );
 
     /*
-     * 2. Setup the listening TCP socket
+     * 3. Setup the listening TCP socket
      */
     mbedtls_printf( "  . Bind on https://localhost:4433/ ..." );
     fflush( stdout );
@@ -176,22 +193,6 @@
     mbedtls_printf( " ok\n" );
 
     /*
-     * 3. Seed the RNG
-     */
-    mbedtls_printf( "  . Seeding the random number generator..." );
-    fflush( stdout );
-
-    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
-                               (const unsigned char *) pers,
-                               strlen( pers ) ) ) != 0 )
-    {
-        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
-        goto exit;
-    }
-
-    mbedtls_printf( " ok\n" );
-
-    /*
      * 4. Setup stuff
      */
     mbedtls_printf( "  . Setting up the SSL data...." );
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index de4eb6d..51125bd 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -525,6 +525,8 @@
     (out_be)[(i) + 7] = (unsigned char)( ( (in_le) >> 0  ) & 0xFF );    \
 }
 
+/* This is global so it can be easily accessed by callback functions */
+rng_context_t rng;
 
 /*
  * global options
@@ -727,7 +729,7 @@
         mbedtls_pk_init( new->key );
 
         if( mbedtls_x509_crt_parse_file( new->cert, crt_file ) != 0 ||
-            mbedtls_pk_parse_keyfile( new->key, key_file, "" ) != 0 )
+            mbedtls_pk_parse_keyfile( new->key, key_file, "", rng_get, &rng ) != 0 )
             goto error;
 
         if( strcmp( ca_file, "-" ) != 0 )
@@ -1045,7 +1047,8 @@
     for( slot = 0; slot < config_data->slots_used; slot++ )
     {
         if( mbedtls_pk_check_pair( &cert->pk,
-                                   config_data->slots[slot].pk ) == 0 )
+                                   config_data->slots[slot].pk,
+                                   rng_get, &rng ) == 0 )
             break;
     }
     if( slot == config_data->slots_used )
@@ -1271,7 +1274,6 @@
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default;
 #endif
-    rng_context_t rng;
     mbedtls_ssl_context ssl;
     mbedtls_ssl_config conf;
 #if defined(MBEDTLS_TIMING_C)
@@ -2257,7 +2259,7 @@
     {
         key_cert_init++;
         if( ( ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file,
-                                              opt.key_pwd ) ) != 0 )
+                                              opt.key_pwd, rng_get, &rng ) ) != 0 )
         {
             mbedtls_printf( " failed\n  !  mbedtls_pk_parse_keyfile returned -0x%x\n\n", (unsigned int) -ret );
             goto exit;
@@ -2283,7 +2285,7 @@
     {
         key_cert_init2++;
         if( ( ret = mbedtls_pk_parse_keyfile( &pkey2, opt.key_file2,
-                                              opt.key_pwd2 ) ) != 0 )
+                                              opt.key_pwd2, rng_get, &rng ) ) != 0 )
         {
             mbedtls_printf( " failed\n  !  mbedtls_pk_parse_keyfile(2) returned -0x%x\n\n",
                             (unsigned int) -ret );
@@ -2314,7 +2316,8 @@
         }
         if( ( ret = mbedtls_pk_parse_key( &pkey,
                                   (const unsigned char *) mbedtls_test_srv_key_rsa,
-                                  mbedtls_test_srv_key_rsa_len, NULL, 0 ) ) != 0 )
+                                  mbedtls_test_srv_key_rsa_len, NULL, 0,
+                                  rng_get, &rng ) ) != 0 )
         {
             mbedtls_printf( " failed\n  !  mbedtls_pk_parse_key returned -0x%x\n\n",
                             (unsigned int) -ret );
@@ -2333,7 +2336,8 @@
         }
         if( ( ret = mbedtls_pk_parse_key( &pkey2,
                                   (const unsigned char *) mbedtls_test_srv_key_ec,
-                                  mbedtls_test_srv_key_ec_len, NULL, 0 ) ) != 0 )
+                                  mbedtls_test_srv_key_ec_len, NULL, 0,
+                                  rng_get, &rng ) ) != 0 )
         {
             mbedtls_printf( " failed\n  !  pk_parse_key2 returned -0x%x\n\n",
                             (unsigned int) -ret );
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index 3eceec0..6a53647 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -74,10 +74,41 @@
 
 #include "mbedtls/error.h"
 
+#ifndef asm
+#define asm __asm
+#endif
+
+#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
+
+#include <windows.h>
+#include <process.h>
+
+struct _hr_time
+{
+    LARGE_INTEGER start;
+};
+
+#else
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <time.h>
+
+struct _hr_time
+{
+    struct timeval start;
+};
+
+#endif /* _WIN32 && !EFIX64 && !EFI32 */
+
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
 #include "mbedtls/memory_buffer_alloc.h"
 #endif
 
+static void mbedtls_set_alarm( int seconds );
+
 /*
  * For heap usage estimates, we need an estimate of the overhead per allocated
  * block. ptmalloc2/3 (used in gnu libc for instance) uses 2 size_t per block,
@@ -209,6 +240,226 @@
     }                                                                   \
 } while( 0 )
 
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
+    ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__)
+
+#define HAVE_HARDCLOCK
+
+static unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long tsc;
+    __asm   rdtsc
+    __asm   mov  [tsc], eax
+    return( tsc );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */
+
+/* some versions of mingw-64 have 32-bit longs even on x84_64 */
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
+    defined(__GNUC__) && ( defined(__i386__) || (                       \
+    ( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) )
+
+#define HAVE_HARDCLOCK
+
+static unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long lo, hi;
+    asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
+    return( lo );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && __i386__ */
+
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
+    defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) )
+
+#define HAVE_HARDCLOCK
+
+static unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long lo, hi;
+    asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
+    return( lo | ( hi << 32 ) );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && ( __amd64__ || __x86_64__ ) */
+
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
+    defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) )
+
+#define HAVE_HARDCLOCK
+
+static unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long tbl, tbu0, tbu1;
+
+    do
+    {
+        asm volatile( "mftbu %0" : "=r" (tbu0) );
+        asm volatile( "mftb  %0" : "=r" (tbl ) );
+        asm volatile( "mftbu %0" : "=r" (tbu1) );
+    }
+    while( tbu0 != tbu1 );
+
+    return( tbl );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && ( __powerpc__ || __ppc__ ) */
+
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
+    defined(__GNUC__) && defined(__sparc64__)
+
+#if defined(__OpenBSD__)
+#warning OpenBSD does not allow access to tick register using software version instead
+#else
+#define HAVE_HARDCLOCK
+
+static unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long tick;
+    asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) );
+    return( tick );
+}
+#endif /* __OpenBSD__ */
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && __sparc64__ */
+
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
+    defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__)
+
+#define HAVE_HARDCLOCK
+
+static unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long tick;
+    asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" );
+    asm volatile( "mov   %%g1, %0" : "=r" (tick) );
+    return( tick );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && __sparc__ && !__sparc64__ */
+
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&      \
+    defined(__GNUC__) && defined(__alpha__)
+
+#define HAVE_HARDCLOCK
+
+static unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long cc;
+    asm volatile( "rpcc %0" : "=r" (cc) );
+    return( cc & 0xFFFFFFFF );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && __alpha__ */
+
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&      \
+    defined(__GNUC__) && defined(__ia64__)
+
+#define HAVE_HARDCLOCK
+
+static unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long itc;
+    asm volatile( "mov %0 = ar.itc" : "=r" (itc) );
+    return( itc );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && __ia64__ */
+
+#if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \
+    !defined(EFIX64) && !defined(EFI32)
+
+#define HAVE_HARDCLOCK
+
+static unsigned long mbedtls_timing_hardclock( void )
+{
+    LARGE_INTEGER offset;
+
+    QueryPerformanceCounter( &offset );
+
+    return( (unsigned long)( offset.QuadPart ) );
+}
+#endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */
+
+#if !defined(HAVE_HARDCLOCK)
+
+#define HAVE_HARDCLOCK
+
+static int hardclock_init = 0;
+static struct timeval tv_init;
+
+static unsigned long mbedtls_timing_hardclock( void )
+{
+    struct timeval tv_cur;
+
+    if( hardclock_init == 0 )
+    {
+        gettimeofday( &tv_init, NULL );
+        hardclock_init = 1;
+    }
+
+    gettimeofday( &tv_cur, NULL );
+    return( ( tv_cur.tv_sec  - tv_init.tv_sec  ) * 1000000
+          + ( tv_cur.tv_usec - tv_init.tv_usec ) );
+}
+#endif /* !HAVE_HARDCLOCK */
+
+volatile int mbedtls_timing_alarmed = 0;
+
+#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
+
+/* It's OK to use a global because alarm() is supposed to be global anyway */
+static DWORD alarmMs;
+
+static void TimerProc( void *TimerContext )
+{
+    (void) TimerContext;
+    Sleep( alarmMs );
+    mbedtls_timing_alarmed = 1;
+    /* _endthread will be called implicitly on return
+     * That ensures execution of thread funcition's epilogue */
+}
+
+static void mbedtls_set_alarm( int seconds )
+{
+    if( seconds == 0 )
+    {
+        /* No need to create a thread for this simple case.
+         * Also, this shorcut is more reliable at least on MinGW32 */
+        mbedtls_timing_alarmed = 1;
+        return;
+    }
+
+    mbedtls_timing_alarmed = 0;
+    alarmMs = seconds * 1000;
+    (void) _beginthread( TimerProc, 0, NULL );
+}
+
+#else /* _WIN32 && !EFIX64 && !EFI32 */
+
+static void sighandler( int signum )
+{
+    mbedtls_timing_alarmed = 1;
+    signal( signum, sighandler );
+}
+
+static void mbedtls_set_alarm( int seconds )
+{
+    mbedtls_timing_alarmed = 0;
+    signal( SIGALRM, sighandler );
+    alarm( seconds );
+    if( seconds == 0 )
+    {
+        /* alarm(0) cancelled any previous pending alarm, but the
+           handler won't fire, so raise the flag straight away. */
+        mbedtls_timing_alarmed = 1;
+    }
+}
+
+#endif /* _WIN32 && !EFIX64 && !EFI32 */
+
 static int myrand( void *rng_state, unsigned char *output, size_t len )
 {
     size_t use_len;
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index 8829d54..87d8a13 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -330,10 +330,6 @@
 #if defined(MBEDTLS_PKCS5_C)
     {"pkcs5", mbedtls_pkcs5_self_test},
 #endif
-/* Slower test after the faster ones */
-#if defined(MBEDTLS_TIMING_C)
-    {"timing", mbedtls_timing_self_test},
-#endif
 /* Heap test comes last */
 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
     {"memory_buffer_alloc", mbedtls_memory_buffer_alloc_free_and_self_test},
diff --git a/programs/util/CMakeLists.txt b/programs/util/CMakeLists.txt
index 2a11212..7fc58cb 100644
--- a/programs/util/CMakeLists.txt
+++ b/programs/util/CMakeLists.txt
@@ -10,6 +10,7 @@
 foreach(exe IN LISTS executables)
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
     target_link_libraries(${exe} ${libs})
+    target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
 endforeach()
 
 install(TARGETS ${executables}
diff --git a/programs/x509/CMakeLists.txt b/programs/x509/CMakeLists.txt
index cf57ca4..a04fa8b 100644
--- a/programs/x509/CMakeLists.txt
+++ b/programs/x509/CMakeLists.txt
@@ -13,6 +13,7 @@
 foreach(exe IN LISTS executables)
     add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
     target_link_libraries(${exe} ${libs})
+    target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
 endforeach()
 
 target_link_libraries(cert_app ${mbedtls_target})
diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c
index 18d2e8c..0ea2607 100644
--- a/programs/x509/cert_req.c
+++ b/programs/x509/cert_req.c
@@ -346,7 +346,8 @@
     mbedtls_printf( "  . Loading the private key ..." );
     fflush( stdout );
 
-    ret = mbedtls_pk_parse_keyfile( &key, opt.filename, opt.password );
+    ret = mbedtls_pk_parse_keyfile( &key, opt.filename, opt.password,
+                                    mbedtls_ctr_drbg_random, &ctr_drbg );
 
     if( ret != 0 )
     {
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index c22f5a4..f1e5c6b 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -577,7 +577,7 @@
         fflush( stdout );
 
         ret = mbedtls_pk_parse_keyfile( &loaded_subject_key, opt.subject_key,
-                                 opt.subject_pwd );
+                opt.subject_pwd, mbedtls_ctr_drbg_random, &ctr_drbg );
         if( ret != 0 )
         {
             mbedtls_strerror( ret, buf, 1024 );
@@ -593,7 +593,7 @@
     fflush( stdout );
 
     ret = mbedtls_pk_parse_keyfile( &loaded_issuer_key, opt.issuer_key,
-                             opt.issuer_pwd );
+            opt.issuer_pwd, mbedtls_ctr_drbg_random, &ctr_drbg );
     if( ret != 0 )
     {
         mbedtls_strerror( ret, buf, 1024 );
@@ -606,7 +606,8 @@
     //
     if( strlen( opt.issuer_crt ) )
     {
-        if( mbedtls_pk_check_pair( &issuer_crt.MBEDTLS_PRIVATE(pk), issuer_key ) != 0 )
+        if( mbedtls_pk_check_pair( &issuer_crt.MBEDTLS_PRIVATE(pk), issuer_key,
+                                   mbedtls_ctr_drbg_random, &ctr_drbg ) != 0 )
         {
             mbedtls_printf( " failed\n  !  issuer_key does not match "
                             "issuer certificate\n\n" );
diff --git a/scripts/config.py b/scripts/config.py
index e27f322..cbce1eb 100755
--- a/scripts/config.py
+++ b/scripts/config.py
@@ -181,7 +181,6 @@
     'MBEDTLS_DEPRECATED_WARNING', # conflicts with deprecated options
     'MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED', # influences the use of ECDH in TLS
     'MBEDTLS_ECP_NO_FALLBACK', # removes internal ECP implementation
-    'MBEDTLS_ECP_NO_INTERNAL_RNG', # removes a feature
     'MBEDTLS_ECP_RESTARTABLE', # incompatible with USE_PSA_CRYPTO
     'MBEDTLS_ENTROPY_FORCE_SHA256', # interacts with CTR_DRBG_128_BIT_KEY
     'MBEDTLS_HAVE_SSE2', # hardware dependency
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 88f8b35..1a3bede 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1000,7 +1000,6 @@
     scripts/config.py unset MBEDTLS_CTR_DRBG_C
     scripts/config.py unset MBEDTLS_HMAC_DRBG_C
     scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
-    scripts/config.py set MBEDTLS_ECP_NO_INTERNAL_RNG
     # When MBEDTLS_USE_PSA_CRYPTO is disabled and there is no DRBG,
     # the SSL test programs don't have an RNG and can't work. Explicitly
     # make them use the PSA RNG with -DMBEDTLS_TEST_USE_PSA_CRYPTO_RNG.
@@ -1023,7 +1022,6 @@
     scripts/config.py unset MBEDTLS_CTR_DRBG_C
     scripts/config.py unset MBEDTLS_HMAC_DRBG_C
     scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
-    scripts/config.py set MBEDTLS_ECP_NO_INTERNAL_RNG
     make CFLAGS="$ASAN_CFLAGS -O2" LDFLAGS="$ASAN_CFLAGS"
 
     msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, PSA crypto - main suites"
@@ -1048,43 +1046,6 @@
     if_build_succeeded tests/ssl-opt.sh -f 'Default\|opaque'
 }
 
-component_test_ecp_no_internal_rng () {
-    msg "build: Default plus ECP_NO_INTERNAL_RNG minus DRBG modules"
-    scripts/config.py set MBEDTLS_ECP_NO_INTERNAL_RNG
-    scripts/config.py unset MBEDTLS_CTR_DRBG_C
-    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
-    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_C # requires a DRBG
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C # requires PSA Crypto
-
-    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: ECP_NO_INTERNAL_RNG, no DRBG module"
-    make test
-
-    # no SSL tests as they all depend on having a DRBG
-}
-
-component_test_ecp_restartable_no_internal_rng () {
-    msg "build: Default plus ECP_RESTARTABLE and ECP_NO_INTERNAL_RNG, no DRBG"
-    scripts/config.py set MBEDTLS_ECP_NO_INTERNAL_RNG
-    scripts/config.py set MBEDTLS_ECP_RESTARTABLE
-    scripts/config.py unset MBEDTLS_CTR_DRBG_C
-    scripts/config.py unset MBEDTLS_HMAC_DRBG_C
-    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_C # requires CTR_DRBG
-    scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C # requires PSA Crypto
-
-    CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
-    make
-
-    msg "test: ECP_RESTARTABLE and ECP_NO_INTERNAL_RNG, no DRBG module"
-    make test
-
-    # no SSL tests as they all depend on having a DRBG
-}
-
 component_test_everest () {
     msg "build: Everest ECDH context (ASan build)" # ~ 6 min
     scripts/config.py set MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
diff --git a/tests/suites/test_suite_dhm.function b/tests/suites/test_suite_dhm.function
index 62e634a..5286bc7 100644
--- a/tests/suites/test_suite_dhm.function
+++ b/tests/suites/test_suite_dhm.function
@@ -150,7 +150,10 @@
                                           &sec_srv_len,
                                           &mbedtls_test_rnd_pseudo_rand,
                                           &rnd_info ) == 0 );
-    TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_cli, sec_cli, sizeof( sec_cli ), &sec_cli_len, NULL, NULL ) == 0 );
+    TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_cli, sec_cli, sizeof( sec_cli ),
+                                          &sec_cli_len,
+                                          &mbedtls_test_rnd_pseudo_rand,
+                                          &rnd_info ) == 0 );
 
     TEST_ASSERT( sec_srv_len == sec_cli_len );
     TEST_ASSERT( sec_srv_len != 0 );
@@ -206,7 +209,10 @@
                                           &sec_srv_len,
                                           &mbedtls_test_rnd_pseudo_rand,
                                           &rnd_info ) == 0 );
-    TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_cli, sec_cli, sizeof( sec_cli ), &sec_cli_len, NULL, NULL ) == 0 );
+    TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_cli, sec_cli, sizeof( sec_cli ),
+                                          &sec_cli_len,
+                                          &mbedtls_test_rnd_pseudo_rand,
+                                          &rnd_info ) == 0 );
 
     TEST_ASSERT( sec_srv_len == sec_cli_len );
     TEST_ASSERT( sec_srv_len != 0 );
diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function
index 6e8459d..94030d8 100644
--- a/tests/suites/test_suite_ecdh.function
+++ b/tests/suites/test_suite_ecdh.function
@@ -85,7 +85,8 @@
                                               &mbedtls_test_rnd_pseudo_rand,
                                               &rnd_info ) == 0 );
     TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zB, &qA, &dB,
-                                      NULL, NULL ) == 0 );
+                                              &mbedtls_test_rnd_pseudo_rand,
+                                              &rnd_info ) == 0 );
 
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &zA, &zB ) == 0 );
 
@@ -106,11 +107,13 @@
     mbedtls_ecp_point qA, qB;
     mbedtls_mpi dA, dB, zA, zB, check;
     mbedtls_test_rnd_buf_info rnd_info_A, rnd_info_B;
+    mbedtls_test_rnd_pseudo_info rnd_info;
 
     mbedtls_ecp_group_init( &grp );
     mbedtls_ecp_point_init( &qA ); mbedtls_ecp_point_init( &qB );
     mbedtls_mpi_init( &dA ); mbedtls_mpi_init( &dB );
     mbedtls_mpi_init( &zA ); mbedtls_mpi_init( &zB ); mbedtls_mpi_init( &check );
+    memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) );
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
@@ -169,9 +172,13 @@
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qB.Y, &check ) == 0 );
 
     TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, z_str ) == 0 );
-    TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zA, &qB, &dA, NULL, NULL ) == 0 );
+    TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zA, &qB, &dA,
+                                              &mbedtls_test_rnd_pseudo_rand,
+                                              &rnd_info ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &zA, &check ) == 0 );
-    TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zB, &qA, &dB, NULL, NULL ) == 0 );
+    TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zB, &qA, &dB,
+                                              &mbedtls_test_rnd_pseudo_rand,
+                                              &rnd_info ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &zB, &check ) == 0 );
 
 exit:
@@ -215,7 +222,8 @@
                                            &mbedtls_test_rnd_pseudo_rand,
                                            &rnd_info ) == 0 );
     TEST_ASSERT( mbedtls_ecdh_calc_secret( &cli, &res_len, res_buf, 1000,
-                                           NULL, NULL ) == 0 );
+                                           &mbedtls_test_rnd_pseudo_rand,
+                                           &rnd_info ) == 0 );
     TEST_ASSERT( len == res_len );
     TEST_ASSERT( memcmp( buf, res_buf, len ) == 0 );
 
@@ -235,12 +243,14 @@
     const unsigned char *vbuf;
     size_t len;
     mbedtls_test_rnd_buf_info rnd_info_A, rnd_info_B;
+    mbedtls_test_rnd_pseudo_info rnd_info;
     int cnt_restart;
     mbedtls_ecp_group grp;
 
     mbedtls_ecp_group_init( &grp );
     mbedtls_ecdh_init( &srv );
     mbedtls_ecdh_init( &cli );
+    memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) );
 
     rnd_info_A.fallback_f_rng = mbedtls_test_rnd_std_rand;
     rnd_info_A.fallback_p_rng = NULL;
@@ -315,7 +325,8 @@
     cnt_restart = 0;
     do {
         ret = mbedtls_ecdh_calc_secret( &srv, &len, buf, sizeof( buf ),
-                                              NULL, NULL );
+                                        &mbedtls_test_rnd_pseudo_rand,
+                                        &rnd_info );
     } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
 
     TEST_ASSERT( ret == 0 );
@@ -332,7 +343,8 @@
     cnt_restart = 0;
     do {
         ret = mbedtls_ecdh_calc_secret( &cli, &len, buf, sizeof( buf ),
-                                              NULL, NULL );
+                                        &mbedtls_test_rnd_pseudo_rand,
+                                        &rnd_info );
     } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
 
     TEST_ASSERT( ret == 0 );
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index f2b6376..d795fe2 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -124,12 +124,14 @@
     mbedtls_mpi dA, xA, yA, dB, xZ, yZ;
     int cnt_restarts;
     int ret;
+    mbedtls_test_rnd_pseudo_info rnd_info;
 
     mbedtls_ecp_restart_init( &ctx );
     mbedtls_ecp_group_init( &grp );
     mbedtls_ecp_point_init( &R ); mbedtls_ecp_point_init( &P );
     mbedtls_mpi_init( &dA ); mbedtls_mpi_init( &xA ); mbedtls_mpi_init( &yA );
     mbedtls_mpi_init( &dB ); mbedtls_mpi_init( &xZ ); mbedtls_mpi_init( &yZ );
+    memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) );
 
     TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
 
@@ -147,7 +149,8 @@
     cnt_restarts = 0;
     do {
         ECP_PT_RESET( &R );
-        ret = mbedtls_ecp_mul_restartable( &grp, &R, &dA, &grp.G, NULL, NULL, &ctx );
+        ret = mbedtls_ecp_mul_restartable( &grp, &R, &dA, &grp.G,
+                &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx );
     } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts );
 
     TEST_ASSERT( ret == 0 );
@@ -162,7 +165,8 @@
     cnt_restarts = 0;
     do {
         ECP_PT_RESET( &R );
-        ret = mbedtls_ecp_mul_restartable( &grp, &R, &dB, &P, NULL, NULL, &ctx );
+        ret = mbedtls_ecp_mul_restartable( &grp, &R, &dB, &P,
+                &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx );
     } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts );
 
     TEST_ASSERT( ret == 0 );
@@ -176,7 +180,8 @@
      * This test only makes sense when we actually restart */
     if( min_restarts > 0 )
     {
-        ret = mbedtls_ecp_mul_restartable( &grp, &R, &dB, &P, NULL, NULL, &ctx );
+        ret = mbedtls_ecp_mul_restartable( &grp, &R, &dB, &P,
+                &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx );
         TEST_ASSERT( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
     }
 
@@ -294,12 +299,14 @@
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xA ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.Y, &yA ) == 0 );
     TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
-    TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dB, &R, NULL, NULL ) == 0 );
+    TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dB, &R,
+                          &mbedtls_test_rnd_pseudo_rand, &rnd_info ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xZ ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.Y, &yZ ) == 0 );
     TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
 
-    TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dB, &grp.G, NULL, NULL ) == 0 );
+    TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dB, &grp.G,
+                          &mbedtls_test_rnd_pseudo_rand, &rnd_info ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xB ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.Y, &yB ) == 0 );
     TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
@@ -351,11 +358,13 @@
     TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xS ) == 0 );
 
-    TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dB, &grp.G, NULL, NULL ) == 0 );
+    TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dB, &grp.G,
+                          &mbedtls_test_rnd_pseudo_rand, &rnd_info ) == 0 );
     TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xB ) == 0 );
 
-    TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dA, &R, NULL, NULL ) == 0 );
+    TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dA, &R,
+                          &mbedtls_test_rnd_pseudo_rand, &rnd_info ) == 0 );
     TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
     TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xS ) == 0 );
 
@@ -767,9 +776,11 @@
                                  int ret )
 {
     mbedtls_ecp_keypair pub, prv;
+    mbedtls_test_rnd_pseudo_info rnd_info;
 
     mbedtls_ecp_keypair_init( &pub );
     mbedtls_ecp_keypair_init( &prv );
+    memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) );
 
     if( id_pub != MBEDTLS_ECP_DP_NONE )
         TEST_ASSERT( mbedtls_ecp_group_load( &pub.grp, id_pub ) == 0 );
@@ -780,7 +791,8 @@
     TEST_ASSERT( mbedtls_ecp_point_read_string( &prv.Q, 16, Qx, Qy ) == 0 );
     TEST_ASSERT( mbedtls_mpi_read_string( &prv.d, 16, d ) == 0 );
 
-    TEST_ASSERT( mbedtls_ecp_check_pub_priv( &pub, &prv ) == ret );
+    TEST_ASSERT( mbedtls_ecp_check_pub_priv( &pub, &prv,
+                          &mbedtls_test_rnd_pseudo_rand, &rnd_info ) == ret );
 
 exit:
     mbedtls_ecp_keypair_free( &pub );
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 573c9d4..5ccb072 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -177,7 +177,8 @@
     /* unsupported functions: check_pair, debug */
     TEST_ASSERT( mbedtls_pk_setup( &pk2,
                  mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == 0 );
-    TEST_ASSERT( mbedtls_pk_check_pair( &pk, &pk2 )
+    TEST_ASSERT( mbedtls_pk_check_pair( &pk, &pk2,
+                                        mbedtls_test_rnd_std_rand, NULL )
                  == MBEDTLS_ERR_PK_TYPE_MISMATCH );
     TEST_ASSERT( mbedtls_pk_debug( &pk, &dbg )
                  == MBEDTLS_ERR_PK_TYPE_MISMATCH );
@@ -278,7 +279,8 @@
                  MBEDTLS_ERR_PK_BAD_INPUT_DATA );
 
 #if defined(MBEDTLS_PK_PARSE_C)
-    TEST_ASSERT( mbedtls_pk_parse_key( &pk, NULL, 0, NULL, 1 ) ==
+    TEST_ASSERT( mbedtls_pk_parse_key( &pk, NULL, 0, NULL, 1,
+                                       mbedtls_test_rnd_std_rand, NULL ) ==
                  MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
 
     TEST_ASSERT( mbedtls_pk_parse_public_key( &pk, NULL, 0 ) ==
@@ -295,8 +297,8 @@
     /* For the write tests to be effective, we need a valid key pair. */
     mbedtls_pk_init( &pk );
     TEST_ASSERT( mbedtls_pk_parse_key( &pk,
-                                       key_data->x, key_data->len,
-                                       NULL, 0 ) == 0 );
+                key_data->x, key_data->len, NULL, 0,
+                mbedtls_test_rnd_std_rand, NULL ) == 0 );
 
     TEST_ASSERT( mbedtls_pk_write_key_der( &pk, NULL, 0 ) ==
                  MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
@@ -348,9 +350,13 @@
     mbedtls_pk_init( &alt );
 
     TEST_ASSERT( mbedtls_pk_parse_public_keyfile( &pub, pub_file ) == 0 );
-    TEST_ASSERT( mbedtls_pk_parse_keyfile( &prv, prv_file, NULL ) == 0 );
+    TEST_ASSERT( mbedtls_pk_parse_keyfile( &prv, prv_file, NULL,
+                                           mbedtls_test_rnd_std_rand, NULL )
+                 == 0 );
 
-    TEST_ASSERT( mbedtls_pk_check_pair( &pub, &prv ) == ret );
+    TEST_ASSERT( mbedtls_pk_check_pair( &pub, &prv,
+                                        mbedtls_test_rnd_std_rand, NULL )
+                 == ret );
 
 #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
     if( mbedtls_pk_get_type( &prv ) == MBEDTLS_PK_RSA )
@@ -358,7 +364,9 @@
         TEST_ASSERT( mbedtls_pk_setup_rsa_alt( &alt, mbedtls_pk_rsa( prv ),
                      mbedtls_rsa_decrypt_func, mbedtls_rsa_sign_func,
                      mbedtls_rsa_key_len_func ) == 0 );
-        TEST_ASSERT( mbedtls_pk_check_pair( &pub, &alt ) == ret );
+        TEST_ASSERT( mbedtls_pk_check_pair( &pub, &alt,
+                                            mbedtls_test_rnd_std_rand, NULL )
+                     == ret );
     }
 #endif
 
diff --git a/tests/suites/test_suite_pkparse.function b/tests/suites/test_suite_pkparse.function
index 4650d33..4c7f3d2 100644
--- a/tests/suites/test_suite_pkparse.function
+++ b/tests/suites/test_suite_pkparse.function
@@ -21,7 +21,8 @@
     if( strcmp( pwd, "NULL" ) == 0 )
         pwd = NULL;
 
-    res = mbedtls_pk_parse_keyfile( &ctx, key_file, pwd );
+    res = mbedtls_pk_parse_keyfile( &ctx, key_file, pwd,
+            mbedtls_test_rnd_std_rand, NULL );
 
     TEST_ASSERT( res == result );
 
@@ -96,7 +97,8 @@
 
     mbedtls_pk_init( &ctx );
 
-    res = mbedtls_pk_parse_keyfile( &ctx, key_file, password );
+    res = mbedtls_pk_parse_keyfile( &ctx, key_file, password,
+            mbedtls_test_rnd_std_rand, NULL );
 
     TEST_ASSERT( res == result );
 
@@ -120,7 +122,8 @@
 
     mbedtls_pk_init( &pk );
 
-    TEST_ASSERT( mbedtls_pk_parse_key( &pk, buf->x, buf->len, NULL, 0 ) == result );
+    TEST_ASSERT( mbedtls_pk_parse_key( &pk, buf->x, buf->len, NULL, 0,
+                        mbedtls_test_rnd_std_rand, NULL ) == result );
 
 exit:
     mbedtls_pk_free( &pk );
diff --git a/tests/suites/test_suite_pkwrite.function b/tests/suites/test_suite_pkwrite.function
index 2bad4ed..d1e029a 100644
--- a/tests/suites/test_suite_pkwrite.function
+++ b/tests/suites/test_suite_pkwrite.function
@@ -63,7 +63,8 @@
     memset( check_buf, 0, sizeof( check_buf ) );
 
     mbedtls_pk_init( &key );
-    TEST_ASSERT( mbedtls_pk_parse_keyfile( &key, key_file, NULL ) == 0 );
+    TEST_ASSERT( mbedtls_pk_parse_keyfile( &key, key_file, NULL,
+                        mbedtls_test_rnd_std_rand, NULL ) == 0 );
 
     ret = mbedtls_pk_write_key_pem( &key, buf, sizeof( buf ));
     TEST_ASSERT( ret == 0 );
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index b4df5ec..5ed485e 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -2761,6 +2761,22 @@
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
 derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_NONE:PSA_SUCCESS
 
+PSA key derivation: HKDF-SHA-256, good case, omitted salt
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):0:UNUSED:"":UNUSED:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_NONE:PSA_SUCCESS
+
+PSA key derivation: HKDF-SHA-256, good case, info first
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_KEY_TYPE_NONE:PSA_SUCCESS
+
+PSA key derivation: HKDF-SHA-256, good case, info after salt
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_NONE:PSA_SUCCESS
+
+PSA key derivation: HKDF-SHA-256, good case, omitted salt, info first
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_SUCCESS
+
 PSA key derivation: HKDF-SHA-256, good case, key output
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
 derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_DERIVE:PSA_SUCCESS
@@ -2795,6 +2811,10 @@
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
 derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_RAW_DATA:PSA_ERROR_NOT_PERMITTED
 
+PSA key derivation: HKDF-SHA-256, missing secret, key output
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:0:UNUSED:"":UNUSED:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_RAW_DATA:PSA_ERROR_NOT_PERMITTED
+
 PSA key derivation: HKDF-SHA-256, RAW_DATA key as salt
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
 derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_RAW_DATA:"412073616c74":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_DERIVE:PSA_SUCCESS
@@ -2817,14 +2837,94 @@
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
 derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_DERIVE:"4120696e666f":PSA_ERROR_INVALID_ARGUMENT:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
 
+PSA key derivation: HKDF-SHA-256, salt after secret
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: HKDF-SHA-256, missing secret
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:0:UNUSED:"":UNUSED:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: HKDF-SHA-256, missing info
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: HKDF-SHA-256, duplicate salt step
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: HKDF-SHA-256, duplicate secret step (direct, direct)
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: HKDF-SHA-256, duplicate secret step (direct, key)
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: HKDF-SHA-256, duplicate secret step (key, direct)
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0a0a0a0a":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_NONE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: HKDF-SHA-256, duplicate secret step (key, key)
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0a0a0a0a":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: HKDF-SHA-256, duplicate info step (non-consecutive)
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: HKDF-SHA-256, duplicate info step (consecutive)
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: HKDF-SHA-256, reject label step
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_LABEL:PSA_KEY_TYPE_NONE:"":PSA_ERROR_INVALID_ARGUMENT:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: HKDF-SHA-256, reject seed step
+depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SEED:PSA_KEY_TYPE_NONE:"":PSA_ERROR_INVALID_ARGUMENT:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
 PSA key derivation: TLS 1.2 PRF SHA-256, good case
 depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
 derive_input:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SEED:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_LABEL:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_DERIVE:PSA_SUCCESS
 
+PSA key derivation: ECDH with TLS 1.2 PRF SHA-256, good case
+depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
+derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)):PSA_KEY_DERIVATION_INPUT_SEED:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_LABEL:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_NONE:PSA_SUCCESS
+
+PSA key derivation: TLS 1.2 PRF SHA-256, missing label
+depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
+derive_input:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SEED:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_SUCCESS:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: ECDH with TLS 1.2 PRF SHA-256, missing label
+depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
+derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)):PSA_KEY_DERIVATION_INPUT_SEED:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":PSA_SUCCESS:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: TLS 1.2 PRF SHA-256, missing label and secret
+depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
+derive_input:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SEED:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: ECDH with TLS 1.2 PRF SHA-256, missing label and secret
+depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
+derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)):PSA_KEY_DERIVATION_INPUT_SEED:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: TLS 1.2 PRF SHA-256, no inputs
+depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
+derive_input:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: ECDH with TLS 1.2 PRF SHA-256, no inputs
+depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
+derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)):0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
 PSA key derivation: TLS 1.2 PRF SHA-256, key first
 depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
 derive_input:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_SEED:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_LABEL:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
 
+PSA key derivation: ECDH with TLS 1.2 PRF SHA-256, key first
+depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256
+derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)):PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_SEED:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_LABEL:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
 PSA key derivation: TLS 1.2 PRF SHA-256, label first
 depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
 derive_input:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_LABEL:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_SEED:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
@@ -2877,20 +2977,36 @@
 depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
 derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_NONE:PSA_SUCCESS
 
+PSA key derivation: ECDH on P256 with HKDF-SHA256, omitted salt
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
+derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):0:UNUSED:"":UNUSED:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_NONE:PSA_SUCCESS
+
+PSA key derivation: ECDH on P256 with HKDF-SHA256, info first
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
+derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":PSA_SUCCESS:PSA_KEY_TYPE_NONE:PSA_SUCCESS
+
 PSA key derivation: ECDH on P256 with HKDF-SHA256, key output
 depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
 derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_TYPE_RAW_DATA:PSA_SUCCESS
 
-PSA key derivation: HKDF invalid state (double generate + read past capacity)
+PSA key derivation: ECDH on P256 with HKDF-SHA256, salt after secret
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
+derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation: ECDH on P256 with HKDF-SHA256, missing info
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256
+derive_input:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":PSA_SUCCESS:0:UNUSED:"":UNUSED:PSA_KEY_TYPE_NONE:PSA_ERROR_BAD_STATE
+
+PSA key derivation over capacity: HKDF
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
-test_derive_invalid_key_derivation_state:PSA_ALG_HKDF(PSA_ALG_SHA_256)
+derive_over_capacity:PSA_ALG_HKDF(PSA_ALG_SHA_256)
 
-PSA key derivation: TLS 1.2 PRF invalid state (double generate + read past capacity)
+PSA key derivation over capacity: TLS 1.2 PRF
 depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF
-test_derive_invalid_key_derivation_state:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)
+derive_over_capacity:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)
 
-PSA key derivation: invalid state (call read/get_capacity after init and abort)
-test_derive_invalid_key_derivation_tests:
+PSA key derivation: actions without setup
+derive_actions_without_setup:
 
 PSA key derivation: HKDF SHA-256, RFC5869 #1, output 42+0
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 5b5531f..7a774e5 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -16,6 +16,9 @@
 #include "test/psa_crypto_helpers.h"
 #include "test/psa_exercise_key.h"
 
+/* If this comes up, it's a bug in the test code or in the test data. */
+#define UNUSED 0xdeadbeef
+
 /** An invalid export length that will never be set by psa_export_key(). */
 static const size_t INVALID_EXPORT_LENGTH = ~0U;
 
@@ -4027,7 +4030,12 @@
 
     for( i = 0; i < ARRAY_LENGTH( steps ); i++ )
     {
-        if( key_types[i] != PSA_KEY_TYPE_NONE )
+        mbedtls_test_set_step( i );
+        if( steps[i] == 0 )
+        {
+            /* Skip this step */
+        }
+        else if( key_types[i] != PSA_KEY_TYPE_NONE )
         {
             psa_set_key_type( &attributes, key_types[i] );
             PSA_ASSERT( psa_import_key( &attributes,
@@ -4086,7 +4094,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void test_derive_invalid_key_derivation_state( int alg_arg )
+void derive_over_capacity( int alg_arg )
 {
     psa_algorithm_t alg = alg_arg;
     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
@@ -4137,7 +4145,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void test_derive_invalid_key_derivation_tests( )
+void derive_actions_without_setup( )
 {
     uint8_t output_buffer[16];
     size_t buffer_size = 16;
diff --git a/tests/suites/test_suite_psa_crypto_init.function b/tests/suites/test_suite_psa_crypto_init.function
index d612548..9f72b47 100644
--- a/tests/suites/test_suite_psa_crypto_init.function
+++ b/tests/suites/test_suite_psa_crypto_init.function
@@ -85,12 +85,6 @@
                                     MBEDTLS_ENTROPY_MIN_PLATFORM,
                                     MBEDTLS_ENTROPY_SOURCE_STRONG );
 #endif
-#if defined(MBEDTLS_TIMING_C)
-    if( custom_entropy_sources_mask & ENTROPY_SOURCE_TIMING )
-        mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL,
-                                    MBEDTLS_ENTROPY_MIN_HARDCLOCK,
-                                    MBEDTLS_ENTROPY_SOURCE_WEAK );
-#endif
 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
     if( custom_entropy_sources_mask & ENTROPY_SOURCE_HARDWARE )
         mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL,
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index c555d74..d4aad60 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -800,7 +800,8 @@
 
             ret = mbedtls_pk_parse_key( &( cert->pkey ),
                             (const unsigned char*) mbedtls_test_srv_key_rsa_der,
-                            mbedtls_test_srv_key_rsa_der_len, NULL, 0 );
+                            mbedtls_test_srv_key_rsa_der_len, NULL, 0,
+                            mbedtls_test_rnd_std_rand, NULL );
             TEST_ASSERT( ret == 0 );
         }
         else
@@ -812,7 +813,8 @@
 
             ret = mbedtls_pk_parse_key( &( cert->pkey ),
                             (const unsigned char*) mbedtls_test_srv_key_ec_der,
-                            mbedtls_test_srv_key_ec_der_len, NULL, 0 );
+                            mbedtls_test_srv_key_ec_der_len, NULL, 0,
+                            mbedtls_test_rnd_std_rand, NULL );
             TEST_ASSERT( ret == 0 );
         }
     }
@@ -827,7 +829,8 @@
 
             ret = mbedtls_pk_parse_key( &( cert->pkey ),
                           (const unsigned char *) mbedtls_test_cli_key_rsa_der,
-                          mbedtls_test_cli_key_rsa_der_len, NULL, 0 );
+                          mbedtls_test_cli_key_rsa_der_len, NULL, 0,
+                          mbedtls_test_rnd_std_rand, NULL );
             TEST_ASSERT( ret == 0 );
         }
         else
@@ -839,7 +842,8 @@
 
             ret = mbedtls_pk_parse_key( &( cert->pkey ),
                           (const unsigned char *) mbedtls_test_cli_key_ec_der,
-                          mbedtls_test_cli_key_ec_der_len, NULL, 0 );
+                          mbedtls_test_cli_key_ec_der_len, NULL, 0,
+                          mbedtls_test_rnd_std_rand, NULL );
             TEST_ASSERT( ret == 0 );
         }
     }
diff --git a/tests/suites/test_suite_timing.data b/tests/suites/test_suite_timing.data
index 2522da1..de89239 100644
--- a/tests/suites/test_suite_timing.data
+++ b/tests/suites/test_suite_timing.data
@@ -1,15 +1,6 @@
-Timing: hardclock
-timing_hardclock:
-
 Timing: get timer
 timing_get_timer:
 
-Timing: set alarm with no delay
-timing_set_alarm:0:
-
-Timing: set alarm with 1s delay
-timing_set_alarm:1:
-
 Timing: delay 0ms
 timing_delay:0:
 
diff --git a/tests/suites/test_suite_timing.function b/tests/suites/test_suite_timing.function
index 74dc823..3483d85 100644
--- a/tests/suites/test_suite_timing.function
+++ b/tests/suites/test_suite_timing.function
@@ -17,15 +17,6 @@
  */
 
 /* BEGIN_CASE */
-void timing_hardclock( )
-{
-    (void) mbedtls_timing_hardclock();
-    /* This goto is added to avoid warnings from the generated code. */
-    goto exit;
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
 void timing_get_timer( )
 {
     struct mbedtls_timing_hr_time time;
@@ -37,23 +28,6 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void timing_set_alarm( int seconds )
-{
-    if( seconds == 0 )
-    {
-        mbedtls_set_alarm( seconds );
-        TEST_ASSERT( mbedtls_timing_alarmed == 1 );
-    }
-    else
-    {
-        mbedtls_set_alarm( seconds );
-        TEST_ASSERT( mbedtls_timing_alarmed == 0 ||
-                     mbedtls_timing_alarmed == 1 );
-    }
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
 void timing_delay( int fin_ms )
 {
     mbedtls_timing_delay_context ctx;
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index 44f846f..c9b7cf9 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -94,7 +94,8 @@
     memset( &rnd_info, 0x2a, sizeof( mbedtls_test_rnd_pseudo_info ) );
 
     mbedtls_pk_init( &key );
-    TEST_ASSERT( mbedtls_pk_parse_keyfile( &key, key_file, NULL ) == 0 );
+    TEST_ASSERT( mbedtls_pk_parse_keyfile( &key, key_file, NULL,
+                        mbedtls_test_rnd_std_rand, NULL ) == 0 );
 
     mbedtls_x509write_csr_init( &req );
     mbedtls_x509write_csr_set_md_alg( &req, md_type );
@@ -163,7 +164,8 @@
     TEST_ASSERT( md_alg_psa != MBEDTLS_MD_NONE );
 
     mbedtls_pk_init( &key );
-    TEST_ASSERT( mbedtls_pk_parse_keyfile( &key, key_file, NULL ) == 0 );
+    TEST_ASSERT( mbedtls_pk_parse_keyfile( &key, key_file, NULL,
+                        mbedtls_test_rnd_std_rand, NULL ) == 0 );
     TEST_ASSERT( mbedtls_pk_wrap_as_opaque( &key, &key_id, md_alg_psa ) == 0 );
 
     mbedtls_x509write_csr_init( &req );
@@ -225,10 +227,10 @@
     mbedtls_x509write_crt_init( &crt );
 
     TEST_ASSERT( mbedtls_pk_parse_keyfile( &subject_key, subject_key_file,
-                                         subject_pwd ) == 0 );
+                    subject_pwd, mbedtls_test_rnd_std_rand, NULL ) == 0 );
 
     TEST_ASSERT( mbedtls_pk_parse_keyfile( &issuer_key, issuer_key_file,
-                                         issuer_pwd ) == 0 );
+                    issuer_pwd, mbedtls_test_rnd_std_rand, NULL ) == 0 );
 
 #if defined(MBEDTLS_RSA_C)
     /* For RSA PK contexts, create a copy as an alternative RSA context. */