1a8e1175bSopenharmony_ci/* BEGIN_HEADER */ 2a8e1175bSopenharmony_ci#include <stdint.h> 3a8e1175bSopenharmony_ci#include <string.h> 4a8e1175bSopenharmony_ci 5a8e1175bSopenharmony_ci#include <psa/crypto.h> 6a8e1175bSopenharmony_ci 7a8e1175bSopenharmony_ci#include "mbedtls/entropy.h" 8a8e1175bSopenharmony_ci#include "entropy_poll.h" 9a8e1175bSopenharmony_ci 10a8e1175bSopenharmony_ci/* Calculating the minimum allowed entropy size in bytes */ 11a8e1175bSopenharmony_ci#define MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, \ 12a8e1175bSopenharmony_ci MBEDTLS_ENTROPY_BLOCK_SIZE) 13a8e1175bSopenharmony_ci 14a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_INJECT_ENTROPY) 15a8e1175bSopenharmony_ci#include <psa_crypto_its.h> 16a8e1175bSopenharmony_ci 17a8e1175bSopenharmony_ci/* Check the entropy seed file. 18a8e1175bSopenharmony_ci * 19a8e1175bSopenharmony_ci * \param expected_size Expected size in bytes. 20a8e1175bSopenharmony_ci * If 0, the file must not exist. 21a8e1175bSopenharmony_ci * 22a8e1175bSopenharmony_ci * \retval 1 Either \p expected_size is nonzero and 23a8e1175bSopenharmony_ci * the entropy seed file exists and has exactly this size, 24a8e1175bSopenharmony_ci * or \p expected_size is zero and the file does not exist. 25a8e1175bSopenharmony_ci * \retval 0 Either \p expected_size is nonzero but 26a8e1175bSopenharmony_ci * the entropy seed file does not exist or has a different size, 27a8e1175bSopenharmony_ci * or \p expected_size is zero but the file exists. 28a8e1175bSopenharmony_ci * In this case, the test case is marked as failed. 29a8e1175bSopenharmony_ci * 30a8e1175bSopenharmony_ci * \note We enforce that the seed is in a specific ITS file. 31a8e1175bSopenharmony_ci * This must not change, otherwise we break backward compatibility if 32a8e1175bSopenharmony_ci * the library is upgraded on a device with an existing seed. 33a8e1175bSopenharmony_ci */ 34a8e1175bSopenharmony_ciint check_random_seed_file(size_t expected_size) 35a8e1175bSopenharmony_ci{ 36a8e1175bSopenharmony_ci /* The value of the random seed UID must not change. Otherwise that would 37a8e1175bSopenharmony_ci * break upgrades of the library on devices that already contain a seed 38a8e1175bSopenharmony_ci * file. If this test assertion fails, you've presumably broken backward 39a8e1175bSopenharmony_ci * compatibility! */ 40a8e1175bSopenharmony_ci TEST_EQUAL(PSA_CRYPTO_ITS_RANDOM_SEED_UID, 0xFFFFFF52); 41a8e1175bSopenharmony_ci 42a8e1175bSopenharmony_ci struct psa_storage_info_t info = { 0, 0 }; 43a8e1175bSopenharmony_ci psa_status_t status = psa_its_get_info(PSA_CRYPTO_ITS_RANDOM_SEED_UID, 44a8e1175bSopenharmony_ci &info); 45a8e1175bSopenharmony_ci 46a8e1175bSopenharmony_ci if (expected_size == 0) { 47a8e1175bSopenharmony_ci TEST_EQUAL(status, PSA_ERROR_DOES_NOT_EXIST); 48a8e1175bSopenharmony_ci } else { 49a8e1175bSopenharmony_ci TEST_EQUAL(status, PSA_SUCCESS); 50a8e1175bSopenharmony_ci TEST_EQUAL(info.size, expected_size); 51a8e1175bSopenharmony_ci } 52a8e1175bSopenharmony_ci return 1; 53a8e1175bSopenharmony_ci 54a8e1175bSopenharmony_ciexit: 55a8e1175bSopenharmony_ci return 0; 56a8e1175bSopenharmony_ci} 57a8e1175bSopenharmony_ci 58a8e1175bSopenharmony_ci/* Remove the entropy seed file. 59a8e1175bSopenharmony_ci * 60a8e1175bSopenharmony_ci * See check_random_seed_file() regarding abstraction boundaries. 61a8e1175bSopenharmony_ci */ 62a8e1175bSopenharmony_cipsa_status_t remove_seed_file(void) 63a8e1175bSopenharmony_ci{ 64a8e1175bSopenharmony_ci return psa_its_remove(PSA_CRYPTO_ITS_RANDOM_SEED_UID); 65a8e1175bSopenharmony_ci} 66a8e1175bSopenharmony_ci 67a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_INJECT_ENTROPY */ 68a8e1175bSopenharmony_ci 69a8e1175bSopenharmony_ci/* END_HEADER */ 70a8e1175bSopenharmony_ci 71a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ 72a8e1175bSopenharmony_civoid external_rng_failure_generate() 73a8e1175bSopenharmony_ci{ 74a8e1175bSopenharmony_ci psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 75a8e1175bSopenharmony_ci psa_set_key_type(&attributes, PSA_KEY_TYPE_DERIVE); 76a8e1175bSopenharmony_ci psa_set_key_bits(&attributes, 128); 77a8e1175bSopenharmony_ci mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; 78a8e1175bSopenharmony_ci uint8_t output[1]; 79a8e1175bSopenharmony_ci 80a8e1175bSopenharmony_ci PSA_ASSERT(psa_crypto_init()); 81a8e1175bSopenharmony_ci 82a8e1175bSopenharmony_ci PSA_ASSERT(psa_generate_random(output, sizeof(output))); 83a8e1175bSopenharmony_ci PSA_ASSERT(psa_generate_key(&attributes, &key)); 84a8e1175bSopenharmony_ci PSA_ASSERT(psa_destroy_key(key)); 85a8e1175bSopenharmony_ci 86a8e1175bSopenharmony_ci mbedtls_test_disable_insecure_external_rng(); 87a8e1175bSopenharmony_ci TEST_EQUAL(PSA_ERROR_INSUFFICIENT_ENTROPY, 88a8e1175bSopenharmony_ci psa_generate_random(output, sizeof(output))); 89a8e1175bSopenharmony_ci TEST_EQUAL(PSA_ERROR_INSUFFICIENT_ENTROPY, 90a8e1175bSopenharmony_ci psa_generate_key(&attributes, &key)); 91a8e1175bSopenharmony_ci 92a8e1175bSopenharmony_ciexit: 93a8e1175bSopenharmony_ci psa_destroy_key(key); 94a8e1175bSopenharmony_ci PSA_DONE(); 95a8e1175bSopenharmony_ci} 96a8e1175bSopenharmony_ci/* END_CASE */ 97a8e1175bSopenharmony_ci 98a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ 99a8e1175bSopenharmony_civoid external_rng_failure_sign(int key_type, data_t *key_data, int alg, 100a8e1175bSopenharmony_ci int input_size_arg) 101a8e1175bSopenharmony_ci{ 102a8e1175bSopenharmony_ci /* This test case is only expected to pass if the signature mechanism 103a8e1175bSopenharmony_ci * requires randomness, either because it is a randomized signature 104a8e1175bSopenharmony_ci * or because the implementation uses blinding. */ 105a8e1175bSopenharmony_ci 106a8e1175bSopenharmony_ci psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 107a8e1175bSopenharmony_ci psa_set_key_type(&attributes, key_type); 108a8e1175bSopenharmony_ci psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); 109a8e1175bSopenharmony_ci psa_set_key_algorithm(&attributes, alg); 110a8e1175bSopenharmony_ci mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; 111a8e1175bSopenharmony_ci size_t input_size = input_size_arg; 112a8e1175bSopenharmony_ci uint8_t *input = NULL; 113a8e1175bSopenharmony_ci uint8_t *signature = NULL; 114a8e1175bSopenharmony_ci size_t signature_size = PSA_SIGNATURE_MAX_SIZE; 115a8e1175bSopenharmony_ci size_t signature_length; 116a8e1175bSopenharmony_ci 117a8e1175bSopenharmony_ci TEST_CALLOC(input, input_size); 118a8e1175bSopenharmony_ci TEST_CALLOC(signature, signature_size); 119a8e1175bSopenharmony_ci 120a8e1175bSopenharmony_ci PSA_ASSERT(psa_crypto_init()); 121a8e1175bSopenharmony_ci PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, 122a8e1175bSopenharmony_ci &key)); 123a8e1175bSopenharmony_ci PSA_ASSERT(psa_sign_hash(key, alg, 124a8e1175bSopenharmony_ci input, input_size, 125a8e1175bSopenharmony_ci signature, signature_size, 126a8e1175bSopenharmony_ci &signature_length)); 127a8e1175bSopenharmony_ci PSA_ASSERT(psa_destroy_key(key)); 128a8e1175bSopenharmony_ci 129a8e1175bSopenharmony_ci mbedtls_test_disable_insecure_external_rng(); 130a8e1175bSopenharmony_ci /* Import the key again, because for RSA Mbed TLS caches blinding values 131a8e1175bSopenharmony_ci * in the key object and this could perturb the test. */ 132a8e1175bSopenharmony_ci PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, 133a8e1175bSopenharmony_ci &key)); 134a8e1175bSopenharmony_ci TEST_EQUAL(PSA_ERROR_INSUFFICIENT_ENTROPY, 135a8e1175bSopenharmony_ci psa_sign_hash(key, alg, 136a8e1175bSopenharmony_ci input, input_size, 137a8e1175bSopenharmony_ci signature, signature_size, 138a8e1175bSopenharmony_ci &signature_length)); 139a8e1175bSopenharmony_ci PSA_ASSERT(psa_destroy_key(key)); 140a8e1175bSopenharmony_ci 141a8e1175bSopenharmony_ciexit: 142a8e1175bSopenharmony_ci psa_destroy_key(key); 143a8e1175bSopenharmony_ci PSA_DONE(); 144a8e1175bSopenharmony_ci mbedtls_free(input); 145a8e1175bSopenharmony_ci mbedtls_free(signature); 146a8e1175bSopenharmony_ci} 147a8e1175bSopenharmony_ci/* END_CASE */ 148a8e1175bSopenharmony_ci 149a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_PSA_INJECT_ENTROPY */ 150a8e1175bSopenharmony_civoid validate_entropy_seed_injection(int seed_length_a, 151a8e1175bSopenharmony_ci int expected_status_a, 152a8e1175bSopenharmony_ci int seed_length_b, 153a8e1175bSopenharmony_ci int expected_status_b) 154a8e1175bSopenharmony_ci{ 155a8e1175bSopenharmony_ci psa_status_t status; 156a8e1175bSopenharmony_ci uint8_t output[32] = { 0 }; 157a8e1175bSopenharmony_ci uint8_t zeros[32] = { 0 }; 158a8e1175bSopenharmony_ci uint8_t *seed = NULL; 159a8e1175bSopenharmony_ci int i; 160a8e1175bSopenharmony_ci int seed_size; 161a8e1175bSopenharmony_ci if (seed_length_a > seed_length_b) { 162a8e1175bSopenharmony_ci seed_size = seed_length_a; 163a8e1175bSopenharmony_ci } else { 164a8e1175bSopenharmony_ci seed_size = seed_length_b; 165a8e1175bSopenharmony_ci } 166a8e1175bSopenharmony_ci TEST_CALLOC(seed, seed_size); 167a8e1175bSopenharmony_ci /* fill seed with some data */ 168a8e1175bSopenharmony_ci for (i = 0; i < seed_size; ++i) { 169a8e1175bSopenharmony_ci seed[i] = i; 170a8e1175bSopenharmony_ci } 171a8e1175bSopenharmony_ci status = remove_seed_file(); 172a8e1175bSopenharmony_ci TEST_ASSERT((status == PSA_SUCCESS) || 173a8e1175bSopenharmony_ci (status == PSA_ERROR_DOES_NOT_EXIST)); 174a8e1175bSopenharmony_ci if (!check_random_seed_file(0)) { 175a8e1175bSopenharmony_ci goto exit; 176a8e1175bSopenharmony_ci } 177a8e1175bSopenharmony_ci 178a8e1175bSopenharmony_ci status = mbedtls_psa_inject_entropy(seed, seed_length_a); 179a8e1175bSopenharmony_ci TEST_EQUAL(status, expected_status_a); 180a8e1175bSopenharmony_ci if (!check_random_seed_file(expected_status_a == PSA_SUCCESS ? seed_length_a : 181a8e1175bSopenharmony_ci 0)) { 182a8e1175bSopenharmony_ci goto exit; 183a8e1175bSopenharmony_ci } 184a8e1175bSopenharmony_ci 185a8e1175bSopenharmony_ci status = mbedtls_psa_inject_entropy(seed, seed_length_b); 186a8e1175bSopenharmony_ci TEST_EQUAL(status, expected_status_b); 187a8e1175bSopenharmony_ci if (!check_random_seed_file(expected_status_a == PSA_SUCCESS ? seed_length_a : 188a8e1175bSopenharmony_ci expected_status_b == PSA_SUCCESS ? seed_length_b : 189a8e1175bSopenharmony_ci 0)) { 190a8e1175bSopenharmony_ci goto exit; 191a8e1175bSopenharmony_ci } 192a8e1175bSopenharmony_ci 193a8e1175bSopenharmony_ci PSA_ASSERT(psa_crypto_init()); 194a8e1175bSopenharmony_ci PSA_ASSERT(psa_generate_random(output, 195a8e1175bSopenharmony_ci sizeof(output))); 196a8e1175bSopenharmony_ci TEST_ASSERT(memcmp(output, zeros, sizeof(output)) != 0); 197a8e1175bSopenharmony_ci 198a8e1175bSopenharmony_ciexit: 199a8e1175bSopenharmony_ci mbedtls_free(seed); 200a8e1175bSopenharmony_ci PSA_DONE(); 201a8e1175bSopenharmony_ci mbedtls_test_inject_entropy_restore(); 202a8e1175bSopenharmony_ci} 203a8e1175bSopenharmony_ci/* END_CASE */ 204a8e1175bSopenharmony_ci 205a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_PSA_INJECT_ENTROPY */ 206a8e1175bSopenharmony_civoid run_entropy_inject_with_crypto_init() 207a8e1175bSopenharmony_ci{ 208a8e1175bSopenharmony_ci psa_status_t status; 209a8e1175bSopenharmony_ci size_t i; 210a8e1175bSopenharmony_ci uint8_t seed[MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE] = { 0 }; 211a8e1175bSopenharmony_ci /* fill seed with some data */ 212a8e1175bSopenharmony_ci for (i = 0; i < sizeof(seed); ++i) { 213a8e1175bSopenharmony_ci seed[i] = i; 214a8e1175bSopenharmony_ci } 215a8e1175bSopenharmony_ci 216a8e1175bSopenharmony_ci status = remove_seed_file(); 217a8e1175bSopenharmony_ci TEST_ASSERT((status == PSA_SUCCESS) || 218a8e1175bSopenharmony_ci (status == PSA_ERROR_DOES_NOT_EXIST)); 219a8e1175bSopenharmony_ci if (!check_random_seed_file(0)) { 220a8e1175bSopenharmony_ci goto exit; 221a8e1175bSopenharmony_ci } 222a8e1175bSopenharmony_ci status = mbedtls_psa_inject_entropy(seed, sizeof(seed)); 223a8e1175bSopenharmony_ci PSA_ASSERT(status); 224a8e1175bSopenharmony_ci TEST_ASSERT(check_random_seed_file(sizeof(seed))); 225a8e1175bSopenharmony_ci status = remove_seed_file(); 226a8e1175bSopenharmony_ci TEST_EQUAL(status, PSA_SUCCESS); 227a8e1175bSopenharmony_ci if (!check_random_seed_file(0)) { 228a8e1175bSopenharmony_ci goto exit; 229a8e1175bSopenharmony_ci } 230a8e1175bSopenharmony_ci 231a8e1175bSopenharmony_ci status = psa_crypto_init(); 232a8e1175bSopenharmony_ci TEST_EQUAL(status, PSA_ERROR_INSUFFICIENT_ENTROPY); 233a8e1175bSopenharmony_ci status = mbedtls_psa_inject_entropy(seed, sizeof(seed)); 234a8e1175bSopenharmony_ci PSA_ASSERT(status); 235a8e1175bSopenharmony_ci if (!check_random_seed_file(sizeof(seed))) { 236a8e1175bSopenharmony_ci goto exit; 237a8e1175bSopenharmony_ci } 238a8e1175bSopenharmony_ci 239a8e1175bSopenharmony_ci status = psa_crypto_init(); 240a8e1175bSopenharmony_ci PSA_ASSERT(status); 241a8e1175bSopenharmony_ci PSA_DONE(); 242a8e1175bSopenharmony_ci 243a8e1175bSopenharmony_ci /* The seed is written by nv_seed callback functions therefore the injection will fail */ 244a8e1175bSopenharmony_ci status = mbedtls_psa_inject_entropy(seed, sizeof(seed)); 245a8e1175bSopenharmony_ci TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED); 246a8e1175bSopenharmony_ci 247a8e1175bSopenharmony_ciexit: 248a8e1175bSopenharmony_ci PSA_DONE(); 249a8e1175bSopenharmony_ci mbedtls_test_inject_entropy_restore(); 250a8e1175bSopenharmony_ci} 251a8e1175bSopenharmony_ci/* END_CASE */ 252