Gate entropy injection through a dedicated configuration option

Entropy injection has specific testing requirements. Therefore it
should depend on a specific option.
This commit is contained in:
Gilles Peskine 2019-02-25 11:04:06 +01:00
parent 6bf4baef95
commit e3dbdd8d90
11 changed files with 125 additions and 31 deletions

View file

@ -1231,6 +1231,19 @@
*/ */
//#define MBEDTLS_PSA_CRYPTO_SPM //#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 * \def MBEDTLS_RSA_NO_CRT
* *
@ -2715,7 +2728,7 @@
* *
* Requires: MBEDTLS_FS_IO * Requires: MBEDTLS_FS_IO
*/ */
//#define MBEDTLS_PSA_ITS_FILE_C #define MBEDTLS_PSA_ITS_FILE_C
/** /**
* \def MBEDTLS_RIPEMD160_C * \def MBEDTLS_RIPEMD160_C

View file

@ -530,6 +530,17 @@
#error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites" #error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites"
#endif #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) && \ #if defined(MBEDTLS_PSA_ITS_FILE_C) && \
!defined(MBEDTLS_FS_IO) !defined(MBEDTLS_FS_IO)
#error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites" #error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites"

View file

@ -1251,6 +1251,19 @@
*/ */
//#define MBEDTLS_PSA_CRYPTO_SPM //#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 * \def MBEDTLS_RSA_NO_CRT
* *

View file

@ -114,10 +114,9 @@ void mbedtls_psa_crypto_free( void );
* This is an Mbed TLS extension. * This is an Mbed TLS extension.
* *
* \note This function is only available on the following platforms: * \note This function is only available on the following platforms:
* * If the compile-time options MBEDTLS_ENTROPY_NV_SEED and * * If the compile-time option MBEDTLS_PSA_INJECT_ENTROPY is enabled.
* MBEDTLS_PSA_CRYPTO_STORAGE_C are both enabled. Note that you * Note that you must provide compatible implementations of
* must provide compatible implementations of mbedtls_nv_seed_read * mbedtls_nv_seed_read and mbedtls_nv_seed_write.
* and mbedtls_nv_seed_write.
* * In a client-server integration of PSA Cryptography, on the client side, * * In a client-server integration of PSA Cryptography, on the client side,
* if the server supports this feature. * if the server supports this feature.
* \param[in] seed Buffer containing the seed value to inject. * \param[in] seed Buffer containing the seed value to inject.

View file

@ -60,7 +60,6 @@
#include "mbedtls/ecdh.h" #include "mbedtls/ecdh.h"
#include "mbedtls/ecp.h" #include "mbedtls/ecp.h"
#include "mbedtls/entropy.h" #include "mbedtls/entropy.h"
#include "mbedtls/entropy_poll.h"
#include "mbedtls/error.h" #include "mbedtls/error.h"
#include "mbedtls/gcm.h" #include "mbedtls/gcm.h"
#include "mbedtls/md2.h" #include "mbedtls/md2.h"
@ -4419,13 +4418,12 @@ psa_status_t psa_generate_random( uint8_t *output,
return( mbedtls_to_psa_error( ret ) ); return( mbedtls_to_psa_error( ret ) );
} }
#if defined(MBEDTLS_ENTROPY_NV_SEED) && \ #if defined(MBEDTLS_PSA_INJECT_ENTROPY)
defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) #include "mbedtls/entropy_poll.h"
psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed, psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
size_t seed_size ) size_t seed_size )
{ {
psa_status_t status;
struct psa_storage_info_t p_info;
if( global_data.initialized ) if( global_data.initialized )
return( PSA_ERROR_NOT_PERMITTED ); return( PSA_ERROR_NOT_PERMITTED );
@ -4434,20 +4432,9 @@ psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) ) ( seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) )
return( PSA_ERROR_INVALID_ARGUMENT ); return( PSA_ERROR_INVALID_ARGUMENT );
status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info ); return( mbedtls_psa_storage_inject_entropy( seed, seed_size ) );
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 #endif /* MBEDTLS_PSA_INJECT_ENTROPY */
psa_status_t psa_generate_key( psa_key_handle_t handle, psa_status_t psa_generate_key( psa_key_handle_t handle,
psa_key_type_t type, psa_key_type_t type,

View file

@ -391,4 +391,26 @@ exit:
return( status ); 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 */ #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */

View file

@ -203,6 +203,22 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
psa_key_type_t *type, psa_key_type_t *type,
psa_key_policy_t *policy ); 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -432,6 +432,9 @@ static const char *features[] = {
#if defined(MBEDTLS_PSA_CRYPTO_SPM) #if defined(MBEDTLS_PSA_CRYPTO_SPM)
"MBEDTLS_PSA_CRYPTO_SPM", "MBEDTLS_PSA_CRYPTO_SPM",
#endif /* 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) #if defined(MBEDTLS_RSA_NO_CRT)
"MBEDTLS_RSA_NO_CRT", "MBEDTLS_RSA_NO_CRT",
#endif /* MBEDTLS_RSA_NO_CRT */ #endif /* MBEDTLS_RSA_NO_CRT */

View file

@ -1194,6 +1194,14 @@ int query_config( const char *config )
} }
#endif /* MBEDTLS_PSA_CRYPTO_SPM */ #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 defined(MBEDTLS_RSA_NO_CRT)
if( strcmp( "MBEDTLS_RSA_NO_CRT", config ) == 0 ) if( strcmp( "MBEDTLS_RSA_NO_CRT", config ) == 0 )
{ {

View file

@ -102,6 +102,7 @@ MBEDTLS_NO_UDBL_DIVISION
MBEDTLS_NO_64BIT_MULTIPLICATION MBEDTLS_NO_64BIT_MULTIPLICATION
MBEDTLS_PSA_CRYPTO_SPM MBEDTLS_PSA_CRYPTO_SPM
MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
MBEDTLS_PSA_INJECT_ENTROPY
MBEDTLS_USE_PSA_CRYPTO MBEDTLS_USE_PSA_CRYPTO
_ALT\s*$ _ALT\s*$
); );

