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 */