diff --git a/include/psa/crypto.h b/include/psa/crypto.h index c3899bfe7f..d976d7b182 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -323,6 +323,14 @@ typedef int32_t psa_status_t; * Applications may call this function more than once. Once a call * succeeds, subsequent calls are guaranteed to succeed. * + * If the application calls other functions before calling psa_crypto_init(), + * the behavior is undefined. Implementations are encouraged to either perform + * the operation as if the library had been initialized or to return + * #PSA_ERROR_BAD_STATE or some other applicable error. In particular, + * implementations should not return a success status if the lack of + * initialization may have security implications, for example due to improper + * seeding of the random number generator. + * * \retval #PSA_SUCCESS * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_COMMUNICATION_FAILURE @@ -1104,6 +1112,10 @@ typedef uint32_t psa_algorithm_t; * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_import_key(psa_key_slot_t key, psa_key_type_t type, @@ -1142,6 +1154,10 @@ psa_status_t psa_import_key(psa_key_slot_t key, * An unexpected condition which is not a storage corruption or * a communication failure occurred. The cryptoprocessor may have * been compromised. + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_destroy_key(psa_key_slot_t key); @@ -1162,6 +1178,10 @@ psa_status_t psa_destroy_key(psa_key_slot_t key); * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_get_key_information(psa_key_slot_t key, psa_key_type_t *type, @@ -1256,6 +1276,10 @@ psa_status_t psa_get_key_information(psa_key_slot_t key, * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_export_key(psa_key_slot_t key, uint8_t *data, @@ -1354,6 +1378,10 @@ psa_status_t psa_export_key(psa_key_slot_t key, * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_export_public_key(psa_key_slot_t key, uint8_t *data, @@ -1491,6 +1519,10 @@ psa_algorithm_t psa_key_policy_get_algorithm(const psa_key_policy_t *policy); * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_set_key_policy(psa_key_slot_t key, const psa_key_policy_t *policy); @@ -1504,6 +1536,10 @@ psa_status_t psa_set_key_policy(psa_key_slot_t key, * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_get_key_policy(psa_key_slot_t key, psa_key_policy_t *policy); @@ -1547,6 +1583,10 @@ typedef uint32_t psa_key_lifetime_t; * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_get_key_lifetime(psa_key_slot_t key, psa_key_lifetime_t *lifetime); @@ -1574,6 +1614,10 @@ psa_status_t psa_get_key_lifetime(psa_key_slot_t key, * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_set_key_lifetime(psa_key_slot_t key, psa_key_lifetime_t lifetime); @@ -1848,6 +1892,10 @@ typedef struct psa_mac_operation_s psa_mac_operation_t; * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, psa_key_slot_t key, @@ -1896,6 +1944,10 @@ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, psa_key_slot_t key, @@ -2092,6 +2144,10 @@ typedef struct psa_cipher_operation_s psa_cipher_operation_t; * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, psa_key_slot_t key, @@ -2141,6 +2197,10 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, psa_key_slot_t key, @@ -2384,6 +2444,10 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_aead_encrypt(psa_key_slot_t key, psa_algorithm_t alg, @@ -2437,6 +2501,10 @@ psa_status_t psa_aead_encrypt(psa_key_slot_t key, * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_aead_decrypt(psa_key_slot_t key, psa_algorithm_t alg, @@ -2500,6 +2568,10 @@ psa_status_t psa_aead_decrypt(psa_key_slot_t key, * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_asymmetric_sign(psa_key_slot_t key, psa_algorithm_t alg, @@ -2539,6 +2611,10 @@ psa_status_t psa_asymmetric_sign(psa_key_slot_t key, * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_asymmetric_verify(psa_key_slot_t key, psa_algorithm_t alg, @@ -2593,6 +2669,10 @@ psa_status_t psa_asymmetric_verify(psa_key_slot_t key, * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_asymmetric_encrypt(psa_key_slot_t key, psa_algorithm_t alg, @@ -2645,6 +2725,10 @@ psa_status_t psa_asymmetric_encrypt(psa_key_slot_t key, * \retval #PSA_ERROR_TAMPERING_DETECTED * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY * \retval #PSA_ERROR_INVALID_PADDING + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_asymmetric_decrypt(psa_key_slot_t key, psa_algorithm_t alg, @@ -2795,6 +2879,10 @@ psa_status_t psa_generator_read(psa_crypto_generator_t *generator, * \retval PSA_ERROR_COMMUNICATION_FAILURE * \retval PSA_ERROR_HARDWARE_FAILURE * \retval PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_generator_import_key(psa_key_slot_t key, psa_key_type_t type, @@ -2868,6 +2956,10 @@ psa_status_t psa_generator_abort(psa_crypto_generator_t *generator); * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_key_derivation(psa_crypto_generator_t *generator, psa_key_slot_t key, @@ -2902,6 +2994,10 @@ psa_status_t psa_key_derivation(psa_crypto_generator_t *generator, * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_generate_random(uint8_t *output, size_t output_size); @@ -2956,6 +3052,10 @@ typedef struct { * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. */ psa_status_t psa_generate_key(psa_key_slot_t key, psa_key_type_t type, diff --git a/library/psa_crypto.c b/library/psa_crypto.c index dfbb6800f5..8aa3145bd8 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -148,6 +148,10 @@ typedef struct static psa_global_data_t global_data; +#define GUARD_MODULE_INITIALIZED \ + if( global_data.initialized == 0 ) \ + return( PSA_ERROR_BAD_STATE ); + static psa_status_t mbedtls_to_psa_error( int ret ) { /* If there's both a high-level code and low-level code, dispatch on @@ -343,6 +347,8 @@ static psa_status_t mbedtls_to_psa_error( int ret ) static psa_status_t psa_get_key_slot( psa_key_slot_t key, key_slot_t **p_slot ) { + GUARD_MODULE_INITIALIZED; + /* 0 is not a valid slot number under any circumstance. This * implementation provides slots number 1 to N where N is the * number of available slots. */ @@ -3360,8 +3366,10 @@ psa_status_t psa_key_derivation( psa_crypto_generator_t *generator, psa_status_t psa_generate_random( uint8_t *output, size_t output_size ) { - int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, - output, output_size ); + int ret; + GUARD_MODULE_INITIALIZED; + + ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size ); return( mbedtls_to_psa_error( ret ) ); } diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 01be797abe..b4c2763778 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1178,3 +1178,9 @@ generate_key:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):256:PSA_KEY_USAGE PSA generate key: ECC, SECP256R1, incorrect bit size depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDSA_C generate_key:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:PSA_ERROR_INVALID_ARGUMENT + +PSA validate module initialization: random +validate_module_init_generate_random: + +PSA validate module initialization: key based +validate_module_init_key_based: diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index e14b2256de..2b1a946ecd 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -3451,3 +3451,23 @@ exit: mbedtls_psa_crypto_free( ); } /* END_CASE */ + +/* BEGIN_CASE */ +void validate_module_init_generate_random( ) +{ + psa_status_t status; + uint8_t random[10] = { 0 }; + status = psa_generate_random( random, sizeof( random ) ); + TEST_ASSERT( status == PSA_ERROR_BAD_STATE ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void validate_module_init_key_based( ) +{ + psa_status_t status; + uint8_t data[10] = { 0 }; + status = psa_import_key( 1, PSA_KEY_TYPE_RAW_DATA, data, sizeof( data ) ); + TEST_ASSERT( status == PSA_ERROR_BAD_STATE ); +} +/* END_CASE */