View file

@ -2,17 +2,38 @@
#include <stdint.h> #include <stdint.h>
#include "psa/crypto.h" #include "psa/crypto.h"
#include "psa_prot_internal_storage.h"
#include "mbedtls/entropy.h" #include "mbedtls/entropy.h"
#include "mbedtls/entropy_poll.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 */ /* Calculating the minimum allowed entropy size in bytes */
#define MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE) #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 */ /* END_HEADER */
/* BEGIN_DEPENDENCIES /* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PSA_CRYPTO_STORAGE_C * depends_on:MBEDTLS_PSA_INJECT_ENTROPY
* END_DEPENDENCIES * END_DEPENDENCIES
*/ */
@ -42,7 +63,7 @@ void validate_entropy_seed_injection( int seed_length_a,
{ {
seed[i] = i; seed[i] = i;
} }
status = psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID ); status = remove_seed_file( );
TEST_ASSERT( ( status == PSA_SUCCESS ) || TEST_ASSERT( ( status == PSA_SUCCESS ) ||
( status == PSA_ERROR_DOES_NOT_EXIST ) ); ( status == PSA_ERROR_DOES_NOT_EXIST ) );
status = mbedtls_psa_inject_entropy( seed, seed_length_a ); status = mbedtls_psa_inject_entropy( seed, seed_length_a );
@ -55,7 +76,7 @@ void validate_entropy_seed_injection( int seed_length_a,
TEST_ASSERT( memcmp( output, zeros, sizeof( output ) ) != 0 ); TEST_ASSERT( memcmp( output, zeros, sizeof( output ) ) != 0 );
exit: exit:
mbedtls_free( seed ); mbedtls_free( seed );
psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID ); remove_seed_file( );
mbedtls_psa_crypto_free( ); mbedtls_psa_crypto_free( );
} }
/* END_CASE */ /* END_CASE */
@ -64,19 +85,19 @@ exit:
void run_entropy_inject_with_crypto_init( ) void run_entropy_inject_with_crypto_init( )
{ {
psa_status_t status; psa_status_t status;
int i; size_t i;
uint8_t seed[MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE] = { 0 }; uint8_t seed[MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE] = { 0 };
/* fill seed with some data */ /* fill seed with some data */
for( i = 0; i < sizeof( seed ); ++i ) for( i = 0; i < sizeof( seed ); ++i )
{ {
seed[i] = i; seed[i] = i;
} }
status = psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID ); status = remove_seed_file( );
TEST_ASSERT( ( status == PSA_SUCCESS ) || TEST_ASSERT( ( status == PSA_SUCCESS ) ||
( status == PSA_ERROR_DOES_NOT_EXIST ) ); ( status == PSA_ERROR_DOES_NOT_EXIST ) );
status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) ); status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) );
PSA_ASSERT( status ); PSA_ASSERT( status );
status = psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID ); status = remove_seed_file( );
TEST_EQUAL( status, PSA_SUCCESS ); TEST_EQUAL( status, PSA_SUCCESS );
status = psa_crypto_init( ); status = psa_crypto_init( );
TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_ENTROPY ); TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_ENTROPY );
@ -89,7 +110,7 @@ void run_entropy_inject_with_crypto_init( )
status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) ); status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) );
TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED ); TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
exit: exit:
psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID ); remove_seed_file( );
mbedtls_psa_crypto_free( ); mbedtls_psa_crypto_free( );
} }
/* END_CASE */ /* END_CASE */