1/* BEGIN_HEADER */ 2 3#include <psa/crypto.h> 4 5#include <test/psa_crypto_helpers.h> 6#include <test/psa_exercise_key.h> 7 8#include <psa_crypto_its.h> 9 10#define TEST_FLAG_EXERCISE 0x00000001 11#define TEST_FLAG_READ_ONLY 0x00000002 12 13/** Write a key with the given attributes and key material to storage. 14 * Test that it has the expected representation. 15 * 16 * On error, including if the key representation in storage differs, 17 * mark the test case as failed and return 0. On success, return 1. 18 */ 19static int test_written_key(const psa_key_attributes_t *attributes, 20 const data_t *material, 21 psa_storage_uid_t uid, 22 const data_t *expected_representation) 23{ 24 mbedtls_svc_key_id_t created_key_id = MBEDTLS_SVC_KEY_ID_INIT; 25 uint8_t *actual_representation = NULL; 26 size_t length; 27 struct psa_storage_info_t storage_info; 28 int ok = 0; 29 30 /* Create a key with the given parameters. */ 31 PSA_ASSERT(psa_import_key(attributes, material->x, material->len, 32 &created_key_id)); 33 TEST_ASSERT(mbedtls_svc_key_id_equal(psa_get_key_id(attributes), 34 created_key_id)); 35 36 /* Check that the key is represented as expected. */ 37 PSA_ASSERT(psa_its_get_info(uid, &storage_info)); 38 TEST_EQUAL(storage_info.size, expected_representation->len); 39 TEST_CALLOC(actual_representation, storage_info.size); 40 PSA_ASSERT(psa_its_get(uid, 0, storage_info.size, 41 actual_representation, &length)); 42 TEST_MEMORY_COMPARE(expected_representation->x, expected_representation->len, 43 actual_representation, length); 44 45 ok = 1; 46 47exit: 48 mbedtls_free(actual_representation); 49 return ok; 50} 51 52/** Check if a key is exportable. */ 53static int can_export(const psa_key_attributes_t *attributes) 54{ 55 if (psa_get_key_usage_flags(attributes) & PSA_KEY_USAGE_EXPORT) { 56 return 1; 57 } else if (PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(attributes))) { 58 return 1; 59 } else { 60 return 0; 61 } 62} 63 64#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) 65static int is_accelerated_rsa(psa_algorithm_t alg) 66{ 67#if defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN) 68 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) { 69 return 1; 70 } 71#endif 72#if defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PSS) 73 if (PSA_ALG_IS_RSA_PSS(alg)) { 74 return 1; 75 } 76#endif 77#if defined(MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP) 78 if (PSA_ALG_IS_RSA_OAEP(alg)) { 79 return 1; 80 } 81#endif 82 (void) alg; 83 return 0; 84} 85#endif 86 87/* Mbed TLS doesn't support certain combinations of key type and algorithm 88 * in certain configurations. */ 89static int can_exercise(const psa_key_attributes_t *attributes) 90{ 91 psa_key_type_t key_type = psa_get_key_type(attributes); 92 psa_algorithm_t alg = psa_get_key_algorithm(attributes); 93 psa_algorithm_t hash_alg = 94 PSA_ALG_IS_HASH_AND_SIGN(alg) ? PSA_ALG_SIGN_GET_HASH(alg) : 95 PSA_ALG_IS_RSA_OAEP(alg) ? PSA_ALG_RSA_OAEP_GET_HASH(alg) : 96 PSA_ALG_NONE; 97 psa_key_usage_t usage = psa_get_key_usage_flags(attributes); 98 99#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) 100 /* We test some configurations using drivers where the driver doesn't 101 * support certain hash algorithms, but declares that it supports 102 * compound algorithms that use those hashes. Until this is fixed, 103 * in those configurations, don't try to actually perform operations. 104 * 105 * Hash-and-sign algorithms where the asymmetric part doesn't use 106 * a hash operation are ok. So randomized ECDSA signature is fine, 107 * ECDSA verification is fine, but deterministic ECDSA signature is 108 * affected. All RSA signatures are affected except raw PKCS#1v1.5. 109 * OAEP is also affected. 110 */ 111 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg) && 112 !(usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE))) { 113 /* Verification only. Verification doesn't use the hash algorithm. */ 114 return 1; 115 } 116 117#if defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA) 118 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg) && 119 (hash_alg == PSA_ALG_MD5 || 120 hash_alg == PSA_ALG_RIPEMD160 || 121 hash_alg == PSA_ALG_SHA_1)) { 122 return 0; 123 } 124#endif 125 126 if (is_accelerated_rsa(alg) && 127 (hash_alg == PSA_ALG_RIPEMD160 || hash_alg == PSA_ALG_SHA_384)) { 128 return 0; 129 } 130#endif /* MBEDTLS_TEST_LIBTESTDRIVER1 */ 131 132 (void) key_type; 133 (void) alg; 134 (void) hash_alg; 135 (void) usage; 136 return 1; 137} 138 139/** Write a key with the given representation to storage, then check 140 * that it has the given attributes and (if exportable) key material. 141 * 142 * On error, including if the key representation in storage differs, 143 * mark the test case as failed and return 0. On success, return 1. 144 */ 145static int test_read_key(const psa_key_attributes_t *expected_attributes, 146 const data_t *expected_material, 147 psa_storage_uid_t uid, 148 const data_t *representation, 149 int flags) 150{ 151 psa_key_attributes_t actual_attributes = PSA_KEY_ATTRIBUTES_INIT; 152 mbedtls_svc_key_id_t key_id = psa_get_key_id(expected_attributes); 153 struct psa_storage_info_t storage_info; 154 int ok = 0; 155 uint8_t *exported_material = NULL; 156 size_t length; 157 158 /* Prime the storage with a key file. */ 159 PSA_ASSERT(psa_its_set(uid, representation->len, representation->x, 0)); 160 161 /* Check that the injected key exists and looks as expected. */ 162 PSA_ASSERT(psa_get_key_attributes(key_id, &actual_attributes)); 163 TEST_ASSERT(mbedtls_svc_key_id_equal(key_id, 164 psa_get_key_id(&actual_attributes))); 165 TEST_EQUAL(psa_get_key_lifetime(expected_attributes), 166 psa_get_key_lifetime(&actual_attributes)); 167 TEST_EQUAL(psa_get_key_type(expected_attributes), 168 psa_get_key_type(&actual_attributes)); 169 TEST_EQUAL(psa_get_key_bits(expected_attributes), 170 psa_get_key_bits(&actual_attributes)); 171 TEST_EQUAL(psa_get_key_usage_flags(expected_attributes), 172 psa_get_key_usage_flags(&actual_attributes)); 173 TEST_EQUAL(psa_get_key_algorithm(expected_attributes), 174 psa_get_key_algorithm(&actual_attributes)); 175 TEST_EQUAL(psa_get_key_enrollment_algorithm(expected_attributes), 176 psa_get_key_enrollment_algorithm(&actual_attributes)); 177 if (can_export(expected_attributes)) { 178 TEST_CALLOC(exported_material, expected_material->len); 179 PSA_ASSERT(psa_export_key(key_id, 180 exported_material, expected_material->len, 181 &length)); 182 TEST_MEMORY_COMPARE(expected_material->x, expected_material->len, 183 exported_material, length); 184 } 185 186 if ((flags & TEST_FLAG_EXERCISE) && can_exercise(&actual_attributes)) { 187 TEST_ASSERT(mbedtls_test_psa_exercise_key( 188 key_id, 189 psa_get_key_usage_flags(expected_attributes), 190 psa_get_key_algorithm(expected_attributes), 0)); 191 } 192 193 194 if (flags & TEST_FLAG_READ_ONLY) { 195 /* Read-only keys cannot be removed through the API. 196 * The key will be removed through ITS in the cleanup code below. */ 197 TEST_EQUAL(PSA_ERROR_NOT_PERMITTED, psa_destroy_key(key_id)); 198 } else { 199 /* Destroy the key. Confirm through direct access to the storage. */ 200 PSA_ASSERT(psa_destroy_key(key_id)); 201 TEST_EQUAL(PSA_ERROR_DOES_NOT_EXIST, 202 psa_its_get_info(uid, &storage_info)); 203 } 204 205 ok = 1; 206 207exit: 208 psa_reset_key_attributes(&actual_attributes); 209 psa_its_remove(uid); 210 mbedtls_free(exported_material); 211 return ok; 212} 213 214/* END_HEADER */ 215 216/* BEGIN_DEPENDENCIES 217 * depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_PSA_CRYPTO_STORAGE_C 218 * END_DEPENDENCIES 219 */ 220 221/* BEGIN_CASE */ 222void key_storage_save(int lifetime_arg, int type_arg, int bits_arg, 223 int usage_arg, int alg_arg, int alg2_arg, 224 data_t *material, 225 data_t *representation) 226{ 227 /* Forward compatibility: save a key in the current format and 228 * check that it has the expected format so that future versions 229 * will still be able to read it. */ 230 231 psa_key_lifetime_t lifetime = lifetime_arg; 232 psa_key_type_t type = type_arg; 233 size_t bits = bits_arg; 234 psa_key_usage_t usage = usage_arg; 235 psa_algorithm_t alg = alg_arg; 236 psa_algorithm_t alg2 = alg2_arg; 237 mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make(0, 1); 238 psa_storage_uid_t uid = 1; 239 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 240 241 PSA_INIT(); 242 TEST_USES_KEY_ID(key_id); 243 244 psa_set_key_lifetime(&attributes, lifetime); 245 psa_set_key_id(&attributes, key_id); 246 psa_set_key_type(&attributes, type); 247 psa_set_key_bits(&attributes, bits); 248 psa_set_key_usage_flags(&attributes, usage); 249 psa_set_key_algorithm(&attributes, alg); 250 psa_set_key_enrollment_algorithm(&attributes, alg2); 251 252 /* This is the current storage format. Test that we know exactly how 253 * the key is stored. The stability of the test data in future 254 * versions of Mbed TLS will guarantee that future versions 255 * can read back what this version wrote. */ 256 TEST_ASSERT(test_written_key(&attributes, material, 257 uid, representation)); 258 259exit: 260 psa_reset_key_attributes(&attributes); 261 psa_destroy_key(key_id); 262 PSA_DONE(); 263} 264/* END_CASE */ 265 266/* BEGIN_CASE */ 267void key_storage_read(int lifetime_arg, int type_arg, int bits_arg, 268 int usage_arg, int alg_arg, int alg2_arg, 269 data_t *material, 270 data_t *representation, int flags) 271{ 272 /* Backward compatibility: read a key in the format of a past version 273 * and check that this version can use it. */ 274 275 psa_key_lifetime_t lifetime = lifetime_arg; 276 psa_key_type_t type = type_arg; 277 size_t bits = bits_arg; 278 psa_key_usage_t usage = usage_arg; 279 psa_algorithm_t alg = alg_arg; 280 psa_algorithm_t alg2 = alg2_arg; 281 mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make(0, 1); 282 psa_storage_uid_t uid = 1; 283 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 284 285 PSA_INIT(); 286 TEST_USES_KEY_ID(key_id); 287 288 psa_set_key_lifetime(&attributes, lifetime); 289 psa_set_key_id(&attributes, key_id); 290 psa_set_key_type(&attributes, type); 291 psa_set_key_bits(&attributes, bits); 292 psa_set_key_usage_flags(&attributes, usage); 293 psa_set_key_algorithm(&attributes, alg); 294 psa_set_key_enrollment_algorithm(&attributes, alg2); 295 296 /* Test that we can use a key with the given representation. This 297 * guarantees backward compatibility with keys that were stored by 298 * past versions of Mbed TLS. */ 299 TEST_ASSERT(test_read_key(&attributes, material, 300 uid, representation, flags)); 301 302exit: 303 psa_reset_key_attributes(&attributes); 304 PSA_DONE(); 305} 306/* END_CASE */ 307