Gate entropy injection through a dedicated configuration option

Entropy injection has specific testing requirements. Therefore it
should depend on a specific option.
diff --git a/configs/config-psa-crypto.h b/configs/config-psa-crypto.h
index 7f7c0cf..4873c36 100644
--- a/configs/config-psa-crypto.h
+++ b/configs/config-psa-crypto.h
@@ -1232,6 +1232,19 @@
 //#define MBEDTLS_PSA_CRYPTO_SPM
 
 /**
+ * \def MBEDTLS_PSA_INJECT_ENTROPY
+ *
+ * Enable support for entropy injection at first boot. This feature is
+ * required on systems that do not have a built-in entropy source (TRNG).
+ * This feature is currently not supported on systems that have a built-in
+ * entropy source.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED
+ *
+ */
+//#define MBEDTLS_PSA_INJECT_ENTROPY
+
+/**
  * \def MBEDTLS_RSA_NO_CRT
  *
  * Do not use the Chinese Remainder Theorem
@@ -2715,7 +2728,7 @@
  *
  * Requires: MBEDTLS_FS_IO
  */
-//#define MBEDTLS_PSA_ITS_FILE_C
+#define MBEDTLS_PSA_ITS_FILE_C
 
 /**
  * \def MBEDTLS_RIPEMD160_C
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 607deb9..c1450db 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -530,6 +530,17 @@
 #error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites"
 #endif
 
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY) &&      \
+    !( defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \
+       defined(MBEDTLS_ENTROPY_NV_SEED) )
+#error "MBEDTLS_PSA_INJECT_ENTROPY defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY) &&              \
+    !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
+#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with actual entropy sources"
+#endif
+
 #if defined(MBEDTLS_PSA_ITS_FILE_C) && \
     !defined(MBEDTLS_FS_IO)
 #error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites"
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index a358a20..5621965 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1252,6 +1252,19 @@
 //#define MBEDTLS_PSA_CRYPTO_SPM
 
 /**
+ * \def MBEDTLS_PSA_INJECT_ENTROPY
+ *
+ * Enable support for entropy injection at first boot. This feature is
+ * required on systems that do not have a built-in entropy source (TRNG).
+ * This feature is currently not supported on systems that have a built-in
+ * entropy source.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED
+ *
+ */
+//#define MBEDTLS_PSA_INJECT_ENTROPY
+
+/**
  * \def MBEDTLS_RSA_NO_CRT
  *
  * Do not use the Chinese Remainder Theorem
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index 545dd4b..c89c55d 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -114,10 +114,9 @@
  * This is an Mbed TLS extension.
  *
  * \note This function is only available on the following platforms:
- * * If the compile-time options MBEDTLS_ENTROPY_NV_SEED and
- *   MBEDTLS_PSA_CRYPTO_STORAGE_C are both enabled. Note that you
- *   must provide compatible implementations of mbedtls_nv_seed_read
- *   and mbedtls_nv_seed_write.
+ * * If the compile-time option MBEDTLS_PSA_INJECT_ENTROPY is enabled.
+ *   Note that you must provide compatible implementations of
+ *   mbedtls_nv_seed_read and mbedtls_nv_seed_write.
  * * In a client-server integration of PSA Cryptography, on the client side,
  *   if the server supports this feature.
  * \param[in] seed          Buffer containing the seed value to inject.
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 1b554b5..3b9c78f 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -60,7 +60,6 @@
 #include "mbedtls/ecdh.h"
 #include "mbedtls/ecp.h"
 #include "mbedtls/entropy.h"
-#include "mbedtls/entropy_poll.h"
 #include "mbedtls/error.h"
 #include "mbedtls/gcm.h"
 #include "mbedtls/md2.h"
@@ -4419,13 +4418,12 @@
     return( mbedtls_to_psa_error( ret ) );
 }
 
-#if defined(MBEDTLS_ENTROPY_NV_SEED) && \
-    defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
+#include "mbedtls/entropy_poll.h"
+
 psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
                                          size_t seed_size )
 {
-    psa_status_t status;
-    struct psa_storage_info_t p_info;
     if( global_data.initialized )
         return( PSA_ERROR_NOT_PERMITTED );
 
@@ -4434,20 +4432,9 @@
           ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
             return( PSA_ERROR_INVALID_ARGUMENT );
 
-    status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
-
-    if( PSA_ERROR_DOES_NOT_EXIST == status ) /* No seed exists */
-    {
-        status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 );
-    }
-    else if( PSA_SUCCESS == status )
-    {
-        /* You should not be here. Seed needs to be injected only once */
-        status = PSA_ERROR_NOT_PERMITTED;
-    }
-    return( status );
+    return( mbedtls_psa_storage_inject_entropy( seed, seed_size ) );
 }
-#endif
+#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
 
 psa_status_t psa_generate_key( psa_key_handle_t handle,
                                psa_key_type_t type,
diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c
index bda9c0c..6c2e865 100644
--- a/library/psa_crypto_storage.c
+++ b/library/psa_crypto_storage.c
@@ -391,4 +391,26 @@
     return( status );
 }
 
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
+psa_status_t mbedtls_psa_storage_inject_entropy( const unsigned char *seed,
+                                                 size_t seed_size )
+{
+    psa_status_t status;
+    struct psa_storage_info_t p_info;
+
+    status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
+
+    if( PSA_ERROR_DOES_NOT_EXIST == status ) /* No seed exists */
+    {
+        status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 );
+    }
+    else if( PSA_SUCCESS == status )
+    {
+        /* You should not be here. Seed needs to be injected only once */
+        status = PSA_ERROR_NOT_PERMITTED;
+    }
+    return( status );
+}
+#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
+
 #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
