1/* BEGIN_HEADER */ 2#include <stdint.h> 3#include <string.h> 4 5#include <psa/crypto.h> 6 7#include "mbedtls/entropy.h" 8#include "entropy_poll.h" 9 10/* Calculating the minimum allowed entropy size in bytes */ 11#define MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, \ 12 MBEDTLS_ENTROPY_BLOCK_SIZE) 13 14#if defined(MBEDTLS_PSA_INJECT_ENTROPY) 15 16#if defined(MBEDTLS_PSA_ITS_FILE_C) 17#include <stdio.h> 18#else 19#include <psa/internal_trusted_storage.h> 20#endif 21 22/* Remove the entropy seed file. Since the library does not expose a way 23 * to do this (it would be a security risk if such a function was ever 24 * accessible in production), implement this functionality in a white-box 25 * manner. */ 26psa_status_t remove_seed_file(void) 27{ 28#if defined(MBEDTLS_PSA_ITS_FILE_C) 29 if (remove("00000000ffffff52.psa_its") == 0) { 30 return PSA_SUCCESS; 31 } else { 32 return PSA_ERROR_DOES_NOT_EXIST; 33 } 34#else 35 return psa_its_remove(PSA_CRYPTO_ITS_RANDOM_SEED_UID); 36#endif 37} 38 39#endif /* MBEDTLS_PSA_INJECT_ENTROPY */ 40 41/* END_HEADER */ 42 43/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ 44void external_rng_failure_generate() 45{ 46 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 47 psa_set_key_type(&attributes, PSA_KEY_TYPE_DERIVE); 48 psa_set_key_bits(&attributes, 128); 49 mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; 50 uint8_t output[1]; 51 52 PSA_ASSERT(psa_crypto_init()); 53 54 PSA_ASSERT(psa_generate_random(output, sizeof(output))); 55 PSA_ASSERT(psa_generate_key(&attributes, &key)); 56 PSA_ASSERT(psa_destroy_key(key)); 57 58 mbedtls_test_disable_insecure_external_rng(); 59 TEST_EQUAL(PSA_ERROR_INSUFFICIENT_ENTROPY, 60 psa_generate_random(output, sizeof(output))); 61 TEST_EQUAL(PSA_ERROR_INSUFFICIENT_ENTROPY, 62 psa_generate_key(&attributes, &key)); 63 64exit: 65 psa_destroy_key(key); 66 PSA_DONE(); 67} 68/* END_CASE */ 69 70/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ 71void external_rng_failure_sign(int key_type, data_t *key_data, int alg, 72 int input_size_arg) 73{ 74 /* This test case is only expected to pass if the signature mechanism 75 * requires randomness, either because it is a randomized signature 76 * or because the implementation uses blinding. */ 77 78 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 79 psa_set_key_type(&attributes, key_type); 80 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); 81 psa_set_key_algorithm(&attributes, alg); 82 mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; 83 size_t input_size = input_size_arg; 84 uint8_t *input = NULL; 85 uint8_t *signature = NULL; 86 size_t signature_size = PSA_SIGNATURE_MAX_SIZE; 87 size_t signature_length; 88 89 ASSERT_ALLOC(input, input_size); 90 ASSERT_ALLOC(signature, signature_size); 91 92 PSA_ASSERT(psa_crypto_init()); 93 PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, 94 &key)); 95 PSA_ASSERT(psa_sign_hash(key, alg, 96 input, input_size, 97 signature, signature_size, 98 &signature_length)); 99 PSA_ASSERT(psa_destroy_key(key)); 100 101 mbedtls_test_disable_insecure_external_rng(); 102 /* Import the key again, because for RSA Mbed TLS caches blinding values 103 * in the key object and this could perturb the test. */ 104 PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, 105 &key)); 106 TEST_EQUAL(PSA_ERROR_INSUFFICIENT_ENTROPY, 107 psa_sign_hash(key, alg, 108 input, input_size, 109 signature, signature_size, 110 &signature_length)); 111 PSA_ASSERT(psa_destroy_key(key)); 112 113exit: 114 psa_destroy_key(key); 115 PSA_DONE(); 116 mbedtls_free(input); 117 mbedtls_free(signature); 118} 119/* END_CASE */ 120 121/* BEGIN_CASE depends_on:MBEDTLS_PSA_INJECT_ENTROPY */ 122void validate_entropy_seed_injection(int seed_length_a, 123 int expected_status_a, 124 int seed_length_b, 125 int expected_status_b) 126{ 127 psa_status_t status; 128 uint8_t output[32] = { 0 }; 129 uint8_t zeros[32] = { 0 }; 130 uint8_t *seed = NULL; 131 int i; 132 int seed_size; 133 if (seed_length_a > seed_length_b) { 134 seed_size = seed_length_a; 135 } else { 136 seed_size = seed_length_b; 137 } 138 ASSERT_ALLOC(seed, seed_size); 139 /* fill seed with some data */ 140 for (i = 0; i < seed_size; ++i) { 141 seed[i] = i; 142 } 143 status = remove_seed_file(); 144 TEST_ASSERT((status == PSA_SUCCESS) || 145 (status == PSA_ERROR_DOES_NOT_EXIST)); 146 status = mbedtls_psa_inject_entropy(seed, seed_length_a); 147 TEST_EQUAL(status, expected_status_a); 148 status = mbedtls_psa_inject_entropy(seed, seed_length_b); 149 TEST_EQUAL(status, expected_status_b); 150 PSA_ASSERT(psa_crypto_init()); 151 PSA_ASSERT(psa_generate_random(output, 152 sizeof(output))); 153 TEST_ASSERT(memcmp(output, zeros, sizeof(output)) != 0); 154exit: 155 mbedtls_free(seed); 156 remove_seed_file(); 157 PSA_DONE(); 158} 159/* END_CASE */ 160 161/* BEGIN_CASE depends_on:MBEDTLS_PSA_INJECT_ENTROPY */ 162void run_entropy_inject_with_crypto_init() 163{ 164 psa_status_t status; 165 size_t i; 166 uint8_t seed[MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE] = { 0 }; 167 /* fill seed with some data */ 168 for (i = 0; i < sizeof(seed); ++i) { 169 seed[i] = i; 170 } 171 status = remove_seed_file(); 172 TEST_ASSERT((status == PSA_SUCCESS) || 173 (status == PSA_ERROR_DOES_NOT_EXIST)); 174 status = mbedtls_psa_inject_entropy(seed, sizeof(seed)); 175 PSA_ASSERT(status); 176 status = remove_seed_file(); 177 TEST_EQUAL(status, PSA_SUCCESS); 178 status = psa_crypto_init(); 179 TEST_EQUAL(status, PSA_ERROR_INSUFFICIENT_ENTROPY); 180 status = mbedtls_psa_inject_entropy(seed, sizeof(seed)); 181 PSA_ASSERT(status); 182 status = psa_crypto_init(); 183 PSA_ASSERT(status); 184 PSA_DONE(); 185 /* The seed is written by nv_seed callback functions therefore the injection will fail */ 186 status = mbedtls_psa_inject_entropy(seed, sizeof(seed)); 187 TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED); 188exit: 189 remove_seed_file(); 190 PSA_DONE(); 191} 192/* END_CASE */ 193