test_suite_pkparse.function (10733B)
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) 18 static 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 78 exit: 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. */ 87 static 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 */ 114 void pk_parse_keyfile_rsa(char *key_file, char *password, int result) 115 { 116 mbedtls_pk_context ctx; 117 mbedtls_pk_init(&ctx); 118 int res; 119 char *pwd = password; 120 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 153 exit: 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 */ 161 void pk_parse_public_keyfile_rsa(char *key_file, int result) 162 { 163 mbedtls_pk_context ctx; 164 mbedtls_pk_init(&ctx); 165 int res; 166 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 191 exit: 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 */ 198 void 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 231 exit: 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 */ 238 void 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 272 exit: 273 mbedtls_pk_free(&ctx); 274 PSA_DONE(); 275 } 276 /* END_CASE */ 277 278 /* BEGIN_CASE */ 279 void 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 289 exit: 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 */ 296 void 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); 307 exit: 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 */ 314 void 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 340 exit: 341 if (output_key != NULL) { 342 mbedtls_free(output_key); 343 } 344 mbedtls_pk_free(&pk); 345 USE_PSA_DONE(); 346 } 347 /* END_CASE */