1/* BEGIN_HEADER */ 2#include "mbedtls/pk.h" 3#include "mbedtls/pem.h" 4#include "mbedtls/oid.h" 5#include "mbedtls/ecp.h" 6#include "mbedtls/psa_util.h" 7#include "pk_internal.h" 8 9#if defined(MBEDTLS_PSA_CRYPTO_C) 10#include "test/psa_exercise_key.h" 11#endif 12 13#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) 14#define HAVE_mbedtls_pk_parse_key_pkcs8_encrypted_der 15#endif 16 17#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_FS_IO) 18static int test_psa_bridge(const mbedtls_pk_context *ctx, 19 psa_key_usage_t usage_flag) 20{ 21 switch (usage_flag) { 22 case PSA_KEY_USAGE_SIGN_HASH: 23 mbedtls_test_set_step(0); 24 break; 25 case PSA_KEY_USAGE_SIGN_MESSAGE: 26 mbedtls_test_set_step(1); 27 break; 28 case PSA_KEY_USAGE_DECRYPT: 29 mbedtls_test_set_step(2); 30 break; 31 case PSA_KEY_USAGE_DERIVE: 32 mbedtls_test_set_step(3); 33 break; 34 case PSA_KEY_USAGE_VERIFY_HASH: 35 mbedtls_test_set_step(4); 36 break; 37 case PSA_KEY_USAGE_VERIFY_MESSAGE: 38 mbedtls_test_set_step(5); 39 break; 40 case PSA_KEY_USAGE_ENCRYPT: 41 mbedtls_test_set_step(6); 42 break; 43 } 44 45 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 46 mbedtls_svc_key_id_t psa_key = MBEDTLS_SVC_KEY_ID_INIT; 47 int ok = 0; 48 49 TEST_EQUAL(mbedtls_pk_get_psa_attributes(ctx, usage_flag, &attributes), 0); 50 int ret = mbedtls_pk_import_into_psa(ctx, &attributes, &psa_key); 51 if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_RSA && 52 mbedtls_pk_get_bitlen(ctx) % 8 != 0 && 53 ret == MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) { 54 /* There is a historical limitation with support for RSA keys in PSA: 55 * only byte-aligned sizes are supported. 56 * https://github.com/Mbed-TLS/mbedtls/issues/9048 57 * For now, for such keys, treat not-supported from PSA as a success. 58 */ 59 ok = 1; 60 goto exit; 61 } 62 TEST_EQUAL(ret, 0); 63 if (!mbedtls_test_key_consistency_psa_pk(psa_key, ctx)) { 64 goto exit; 65 } 66 67 psa_algorithm_t exercise_usage = psa_get_key_usage_flags(&attributes); 68 psa_algorithm_t exercise_alg = psa_get_key_algorithm(&attributes); 69 if (mbedtls_test_can_exercise_psa_algorithm(exercise_alg)) { 70 TEST_ASSERT(mbedtls_test_psa_exercise_key(psa_key, 71 exercise_usage, 72 exercise_alg, 0)); 73 } 74 75 mbedtls_test_set_step((unsigned long) -1); 76 ok = 1; 77 78exit: 79 psa_destroy_key(psa_key); 80 psa_reset_key_attributes(&attributes); 81 return ok; 82} 83 84#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 85/* Whether a pk key can do ECDSA. Opaque keys are not supported since this 86 * test suite does not create opaque keys. */ 87static int pk_can_ecdsa(const mbedtls_pk_context *ctx) 88{ 89 /* Check whether we have an EC key. Unfortunately this also accepts 90 * keys on Montgomery curves, which can only do ECDH, so we'll have 91 * to dig further. */ 92 if (!mbedtls_pk_can_do(ctx, MBEDTLS_PK_ECDSA)) { 93 return 0; 94 } 95#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 96 return ctx->ec_family != PSA_ECC_FAMILY_MONTGOMERY; 97#elif defined(MBEDTLS_ECDSA_C) 98 return mbedtls_ecdsa_can_do(mbedtls_pk_ec_ro(*ctx)->grp.id); 99#else 100 return 0; 101#endif 102} 103#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 104#endif /* MBEDTLS_PSA_CRYPTO_C && && MBEDTLS_FS_IO */ 105 106/* END_HEADER */ 107 108/* BEGIN_DEPENDENCIES 109 * depends_on:MBEDTLS_PK_PARSE_C 110 * END_DEPENDENCIES 111 */ 112 113/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_FS_IO */ 114void pk_parse_keyfile_rsa(char *key_file, char *password, int result) 115{ 116 mbedtls_pk_context ctx; 117 int res; 118 char *pwd = password; 119 120 mbedtls_pk_init(&ctx); 121 MD_PSA_INIT(); 122 123 if (strcmp(pwd, "NULL") == 0) { 124 pwd = NULL; 125 } 126 127 res = mbedtls_pk_parse_keyfile(&ctx, key_file, pwd, 128 mbedtls_test_rnd_std_rand, NULL); 129 130 TEST_EQUAL(res, result); 131 132 if (res == 0) { 133 mbedtls_rsa_context *rsa; 134 TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_RSA)); 135 rsa = mbedtls_pk_rsa(ctx); 136 TEST_EQUAL(mbedtls_rsa_check_privkey(rsa), 0); 137 138 size_t bitlen = mbedtls_rsa_get_bitlen(rsa); 139 TEST_EQUAL(mbedtls_pk_get_bitlen(&ctx), bitlen); 140 TEST_EQUAL(mbedtls_pk_get_len(&ctx), (bitlen + 7) / 8); 141 142#if defined(MBEDTLS_PSA_CRYPTO_C) 143 PSA_INIT(); 144 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_SIGN_HASH)); 145 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_SIGN_MESSAGE)); 146 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_DECRYPT)); 147 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_HASH)); 148 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_MESSAGE)); 149 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_ENCRYPT)); 150#endif 151 } 152 153exit: 154 mbedtls_pk_free(&ctx); 155 PSA_DONE(); 156} 157 158/* END_CASE */ 159 160/* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_FS_IO */ 161void pk_parse_public_keyfile_rsa(char *key_file, int result) 162{ 163 mbedtls_pk_context ctx; 164 int res; 165 166 mbedtls_pk_init(&ctx); 167 MD_PSA_INIT(); 168 169 res = mbedtls_pk_parse_public_keyfile(&ctx, key_file); 170 171 TEST_EQUAL(res, result); 172 173 if (res == 0) { 174 mbedtls_rsa_context *rsa; 175 TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_RSA)); 176 rsa = mbedtls_pk_rsa(ctx); 177 TEST_EQUAL(mbedtls_rsa_check_pubkey(rsa), 0); 178 179 size_t bitlen = mbedtls_rsa_get_bitlen(rsa); 180 TEST_EQUAL(mbedtls_pk_get_bitlen(&ctx), bitlen); 181 TEST_EQUAL(mbedtls_pk_get_len(&ctx), (bitlen + 7) / 8); 182 183#if defined(MBEDTLS_PSA_CRYPTO_C) 184 PSA_INIT(); 185 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_HASH)); 186 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_MESSAGE)); 187 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_ENCRYPT)); 188#endif 189 } 190 191exit: 192 mbedtls_pk_free(&ctx); 193 PSA_DONE(); 194} 195/* END_CASE */ 196 197/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_PK_HAVE_ECC_KEYS */ 198void pk_parse_public_keyfile_ec(char *key_file, int result) 199{ 200 mbedtls_pk_context ctx; 201 int res; 202 203 mbedtls_pk_init(&ctx); 204 MD_OR_USE_PSA_INIT(); 205 206 res = mbedtls_pk_parse_public_keyfile(&ctx, key_file); 207 208 TEST_EQUAL(res, result); 209 210 if (res == 0) { 211 TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_ECKEY)); 212#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 213 /* No need to check whether the parsed public point is on the curve or 214 * not because this is already done by the internal "pk_get_ecpubkey()" 215 * function */ 216#else 217 const mbedtls_ecp_keypair *eckey; 218 eckey = mbedtls_pk_ec_ro(ctx); 219 TEST_EQUAL(mbedtls_ecp_check_pubkey(&eckey->grp, &eckey->Q), 0); 220#endif 221 222#if defined(MBEDTLS_PSA_CRYPTO_C) 223 PSA_INIT(); 224 if (pk_can_ecdsa(&ctx)) { 225 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_HASH)); 226 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_MESSAGE)); 227 } 228#endif 229 } 230 231exit: 232 mbedtls_pk_free(&ctx); 233 PSA_DONE(); 234} 235/* END_CASE */ 236 237/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_PK_HAVE_ECC_KEYS */ 238void pk_parse_keyfile_ec(char *key_file, char *password, int result) 239{ 240 mbedtls_pk_context ctx; 241 int res; 242 243 mbedtls_pk_init(&ctx); 244 MD_OR_USE_PSA_INIT(); 245 246 res = mbedtls_pk_parse_keyfile(&ctx, key_file, password, 247 mbedtls_test_rnd_std_rand, NULL); 248 249 TEST_EQUAL(res, result); 250 251 if (res == 0) { 252 TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_ECKEY)); 253#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 254 /* PSA keys are already checked on import so nothing to do here. */ 255#else 256 const mbedtls_ecp_keypair *eckey = mbedtls_pk_ec_ro(ctx); 257 TEST_EQUAL(mbedtls_ecp_check_privkey(&eckey->grp, &eckey->d), 0); 258#endif 259 260#if defined(MBEDTLS_PSA_CRYPTO_C) 261 PSA_INIT(); 262 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_DERIVE)); 263 if (pk_can_ecdsa(&ctx)) { 264 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_SIGN_HASH)); 265 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_SIGN_MESSAGE)); 266 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_HASH)); 267 TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_MESSAGE)); 268 } 269#endif 270 } 271 272exit: 273 mbedtls_pk_free(&ctx); 274 PSA_DONE(); 275} 276/* END_CASE */ 277 278/* BEGIN_CASE */ 279void pk_parse_key(data_t *buf, int result) 280{ 281 mbedtls_pk_context pk; 282 283 mbedtls_pk_init(&pk); 284 USE_PSA_INIT(); 285 286 TEST_ASSERT(mbedtls_pk_parse_key(&pk, buf->x, buf->len, NULL, 0, 287 mbedtls_test_rnd_std_rand, NULL) == result); 288 289exit: 290 mbedtls_pk_free(&pk); 291 USE_PSA_DONE(); 292} 293/* END_CASE */ 294 295/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:HAVE_mbedtls_pk_parse_key_pkcs8_encrypted_der */ 296void pk_parse_key_encrypted(data_t *buf, data_t *pass, int result) 297{ 298 mbedtls_pk_context pk; 299 300 mbedtls_pk_init(&pk); 301 USE_PSA_INIT(); 302 303 TEST_EQUAL(mbedtls_pk_parse_key_pkcs8_encrypted_der(&pk, buf->x, buf->len, 304 pass->x, pass->len, 305 mbedtls_test_rnd_std_rand, 306 NULL), result); 307exit: 308 mbedtls_pk_free(&pk); 309 USE_PSA_DONE(); 310} 311/* END_CASE */ 312 313/* BEGIN_CASE depends_on:MBEDTLS_PK_HAVE_ECC_KEYS:MBEDTLS_PK_WRITE_C */ 314void pk_parse_fix_montgomery(data_t *input_key, data_t *exp_output) 315{ 316 /* Montgomery keys have specific bits set to either 0 or 1 depending on 317 * their position. This is enforced during parsing (please see the implementation 318 * of mbedtls_ecp_read_key() for more details). The scope of this function 319 * is to verify this enforcing by feeding the parse algorithm with a x25519 320 * key which does not have those bits set properly. */ 321 mbedtls_pk_context pk; 322 unsigned char *output_key = NULL; 323 size_t output_key_len = 0; 324 325 mbedtls_pk_init(&pk); 326 USE_PSA_INIT(); 327 328 TEST_EQUAL(mbedtls_pk_parse_key(&pk, input_key->x, input_key->len, NULL, 0, 329 mbedtls_test_rnd_std_rand, NULL), 0); 330 331 output_key_len = input_key->len; 332 TEST_CALLOC(output_key, output_key_len); 333 /* output_key_len is updated with the real amount of data written to 334 * output_key buffer. */ 335 output_key_len = mbedtls_pk_write_key_der(&pk, output_key, output_key_len); 336 TEST_ASSERT(output_key_len > 0); 337 338 TEST_MEMORY_COMPARE(exp_output->x, exp_output->len, output_key, output_key_len); 339 340exit: 341 if (output_key != NULL) { 342 mbedtls_free(output_key); 343 } 344 mbedtls_pk_free(&pk); 345 USE_PSA_DONE(); 346} 347/* END_CASE */ 348