diff --git a/library/psa_crypto_storage.h b/library/psa_crypto_storage.h
index 902e302..5434d05 100644
--- a/library/psa_crypto_storage.h
+++ b/library/psa_crypto_storage.h
@@ -203,6 +203,22 @@
                                               psa_key_type_t *type,
                                               psa_key_policy_t *policy );
 
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
+/** Backend side of mbedtls_psa_inject_entropy().
+ *
+ * This function stores the supplied data into the entropy seed file.
+ *
+ * \retval #PSA_SUCCESS
+ *         Success
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ *         The entropy seed file already exists.
+ */
+psa_status_t mbedtls_psa_storage_inject_entropy( const unsigned char *seed,
+                                                 size_t seed_size );
+#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/library/version_features.c b/library/version_features.c
index 92b1af1..00fd2e9 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -432,6 +432,9 @@
 #if defined(MBEDTLS_PSA_CRYPTO_SPM)
     "MBEDTLS_PSA_CRYPTO_SPM",
 #endif /* MBEDTLS_PSA_CRYPTO_SPM */
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
+    "MBEDTLS_PSA_INJECT_ENTROPY",
+#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
 #if defined(MBEDTLS_RSA_NO_CRT)
     "MBEDTLS_RSA_NO_CRT",
 #endif /* MBEDTLS_RSA_NO_CRT */
diff --git a/programs/test/query_config.c b/programs/test/query_config.c
index 52db0b2..d940b0d 100644
--- a/programs/test/query_config.c
+++ b/programs/test/query_config.c
@@ -1194,6 +1194,14 @@
     }
 #endif /* MBEDTLS_PSA_CRYPTO_SPM */
 
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
+    if( strcmp( "MBEDTLS_PSA_INJECT_ENTROPY", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_INJECT_ENTROPY );
+        return( 0 );
+    }
+#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
+
 #if defined(MBEDTLS_RSA_NO_CRT)
     if( strcmp( "MBEDTLS_RSA_NO_CRT", config ) == 0 )
     {
diff --git a/scripts/config.pl b/scripts/config.pl
index fc71f65..6927c4b 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -102,6 +102,7 @@
 MBEDTLS_NO_64BIT_MULTIPLICATION
 MBEDTLS_PSA_CRYPTO_SPM
 MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
+MBEDTLS_PSA_INJECT_ENTROPY
 MBEDTLS_USE_PSA_CRYPTO
 _ALT\s*$
 );
diff --git a/tests/suites/test_suite_psa_crypto_entropy.function b/tests/suites/test_suite_psa_crypto_entropy.function
index 76a7b58..91e210e 100644
--- a/tests/suites/test_suite_psa_crypto_entropy.function
+++ b/tests/suites/test_suite_psa_crypto_entropy.function
@@ -2,17 +2,38 @@
 #include <stdint.h>
 
 #include "psa/crypto.h"
-#include "psa_prot_internal_storage.h"
 #include "mbedtls/entropy.h"
 #include "mbedtls/entropy_poll.h"
 
+#if defined(MBEDTLS_PSA_ITS_FILE_C)
+#include <stdio.h>
+#else
+#include <psa/internal_trusted_storage.h>
+#endif
+
 /* Calculating the minimum allowed entropy size in bytes */
 #define MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)
 
+/* Remove the entropy seed file. Since the library does not expose a way
+ * to do this (it would be a security risk if such a function was ever
+ * accessible in production), implement this functionality in a white-box
+ * manner. */
+psa_status_t remove_seed_file( void )
+{
+#if defined(MBEDTLS_PSA_ITS_FILE_C)
+    if( remove( "00000000ffffff52.psa_its" ) == 0 )
+        return( PSA_SUCCESS );
+    else
+        return( PSA_ERROR_DOES_NOT_EXIST );
+#else
+    return( psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID ) );
+#endif
+}
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
- * depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PSA_CRYPTO_STORAGE_C
+ * depends_on:MBEDTLS_PSA_INJECT_ENTROPY
  * END_DEPENDENCIES
  */
 
@@ -42,7 +63,7 @@
     {
         seed[i] = i;
     }
-    status =  psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID );
+    status =  remove_seed_file( );
     TEST_ASSERT( ( status == PSA_SUCCESS ) ||
                  ( status == PSA_ERROR_DOES_NOT_EXIST ) );
     status = mbedtls_psa_inject_entropy( seed, seed_length_a );
@@ -55,7 +76,7 @@
     TEST_ASSERT( memcmp( output, zeros, sizeof( output ) ) != 0 );
 exit:
     mbedtls_free( seed );
-    psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID );
+    remove_seed_file( );
     mbedtls_psa_crypto_free( );
 }
 /* END_CASE */
@@ -64,19 +85,19 @@
 void run_entropy_inject_with_crypto_init( )
 {
     psa_status_t status;
-    int i;
+    size_t i;
     uint8_t seed[MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE] = { 0 };
     /* fill seed with some data */
     for( i = 0; i < sizeof( seed ); ++i )
     {
         seed[i] = i;
     }
-    status =  psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID );
+    status =  remove_seed_file( );
     TEST_ASSERT( ( status == PSA_SUCCESS ) ||
                  ( status == PSA_ERROR_DOES_NOT_EXIST ) );
     status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) );
     PSA_ASSERT( status );
-    status =  psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID );
+    status =  remove_seed_file( );
     TEST_EQUAL( status, PSA_SUCCESS );
     status = psa_crypto_init( );
     TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_ENTROPY );
@@ -89,7 +110,7 @@
     status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) );
     TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 exit:
-    psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID );
+    remove_seed_file( );
     mbedtls_psa_crypto_free( );
 }
 /* END_CASE */