Repository: Mbed-TLS/TF-PSA-Crypto
Pull request #212: [tf-psa-crypto] MBEDTLS_PLATFORM_GET_ENTROPY_ALT in 4.0
Author: login: valeriosetti
Labels: name: size-s
description: Estimated task size: small (~2d)
name: needs-review
description: Every commit must be reviewed by at least two team members
name: priority-high
description: High priority - will be reviewed soon
Created: 2025-03-18T13:42:53Z | Merged: 2025-05-06T16:28:56Z

## Description

This helps resolving https://github.com/Mbed-TLS/mbedtls/issues/9618

## CI note

Due to dependencies with the [main repo PR](https://github.com/Mbed-TLS/mbedtls/pull/10090) please evaluate the CI of 10090 as validation of this PR.

## PR checklist

- [x] **changelog** done
- [x] **framework PR**
    - [ ] https://github.com/Mbed-TLS/mbedtls-framework/pull/151
    - [ ] https://github.com/Mbed-TLS/mbedtls-framework/pull/161
    - [ ] https://github.com/Mbed-TLS/mbedtls-framework/pull/165
- [x] **mbedtls development PR** https://github.com/Mbed-TLS/mbedtls/pull/10090
- [x] **mbedtls 3.6 PR** not required: new feature
- [ ] **tests**  TODO


Diff:
diff --git a/ChangeLog.d/9618.txt b/ChangeLog.d/9618.txt
new file mode 100644
index 0000000000..c3af42da2b
--- /dev/null
+++ b/ChangeLog.d/9618.txt
@@ -0,0 +1,16 @@
+Removals
+   * MBEDTLS_NO_PLATFORM_ENTROPY and the previously deprecated
+     MBEDTLS_ENTROPY_HARDWARE_ALT are removed. See the documentation of
+     MBEDTLS_PLATFORM_GET_ENTROPY_ALT for a description on how the entropy
+     module gathers entropy data.
+   * MBEDTLS_ENTROPY_MIN_HARDWARE is also removed following the removal of
+     MBEDTLS_ENTROPY_HARDWARE_ALT.
+
+Features
+   * To supply a platform-specific entropy source, define the compilation option
+     MBEDTLS_PLATFORM_GET_ENTROPY_ALT and provide the callback function
+     mbedtls_platform_get_entropy_alt(). This function should typically access
+     a TRNG ("true hardware random generator") device on bare-metal platforms,
+     or call an operating system function to obtain cryptographic-quality random
+     data. Mbed TLS requires that a minimum of 32 bytes (not configurable) are
+     returned from this function for a successful entropy gathering round.
diff --git a/configs/crypto-config-ccm-aes-sha256.h b/configs/crypto-config-ccm-aes-sha256.h
index be8a7467eb..c001425444 100644
--- a/configs/crypto-config-ccm-aes-sha256.h
+++ b/configs/crypto-config-ccm-aes-sha256.h
@@ -24,5 +24,6 @@
 #define MBEDTLS_PSA_CRYPTO_C
 #define MBEDTLS_CTR_DRBG_C
 #define MBEDTLS_ENTROPY_C
+#define MBEDTLS_PLATFORM_C
 
 #endif /* PSA_CRYPTO_CONFIG_H */
diff --git a/configs/ext/crypto_config_profile_medium.h b/configs/ext/crypto_config_profile_medium.h
index ca6478c0df..42f97db867 100644
--- a/configs/ext/crypto_config_profile_medium.h
+++ b/configs/ext/crypto_config_profile_medium.h
@@ -254,6 +254,19 @@
  */
 #define MBEDTLS_ENTROPY_C
 
+/**
+ * \def MBEDTLS_PLATFORM_GET_ENTROPY_ALT
+ *
+ * By default Mbed TLS uses standard platform sources (/dev/urandom on Linux
+ * and CryptoAPI on Windows) to gather entropy data. If these functions are
+ * not available for some reason (ex: working on a baremetal project), the
+ * following symbol allows the user to define a custom callback function that
+ * Mbed TLS will use to gather entropy data.
+ * Public header `mbedtls/platform.h` provides the prototype for this callback
+ * function and also the documentation for its parameters.
+ */
+#define MBEDTLS_PLATFORM_GET_ENTROPY_ALT
+
 /**
  * \def MBEDTLS_ENTROPY_NV_SEED
  *
@@ -282,17 +295,6 @@
  */
 #define MBEDTLS_ENTROPY_NV_SEED
 
-/**
- * \def MBEDTLS_NO_PLATFORM_ENTROPY
- *
- * Do not use built-in platform entropy functions.
- * This is useful if your platform does not support
- * standards like the /dev/urandom or Windows CryptoAPI.
- *
- * Uncomment this macro to disable the built-in platform entropy functions.
- */
-#define MBEDTLS_NO_PLATFORM_ENTROPY
-
 /**
  * \def MBEDTLS_PSA_CRYPTO_C
  *
@@ -611,10 +613,10 @@
  * variables accordingly.
  */
 #if defined(__IAR_SYSTEMS_ICC__) || defined(__ARMCC_VERSION) || defined(__ARM_EABI__)
-#define MBEDTLS_NO_PLATFORM_ENTROPY
+#define MBEDTLS_PLATFORM_GET_ENTROPY_ALT
 #else
 /* Use built-in platform entropy functions (TF-M provides its own). */
-#undef MBEDTLS_NO_PLATFORM_ENTROPY
+#undef MBEDTLS_PLATFORM_GET_ENTROPY_ALT
 #endif
 
 /***********************************************************************
diff --git a/docs/4.0-migration-guide/platform-entropy-gathering.md b/docs/4.0-migration-guide/platform-entropy-gathering.md
new file mode 100644
index 0000000000..247d085e39
--- /dev/null
+++ b/docs/4.0-migration-guide/platform-entropy-gathering.md
@@ -0,0 +1,83 @@
+## Platform-specific Entropy Gathering
+
+`MBEDTLS_ENTROPY_HARDWARE_ALT` has been renamed to `MBEDTLS_PLATFORM_GET_ENTROPY_ALT`.
+The prototype for the custom entropy callback function changed from:
+
+```c
+int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len,
+                          size_t *olen);
+```
+
+to:
+
+```c
+int mbedtls_platform_get_entropy(unsigned char *output, size_t output_size,
+                                 size_t *output_len, size_t *entropy_content);
+```
+
+This new prototype is placed in the public header `mbedtls/platform.h` instead
+of the private `library/entropy_poll.h` one as it was previously.
+
+The `data` parameter was previously always `NULL`, and has been removed.
+
+The new `entropy_content` parameter measures (in bit) the amount of entropy
+contained in the returned `output` buffer.
+For the time being, TF-PSA-Crypto only supports callbacks that provide full
+entropy. That means that the content of the output buffer must be uniformly
+random, allowing you to report that `entropy_content = 8 * *output_len`.
+Typically `*output_len == output_size`, but if it is smaller, the library will
+call the callback again in a loop.
+
+If you implement this callback for hardware that delivers partial entropy, a
+typical technique is to gather enough entropy then hash the result. Hashing does
+not increase the entropy, but it distributes it throughout the buffer. For
+example, suppose your hardware has a 32-bit register which is documented as
+having a single bit of entropy each time it is read after calling a priming
+function. The following code snippet collects 8 bits of entropy and outputs it
+in one byte.
+
+```c
+int mbedtls_platform_get_entropy(unsigned char *output, size_t output_size,
+                                 size_t *output_len, size_t *entropy_content) {
+    uint32_t reads[8];
+    uint8_t hash[32];
+    int ret;
+    psa_status_t status;
+    (void) output_size;
+
+    for (int i = 0; i < 8; i++) {
+        ret = myhardware_prime_magic_random_register();
+        if (ret != 0) {
+            return PSA_ERROR_INSUFFICIENT_ENTROPY;
+        }
+        reads[i] = myhardware_magic_random_register_read();
+    }
+    size_t hash_len;
+
+    status = psa_hash_compute(PSA_ALG_SHA_256, (uint_t*) reads, sizeof(reads),
+                              hash, sizeof(hash), &hash_len);
+    if (ret != PSA_SUCCESS) {
+        return PSA_ERROR_INSUFFICIENT_ENTROPY;
+    }
+
+    output[0] = hash[0];
+    *output_len = 1;
+    *entropy_content = 8;
+
+    return 0;
+}
+```
+
+`MBEDTLS_ENTROPY_MIN_HARDWARE` is also removed and the entropy module assumes
+that 32 bytes are enough to declare the hardware entropy polling completed.
+This value is not user configurable.
+
+The option MBEDTLS_PLATFORM_GET_ENTROPY_ALT disables the built-in entropy
+sources, unlike its predecessor MBEDTLS_ENTROPY_HARDWARE_ALT, because one
+entropy source is generally sufficient. If you want to add a custom entropy
+source while retaining the platform's default source, call the platform's
+default source in your callback.
+
+The option MBEDTLS_NO_PLATFORM_ENTROPY is removed. TF-PSA-Crypto 1.0 no longer
+supports platforms without an entropy source. This ability will be reintroduced
+in a future minor release.
diff --git a/drivers/builtin/include/mbedtls/entropy.h b/drivers/builtin/include/mbedtls/entropy.h
index cf5ec435b0..fcac6ed015 100644
--- a/drivers/builtin/include/mbedtls/entropy.h
+++ b/drivers/builtin/include/mbedtls/entropy.h
@@ -118,14 +118,6 @@ typedef struct mbedtls_entropy_context {
 }
 mbedtls_entropy_context;
 
-#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
-/**
- * \brief           Platform-specific entropy poll callback
- */
-int mbedtls_platform_entropy_poll(void *data,
-                                  unsigned char *output, size_t len, size_t *olen);
-#endif
-
 /**
  * \brief           Initialize the context
  *
@@ -248,7 +240,7 @@ int mbedtls_entropy_update_seed_file(mbedtls_entropy_context *ctx, const char *p
  */
 int mbedtls_entropy_self_test(int verbose);
 
-#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+#if defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
 /**
  * \brief          Checkup routine
  *
@@ -263,7 +255,7 @@ int mbedtls_entropy_self_test(int verbose);
  * \return         0 if successful, or 1 if a test failed
  */
 int mbedtls_entropy_source_self_test(int verbose);
-#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
+#endif /* MBEDTLS_PLATFORM_GET_ENTROPY_ALT */
 #endif /* MBEDTLS_SELF_TEST */
 
 #ifdef __cplusplus
diff --git a/drivers/builtin/include/mbedtls/platform.h b/drivers/builtin/include/mbedtls/platform.h
index f21a17ec58..3dd3d4f0ce 100644
--- a/drivers/builtin/include/mbedtls/platform.h
+++ b/drivers/builtin/include/mbedtls/platform.h
@@ -446,6 +446,40 @@ mbedtls_platform_context;
 #include "platform_alt.h"
 #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
 
+/**
+ * \brief       User defined callback function that is used from the entropy
+ *              module to gather entropy data from some hardware device.
+ *
+ * \param[out] output           Output buffer where the entropy data will be
+ *                              stored.
+ * \param[in] output_size       Size of the \p output buffer in bytes.
+ * \param[out] output_len       Amount of bytes effectively written in the
+ *                              \p output buffer.
+ * \param[out] entropy_content  Measure of the entropy content (in bits) of the
+ *                              data written in the \p output buffer.*
+ *
+ * \return                      \c 0 for success, MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+ *                              or some other negative value on error.
+ *
+ * \warning     For the time being TF-PSA-Crypto only supports implementations
+ *              that return a maximum entropy output on each call, i.e.
+ *              \p entropy_content = `8 * output_len`. Returning a smaller
+ *              entropy content is the same as returning
+ *              MBEDTLS_ERR_ENTROPY_SOURCE_FAILED so the hardware polling will
+ *              fail.
+ *              In the future TF-PSA-Crypto will be smarter and capable to cope
+ *              with entropy sources with lower entropy content (i.e.
+ *              0 < \p entropy_content < 8 * output_len) by calling the callback
+ *              function in loop.
+ *
+ * \note        This function is not meant to be called by application code, and
+ *              it is not guaranteed that this function will exist or will behave
+ *              in the same way in future versions of the library. Applications
+ *              should call psa_generate_random() to obtain random data.
+ */
+int mbedtls_platform_get_entropy(unsigned char *output, size_t output_size,
+                                 size_t *output_len, size_t *entropy_content);
+
 /**
  * \brief   This function performs any platform-specific initialization
  *          operations.
diff --git a/drivers/builtin/src/entropy.c b/drivers/builtin/src/entropy.c
index fd222c0d74..1984bdb151 100644
--- a/drivers/builtin/src/entropy.c
+++ b/drivers/builtin/src/entropy.c
@@ -40,16 +40,9 @@ void mbedtls_entropy_init(mbedtls_entropy_context *ctx)
      *           when adding more strong entropy sources here. */
 
 #if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
-#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
-    mbedtls_entropy_add_source(ctx, mbedtls_platform_entropy_poll, NULL,
-                               MBEDTLS_ENTROPY_MIN_PLATFORM,
+    mbedtls_entropy_add_source(ctx, mbedtls_entropy_poll_platform, NULL,
+                               MBEDTLS_ENTROPY_POLL_PLATFORM_MIN,
                                MBEDTLS_ENTROPY_SOURCE_STRONG);
-#endif
-#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
-    mbedtls_entropy_add_source(ctx, mbedtls_hardware_poll, NULL,
-                               MBEDTLS_ENTROPY_MIN_HARDWARE,
-                               MBEDTLS_ENTROPY_SOURCE_STRONG);
-#endif
 #if defined(MBEDTLS_ENTROPY_NV_SEED)
     mbedtls_entropy_add_source(ctx, mbedtls_nv_seed_poll, NULL,
                                MBEDTLS_ENTROPY_BLOCK_SIZE,
@@ -494,7 +487,7 @@ static int entropy_dummy_source(void *data, unsigned char *output,
     return 0;
 }
 
-#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+#if defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
 
 static int mbedtls_entropy_source_self_test_gather(unsigned char *buf, size_t buf_len)
 {
@@ -504,8 +497,8 @@ static int mbedtls_entropy_source_self_test_gather(unsigned char *buf, size_t bu
     size_t attempts = buf_len;
 
     while (attempts > 0 && entropy_len < buf_len) {
-        if ((ret = mbedtls_hardware_poll(NULL, buf + entropy_len,
-                                         buf_len - entropy_len, &olen)) != 0) {
+        if ((ret = mbedtls_entropy_poll_platform(NULL, buf + entropy_len,
+                                                 buf_len - entropy_len, &olen)) != 0) {
             return ret;
         }
 
@@ -593,7 +586,7 @@ int mbedtls_entropy_source_self_test(int verbose)
     return ret != 0;
 }
 
-#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
+#endif /* MBEDTLS_PLATFORM_GET_ENTROPY_ALT */
 
 /*
  * The actual entropy quality is hard to test, but we can at least
@@ -654,7 +647,7 @@ int mbedtls_entropy_self_test(int verbose)
         }
     }
 
-#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+#if defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
     if ((ret = mbedtls_entropy_source_self_test(0)) != 0) {
         goto cleanup;
     }
diff --git a/drivers/builtin/src/entropy_poll.c b/drivers/builtin/src/entropy_poll.c
index bafb8d54cf..57ece4dd9c 100644
--- a/drivers/builtin/src/entropy_poll.c
+++ b/drivers/builtin/src/entropy_poll.c
@@ -5,200 +5,34 @@
  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  */
 
-#if defined(__linux__) || defined(__midipix__)
-/* Ensure that syscall() is available even when compiling with -std=c99 */
-#if !defined(_GNU_SOURCE)
-#define _GNU_SOURCE
-#endif
-#endif
-
 #include "common.h"
 
 #include <string.h>
 
 #if defined(MBEDTLS_ENTROPY_C)
 
+#include "mbedtls/platform.h"
 #include "mbedtls/entropy.h"
 #include "entropy_poll.h"
 #include "mbedtls/error_common.h"
 
-#include "mbedtls/platform.h"
-
-#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
-
-#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
-    !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
-    !defined(__HAIKU__) && !defined(__midipix__) && !defined(__MVS__)
-#error \
-    "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in mbedtls_config.h"
-#endif
-
-#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
-
-#include <windows.h>
-#include <bcrypt.h>
-#include <intsafe.h>
-
-int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len,
-                                  size_t *olen)
+int mbedtls_entropy_poll_platform(void *data, unsigned char *output, size_t len, size_t *olen)
 {
-    ((void) data);
-    *olen = 0;
-
-    /*
-     * BCryptGenRandom takes ULONG for size, which is smaller than size_t on
-     * 64-bit Windows platforms. Extract entropy in chunks of len (dependent
-     * on ULONG_MAX) size.
-     */
-    while (len != 0) {
-        unsigned long ulong_bytes =
-            (len > ULONG_MAX) ? ULONG_MAX : (unsigned long) len;
+    int ret;
+    size_t entropy_content = 0;
+    (void) data;
 
-        if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, ulong_bytes,
-                                            BCRYPT_USE_SYSTEM_PREFERRED_RNG))) {
-            return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
-        }
-
-        *olen += ulong_bytes;
-        len -= ulong_bytes;
+    ret = mbedtls_platform_get_entropy(output, len, olen, &entropy_content);
+    if (ret != 0) {
+        return ret;
     }
 
-    return 0;
-}
-#else /* _WIN32 && !EFIX64 && !EFI32 */
-
-/*
- * Test for Linux getrandom() support.
- * Since there is no wrapper in the libc yet, use the generic syscall wrapper
- * available in GNU libc and compatible libc's (eg uClibc).
- */
-#if ((defined(__linux__) && defined(__GLIBC__)) || defined(__midipix__))
-#include <unistd.h>
-#include <sys/syscall.h>
-#if defined(SYS_getrandom)
-#define HAVE_GETRANDOM
-#include <errno.h>
-
-static int getrandom_wrapper(void *buf, size_t buflen, unsigned int flags)
-{
-    /* MemSan cannot understand that the syscall writes to the buffer */
-#if defined(__has_feature)
-#if __has_feature(memory_sanitizer)
-    memset(buf, 0, buflen);
-#endif
-#endif
-    return (int) syscall(SYS_getrandom, buf, buflen, flags);
-}
-#endif /* SYS_getrandom */
-#endif /* __linux__ || __midipix__ */
-
-#if defined(__FreeBSD__) || defined(__DragonFly__)
-#include <sys/param.h>
-#if (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || \
-    (defined(__DragonFly__) && __DragonFly_version >= 500700)
-#include <errno.h>
-#include <sys/random.h>
-#define HAVE_GETRANDOM
-static int getrandom_wrapper(void *buf, size_t buflen, unsigned int flags)
-{
-    return (int) getrandom(buf, buflen, flags);
-}
-#endif /* (__FreeBSD__ && __FreeBSD_version >= 1200000) ||
-          (__DragonFly__ && __DragonFly_version >= 500700) */
-#endif /* __FreeBSD__ || __DragonFly__ */
-
-/*
- * Some BSD systems provide KERN_ARND.
- * This is equivalent to reading from /dev/urandom, only it doesn't require an
- * open file descriptor, and provides up to 256 bytes per call (basically the
- * same as getentropy(), but with a longer history).
- *
- * Documentation: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7
- */
-#if (defined(__FreeBSD__) || defined(__NetBSD__)) && !defined(HAVE_GETRANDOM)
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#if defined(KERN_ARND)
-#define HAVE_SYSCTL_ARND
-
-static int sysctl_arnd_wrapper(unsigned char *buf, size_t buflen)
-{
-    int name[2];
-    size_t len;
-
-    name[0] = CTL_KERN;
-    name[1] = KERN_ARND;
-
-    while (buflen > 0) {
-        len = buflen > 256 ? 256 : buflen;
-        if (sysctl(name, 2, buf, &len, NULL, 0) == -1) {
-            return -1;
-        }
-        buflen -= len;
-        buf += len;
-    }
-    return 0;
-}
-#endif /* KERN_ARND */
-#endif /* __FreeBSD__ || __NetBSD__ */
-
-#include <stdio.h>
-
-int mbedtls_platform_entropy_poll(void *data,
-                                  unsigned char *output, size_t len, size_t *olen)
-{
-    FILE *file;
-    size_t read_len;
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    ((void) data);
-
-#if defined(HAVE_GETRANDOM)
-    ret = getrandom_wrapper(output, len, 0);
-    if (ret >= 0) {
-        *olen = (size_t) ret;
-        return 0;
-    } else if (errno != ENOSYS) {
+    if (entropy_content < (8 * (*olen))) {
         return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
     }
-    /* Fall through if the system call isn't known. */
-#else
-    ((void) ret);
-#endif /* HAVE_GETRANDOM */
-
-#if defined(HAVE_SYSCTL_ARND)
-    ((void) file);
-    ((void) read_len);
-    if (sysctl_arnd_wrapper(output, len) == -1) {
-        return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
-    }
-    *olen = len;
-    return 0;
-#else
-
-    *olen = 0;
-
-    file = fopen("/dev/urandom", "rb");
-    if (file == NULL) {
-        return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
-    }
-
-    /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
-    mbedtls_setbuf(file, NULL);
-
-    read_len = fread(output, 1, len, file);
-    if (read_len != len) {
-        fclose(file);
-        return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
-    }
-
-    fclose(file);
-    *olen = len;
 
     return 0;
-#endif /* HAVE_SYSCTL_ARND */
 }
-#endif /* _WIN32 && !EFIX64 && !EFI32 */
-#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
 
 #if defined(MBEDTLS_ENTROPY_NV_SEED)
 int mbedtls_nv_seed_poll(void *data,
diff --git a/drivers/builtin/src/entropy_poll.h b/drivers/builtin/src/entropy_poll.h
index dd1ee2c0b3..5c0a353724 100644
--- a/drivers/builtin/src/entropy_poll.h
+++ b/drivers/builtin/src/entropy_poll.h
@@ -18,34 +18,22 @@
 extern "C" {
 #endif
 
-/*
- * Default thresholds for built-in sources, in bytes
- */
-#define MBEDTLS_ENTROPY_MIN_PLATFORM     32     /**< Minimum for platform source    */
-#if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE)
-#define MBEDTLS_ENTROPY_MIN_HARDWARE     32     /**< Minimum for the hardware source */
-#endif
-
-#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
-/**
- * \brief           Platform-specific entropy poll callback
- */
-int mbedtls_platform_entropy_poll(void *data,
-                                  unsigned char *output, size_t len, size_t *olen);
-#endif
+#define MBEDTLS_ENTROPY_POLL_PLATFORM_MIN        32
 
-#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
 /**
- * \brief           Entropy poll callback for a hardware source
- *
- * \warning         This is not provided by Mbed TLS!
- *                  See \c MBEDTLS_ENTROPY_HARDWARE_ALT in mbedtls_config.h.
+ * This function get called from the entropy module when it's gathering entropy
+ * data. Backends are:
+ * - On Windows, Linux or BSD systems there's no need to define
+ *   MBEDTLS_PLATFORM_GET_ENTROPY_ALT. In this case Mbed TLS uses platform-specific
+ *   sources such as getrandom(), /dev/urandom or BCryptGenRandom() to gather
+ *   entropy data.
+ * - on baremetal plaform instead define MBEDTLS_PLATFORM_GET_ENTROPY_ALT and
+ *   provide the custom implementation of mbedtls_platform_get_entropy().
+ *   See mbedtls/platform.h for the documentation of the function.
  *
- * \note            This must accept NULL as its first argument.
+ * \note The function must accept \p data == NULL.
  */
-int mbedtls_hardware_poll(void *data,
-                          unsigned char *output, size_t len, size_t *olen);
-#endif
+int mbedtls_entropy_poll_platform(void *data, unsigned char *output, size_t len, size_t *olen);
 
 #if defined(MBEDTLS_ENTROPY_NV_SEED)
 /**
diff --git a/drivers/builtin/src/platform.c b/drivers/builtin/src/platform.c
index c535e9e9da..d26de90023 100644
--- a/drivers/builtin/src/platform.c
+++ b/drivers/builtin/src/platform.c
@@ -399,4 +399,193 @@ void mbedtls_platform_teardown(mbedtls_platform_context *ctx)
 }
 #endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
 
+#if !defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
+
+#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
+    !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
+    !defined(__HAIKU__) && !defined(__midipix__) && !defined(__MVS__)
+#error \
+    "The default platform entropy sources only work on Unix and Windows. " \
+    "Please enable MBEDTLS_PLATFORM_GET_ENTROPY_ALT and implement " \
+    "mbedtls_platform_get_entropy()."
+#endif
+
+#include "mbedtls/entropy.h"
+
+#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
+
+#include <windows.h>
+#include <bcrypt.h>
+#include <intsafe.h>
+
+int mbedtls_platform_get_entropy(unsigned char *output, size_t output_size,
+                                 size_t *output_len, size_t *entropy_content)
+{
+    *output_len = 0;
+
+    /*
+     * BCryptGenRandom takes ULONG for size, which is smaller than size_t on
+     * 64-bit Windows platforms.
+     */
+    if (output_size > ULONG_MAX) {
+        return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+    }
+
+    if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, (unsigned long) output_size,
+                                        BCRYPT_USE_SYSTEM_PREFERRED_RNG))) {
+        return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+    }
+
+    *output_len = output_size;
+    *entropy_content = 8 * *output_len;
+
+    return 0;
+}
+#else /* _WIN32 && !EFIX64 && !EFI32 */
+
+#if defined(__linux__) || defined(__midipix__)
+/* Ensure that syscall() is available even when compiling with -std=c99 */
+#if !defined(_GNU_SOURCE)
+#define _GNU_SOURCE
+#endif
+#if !defined(__USE_MISC)
+#define __USE_MISC
+#endif
+#endif
+
+/*
+ * Test for Linux getrandom() support.
+ * Since there is no wrapper in the libc yet, use the generic syscall wrapper
+ * available in GNU libc and compatible libc's (eg uClibc).
+ */
+#if ((defined(__linux__) && defined(__GLIBC__)) || defined(__midipix__))
+#include <unistd.h>
+#include <sys/syscall.h>
+#if defined(SYS_getrandom)
+#define HAVE_GETRANDOM
+#include <errno.h>
+
+static int getrandom_wrapper(void *buf, size_t buflen, unsigned int flags)
+{
+    /* MemSan cannot understand that the syscall writes to the buffer */
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+    memset(buf, 0, buflen);
+#endif
+#endif
+    return (int) syscall(SYS_getrandom, buf, buflen, flags);
+}
+#endif /* SYS_getrandom */
+#endif /* __linux__ || __midipix__ */
+
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#include <sys/param.h>
+#if (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || \
+    (defined(__DragonFly__) && __DragonFly_version >= 500700)
+#include <errno.h>
+#include <sys/random.h>
+#define HAVE_GETRANDOM
+static int getrandom_wrapper(void *buf, size_t buflen, unsigned int flags)
+{
+    return (int) getrandom(buf, buflen, flags);
+}
+#endif /* (__FreeBSD__ && __FreeBSD_version >= 1200000) ||
+          (__DragonFly__ && __DragonFly_version >= 500700) */
+#endif /* __FreeBSD__ || __DragonFly__ */
+
+/*
+ * Some BSD systems provide KERN_ARND.
+ * This is equivalent to reading from /dev/urandom, only it doesn't require an
+ * open file descriptor, and provides up to 256 bytes per call (basically the
+ * same as getentropy(), but with a longer history).
+ *
+ * Documentation: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7
+ */
+#if (defined(__FreeBSD__) || defined(__NetBSD__)) && !defined(HAVE_GETRANDOM)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#if defined(KERN_ARND)
+#define HAVE_SYSCTL_ARND
+
+static int sysctl_arnd_wrapper(unsigned char *buf, size_t buflen)
+{
+    int name[2];
+    size_t len;
+
+    name[0] = CTL_KERN;
+    name[1] = KERN_ARND;
+
+    while (buflen > 0) {
+        len = buflen > 256 ? 256 : buflen;
+        if (sysctl(name, 2, buf, &len, NULL, 0) == -1) {
+            return -1;
+        }
+        buflen -= len;
+        buf += len;
+    }
+    return 0;
+}
+#endif /* KERN_ARND */
+#endif /* __FreeBSD__ || __NetBSD__ */
+
+#include <stdio.h>
+
+int mbedtls_platform_get_entropy(unsigned char *output, size_t output_size,
+                                 size_t *output_len, size_t *entropy_content)
+{
+    FILE *file;
+    size_t read_len;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+#if defined(HAVE_GETRANDOM)
+    ret = getrandom_wrapper(output, output_size, 0);
+    if (ret >= 0) {
+        *output_len = (size_t) ret;
+        *entropy_content = 8 * *output_len;
+        return 0;
+    } else if (errno != ENOSYS) {
+        return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+    }
+    /* Fall through if the system call isn't known. */
+#else
+    ((void) ret);
+#endif /* HAVE_GETRANDOM */
+
+#if defined(HAVE_SYSCTL_ARND)
+    ((void) file);
+    ((void) read_len);
+    if (sysctl_arnd_wrapper(output, output_size) == -1) {
+        return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+    }
+    *output_len = output_size;
+    *entropy_content = 8 * *output_len;
+    return 0;
+#else
+
+    *output_len = 0;
+
+    file = fopen("/dev/urandom", "rb");
+    if (file == NULL) {
+        return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+    }
+
+    /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
+    mbedtls_setbuf(file, NULL);
+
+    read_len = fread(output, 1, output_size, file);
+    if (read_len != output_size) {
+        fclose(file);
+        return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+    }
+
+    fclose(file);
+    *output_len = output_size;
+    *entropy_content = 8 * *output_len;
+
+    return 0;
+#endif /* HAVE_SYSCTL_ARND */
+}
+#endif /* _WIN32 && !EFIX64 && !EFI32 */
+#endif /* !MBEDTLS_PLATFORM_GET_ENTROPY_ALT */
+
 #endif /* MBEDTLS_PLATFORM_C */
diff --git a/framework b/framework
index 1e7b5d54d3..1a83e0c84d 160000
--- a/framework
+++ b/framework
@@ -1 +1 @@
-Subproject commit 1e7b5d54d3823b65fd4755bcf60f9ca39cfcbca3
+Subproject commit 1a83e0c84d4b7aa11c7cfd3771322486fc87d281
diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h
index 50e4866670..01a2146ded 100644
--- a/include/psa/crypto_config.h
+++ b/include/psa/crypto_config.h
@@ -1057,18 +1057,17 @@
 //#define MBEDTLS_ENTROPY_FORCE_SHA256
 
 /**
- * \def MBEDTLS_ENTROPY_HARDWARE_ALT
+ * \def MBEDTLS_PLATFORM_GET_ENTROPY_ALT
  *
- * Uncomment this macro to let Mbed TLS use your own implementation of a
- * hardware entropy collector.
- *
- * Your function must be called \c mbedtls_hardware_poll(), have the same
- * prototype as declared in library/entropy_poll.h, and accept NULL as first
- * argument.
- *
- * Uncomment to use your own hardware entropy collector.
+ * By default TF-PSA-Crypto uses platform-specific sources such as `getrandom()`,
+ * `/dev/urandom` or `BCryptGenRandom()` to gather entropy data. If these
+ * functions are not available on your platform, the following symbol allows
+ * you to define a custom callback function named mbedtls_platform_get_entropy()
+ * that Mbed TLS will use to gather entropy data.
+ * The public header mbedtls/platform.h provides the prototype for this
+ * callback function and also the documentation for its parameters.
  */
-//#define MBEDTLS_ENTROPY_HARDWARE_ALT
+//#define MBEDTLS_PLATFORM_GET_ENTROPY_ALT
 
 /**
  * \def MBEDTLS_ENTROPY_NV_SEED
@@ -1110,17 +1109,6 @@
  */
 //#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
 
-/**
- * \def MBEDTLS_NO_PLATFORM_ENTROPY
- *
- * Do not use built-in platform entropy functions.
- * This is useful if your platform does not support
- * standards like the /dev/urandom or Windows CryptoAPI.
- *
- * Uncomment this macro to disable the built-in platform entropy functions.
- */
-//#define MBEDTLS_NO_PLATFORM_ENTROPY
-
 /**
  * \def MBEDTLS_PSA_CRYPTO_C
  *
@@ -1325,7 +1313,6 @@
 /* Entropy options */
 //#define MBEDTLS_ENTROPY_MAX_GATHER                128 /**< Maximum amount requested from entropy sources */
 //#define MBEDTLS_ENTROPY_MAX_SOURCES                20 /**< Maximum number of sources supported */
-//#define MBEDTLS_ENTROPY_MIN_HARDWARE               32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */
 
 /**
  * \def MBEDTLS_PSA_CRYPTO_PLATFORM_FILE
diff --git a/scripts/config.py b/scripts/config.py
index f86cf83244..6d12ec9588 100755
--- a/scripts/config.py
+++ b/scripts/config.py
@@ -56,7 +56,6 @@
     'MBEDTLS_MEMORY_DEBUG', # depends on MEMORY_BUFFER_ALLOC_C
     'MBEDTLS_NO_64BIT_MULTIPLICATION', # influences anything that uses bignum
     'MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES', # removes a feature
-    'MBEDTLS_NO_PLATFORM_ENTROPY', # removes a feature
     'MBEDTLS_NO_UDBL_DIVISION', # influences anything that uses bignum
     'MBEDTLS_PSA_P256M_DRIVER_ENABLED', # influences SECP256R1 KeyGen/ECDH/ECDSA
     'MBEDTLS_PLATFORM_NO_STD_FUNCTIONS', # removes a feature
@@ -109,6 +108,7 @@ def is_seamless_alt(name):
     an implementation of the relevant functions and an xxx_alt.h header.
     """
     if name in (
+            'MBEDTLS_PLATFORM_GET_ENTROPY_ALT',
             'MBEDTLS_PLATFORM_GMTIME_R_ALT',
             'MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT',
             'MBEDTLS_PLATFORM_MS_TIME_ALT',
diff --git a/tests/configs/crypto_config_test_driver.h b/tests/configs/crypto_config_test_driver.h
index 2e75b787c8..e9bf562ba4 100644
--- a/tests/configs/crypto_config_test_driver.h
+++ b/tests/configs/crypto_config_test_driver.h
@@ -21,6 +21,7 @@
 #define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1
 #define MBEDTLS_CTR_DRBG_C
 #define MBEDTLS_ENTROPY_C
+#define MBEDTLS_PLATFORM_C
 #define MBEDTLS_ENTROPY_FORCE_SHA256
 
 /*
diff --git a/tests/scripts/components-configuration-platform.sh b/tests/scripts/components-configuration-platform.sh
index 3e2399dced..330513fa60 100644
--- a/tests/scripts/components-configuration-platform.sh
+++ b/tests/scripts/components-configuration-platform.sh
@@ -22,6 +22,22 @@ component_tf_psa_crypto_build_no_std_function () {
     make
 }
 
+component_tf_psa_crypto_test_platform_get_entropy_alt()
+{
+    msg "build: default config + MBEDTLS_PLATFORM_GET_ENTROPY_ALT"
+    # Use hardware polling as the only source for entropy
+    scripts/config.py set MBEDTLS_PLATFORM_GET_ENTROPY_ALT
+    scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED
+
+    cd $OUT_OF_SOURCE_DIR
+    cmake -DCMAKE_C_COMPILER=gcc "$TF_PSA_CRYPTO_ROOT_DIR"
+    make
+
+    # Run all the tests
+    msg "test: default config + MBEDTLS_PLATFORM_GET_ENTROPY_ALT"
+    make test
+}
+
 component_tf_psa_crypto_test_no_date_time () {
     msg "build: default config without MBEDTLS_HAVE_TIME_DATE"
     scripts/config.py unset MBEDTLS_HAVE_TIME_DATE
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 37ed61ac51..4ac4c829b6 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -50,12 +50,9 @@
 /*----------------------------------------------------------------------------*/
 /* Helper flags for complex dependencies */
 
-/* Indicates whether we expect mbedtls_entropy_init
- * to initialize some strong entropy source. */
-#if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) && \
-    (!defined(MBEDTLS_NO_PLATFORM_ENTROPY) ||       \
-    defined(MBEDTLS_ENTROPY_HARDWARE_ALT) ||        \
-    defined(ENTROPY_NV_SEED))
+/* Indicates whether we expect mbedtls_entropy_init to initialize some strong
+ * entropy source. */
+#if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
 #define ENTROPY_HAVE_STRONG
 #endif
 
diff --git a/tests/suites/test_suite_entropy.data b/tests/suites/test_suite_entropy.data
index 514fced49e..b653833d8f 100644
--- a/tests/suites/test_suite_entropy.data
+++ b/tests/suites/test_suite_entropy.data
@@ -84,3 +84,6 @@ entropy_nv_seed:"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
 
 Entropy self test
 entropy_selftest:0
+
+Test platform_get_entropy
+entropy_test_platform_get_entropy_alt:
diff --git a/tests/suites/test_suite_entropy.function b/tests/suites/test_suite_entropy.function
index 885fb8f2ef..42f79648bd 100644
--- a/tests/suites/test_suite_entropy.function
+++ b/tests/suites/test_suite_entropy.function
@@ -3,6 +3,12 @@
 #include "entropy_poll.h"
 #include "mbedtls/md.h"
 #include "string.h"
+#include "test/fake_external_rng_for_test.h"
+
+#define TEST_PLATFORM_GET_ENTROPY_DATA_LENGTH_PER_CALL       8
+#define TEST_PLATFORM_GET_ENTROPY_EXP_CALL_COUNT                            \
+    (MAX(MBEDTLS_ENTROPY_BLOCK_SIZE, MBEDTLS_ENTROPY_POLL_PLATFORM_MIN) /    \
+     TEST_PLATFORM_GET_ENTROPY_DATA_LENGTH_PER_CALL)
 
 typedef enum {
     DUMMY_CONSTANT_LENGTH, /* Output context->length bytes */
@@ -565,3 +571,45 @@ exit:
     MD_PSA_DONE();
 }
 /* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_PLATFORM_C:MBEDTLS_PLATFORM_GET_ENTROPY_ALT */
+void entropy_test_platform_get_entropy_alt(void)
+{
+    mbedtls_entropy_context ctx;
+    uint8_t data[MBEDTLS_ENTROPY_POLL_PLATFORM_MIN];
+    size_t olen, call_count;
+
+    /* Simple callback test -> all fine. */
+    TEST_ASSERT(mbedtls_entropy_poll_platform(NULL, data, sizeof(data), &olen) == 0);
+    TEST_LE_U(1, olen);
+    TEST_LE_U(olen, sizeof(data));
+
+    mbedtls_test_platform_get_entropy_reset();
+
+    /* Force a failure -> return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED. */
+    mbedtls_test_platform_get_entropy_set_force_failure(1);
+    TEST_ASSERT(mbedtls_entropy_poll_platform(NULL, data, sizeof(data), &olen) ==
+                MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
+
+    mbedtls_test_platform_get_entropy_reset();
+
+    /* Return less entropy than expected -> entropy gathering fails */
+    mbedtls_test_platform_get_entropy_set_entropy_content(8 * (sizeof(data) - 1));
+    TEST_ASSERT(mbedtls_entropy_poll_platform(NULL, data, sizeof(data), &olen) ==
+                MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
+
+    mbedtls_test_platform_get_entropy_reset();
+
+    /* Return less data than required -> callback will be called more than once. */
+    mbedtls_entropy_init(&ctx);
+    mbedtls_test_platform_get_entropy_set_output_len(
+        TEST_PLATFORM_GET_ENTROPY_DATA_LENGTH_PER_CALL);
+    TEST_ASSERT(mbedtls_entropy_func(&ctx, data, sizeof(data)) == 0);
+    mbedtls_entropy_free(&ctx);
+    call_count = mbedtls_test_platform_get_entropy_get_call_count();
+    TEST_EQUAL(call_count, TEST_PLATFORM_GET_ENTROPY_EXP_CALL_COUNT);
+
+exit:
+    mbedtls_test_platform_get_entropy_reset();
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_psa_crypto_init.data b/tests/suites/test_suite_psa_crypto_init.data
index b66189379a..49f8059e3c 100644
--- a/tests/suites/test_suite_psa_crypto_init.data
+++ b/tests/suites/test_suite_psa_crypto_init.data
@@ -57,7 +57,7 @@ Fake entropy: two blocks eventually
 fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:0:MBEDTLS_ENTROPY_BLOCK_SIZE:0:MBEDTLS_ENTROPY_BLOCK_SIZE:PSA_SUCCESS
 
 NV seed only: less than minimum
-entropy_from_nv_seed:MBEDTLS_ENTROPY_MIN_PLATFORM - 1:PSA_ERROR_INSUFFICIENT_ENTROPY
+entropy_from_nv_seed:MBEDTLS_ENTROPY_POLL_PLATFORM_MIN - 1:PSA_ERROR_INSUFFICIENT_ENTROPY
 
 NV seed only: less than one block
 entropy_from_nv_seed:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:PSA_ERROR_INSUFFICIENT_ENTROPY
diff --git a/tests/suites/test_suite_psa_crypto_init.function b/tests/suites/test_suite_psa_crypto_init.function
index 954560a24e..9f69dddcd4 100644
--- a/tests/suites/test_suite_psa_crypto_init.function
+++ b/tests/suites/test_suite_psa_crypto_init.function
@@ -26,7 +26,7 @@ exit:
 }
 
 #define ENTROPY_MIN_NV_SEED_SIZE                                        \
-    MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)
+    MAX(MBEDTLS_ENTROPY_POLL_PLATFORM_MIN, MBEDTLS_ENTROPY_BLOCK_SIZE)
 
 #include "psa_crypto_random_impl.h"
 #if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
@@ -94,20 +94,11 @@ static void custom_entropy_init(mbedtls_entropy_context *ctx)
     ctx->accumulator_started = 0;
     mbedtls_md_init(&ctx->accumulator);
 
-#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
-    if (custom_entropy_sources_mask & ENTROPY_SOURCE_PLATFORM) {
-        mbedtls_entropy_add_source(ctx, mbedtls_platform_entropy_poll, NULL,
-                                   MBEDTLS_ENTROPY_MIN_PLATFORM,
-                                   MBEDTLS_ENTROPY_SOURCE_STRONG);
-    }
-#endif
-#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
     if (custom_entropy_sources_mask & ENTROPY_SOURCE_HARDWARE) {
-        mbedtls_entropy_add_source(ctx, mbedtls_hardware_poll, NULL,
-                                   MBEDTLS_ENTROPY_MIN_HARDWARE,
+        mbedtls_entropy_add_source(ctx, mbedtls_entropy_poll_platform, NULL,
+                                   MBEDTLS_ENTROPY_POLL_PLATFORM_MIN,
                                    MBEDTLS_ENTROPY_SOURCE_STRONG);
     }
-#endif
 #if defined(MBEDTLS_ENTROPY_NV_SEED)
     if (custom_entropy_sources_mask & ENTROPY_SOURCE_NV_SEED) {
         mbedtls_entropy_add_source(ctx, mbedtls_nv_seed_poll, NULL,


Reviews:
user: login: gilles-peskine-arm
body: I just did a design review. I won't be able to do a full code review.

We just realized this morning that the issue description wasn't very clear, and several things were in Janos's mind and mine but we hadn't written them down. Sorry about this. I added a note to the issue and some comments here, hopefully that should clarify things.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T13:37:33Z
user: login: valeriosetti
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T12:46:25Z
user: login: bjwtaylor
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T14:26:34Z
user: login: gabor-mezei-arm
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T12:24:54Z
user: login: bjwtaylor
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-04T14:04:12Z
user: login: gabor-mezei-arm
body: LGTM
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T08:56:52Z
user: login: bjwtaylor
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T07:44:07Z
user: login: gilles-peskine-arm
body: * Sorry for the late notice but I think we should make a slight design change and have the new function replace, rather than add to, the default platform entropy. (And if we don't then the new name doesn't fit.)
* The documentation is unclear in places.
* This doesn't resolve https://github.com/Mbed-TLS/mbedtls/issues/9618: it's missing tests and part of the documentation (migration guide). Those can be done in follow-ups, but we need to keep track of the work that's left.

[reviewed 0b4ca69b6387c85993a93db1764a8ad88d64f57a]
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-11T18:00:24Z
user: login: valeriosetti
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T11:38:39Z
user: login: valeriosetti
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T12:13:57Z
user: login: gilles-peskine-arm
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T15:24:48Z
user: login: gilles-peskine-arm
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T15:25:44Z
user: login: gilles-peskine-arm
body: Mostly looks good to me now, apart from some of the documentation.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-17T16:13:03Z
user: login: valeriosetti
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-18T09:16:57Z
user: login: gilles-peskine-arm
body: I'd like more changes to the documentation, especially the migration guide.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T16:38:12Z
user: login: valeriosetti
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-24T10:43:07Z
user: login: bjwtaylor
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-24T13:38:27Z
user: login: gilles-peskine-arm
body: I have more comments in the migration guide. The rest looks good to me, except that reviewing the migration guide has made me revisit a couple of places in the documentation and test coverage.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-24T15:48:26Z
user: login: gilles-peskine-arm
body: Thanks for the updates, looks good to me now except for one little thing I missed earlier.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T15:34:45Z
user: login: gilles-peskine-arm
body: LGTM
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T16:17:35Z
user: login: bjwtaylor
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-29T06:34:13Z
user: login: gilles-peskine-arm
body: LGTM
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-05-05T17:24:59Z
user: login: gilles-peskine-arm
body: LGTM at 1294fd2c30a7c88504aa32f09326d44b3baf317c. The CI is still unhappy but that's expected: we are breaking TF-PSA-Crypto, and https://github.com/Mbed-TLS/mbedtls/pull/10090 will fix it.
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T07:45:49Z
user: login: gilles-peskine-arm
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T14:40:34Z
user: login: gilles-peskine-arm
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T14:50:49Z
user: login: bjwtaylor
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:14:01Z

Review comments:
diff_hunk: @@ -446,6 +446,32 @@ mbedtls_platform_context;
 #include "platform_alt.h"
 #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
 
+#if !defined(MBEDTLS_ENTROPY_HARDWARE_POLL_MIN)
+#define MBEDTLS_ENTROPY_HARDWARE_POLL_MIN     32     /**< Minimum for the hardware source */
+#endif
+
+#if defined(MBEDTLS_ENTROPY_HARDWARE_POLL)
+/**
+ * \brief           User defined callback function that is used from the entropy
+ *                  module to gather entropy data from some hardware device.
+ *
+ * \warning         This is not provided by Mbed TLS.
+ *
+ * \param[out] output           Output buffer where the entropy data will be
+ *                              stored.
+ * \param[in] output_size       Size of the \p output buffer in bytes.
+ * \param[out] output_len       Amount of bytes effectively written in the
+ *                              \p output buffer.
+ * \param[out] entropy_content  Measure of the entropy content (in bits) of the
+ *                              data written in the \p output buffer. The pointer
+ *                              can be \c NULL in case the caller is not interested
+ *                              in such information, so the function must handle
+ *                              this.
+ */
+int mbedtls_entropy_hardware_poll(unsigned char *output, size_t output_size,
path: drivers/builtin/include/mbedtls/platform.h
user: login: gilles-peskine-arm
body: Non-blocker: since the function is now declared in `platform.h`, should we call it `mbedtls_platform_xxx`? Same question about the configuration option. Maybe `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` and `mbedtls_platform_get_entropy()`?
created_at: 2025-03-19T13:13:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -446,6 +446,32 @@ mbedtls_platform_context;
 #include "platform_alt.h"
 #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
 
+#if !defined(MBEDTLS_ENTROPY_HARDWARE_POLL_MIN)
+#define MBEDTLS_ENTROPY_HARDWARE_POLL_MIN     32     /**< Minimum for the hardware source */
+#endif
+
+#if defined(MBEDTLS_ENTROPY_HARDWARE_POLL)
+/**
+ * \brief           User defined callback function that is used from the entropy
+ *                  module to gather entropy data from some hardware device.
+ *
+ * \warning         This is not provided by Mbed TLS.
+ *
+ * \param[out] output           Output buffer where the entropy data will be
+ *                              stored.
+ * \param[in] output_size       Size of the \p output buffer in bytes.
+ * \param[out] output_len       Amount of bytes effectively written in the
+ *                              \p output buffer.
+ * \param[out] entropy_content  Measure of the entropy content (in bits) of the
+ *                              data written in the \p output buffer. The pointer
path: drivers/builtin/include/mbedtls/platform.h
user: login: gilles-peskine-arm
body: Please add the constraint that for the time being, the function must set `entropy_content = 8 * *output_len` on success. The library will be extended later to support partial entropy.
created_at: 2025-03-19T13:15:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -446,6 +446,32 @@ mbedtls_platform_context;
 #include "platform_alt.h"
 #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
 
+#if !defined(MBEDTLS_ENTROPY_HARDWARE_POLL_MIN)
+#define MBEDTLS_ENTROPY_HARDWARE_POLL_MIN     32     /**< Minimum for the hardware source */
+#endif
+
+#if defined(MBEDTLS_ENTROPY_HARDWARE_POLL)
+/**
+ * \brief           User defined callback function that is used from the entropy
+ *                  module to gather entropy data from some hardware device.
+ *
+ * \warning         This is not provided by Mbed TLS.
+ *
+ * \param[out] output           Output buffer where the entropy data will be
+ *                              stored.
+ * \param[in] output_size       Size of the \p output buffer in bytes.
+ * \param[out] output_len       Amount of bytes effectively written in the
+ *                              \p output buffer.
+ * \param[out] entropy_content  Measure of the entropy content (in bits) of the
+ *                              data written in the \p output buffer. The pointer
+ *                              can be \c NULL in case the caller is not interested
+ *                              in such information, so the function must handle
+ *                              this.
path: drivers/builtin/include/mbedtls/platform.h
user: login: gilles-peskine-arm
body: We don't need to support callers that don't want the value. `entropy_content` is guaranteed to be non-null.
created_at: 2025-03-19T13:16:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -446,6 +446,32 @@ mbedtls_platform_context;
 #include "platform_alt.h"
 #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
 
+#if !defined(MBEDTLS_ENTROPY_HARDWARE_POLL_MIN)
+#define MBEDTLS_ENTROPY_HARDWARE_POLL_MIN     32     /**< Minimum for the hardware source */
+#endif
+
+#if defined(MBEDTLS_ENTROPY_HARDWARE_POLL)
+/**
+ * \brief           User defined callback function that is used from the entropy
+ *                  module to gather entropy data from some hardware device.
+ *
+ * \warning         This is not provided by Mbed TLS.
path: drivers/builtin/include/mbedtls/platform.h
user: login: gilles-peskine-arm
body: I don't think “not provided by Mbed TLS” is a useful warning. Also, it's TF-PSA-Crypto now.

On the other hand, the function's documentation should state that this function is only used when `MBEDTLS_ENTROPY_HARDWARE_POLL` is defined. This is otherwise not visible when you read the Doxygen-rendered documentation.
created_at: 2025-03-19T13:23:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,12 @@
+Removals
+   * Previously deprecated build symbol `MBEDTLS_ENTROPY_HARDWARE_ALT` is
+     removed.
+
+Features
+   * The new symbol `MBEDTLS_ENTROPY_HARDWARE_POLL` is added to allow the
+     defintion of a custom callback function which allows to gather entropy
+     data from some hardware device.
+     `MBEDTLS_ENTROPY_HARDWARE_POLL_MIN` can optionally optinally define the
+     minimum number of bytes that should be polled using that function before
+     declaring entropy gathering completed. If not defined, then a default
+     value of 32 bytes is used.
path: ChangeLog.d/9618.txt
user: login: gilles-peskine-arm
body: `MBEDTLS_ENTROPY_HARDWARE_POLL_MIN` should not be a configuration parameter, at least not in this form. The RNG needs a certain amount of entropy. This minimum is up to the system configuration (and in particular the required cryptographic strength for the system), not up to the hardware integration. The person writing the TRNG device driver doesn't get to choose this value.

I think we should just use the existing `MBEDTLS_ENTROPY_MIN_PLATFORM` here. The distinction between “platform source” and “hardware source” doesn't really make sense as it's currently described in `entropy_poll.h`. Actually the “platform source” is the operating system integrations that the library supports out of the box, and the “hardware source” is the one for other systems where the integrator needs to provide a driver.
created_at: 2025-03-19T13:26:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,12 @@
+Removals
+   * Previously deprecated build symbol `MBEDTLS_ENTROPY_HARDWARE_ALT` is
+     removed.
+
+Features
+   * The new symbol `MBEDTLS_ENTROPY_HARDWARE_POLL` is added to allow the
path: ChangeLog.d/9618.txt
user: login: gilles-peskine-arm
body: The changelog entries should probably mention the function names as well as the option names, for easier searching.
created_at: 2025-03-19T13:28:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -57,6 +41,21 @@ int mbedtls_nv_seed_poll(void *data,
                          unsigned char *output, size_t len, size_t *olen);
 #endif
 
+/* Wrapper to allow mbedtls_entropy_hardware_poll() to be used from entropy module
+ * as other entropy polling functions (i.e. mbedtls_platform_entropy_poll and
+ * mbedtls_nv_seed_poll). */
+#if defined(MBEDTLS_ENTROPY_HARDWARE_POLL)
+
+#include <mbedtls/platform.h>
+
+static inline int mbedtls_entropy_hardware_poll_wrapper(
+        void *data, unsigned char *output, size_t len, size_t *olen)
+{
+    (void) data;
+    return mbedtls_entropy_hardware_poll(output, len, olen, NULL);
path: drivers/builtin/src/entropy_poll.h
user: login: gilles-peskine-arm
body: The wrapper should check the entropy content and fail if it's less than full entropy, i.e. if `entropy_output < 8 * *olen`. Please add a unit test for that in `test_suite_entropy`.

Also the entropy collection should fail if `*olen` is too small and as a result there isn't enough entropy, collected from all sources. I believe this is covered by the existing tests in `test_suite_entropy`, but please double-check.
created_at: 2025-03-19T13:35:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -57,6 +41,21 @@ int mbedtls_nv_seed_poll(void *data,
                          unsigned char *output, size_t len, size_t *olen);
 #endif
 
+/* Wrapper to allow mbedtls_entropy_hardware_poll() to be used from entropy module
+ * as other entropy polling functions (i.e. mbedtls_platform_entropy_poll and
+ * mbedtls_nv_seed_poll). */
+#if defined(MBEDTLS_ENTROPY_HARDWARE_POLL)
+
+#include <mbedtls/platform.h>
+
+static inline int mbedtls_entropy_hardware_poll_wrapper(
+        void *data, unsigned char *output, size_t len, size_t *olen)
+{
+    (void) data;
+    return mbedtls_entropy_hardware_poll(output, len, olen, NULL);
path: drivers/builtin/src/entropy_poll.h
user: login: valeriosetti
body: >The wrapper should check the entropy content and fail if it's less than full entropy, i.e. if entropy_output < 8 * *olen. Please add a unit test for that in test_suite_entropy.

While adding the check on the wrapper and testing it with the new component `tf_psa_crypto_platform_get_entropy_alt` I found that tests are already failing if the returned entropy content is not correct, so there seems to be no need for a new test step. As reference implementation I'm using the one proposed in the companion PR https://github.com/Mbed-TLS/mbedtls-framework/pull/151.

created_at: 2025-03-24T12:46:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -57,6 +41,35 @@ int mbedtls_nv_seed_poll(void *data,
                          unsigned char *output, size_t len, size_t *olen);
 #endif
 
+/* Wrapper to allow mbedtls_platform_get_entropy_alt() to be used from entropy
+ * module as other entropy polling functions (i.e. mbedtls_platform_entropy_poll
+ * and mbedtls_nv_seed_poll). */
+#if defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
+
+#include <mbedtls/platform.h>
+
+#define MBEDTLS_ENTROPY_MIN_HARDWARE            32
+
+static inline int mbedtls_hardware_poll(void *data, unsigned char *output,
path: drivers/builtin/src/entropy_poll.h
user: login: gilles-peskine-arm
body: Why is this an inline function in a header file? It's only called inside `entropy.c`, so why not define it there and make it `MBEDTLS_STATIC_TESTABLE`?
created_at: 2025-04-11T17:30:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,9 @@
+Removals
+   * Previously deprecated build symbol `MBEDTLS_ENTROPY_HARDWARE_ALT` is
+     removed.
+
+Features
+   * The new symbol `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` is added to allow the
path: ChangeLog.d/9618.txt
user: login: gilles-peskine-arm
body: `XXX_ALT` normally allows users to override a built-in feature. But here the function comes in addition to the built-in feature: to replace the built-in feature, you also need to enable `MBEDTLS_NO_PLATFORM_ENTROPY`.

The original design called for leaving `MBEDTLS_NO_PLATFORM_ENTROPY` alone. But come to think of it, we only really care about two use cases at this point: either the default platform entropy works, or it gets replaced. While there might be rare scenarios where both are useful, that can wait until we implement the full RNG driver interface.

There's also the case of having neither the default platform entropy source nor the alternative one, but that is controlled by `MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES` (which will need to change since users no longer have access to entropy objects, but that's a separate matter, to be handled in https://github.com/Mbed-TLS/TF-PSA-Crypto/pull/145).

So I propose to remove `MBEDTLS_NO_PLATFORM_ENTROPY` from `crypto_config.h`, i.e. not make it a configurable symbol anymore, and instead make it an equivalent for `!defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)` in `config_adjust_legacy_crypto.h`. And of course adjust the documentation accordingly. We'll simplify the implementation later.

If we don't do that then we should rename the new function and option. But I do think we should take this opportunity to remove one more little piece of legacy.

created_at: 2025-04-11T17:39:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,9 @@
+Removals
+   * Previously deprecated build symbol `MBEDTLS_ENTROPY_HARDWARE_ALT` is
+     removed.
path: ChangeLog.d/9618.txt
user: login: gilles-peskine-arm
body: Changelog entries for removals should give the name of what to use instead.
created_at: 2025-04-11T17:40:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -446,6 +446,32 @@ mbedtls_platform_context;
 #include "platform_alt.h"
 #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
 
+#if defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
+/**
+ * \brief       User defined callback function that is used from the entropy
+ *              module to gather entropy data from some hardware device.
+ *              The function's prototype is only available when
+ *              `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` is defined.
+ *
+ * \param[out] output           Output buffer where the entropy data will be
+ *                              stored.
+ * \param[in] output_size       Size of the \p output buffer in bytes.
+ * \param[out] output_len       Amount of bytes effectively written in the
+ *                              \p output buffer.
+ * \param[out] entropy_content  Measure of the entropy content (in bits) of the
+ *                              data written in the \p output buffer.
+ *
path: drivers/builtin/include/mbedtls/platform.h
user: login: gilles-peskine-arm
body: Please document the possible return values: 0 for success, `MBEDTLS_ERR_ENTROPY_SOURCE_FAILED` or some other negative value on error.
created_at: 2025-04-11T17:43:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -446,6 +446,32 @@ mbedtls_platform_context;
 #include "platform_alt.h"
 #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
 
+#if defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
+/**
+ * \brief       User defined callback function that is used from the entropy
+ *              module to gather entropy data from some hardware device.
+ *              The function's prototype is only available when
+ *              `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` is defined.
+ *
+ * \param[out] output           Output buffer where the entropy data will be
+ *                              stored.
+ * \param[in] output_size       Size of the \p output buffer in bytes.
+ * \param[out] output_len       Amount of bytes effectively written in the
+ *                              \p output buffer.
+ * \param[out] entropy_content  Measure of the entropy content (in bits) of the
+ *                              data written in the \p output buffer.
+ *
+ * \warning     For the time being TF-PSA-Crypto assumes that the function provides
path: drivers/builtin/include/mbedtls/platform.h
user: login: gilles-peskine-arm
body: I don't find the warning clear as to what happens if `entropy_content` is too small. “TF-PSA-Crypto assumes” — so what happens if the assumption is wrong?
created_at: 2025-04-11T17:43:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -654,7 +654,7 @@ int mbedtls_entropy_self_test(int verbose)
         }
     }
 
-#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+#if defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
     if ((ret = mbedtls_entropy_source_self_test(0)) != 0) {
         goto cleanup;
     }
path: drivers/builtin/src/entropy.c
user: login: gilles-peskine-arm
body: Missing: tests. I'd expect `test_suite_entropy` to have at least a test for when `mbedtls_platform_get_entropy_alt` returns an error code, and one for when it returns less entropy than expected.
created_at: 2025-04-11T17:50:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,9 @@
+Removals
+   * Previously deprecated build symbol `MBEDTLS_ENTROPY_HARDWARE_ALT` is
+     removed.
+
+Features
+   * The new symbol `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` is added to allow the
+     defintion of a custom callback function named
+     `mbedtls_platform_get_entropy_alt()` which allows to gather entropy
path: ChangeLog.d/9618.txt
user: login: gilles-peskine-arm
body: Minor: changelog entries are plain text, not markdown, so no backticks.
created_at: 2025-04-11T17:55:29Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,9 @@
+Removals
+   * Previously deprecated build symbol `MBEDTLS_ENTROPY_HARDWARE_ALT` is
+     removed.
+
+Features
+   * The new symbol `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` is added to allow the
+     defintion of a custom callback function named
+     `mbedtls_platform_get_entropy_alt()` which allows to gather entropy
+     data from some hardware device.
path: ChangeLog.d/9618.txt
user: login: gilles-peskine-arm
body: The hardware device is commonly called a “true hardware random generator” (TRNG). (”True“ is not a good name, but it is commonly used.) This is the term that users will look for, so the changelog entry should mention it.

Suggested wording:

> To supply a platform-specific entropy source, define the compilation option MBEDTLS_PLATFORM_GET_ENTROPY_ALT and provide the callback function mbedtls_platform_get_entropy_alt(). This function should typically access a TRNG ("true hardware random generator") device on bare-metal platforms, or call an operating system function to obtain cryptographic-quality random data.

created_at: 2025-04-11T17:57:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -57,6 +41,35 @@ int mbedtls_nv_seed_poll(void *data,
                          unsigned char *output, size_t len, size_t *olen);
 #endif
 
+/* Wrapper to allow mbedtls_platform_get_entropy_alt() to be used from entropy
+ * module as other entropy polling functions (i.e. mbedtls_platform_entropy_poll
+ * and mbedtls_nv_seed_poll). */
+#if defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
+
+#include <mbedtls/platform.h>
+
+#define MBEDTLS_ENTROPY_MIN_HARDWARE            32
+
+static inline int mbedtls_hardware_poll(void *data, unsigned char *output,
path: drivers/builtin/src/entropy_poll.h
user: login: valeriosetti
body: Actually this function is also called from `test_suite_psa_crypto_init.function` in `custom_entropy_init()` function.  If we want to remove the `inline` part, I can move the implementation to `entropy.c` and keep only the definition here. How does this sound?
created_at: 2025-04-14T11:38:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,9 @@
+Removals
+   * Previously deprecated build symbol `MBEDTLS_ENTROPY_HARDWARE_ALT` is
+     removed.
+
+Features
+   * The new symbol `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` is added to allow the
path: ChangeLog.d/9618.txt
user: login: valeriosetti
body: IIUC we would like to have `mbedtls_platform_entropy_poll()` and `mbedtls_hardware_poll()` mutually exclusive, right?
If so, do you think it would make sense to rename `mbedtls_platform_entropy_poll()` to `mbedtls_hardware_poll()` so that we can have a single function prototype with different implementations depending on `MBEDTLS_PLATFORM_GET_ENTROPY_ALT`?
created_at: 2025-04-14T12:13:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,9 @@
+Removals
+   * Previously deprecated build symbol `MBEDTLS_ENTROPY_HARDWARE_ALT` is
+     removed.
+
+Features
+   * The new symbol `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` is added to allow the
path: ChangeLog.d/9618.txt
user: login: gilles-peskine-arm
body: Yes, merging the two functions would probably make sense, though with a name that matches the compilation option.
created_at: 2025-04-14T15:24:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -57,6 +41,35 @@ int mbedtls_nv_seed_poll(void *data,
                          unsigned char *output, size_t len, size_t *olen);
 #endif
 
+/* Wrapper to allow mbedtls_platform_get_entropy_alt() to be used from entropy
+ * module as other entropy polling functions (i.e. mbedtls_platform_entropy_poll
+ * and mbedtls_nv_seed_poll). */
+#if defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
+
+#include <mbedtls/platform.h>
+
+#define MBEDTLS_ENTROPY_MIN_HARDWARE            32
+
+static inline int mbedtls_hardware_poll(void *data, unsigned char *output,
path: drivers/builtin/src/entropy_poll.h
user: login: gilles-peskine-arm
body: `MBEDTLS_STATIC_TESTABLE` lets you call a function from the tests as long as the tests are guarded by `MBEDTLS_TEST_HOOKS`.
created_at: 2025-04-14T15:25:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,9 +1,12 @@
 Removals
path: ChangeLog.d/9618.txt
user: login: gilles-peskine-arm
body: Please add an entry for the removal of `MBEDTLS_NO_PLATFORM_ENTROPY` (or combine the two?).
created_at: 2025-04-17T13:26:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1059,9 +1059,12 @@
 /**
  * \def MBEDTLS_PLATFORM_GET_ENTROPY_ALT
  *
- * Uncomment this to let Mbed TLS call your custom hardware polling function
- * when it's gathering entropy data.
- * Public header `mbedtls/platform.h` provides the prototype for the callback
+ * By default Mbed TLS uses standard platform sources (/dev/urandom on Linux
+ * and CryptoAPI on Windows) to gather entropy data. If these functions are
path: include/psa/crypto_config.h
user: login: gilles-peskine-arm
body: This is not quite accurate: Mbed TLS uses `getrandom` on Linux and BSD if it can. We don't have to be fully precise here (and we definitely don't want to commit to exactly how `getrandom` is detected, or not to change as we adapt to new OS versions). Suggested wording:

> By default Mbed TLS uses platform-specific sources such as `getrandom()`, `/dev/urandom` or `BCryptGenRandom()` to gather entropy data.

created_at: 2025-04-17T14:26:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1059,9 +1059,12 @@
 /**
  * \def MBEDTLS_PLATFORM_GET_ENTROPY_ALT
  *
- * Uncomment this to let Mbed TLS call your custom hardware polling function
- * when it's gathering entropy data.
- * Public header `mbedtls/platform.h` provides the prototype for the callback
+ * By default Mbed TLS uses standard platform sources (/dev/urandom on Linux
+ * and CryptoAPI on Windows) to gather entropy data. If these functions are
+ * not available for some reason (ex: working on a baremetal project), the
+ * following symbol allows the user to define a custom callback function that
path: include/psa/crypto_config.h
user: login: gilles-peskine-arm
body: Please give the name of the callback function, so that Doxygen will format it with a link to the function's documentation.
created_at: 2025-04-17T14:26:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -399,4 +399,192 @@ void mbedtls_platform_teardown(mbedtls_platform_context *ctx)
 }
 #endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
 
+#if !defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
+
+#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
+    !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
+    !defined(__HAIKU__) && !defined(__midipix__) && !defined(__MVS__)
+#error \
+    "Platform entropy sources only work on Unix and Windows"
path: drivers/builtin/src/platform.c
user: login: gilles-peskine-arm
body: The message isn't quite right now, since `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` allows a custom platform entropy source.
```suggestion
    "The default platform entropy sources only work on Unix and Windows. " \
    "Please enable MBEDTLS_PLATFORM_GET_ENTROPY_ALT and implement " \
    "mbedtls_platform_get_entropy()."
```
created_at: 2025-04-17T14:30:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,12 @@
+Removals
path: ChangeLog.d/9618.txt
user: login: gilles-peskine-arm
body: Please add an entry for the removal of `MBEDTLS_ENTROPY_MIN_HARDWARE`.

Note: I'm not sure whether this value should be configurable, or should be unified with some other configuration option. The set of configuration we need to keep for algorithms and thresholds involved in going from an entropy source to a random generator is still an open question in the 1.0 design (https://github.com/Mbed-TLS/TF-PSA-Crypto/blob/79d10321efd0c50ccad9bf37f0223c295cdfa1ba/docs/architecture/0e-plans.md#evolution-of-rng-options in https://github.com/Mbed-TLS/TF-PSA-Crypto/pull/145). In the meantime, I'm fine with either keeping or removing `MBEDTLS_ENTROPY_MIN_HARDWARE`, but I'd like the documentation to be consistent, including the changelog.

created_at: 2025-04-17T14:47:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -190,6 +190,14 @@ struct tm *mbedtls_platform_gmtime_r(const mbedtls_time_t *tt,
                                      struct tm *tm_buf);
 #endif /* MBEDTLS_HAVE_TIME_DATE */
 
+#if !defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
+/* This is the private defintion of mbedtls_platform_get_entropy(). The full
+ * documentation is at drivers/builtin/include/mbedtls/platform.h. */
path: drivers/builtin/include/mbedtls/platform_util.h
user: login: gilles-peskine-arm
body: I don't understand how this is a “private definition”. `mbedtls/platform_util.h` is a public header, just as `mbedtls/platform.h`. (We will make it apparent which headers are public in https://github.com/Mbed-TLS/TF-PSA-Crypto/issues/223.) Why not have a single unconditional declaration?
created_at: 2025-04-17T15:56:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -18,19 +18,22 @@
 extern "C" {
 #endif
 
-#if defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
+#define MBEDTLS_ENTROPY_POLL_PLATFORM_MIN        32
 
-#define MBEDTLS_ENTROPY_MIN_HARDWARE        32
-
-int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen);
-
-#else /* MBEDTLS_PLATFORM_GET_ENTROPY_ALT */
-
-#define MBEDTLS_ENTROPY_MIN_PLATFORM        32
-
-int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len, size_t *olen);
-
-#endif /* MBEDTLS_PLATFORM_GET_ENTROPY_ALT */
+/**
+ * This function get called from the entropy module when it's gathering entropy
+ * data. Backends are:
+ * - on Windows: no need to define MBEDTLS_PLATFORM_GET_ENTROPY_ALT and
+ *              CryptoAPI will be used.
+ * - on Linux: no need to define MBEDTLS_PLATFORM_GET_ENTROPY_ALT and
+ *              /dev/urandom will be used.
path: drivers/builtin/src/entropy_poll.h
user: login: gilles-peskine-arm
body: As in the public documentation: not just `/dev/urandom`, but also `getrandom` and variants are preferred. And this is not just on Linux but also some Linux-like systems and most BSD variants.
created_at: 2025-04-17T16:00:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -190,6 +190,14 @@ struct tm *mbedtls_platform_gmtime_r(const mbedtls_time_t *tt,
                                      struct tm *tm_buf);
 #endif /* MBEDTLS_HAVE_TIME_DATE */
 
+#if !defined(MBEDTLS_PLATFORM_GET_ENTROPY_ALT)
+/* This is the private defintion of mbedtls_platform_get_entropy(). The full
+ * documentation is at drivers/builtin/include/mbedtls/platform.h. */
path: drivers/builtin/include/mbedtls/platform_util.h
user: login: valeriosetti
body: Yeah, the idea was to look for an header file which was only accessible to the library and not to the user in order to hide the prototype of `mbedtls_platform_get_entropy()` when `!MBEDTLS_PLATFORM_GET_ENTROPY_ALT`. Of course after looking around a bit, I fooled myself and I erroneously put that in another public header file. Sorry.
Thinking about it having a single definition in `platform.h` is not that bad. The worst that can happen is that the user has `!MBEDTLS_PLATFORM_GET_ENTROPY_ALT` and they still provide the implementation for `mbedtls_platform_get_entropy()`, but I guess that in this case the compiler will complain about the fact that the same function is implemented twice. So as long as there's a build failure somehow I'm fine :)
created_at: 2025-04-18T09:16:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -410,34 +410,37 @@ void mbedtls_platform_teardown(mbedtls_platform_context *ctx)
     "mbedtls_platform_get_entropy()."
 #endif
 
+#include "mbedtls/entropy.h"
+
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 
 #include <windows.h>
 #include <bcrypt.h>
 #include <intsafe.h>
 
-int mbedtls_platform_get_entropy(void *data, unsigned char *output, size_t len, size_t *olen)
+int mbedtls_platform_get_entropy(unsigned char *output, size_t output_size,
+                                 size_t *output_len, size_t *entropy_content)
 {
-    ((void) data);
-    *olen = 0;
+    *output_len = 0;
 
     /*
      * BCryptGenRandom takes ULONG for size, which is smaller than size_t on
      * 64-bit Windows platforms. Extract entropy in chunks of len (dependent
      * on ULONG_MAX) size.
      */
-    while (len != 0) {
+    while (output_size != 0) {
path: drivers/builtin/src/platform.c
user: login: gilles-peskine-arm
body: Non-blocker: since this is now an internal function, `output_size` always comes from our library code, and we can assume that it has a “reasonable” size — tens of bytes, definitely less than `ULONG_MAX` which is 2^32. So the loop is no longer needed (just error out if `output_size` is out of sensible range).
created_at: 2025-04-23T16:15:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+## Platform-specific Entropy Gathering
+
+### Disclaimer
+
+All the following sections refer to the case where entropy module uses default
+entropy sources, i.e. `MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES` is not defined.
+
+### Background
+
+Up to Mbed TLS 3.6 entropy module supported 3 entropy sources by default:
+
+- Platform
+  - Enabled by default it could be disabled through `MBEDTLS_NO_PLATFORM_ENTROPY`.
+  - It used platform-specific sources such as getrandom(), /dev/urandom or
+    BCryptGenRandom() to gather entropy data.
+  - Only useful when running on high level OSes, not in baremetal projects.
+
+- Hardware
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_HARDWARE_ALT`.
+  - It allowed the user to define a custom function named `mbedtls_hardware_poll()`
+    to gather entropy data from some hardware source.
+  - Very useful for baremetal projects.
+  - Unfortunately the prototype for the function was in a private header file.
+
+- NV seed
path: docs/4.0-migration-guide/platform-entropy-gathering.md
user: login: gilles-peskine-arm
body: The NV seed part hasn't changed. It would be useful to mention it in passing, but the document should not suggest that it has changed or that it has been removed.
created_at: 2025-04-23T16:17:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+## Platform-specific Entropy Gathering
+
+### Disclaimer
+
+All the following sections refer to the case where entropy module uses default
+entropy sources, i.e. `MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES` is not defined.
+
+### Background
path: docs/4.0-migration-guide/platform-entropy-gathering.md
user: login: gilles-peskine-arm
body: I think there's too much detail about what was there before. It's useful to have some explanations, because some readers will be programmers who have to upgrade some part of the application that was written by a long-gone colleague and that they don't understand. But we don't need to explain everything about the old API, especially the parts that haven't changed (e.g. the platform sources are exactly the same as before, what's changed is how you say whether you want to use them).
created_at: 2025-04-23T16:20:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+## Platform-specific Entropy Gathering
+
+### Disclaimer
+
+All the following sections refer to the case where entropy module uses default
+entropy sources, i.e. `MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES` is not defined.
+
+### Background
+
+Up to Mbed TLS 3.6 entropy module supported 3 entropy sources by default:
+
+- Platform
+  - Enabled by default it could be disabled through `MBEDTLS_NO_PLATFORM_ENTROPY`.
+  - It used platform-specific sources such as getrandom(), /dev/urandom or
+    BCryptGenRandom() to gather entropy data.
+  - Only useful when running on high level OSes, not in baremetal projects.
+
+- Hardware
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_HARDWARE_ALT`.
+  - It allowed the user to define a custom function named `mbedtls_hardware_poll()`
+    to gather entropy data from some hardware source.
+  - Very useful for baremetal projects.
+  - Unfortunately the prototype for the function was in a private header file.
+
+- NV seed
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_NV_SEED`.
+  - It allowed the user to store an entropy seed on a non-volatile (NV) memory
+    (ex: filesystem).
+  - This is crucial on systems that do not have a cryptographic entropy source
+    available through the previous 2 options.
+
+Up to Mbed TLS 3.6 all these 3 build symbols could be enabled independently.
+
+### Reasons to change
path: docs/4.0-migration-guide/platform-entropy-gathering.md
user: login: gilles-peskine-arm
body: I don't think a detailed list of reasons is useful in the migration guide. That belongs in an architecture document. The migration guide is a practical document for programmers using the library.
created_at: 2025-04-23T16:21:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+## Platform-specific Entropy Gathering
+
+### Disclaimer
+
+All the following sections refer to the case where entropy module uses default
+entropy sources, i.e. `MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES` is not defined.
+
+### Background
+
+Up to Mbed TLS 3.6 entropy module supported 3 entropy sources by default:
+
+- Platform
+  - Enabled by default it could be disabled through `MBEDTLS_NO_PLATFORM_ENTROPY`.
+  - It used platform-specific sources such as getrandom(), /dev/urandom or
+    BCryptGenRandom() to gather entropy data.
+  - Only useful when running on high level OSes, not in baremetal projects.
+
+- Hardware
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_HARDWARE_ALT`.
+  - It allowed the user to define a custom function named `mbedtls_hardware_poll()`
+    to gather entropy data from some hardware source.
+  - Very useful for baremetal projects.
+  - Unfortunately the prototype for the function was in a private header file.
+
+- NV seed
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_NV_SEED`.
+  - It allowed the user to store an entropy seed on a non-volatile (NV) memory
+    (ex: filesystem).
+  - This is crucial on systems that do not have a cryptographic entropy source
+    available through the previous 2 options.
+
+Up to Mbed TLS 3.6 all these 3 build symbols could be enabled independently.
+
+### Reasons to change
+
+Platform and Hardware entropy sources are most of the times mutually exclusive,
+so that the user will either use one or the other, but it's very unlikely to
+enable both. Therefore it's better to unify them under a single build symbol
+and to use a gathering function with the same name. Moreover this function must
+have the prototype in some public header so that the user can easily integrate
+it in their source code.
+
+### What changes in TF-PSA-Crypto 1.0?
+
+The following build symbols are removed:
+
+- `MBEDTLS_ENTROPY_HARDWARE_ALT`,
+- `MBEDTLS_ENTROPY_MIN_HARDWARE`,
+- `MBEDTLS_NO_PLATFORM_ENTROPY`.
+
+By default entropy module uses Platform entropy source to gather entropy data.
path: docs/4.0-migration-guide/platform-entropy-gathering.md
user: login: gilles-peskine-arm
body: We need to be careful with “by default”: for some users, it means with the default config file, but for other users, it means if you don't define any configuration symbol (empty config file). So we should clarify, e.g. by writing “In the default configuration, the entropy module …”.
created_at: 2025-04-23T16:22:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+## Platform-specific Entropy Gathering
+
+### Disclaimer
+
+All the following sections refer to the case where entropy module uses default
+entropy sources, i.e. `MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES` is not defined.
+
+### Background
+
+Up to Mbed TLS 3.6 entropy module supported 3 entropy sources by default:
+
+- Platform
+  - Enabled by default it could be disabled through `MBEDTLS_NO_PLATFORM_ENTROPY`.
+  - It used platform-specific sources such as getrandom(), /dev/urandom or
+    BCryptGenRandom() to gather entropy data.
+  - Only useful when running on high level OSes, not in baremetal projects.
+
+- Hardware
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_HARDWARE_ALT`.
+  - It allowed the user to define a custom function named `mbedtls_hardware_poll()`
+    to gather entropy data from some hardware source.
+  - Very useful for baremetal projects.
+  - Unfortunately the prototype for the function was in a private header file.
+
+- NV seed
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_NV_SEED`.
+  - It allowed the user to store an entropy seed on a non-volatile (NV) memory
+    (ex: filesystem).
+  - This is crucial on systems that do not have a cryptographic entropy source
+    available through the previous 2 options.
+
+Up to Mbed TLS 3.6 all these 3 build symbols could be enabled independently.
+
+### Reasons to change
+
+Platform and Hardware entropy sources are most of the times mutually exclusive,
+so that the user will either use one or the other, but it's very unlikely to
+enable both. Therefore it's better to unify them under a single build symbol
+and to use a gathering function with the same name. Moreover this function must
+have the prototype in some public header so that the user can easily integrate
+it in their source code.
+
+### What changes in TF-PSA-Crypto 1.0?
+
+The following build symbols are removed:
+
+- `MBEDTLS_ENTROPY_HARDWARE_ALT`,
+- `MBEDTLS_ENTROPY_MIN_HARDWARE`,
+- `MBEDTLS_NO_PLATFORM_ENTROPY`.
+
+By default entropy module uses Platform entropy source to gather entropy data.
+However the user can enable `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` to define their
+own custom implementation of the entropy gathering function and this will
+exclude the Platform one (alternate implementation).
+The prototype of this function can be found in `mbedtls/platform.h` and it's as
path: docs/4.0-migration-guide/platform-entropy-gathering.md
user: login: gilles-peskine-arm
body: This is describe a whole new feature, but that's not what is happening and that's not the goal of the migration guide. The target reader already has code that implements the old `mbedtls_hardware_poll`. So what we should explain here is, if you had an application that enabled `MBEDTLS_ENTROPY_HARDWARE_ALT`, how to change an implementation of `mbedtls_hardware_poll` into an implementation of `mbedtls_platform_get_entropy`.
created_at: 2025-04-23T16:25:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,16 @@
+Removals
+   * MBEDTLS_NO_PLATFORM_ENTROPY and previously deprecated
+     MBEDTLS_ENTROPY_HARDWARE_ALT are removed. See documentation of
+     MBEDTLS_PLATFORM_GET_ENTROPY_ALT for a description on how entropy module
+     gathers entropy data.
path: ChangeLog.d/9618.txt
user: login: gilles-peskine-arm
body: Minor: “and **the** previously deprecated”, “See **the** documentation”, “how **the** entropy module”...
created_at: 2025-04-23T16:27:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+## Platform-specific Entropy Gathering
+
+### Disclaimer
+
+All the following sections refer to the case where entropy module uses default
+entropy sources, i.e. `MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES` is not defined.
+
+### Background
+
+Up to Mbed TLS 3.6 entropy module supported 3 entropy sources by default:
+
+- Platform
+  - Enabled by default it could be disabled through `MBEDTLS_NO_PLATFORM_ENTROPY`.
+  - It used platform-specific sources such as getrandom(), /dev/urandom or
+    BCryptGenRandom() to gather entropy data.
+  - Only useful when running on high level OSes, not in baremetal projects.
+
+- Hardware
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_HARDWARE_ALT`.
+  - It allowed the user to define a custom function named `mbedtls_hardware_poll()`
+    to gather entropy data from some hardware source.
+  - Very useful for baremetal projects.
+  - Unfortunately the prototype for the function was in a private header file.
+
+- NV seed
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_NV_SEED`.
+  - It allowed the user to store an entropy seed on a non-volatile (NV) memory
+    (ex: filesystem).
+  - This is crucial on systems that do not have a cryptographic entropy source
+    available through the previous 2 options.
+
+Up to Mbed TLS 3.6 all these 3 build symbols could be enabled independently.
+
+### Reasons to change
+
+Platform and Hardware entropy sources are most of the times mutually exclusive,
+so that the user will either use one or the other, but it's very unlikely to
+enable both. Therefore it's better to unify them under a single build symbol
+and to use a gathering function with the same name. Moreover this function must
+have the prototype in some public header so that the user can easily integrate
+it in their source code.
+
+### What changes in TF-PSA-Crypto 1.0?
+
+The following build symbols are removed:
+
+- `MBEDTLS_ENTROPY_HARDWARE_ALT`,
+- `MBEDTLS_ENTROPY_MIN_HARDWARE`,
+- `MBEDTLS_NO_PLATFORM_ENTROPY`.
+
+By default entropy module uses Platform entropy source to gather entropy data.
+However the user can enable `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` to define their
+own custom implementation of the entropy gathering function and this will
+exclude the Platform one (alternate implementation).
+The prototype of this function can be found in `mbedtls/platform.h` and it's as
+follows:
+
+```c
+int mbedtls_platform_get_entropy(void *data, unsigned char *output, size_t len, size_t *olen);
path: docs/4.0-migration-guide/platform-entropy-gathering.md
user: login: gilles-peskine-arm
body: The prototype is wrong (in fact it lists the arguments for the old `mbedtls_hardware_poll`).
created_at: 2025-04-23T16:30:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+## Platform-specific Entropy Gathering
+
+### Disclaimer
+
+All the following sections refer to the case where entropy module uses default
+entropy sources, i.e. `MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES` is not defined.
+
+### Background
+
+Up to Mbed TLS 3.6 entropy module supported 3 entropy sources by default:
+
+- Platform
+  - Enabled by default it could be disabled through `MBEDTLS_NO_PLATFORM_ENTROPY`.
+  - It used platform-specific sources such as getrandom(), /dev/urandom or
+    BCryptGenRandom() to gather entropy data.
+  - Only useful when running on high level OSes, not in baremetal projects.
+
+- Hardware
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_HARDWARE_ALT`.
+  - It allowed the user to define a custom function named `mbedtls_hardware_poll()`
+    to gather entropy data from some hardware source.
+  - Very useful for baremetal projects.
+  - Unfortunately the prototype for the function was in a private header file.
+
+- NV seed
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_NV_SEED`.
+  - It allowed the user to store an entropy seed on a non-volatile (NV) memory
+    (ex: filesystem).
+  - This is crucial on systems that do not have a cryptographic entropy source
+    available through the previous 2 options.
+
+Up to Mbed TLS 3.6 all these 3 build symbols could be enabled independently.
+
+### Reasons to change
+
+Platform and Hardware entropy sources are most of the times mutually exclusive,
+so that the user will either use one or the other, but it's very unlikely to
+enable both. Therefore it's better to unify them under a single build symbol
+and to use a gathering function with the same name. Moreover this function must
+have the prototype in some public header so that the user can easily integrate
+it in their source code.
+
+### What changes in TF-PSA-Crypto 1.0?
+
+The following build symbols are removed:
+
+- `MBEDTLS_ENTROPY_HARDWARE_ALT`,
+- `MBEDTLS_ENTROPY_MIN_HARDWARE`,
+- `MBEDTLS_NO_PLATFORM_ENTROPY`.
+
+By default entropy module uses Platform entropy source to gather entropy data.
+However the user can enable `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` to define their
+own custom implementation of the entropy gathering function and this will
+exclude the Platform one (alternate implementation).
+The prototype of this function can be found in `mbedtls/platform.h` and it's as
+follows:
+
+```c
+int mbedtls_platform_get_entropy(void *data, unsigned char *output, size_t len, size_t *olen);
+```
+
+See documentation of this function for futher details about input parameters and
path: docs/4.0-migration-guide/platform-entropy-gathering.md
user: login: gilles-peskine-arm
body: There's no need to go into detail, but the migration guide does need to explain the new parameter `entropy_content`. It's likely to be a bit mysterious to many readers.
created_at: 2025-04-23T16:31:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1057,18 +1057,17 @@
 //#define MBEDTLS_ENTROPY_FORCE_SHA256
 
 /**
- * \def MBEDTLS_ENTROPY_HARDWARE_ALT
+ * \def MBEDTLS_PLATFORM_GET_ENTROPY_ALT
  *
- * Uncomment this macro to let Mbed TLS use your own implementation of a
- * hardware entropy collector.
- *
- * Your function must be called \c mbedtls_hardware_poll(), have the same
- * prototype as declared in library/entropy_poll.h, and accept NULL as first
- * argument.
- *
- * Uncomment to use your own hardware entropy collector.
+ * By default Mbed TLS uses platform-specific sources such as getrandom(),
+ * /dev/urandom or BCryptGenRandom() to gather entropy data. If these functions
+ * are not available for some reason (ex: working on a baremetal project), the
+ * following symbol allows the user to define a custom callback function named
+ * `mbedtls_platform_get_entropy()` that Mbed TLS will use to gather entropy
path: include/psa/crypto_config.h
user: login: gilles-peskine-arm
body: To make the function name into a link:
```suggestion
 * mbedtls_platform_get_entropy() that Mbed TLS will use to gather entropy
```
created_at: 2025-04-23T16:32:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1057,18 +1057,17 @@
 //#define MBEDTLS_ENTROPY_FORCE_SHA256
 
 /**
- * \def MBEDTLS_ENTROPY_HARDWARE_ALT
+ * \def MBEDTLS_PLATFORM_GET_ENTROPY_ALT
  *
- * Uncomment this macro to let Mbed TLS use your own implementation of a
- * hardware entropy collector.
- *
- * Your function must be called \c mbedtls_hardware_poll(), have the same
- * prototype as declared in library/entropy_poll.h, and accept NULL as first
- * argument.
- *
- * Uncomment to use your own hardware entropy collector.
+ * By default Mbed TLS uses platform-specific sources such as getrandom(),
+ * /dev/urandom or BCryptGenRandom() to gather entropy data. If these functions
+ * are not available for some reason (ex: working on a baremetal project), the
+ * following symbol allows the user to define a custom callback function named
+ * `mbedtls_platform_get_entropy()` that Mbed TLS will use to gather entropy
+ * data. Public header `mbedtls/platform.h` provides the prototype for this
path: include/psa/crypto_config.h
user: login: gilles-peskine-arm
body: To make the header name into a link:
```suggestion
 * data. The public header mbedtls/platform.h provides the prototype for this
```
created_at: 2025-04-23T16:32:42Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1057,18 +1057,17 @@
 //#define MBEDTLS_ENTROPY_FORCE_SHA256
 
 /**
- * \def MBEDTLS_ENTROPY_HARDWARE_ALT
+ * \def MBEDTLS_PLATFORM_GET_ENTROPY_ALT
  *
- * Uncomment this macro to let Mbed TLS use your own implementation of a
- * hardware entropy collector.
- *
- * Your function must be called \c mbedtls_hardware_poll(), have the same
- * prototype as declared in library/entropy_poll.h, and accept NULL as first
- * argument.
- *
- * Uncomment to use your own hardware entropy collector.
+ * By default Mbed TLS uses platform-specific sources such as getrandom(),
+ * /dev/urandom or BCryptGenRandom() to gather entropy data. If these functions
path: include/psa/crypto_config.h
user: login: gilles-peskine-arm
body: Minor:
```suggestion
 * By default Mbed TLS uses platform-specific sources such as `getrandom()`,
 * `/dev/urandom` or `BCryptGenRandom()` to gather entropy data. If these functions
```
created_at: 2025-04-23T16:33:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1057,18 +1057,17 @@
 //#define MBEDTLS_ENTROPY_FORCE_SHA256
 
 /**
- * \def MBEDTLS_ENTROPY_HARDWARE_ALT
+ * \def MBEDTLS_PLATFORM_GET_ENTROPY_ALT
  *
- * Uncomment this macro to let Mbed TLS use your own implementation of a
- * hardware entropy collector.
- *
- * Your function must be called \c mbedtls_hardware_poll(), have the same
- * prototype as declared in library/entropy_poll.h, and accept NULL as first
- * argument.
- *
- * Uncomment to use your own hardware entropy collector.
+ * By default Mbed TLS uses platform-specific sources such as getrandom(),
+ * /dev/urandom or BCryptGenRandom() to gather entropy data. If these functions
+ * are not available for some reason (ex: working on a baremetal project), the
path: include/psa/crypto_config.h
user: login: gilles-peskine-arm
body: “for some reason” seems weird to me. We know the reason.
```suggestion
 * the library does not provide an implementation for your platform, the
```
created_at: 2025-04-23T16:34:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1057,18 +1057,17 @@
 //#define MBEDTLS_ENTROPY_FORCE_SHA256
 
 /**
- * \def MBEDTLS_ENTROPY_HARDWARE_ALT
+ * \def MBEDTLS_PLATFORM_GET_ENTROPY_ALT
  *
- * Uncomment this macro to let Mbed TLS use your own implementation of a
- * hardware entropy collector.
- *
- * Your function must be called \c mbedtls_hardware_poll(), have the same
- * prototype as declared in library/entropy_poll.h, and accept NULL as first
- * argument.
- *
- * Uncomment to use your own hardware entropy collector.
+ * By default Mbed TLS uses platform-specific sources such as getrandom(),
path: include/psa/crypto_config.h
user: login: gilles-peskine-arm
body: The product name is now TF-PSA-Crypto, not Mbed TLS.

(We'll probably make a pass to change those near release time anyway.)
created_at: 2025-04-23T16:35:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+## Platform-specific Entropy Gathering
+
+### Disclaimer
+
+All the following sections refer to the case where entropy module uses default
+entropy sources, i.e. `MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES` is not defined.
+
+### Background
+
+Up to Mbed TLS 3.6 entropy module supported 3 entropy sources by default:
+
+- Platform
+  - Enabled by default it could be disabled through `MBEDTLS_NO_PLATFORM_ENTROPY`.
+  - It used platform-specific sources such as getrandom(), /dev/urandom or
+    BCryptGenRandom() to gather entropy data.
+  - Only useful when running on high level OSes, not in baremetal projects.
+
+- Hardware
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_HARDWARE_ALT`.
+  - It allowed the user to define a custom function named `mbedtls_hardware_poll()`
+    to gather entropy data from some hardware source.
+  - Very useful for baremetal projects.
+  - Unfortunately the prototype for the function was in a private header file.
+
+- NV seed
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_NV_SEED`.
+  - It allowed the user to store an entropy seed on a non-volatile (NV) memory
+    (ex: filesystem).
+  - This is crucial on systems that do not have a cryptographic entropy source
+    available through the previous 2 options.
+
+Up to Mbed TLS 3.6 all these 3 build symbols could be enabled independently.
+
+### Reasons to change
+
+Platform and Hardware entropy sources are most of the times mutually exclusive,
+so that the user will either use one or the other, but it's very unlikely to
+enable both. Therefore it's better to unify them under a single build symbol
+and to use a gathering function with the same name. Moreover this function must
+have the prototype in some public header so that the user can easily integrate
+it in their source code.
+
+### What changes in TF-PSA-Crypto 1.0?
+
+The following build symbols are removed:
+
+- `MBEDTLS_ENTROPY_HARDWARE_ALT`,
+- `MBEDTLS_ENTROPY_MIN_HARDWARE`,
+- `MBEDTLS_NO_PLATFORM_ENTROPY`.
+
+By default entropy module uses Platform entropy source to gather entropy data.
+However the user can enable `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` to define their
+own custom implementation of the entropy gathering function and this will
+exclude the Platform one (alternate implementation).
+The prototype of this function can be found in `mbedtls/platform.h` and it's as
+follows:
+
+```c
+int mbedtls_platform_get_entropy(void *data, unsigned char *output, size_t len, size_t *olen);
+```
+
+See documentation of this function for futher details about input parameters and
path: docs/4.0-migration-guide/platform-entropy-gathering.md
user: login: gilles-peskine-arm
body: There's no need to go into detail, but the migration guide does need to explain the new parameter `entropy_content`. It's likely to be a bit mysterious to many readers.
created_at: 2025-04-23T16:36:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+## Platform-specific Entropy Gathering
+
+### Disclaimer
+
+All the following sections refer to the case where entropy module uses default
+entropy sources, i.e. `MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES` is not defined.
+
+### Background
+
+Up to Mbed TLS 3.6 entropy module supported 3 entropy sources by default:
+
+- Platform
+  - Enabled by default it could be disabled through `MBEDTLS_NO_PLATFORM_ENTROPY`.
+  - It used platform-specific sources such as getrandom(), /dev/urandom or
+    BCryptGenRandom() to gather entropy data.
+  - Only useful when running on high level OSes, not in baremetal projects.
+
+- Hardware
+  - Disabled by default, it could be enabled through `MBEDTLS_ENTROPY_HARDWARE_ALT`.
+  - It allowed the user to define a custom function named `mbedtls_hardware_poll()`
+    to gather entropy data from some hardware source.
+  - Very useful for baremetal projects.
+  - Unfortunately the prototype for the function was in a private header file.
+
+- NV seed
path: docs/4.0-migration-guide/platform-entropy-gathering.md
user: login: valeriosetti
body: That's part for the "Background" section indeed where I was trying to give the user an overview of the situation before my changes. I will add a note to clearly state that nothing has changed for NV seed
created_at: 2025-04-24T10:43:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,35 @@
+## Platform-specific Entropy Gathering
+
+`MBEDTLS_ENTROPY_HARDWARE_ALT` has been renamed to `MBEDTLS_PLATFORM_GET_ENTROPY_ALT`.
+The prototype for the custom defined hardware entropy polling function changed
+from:
+
+```c
+int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len,
+                          size_t *olen);
+```
+
+to:
+
+```c
+int mbedtls_platform_get_entropy(unsigned char *output, size_t output_size,
+                                 size_t *output_len, size_t *entropy_content);
+```
+
+This new prototype is placed in the public header `mbedtls/platform.h` instead
+of the private `library/entropy_poll.h` one as it was previously.
+
path: docs/4.0-migration-guide/platform-entropy-gathering.md
user: login: gilles-peskine-arm
body: Some readers may wonder about the `data` parameter, so I think we should mention it briefly. Suggestion:

The `data` parameter was previously always `NULL`, and has been removed.

created_at: 2025-04-24T14:53:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,35 @@
+## Platform-specific Entropy Gathering
+
+`MBEDTLS_ENTROPY_HARDWARE_ALT` has been renamed to `MBEDTLS_PLATFORM_GET_ENTROPY_ALT`.
+The prototype for the custom defined hardware entropy polling function changed
path: docs/4.0-migration-guide/platform-entropy-gathering.md
user: login: gilles-peskine-arm
body: Calling it a “callback” (as we do elsewhere) may help some readers. On the other hand, I think not all the words in “custom defined hardware entropy polling” are useful. How about
```suggestion
The prototype for the custom entropy callback function changed
```
created_at: 2025-04-24T14:54:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -446,6 +446,37 @@ mbedtls_platform_context;
 #include "platform_alt.h"
 #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
 
+/**
+ * \brief       User defined callback function that is used from the entropy
+ *              module to gather entropy data from some hardware device.
+ *              The function's prototype is only available when
+ *              `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` is defined.
path: drivers/builtin/include/mbedtls/platform.h
user: login: gilles-peskine-arm
body: This is no longer true.
created_at: 2025-04-24T14:55:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -446,6 +446,37 @@ mbedtls_platform_context;
 #include "platform_alt.h"
 #endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
 
+/**
+ * \brief       User defined callback function that is used from the entropy
+ *              module to gather entropy data from some hardware device.
+ *              The function's prototype is only available when
+ *              `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` is defined.
+ *
path: drivers/builtin/include/mbedtls/platform.h
user: login: gilles-peskine-arm
body: Please add a paragraph stating that `mbedtls_platform_get_entropy` is not meant to be called by application code, and it is not guaranteed that this function will exist or will behave in the same way in future versions of the library. Applications should call `psa_generate_random()` to obtain random data.

(When we implement PSA random drivers, we'll likely no longer have a function by this name except when `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` is defined.)

created_at: 2025-04-24T14:57:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,35 @@
+## Platform-specific Entropy Gathering
+
+`MBEDTLS_ENTROPY_HARDWARE_ALT` has been renamed to `MBEDTLS_PLATFORM_GET_ENTROPY_ALT`.
+The prototype for the custom defined hardware entropy polling function changed
+from:
+
+```c
+int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len,
+                          size_t *olen);
+```
+
+to:
+
+```c
+int mbedtls_platform_get_entropy(unsigned char *output, size_t output_size,
+                                 size_t *output_len, size_t *entropy_content);
+```
+
+This new prototype is placed in the public header `mbedtls/platform.h` instead
+of the private `library/entropy_poll.h` one as it was previously.
+
+The new `entropy_content` parameter measures (in bit) the amount of entropy
+contained in the returned `output` buffer. For the time being only full entropy
+sources are allowed (i.e. `entropy_content = 8 * *output_len`), but this can
+change in the future.
path: docs/4.0-migration-guide/platform-entropy-gathering.md
user: login: gilles-peskine-arm
body: For many readers, “full entropy” is a fuzzy concept at best. So we should attempt to explain it. Here's my proposal.

For the time being, TF-PSA-Crypto only supports callbacks that provide full entropy. That means that the content of the output buffer must be uniformly random, allowing you to report that `entropy_content = 8 * *output_len`. Typically `*output_len == output_size`, but if it is smaller, the library will call the callback again in a loop.

If you implement this callback for hardware that delivers partial entropy, a typical technique is to gather enough entropy then hash the result. Hashing does not increase the entropy, but it distributes it throughout the buffer. For example, suppose your hardware has a 32-bit register which is documented as having a single bit of entropy each time it is read after calling a priming function. The following code snippet collects 8 bits of entropy and outputs it in one byte.

```
int mbedtls_platform_get_entropy(unsigned char *output, size_t output_size,
                                 size_t *output_len, size_t *entropy_content) {
    uint32_t reads[8];
    uint8_t hash[32];
    int ret;
    for (int i = 0; i < 8; i++) {
        ret = myhardware_prime_magic_random_register();
        if (ret != 0) return PSA_ERROR_INSUFFICIENT_ENTROPY;
        reads[i] << *MYHARDWARE_MAGIC_RANDOM_REGISTER_ADDRESS;
    }
    size_t hash_len;
    ret = psa_hash_compute(PSA_ALG_SHA_256, (uint_t*) reads, sizeof(reads), hash, sizeof(hash), &hash_len);
    if (ret != 0) return PSA_ERROR_INSUFFICIENT_ENTROPY;
    output[0] = hash[0];
    *output_len = 1;
    *entropy_content = 8;
    return 0;
}
```

created_at: 2025-04-24T15:20:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -565,3 +566,19 @@ exit:
     MD_PSA_DONE();
 }
 /* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_PLATFORM_GET_ENTROPY_ALT */
+void entropy_test_platform_get_entropy_alt(void)
+{
+    uint8_t data[MBEDTLS_ENTROPY_POLL_PLATFORM_MIN];
+    size_t olen;
+
+    TEST_ASSERT(mbedtls_entropy_poll_platform(NULL, data, sizeof(data), &olen) == 0);
path: tests/suites/test_suite_entropy.function
user: login: gilles-peskine-arm
body: We should validate the value of `olen`.

```suggestion
    TEST_ASSERT(mbedtls_entropy_poll_platform(NULL, data, sizeof(data), &olen) == 0);
    TEST_LE_U(1, olen);
    TEST_LE_U(olen, sizeof(data));
```
created_at: 2025-04-24T15:22:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -565,3 +566,19 @@ exit:
     MD_PSA_DONE();
 }
 /* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_PLATFORM_GET_ENTROPY_ALT */
+void entropy_test_platform_get_entropy_alt(void)
+{
+    uint8_t data[MBEDTLS_ENTROPY_POLL_PLATFORM_MIN];
+    size_t olen;
+
+    TEST_ASSERT(mbedtls_entropy_poll_platform(NULL, data, sizeof(data), &olen) == 0);
path: tests/suites/test_suite_entropy.function
user: login: gilles-peskine-arm
body: Do we have a test somewhere (presumably in `test_suite_entropy.function`) to validate what happens if the callback reports full entropy but with a smaller output size, i.e. `*olen < output_size`? There's a loop in `entropy.c` that should call the function again until it provides enough entropy, but I'm not sure our tests are up to date with the change we've made to the callback: we'd need to let the test callback know to report less entropy, and I don't see this being done.
created_at: 2025-04-24T15:25:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,35 @@
+## Platform-specific Entropy Gathering
+
+`MBEDTLS_ENTROPY_HARDWARE_ALT` has been renamed to `MBEDTLS_PLATFORM_GET_ENTROPY_ALT`.
+The prototype for the custom defined hardware entropy polling function changed
+from:
+
+```c
+int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len,
+                          size_t *olen);
+```
+
+to:
+
+```c
+int mbedtls_platform_get_entropy(unsigned char *output, size_t output_size,
+                                 size_t *output_len, size_t *entropy_content);
+```
+
+This new prototype is placed in the public header `mbedtls/platform.h` instead
+of the private `library/entropy_poll.h` one as it was previously.
+
+The new `entropy_content` parameter measures (in bit) the amount of entropy
+contained in the returned `output` buffer. For the time being only full entropy
+sources are allowed (i.e. `entropy_content = 8 * *output_len`), but this can
+change in the future.
+
+`MBEDTLS_ENTROPY_MIN_HARDWARE` is also removed and the entropy module assumes
+that 32 bytes are enough to declare the hardware entropy polling completed.
+This value is not user configurable.
+
+While up to Mbed TLS 3.6 Platform and Hardware entropy sources could be
+independently enabled, starting from TF-PSA-Crypto 1.0 they become mutually
+exclusive. `MBEDTLS_NO_PLATFORM_ENTROPY` is therefore removed as
+`MBEDTLS_PLATFORM_GET_ENTROPY_ALT` can be used to switch between Platform
+and Hardware entropy polling.
path: docs/4.0-migration-guide/platform-entropy-gathering.md
user: login: gilles-peskine-arm
body: Before, there were 4 possible settings: builtin, custom, both, or none. Now there are only 2 settings: builtin or custom. The current text addresses the removal of “both” (which isn't really useful), but not the removal of “none”. Suggested wording:

> The option `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` disables the built-in entropy sources, unlike its predecessor `MBEDTLS_ENTROPY_HARDWARE_ALT`, because one entropy source is generally sufficient. If you want to add a custom entropy source while retaining the platform's default source, call the platform's default source in your callback.
>
> The option `MBEDTLS_NO_PLATFORM_ENTROPY` is removed. TF-PSA-Crypto 1.0 no longer supports platforms without an entropy source. This ability will be reintroduced in a future minor release.

created_at: 2025-04-24T15:30:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -567,20 +572,41 @@ exit:
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_PLATFORM_GET_ENTROPY_ALT */
+/* BEGIN_CASE depends_on:MBEDTLS_PLATFORM_C:MBEDTLS_PLATFORM_GET_ENTROPY_ALT */
 void entropy_test_platform_get_entropy_alt(void)
 {
+    mbedtls_entropy_context ctx;
     uint8_t data[MBEDTLS_ENTROPY_POLL_PLATFORM_MIN];
-    size_t olen;
+    size_t olen, call_count;
 
+    /* Simple callback test -> all fine. */
     TEST_ASSERT(mbedtls_entropy_poll_platform(NULL, data, sizeof(data), &olen) == 0);
     TEST_LE_U(1, olen);
     TEST_LE_U(olen, sizeof(data));
-    mbedtls_test_get_entropy_force(1, SIZE_MAX);
+
+    mbedtls_test_platform_get_entropy_reset();
+
+    /* Force a failure -> return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED. */
+    mbedtls_test_platform_get_entropy_set_force_failure(1);
     TEST_ASSERT(mbedtls_entropy_poll_platform(NULL, data, sizeof(data), &olen) ==
                 MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
-    mbedtls_test_get_entropy_force(0, 8 * (sizeof(data) - 1));
+
+    mbedtls_test_platform_get_entropy_reset();
+
+    /* Return less entropy than expected -> entropy gathering fails */
+    mbedtls_test_platform_get_entropy_set_entropy_content(8 * (sizeof(data) - 1));
     TEST_ASSERT(mbedtls_entropy_poll_platform(NULL, data, sizeof(data), &olen) ==
                 MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
+
+    mbedtls_test_platform_get_entropy_reset();
+
+    /* Return less data than required -> callback will be called more than once. */
+    mbedtls_entropy_init(&ctx);
+    mbedtls_test_platform_get_entropy_set_output_len(
+        TEST_PLATFORM_GET_ENTROPY_DATA_LENGTH_PER_CALL);
+    TEST_ASSERT(mbedtls_entropy_func(&ctx, data, sizeof(data)) == 0);
+    mbedtls_entropy_free(&ctx);
+    call_count = mbedtls_test_platform_get_entropy_get_call_count();
+    TEST_EQUAL(call_count, TEST_PLATFORM_GET_ENTROPY_EXP_CALL_COUNT);
 }
path: tests/suites/test_suite_entropy.function
user: login: gilles-peskine-arm
body: Sorry I missed this earlier: if a test assertion fails, it might leave the entropy callback test in a non-default state, which will likely have weird effects on subsequent tests. Please reset the state in the `exit:` block, that's how we normally deal with test state.
created_at: 2025-04-28T15:33:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,5 +24,6 @@
 #define MBEDTLS_PSA_CRYPTO_C
 #define MBEDTLS_CTR_DRBG_C
 #define MBEDTLS_ENTROPY_C
+#define MBEDTLS_PLATFORM_C
path: configs/crypto-config-ccm-aes-sha256.h
user: login: gilles-peskine-arm
body: This shouldn't be necessary. `MBEDTLS_PLATFORM_C` should only be needed to support runtime configuration of platform features. Neither `MBEDTLS_PLATFORM_GET_ENTROPY_ALT` nor `!MBEDTLS_PLATFORM_GET_ENTROPY_ALT` should require `MBEDTLS_PLATFORM_C`.

I think the natural way to fix this is to move the code from `platform.c` to `platform_util.c`.

At this point, given that we're planning to do a disruptive combined merge tonight, I propose to merge as is, and do a follow-up that does the move and removes the added enabling of `MBEDTLS_PLATFORM_C` in both TF-PSA-Crypto and mbedtls.

created_at: 2025-05-06T14:40:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,5 +24,6 @@
 #define MBEDTLS_PSA_CRYPTO_C
 #define MBEDTLS_CTR_DRBG_C
 #define MBEDTLS_ENTROPY_C
+#define MBEDTLS_PLATFORM_C
path: configs/crypto-config-ccm-aes-sha256.h
user: login: gilles-peskine-arm
body: https://github.com/Mbed-TLS/TF-PSA-Crypto/issues/282
created_at: 2025-05-06T14:50:49Z
author_association: CONTRIBUTOR

PR comments:
user: login: valeriosetti
created_at: 2025-04-01T20:06:36Z
body: I think that CI failures in `test_psasim` and `test_suite_with_psasim` can be ignored in this PR as the same tests [in the main PR](https://github.com/Mbed-TLS/mbedtls/pull/10090) are OK
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-04-01T20:07:56Z
body: I just forced push the last commit following the merge of https://github.com/Mbed-TLS/mbedtls-framework/pull/151. No other change was made
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-04-04T12:35:58Z
body: > I think that CI failures in `test_psasim` and `test_suite_with_psasim` can be ignored in this PR as the same tests [in the main PR](https://github.com/Mbed-TLS/mbedtls/pull/10090) are OK

Thinking on this a bit more I think I can explain why `psasim` tests fail in this PR. The [PR on the main repo](https://github.com/Mbed-TLS/mbedtls/pull/10090) modifies `config.py` (only in the main repo) so that the `full` config doesn't set `MBEDTLS_PLATFORM_GET_ENTROPY_ALT`.
The problem is that when https://github.com/Mbed-TLS/mbedtls/pull/10090 is tested then it pick this PR as the tf-psa-crypto version. The opposite is not true: when this PR is tested on the CI, the main repo is checked out at `development` and there the `full` config enables `MBEDTLS_PLATFORM_GET_ENTROPY_ALT`.
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-04-07T12:53:00Z
body: @bjwtaylor @gabor-mezei-arm I had to update this PR to solve a conflict in the `framework` reference. Nothing has been changed on the code.
author_association: CONTRIBUTOR
user: login: gilles-peskine-arm
created_at: 2025-04-07T14:44:54Z
body: At 0b4ca69b6387c85993a93db1764a8ad88d64f57a there is a weird [failure in `test_suite_with_psasim`](https://mbedtls.trustedfirmware.org/job/mbed-tls-tf-psa-crypto-multibranch/job/PR-212-head/8/execution/node/9281/log/) (same on the internal CI, so it's not a glitch):

```
[2025-04-07T08:56:10.964Z] ../tests/psa-client-server/psasim//test/start_server.sh: line 16: ../tests/psa-client-server/psasim//test/psa_server: No such file or directory
[2025-04-07T12:54:35.506Z] Sending interrupt signal to process
```

At first glance it looks like there are two problems:

1. `psa_server` isn't getting built when it should, or where it should.
2. The script hung after that problem (and eventually the CI timed out), rather than erroring out.

Since you're familiar with psasim, can you please investigate?
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-04-08T11:39:04Z
body: > * `psa_server` isn't getting built when it should, or where it should.

Yes, the problem in this case is that `psasim`'s server build fails because of the problem explained [above](https://github.com/Mbed-TLS/TF-PSA-Crypto/pull/212#issuecomment-2778608101). 
 
> * The script hung after that problem (and eventually the CI timed out), rather than erroring out.

I just realized that when I worked on the `psasim` implementation I used to test it as:

`./tests/scripts/all.sh --force test_psasim`

in which case the test component stops immediately in case of build failures, so this would not explain why the CI went on testing. It turns out that I basically never add `--keep-going` on the command line, as the CI does instead, and that's the difference.
I need to investigate a bit and find the proper solution. Thanks for noticing.
author_association: CONTRIBUTOR
user: login: gilles-peskine-arm
created_at: 2025-04-08T11:53:18Z
body: The way `--keep-going` works uses somewhat arcane bash features and tries to do the right thing by default: stop the component if a configure or build step fails, but keep going if a test step fails. But you sometimes need to help it notice a failure, or decide whether the failure is fatal. The code to set this up is `pre_setup_keep_going` (now in `framework/scripts/all-core.sh`).

Having a quick look at `component_test_psasim`, I notice that there are build steps that look like `make … test/…`. The heuristics in `pre_setup_keep_going` recognize this as a build step. They treat `tests` as a directory name that can appear in a build step and otherwise `test` as an indication of a test step, but that doesn't work for psasim which has a directory called `test`.

But beyond that, if the build works but server can't start, the test should stop, not sit forever until it times out.
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-04-08T12:07:59Z
body: @gilles-peskine-arm thanks for the detailed explanation. I added a [fix](https://github.com/Mbed-TLS/mbedtls/pull/10090/commits/ccd05e3ef57f589080d08dab8789c3df500816cf) in the [main repo PR](https://github.com/Mbed-TLS/mbedtls/pull/10090). It won't fix the CI of this PR, of course, but it should be OK for the future.
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-04-08T12:10:17Z
body: I removed the `need-ci` label from this PR because it [cannot](https://github.com/Mbed-TLS/TF-PSA-Crypto/pull/212#issuecomment-2778608101) have CI fully green. It has to be merged manually and then [mbed#10090](https://github.com/Mbed-TLS/mbedtls/pull/10090) must be set on its merge queue immediately after this.
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-04-16T14:39:14Z
body: > * Sorry for the late notice but I think we should make a slight design change and have the new function replace, rather than add to, the default platform entropy. (And if we don't then the new name doesn't fit.)
> 
>     * The documentation is unclear in places.
> 
>     * This doesn't resolve [MBEDTLS_ENTROPY_HARDWARE_ALT in 4.0 mbedtls#9618](https://github.com/Mbed-TLS/mbedtls/issues/9618): it's missing tests and part of the documentation (migration guide). Those can be done in follow-ups, but we need to keep track of the work that's left.

@gilles-peskine-arm I think I've addressed all the requirements so far (including [this](https://github.com/Mbed-TLS/TF-PSA-Crypto/pull/212#discussion_r2042389919)). The only missing thing is the migration document, but before starting it I would like to have a stable design so that I don't have to update documentation too many times.
Can you please take a look at the current state and let me know if it's OK?
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-04-23T07:16:14Z
body: I removed the `need-ci` label because the PR on the main repo ([10090](https://github.com/Mbed-TLS/mbedtls/pull/10090)) now has CI green.
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-04-23T08:23:16Z
body: I removed also the `need-work` label because I've just added the migration guide document so I think I've addressed all the comments (@gilles-peskine-arm). I think the PR is ready for reviews again.
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-04-29T09:00:14Z
body: @gilles-peskine-arm @bjwtaylor I just updated the `framework` reference (since https://github.com/Mbed-TLS/mbedtls-framework/pull/165 was merged) and rebased in top of `development` branch to solve CI issues with main repo.
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-04-30T08:17:41Z
body: Remaining CI failures are:
```
[2025-04-29T14:35:20.193Z] test/selftest.c:229:14: error: implicit declaration of function 'mbedtls_platform_entropy_poll' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
[2025-04-29T14:35:20.193Z]     result = mbedtls_platform_entropy_poll(NULL,
```
which is reasonable since the main repo is tested on the `development` branch. We can rely on the CI of https://github.com/Mbed-TLS/mbedtls/pull/10090 to validate this PR.
author_association: CONTRIBUTOR
user: login: gilles-peskine-arm
created_at: 2025-04-30T08:33:11Z
body: It's problematic to merge something in the crypto repository that breaks the CI, since it means crypto will be broken on all branches that don't have this PR merged yet.

Can you please add a transition function `mbedtls_platform_entropy_poll` that's just good enough for how it's used in `selftest.c`, with a comment stating that it's going to be removed soon? And might as well make a PR that reverts that commit, to be merged in a few weeks.
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-04-30T09:58:39Z
body: > Can you please add a transition function mbedtls_platform_entropy_poll that's just good enough for how it's used in selftest.c, with a comment stating that it's going to be removed soon? And might as well make a PR that reverts that commit, to be merged in a few weeks.

@gilles-peskine-arm I just created https://github.com/Mbed-TLS/TF-PSA-Crypto/issues/273 to track this
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-04-30T10:22:41Z
body: @gilles-peskine-arm although I added the stub function for `mbedtls_platform_entropy_poll` there are remaining failures on the CI related to the fact that the main branch actually needs some more fixes on its codebase to make this PR in (configuration header files, config.py, etc - see https://github.com/Mbed-TLS/mbedtls/pull/10090 for the full list).
I'm not sure I can make the CI fully happy in this PR.,,
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-05-05T16:03:29Z
body: Since we agreed to manually merge this PR and then set https://github.com/Mbed-TLS/mbedtls/pull/10090 on the merge queue immediately after that I removed the temporary commit https://github.com/Mbed-TLS/TF-PSA-Crypto/pull/212/commits/26fdaa1c3650532fc1fd746380ae066888d2621c which was added as [attempt to make the CI fully happy](https://github.com/Mbed-TLS/TF-PSA-Crypto/pull/212#issuecomment-2841225609).
We will rely on CI of [10090](https://github.com/Mbed-TLS/mbedtls/pull/10090) to validate this PR.
author_association: CONTRIBUTOR
user: login: valeriosetti
created_at: 2025-05-06T04:31:30Z
body: Sorry for the last minute fix, but since I had to [modify](https://github.com/Mbed-TLS/mbedtls/pull/10090/commits/1afedacfea918c47ff55f845a22e95d38d84f836) the PR on the main repo to make its CI happy, I preferred to fix the name of the test component being added also in this PR (see [new commit](https://github.com/Mbed-TLS/TF-PSA-Crypto/pull/212/commits/390da553beaf3f32468e69d565e4c8bb72feeece)).
author_association: CONTRIBUTOR
user: login: gilles-peskine-arm
created_at: 2025-05-06T16:28:19Z
body: As previously discussed, I'm going ahead and force-merging this pull request. This will break the CI on TF-PSA-Crypto where it consumes the head of mbedtls, to be fixed by merging https://github.com/Mbed-TLS/mbedtls/pull/10090.
author_association: CONTRIBUTOR