1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-07-30 22:43:08 +03:00

Merge pull request #8738 from gilles-peskine-arm/pk_import_into_psa-use_usage

Implement mbedtls_pk_get_psa_attributes
This commit is contained in:
Gilles Peskine
2024-02-06 17:28:54 +00:00
committed by GitHub
8 changed files with 1208 additions and 26 deletions

View File

@ -29,7 +29,7 @@
#include "mbedtls/ecdsa.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
#include "psa_util_internal.h"
#include "mbedtls/psa_util.h"
#endif
@ -378,6 +378,209 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_PSA_CRYPTO_C)
#if defined(MBEDTLS_RSA_C)
static psa_algorithm_t psa_algorithm_for_rsa(const mbedtls_rsa_context *rsa,
int want_crypt)
{
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
if (want_crypt) {
mbedtls_md_type_t md_type = mbedtls_rsa_get_md_alg(rsa);
return PSA_ALG_RSA_OAEP(mbedtls_md_psa_alg_from_type(md_type));
} else {
return PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH);
}
} else {
if (want_crypt) {
return PSA_ALG_RSA_PKCS1V15_CRYPT;
} else {
return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH);
}
}
}
#endif /* MBEDTLS_RSA_C */
int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk,
psa_key_usage_t usage,
psa_key_attributes_t *attributes)
{
mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
psa_key_usage_t more_usage = usage;
if (usage == PSA_KEY_USAGE_SIGN_MESSAGE) {
more_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE;
} else if (usage == PSA_KEY_USAGE_SIGN_HASH) {
more_usage |= PSA_KEY_USAGE_VERIFY_HASH;
} else if (usage == PSA_KEY_USAGE_DECRYPT) {
more_usage |= PSA_KEY_USAGE_ENCRYPT;
}
more_usage |= PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY;
int want_private = !(usage == PSA_KEY_USAGE_VERIFY_MESSAGE ||
usage == PSA_KEY_USAGE_VERIFY_HASH ||
usage == PSA_KEY_USAGE_ENCRYPT);
switch (pk_type) {
#if defined(MBEDTLS_RSA_C)
case MBEDTLS_PK_RSA:
{
int want_crypt = 0; /* 0: sign/verify; 1: encrypt/decrypt */
switch (usage) {
case PSA_KEY_USAGE_SIGN_MESSAGE:
case PSA_KEY_USAGE_SIGN_HASH:
case PSA_KEY_USAGE_VERIFY_MESSAGE:
case PSA_KEY_USAGE_VERIFY_HASH:
/* Nothing to do. */
break;
case PSA_KEY_USAGE_DECRYPT:
case PSA_KEY_USAGE_ENCRYPT:
want_crypt = 1;
break;
default:
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
/* Detect the presence of a private key in a way that works both
* in CRT and non-CRT configurations. */
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
int has_private = (mbedtls_rsa_check_privkey(rsa) == 0);
if (want_private && !has_private) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
psa_set_key_type(attributes, (want_private ?
PSA_KEY_TYPE_RSA_KEY_PAIR :
PSA_KEY_TYPE_RSA_PUBLIC_KEY));
psa_set_key_bits(attributes, mbedtls_pk_get_bitlen(pk));
psa_set_key_algorithm(attributes,
psa_algorithm_for_rsa(rsa, want_crypt));
break;
}
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
case MBEDTLS_PK_ECKEY:
case MBEDTLS_PK_ECKEY_DH:
case MBEDTLS_PK_ECDSA:
{
int sign_ok = (pk_type != MBEDTLS_PK_ECKEY_DH);
int derive_ok = (pk_type != MBEDTLS_PK_ECDSA);
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
psa_ecc_family_t family = pk->ec_family;
size_t bits = pk->ec_bits;
int has_private = 0;
if (pk->priv_id != MBEDTLS_SVC_KEY_ID_INIT) {
has_private = 1;
}
#else
const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
int has_private = (ec->d.n != 0);
size_t bits = 0;
psa_ecc_family_t family =
mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
#endif
psa_algorithm_t alg = 0;
switch (usage) {
case PSA_KEY_USAGE_SIGN_MESSAGE:
case PSA_KEY_USAGE_SIGN_HASH:
case PSA_KEY_USAGE_VERIFY_MESSAGE:
case PSA_KEY_USAGE_VERIFY_HASH:
if (!sign_ok) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH);
#else
alg = PSA_ALG_ECDSA(PSA_ALG_ANY_HASH);
#endif
break;
case PSA_KEY_USAGE_DERIVE:
alg = PSA_ALG_ECDH;
if (!derive_ok) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
break;
default:
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
if (want_private && !has_private) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
psa_set_key_type(attributes, (want_private ?
PSA_KEY_TYPE_ECC_KEY_PAIR(family) :
PSA_KEY_TYPE_ECC_PUBLIC_KEY(family)));
psa_set_key_bits(attributes, bits);
psa_set_key_algorithm(attributes, alg);
break;
}
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
case MBEDTLS_PK_RSA_ALT:
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
case MBEDTLS_PK_OPAQUE:
{
psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
status = psa_get_key_attributes(pk->priv_id, &old_attributes);
if (status != PSA_SUCCESS) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
psa_key_type_t old_type = psa_get_key_type(&old_attributes);
switch (usage) {
case PSA_KEY_USAGE_SIGN_MESSAGE:
case PSA_KEY_USAGE_SIGN_HASH:
case PSA_KEY_USAGE_VERIFY_MESSAGE:
case PSA_KEY_USAGE_VERIFY_HASH:
if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type) ||
old_type == PSA_KEY_TYPE_RSA_KEY_PAIR)) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
break;
case PSA_KEY_USAGE_DECRYPT:
case PSA_KEY_USAGE_ENCRYPT:
if (old_type != PSA_KEY_TYPE_RSA_KEY_PAIR) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
break;
case PSA_KEY_USAGE_DERIVE:
if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type))) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
break;
default:
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
psa_key_type_t new_type = old_type;
/* Opaque keys are always key pairs, so we don't need a check
* on the input if the required usage is private. We just need
* to adjust the type correctly if the required usage is public. */
if (!want_private) {
new_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(new_type);
}
more_usage = psa_get_key_usage_flags(&old_attributes);
if ((usage & more_usage) == 0) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
psa_set_key_type(attributes, new_type);
psa_set_key_bits(attributes, psa_get_key_bits(&old_attributes));
psa_set_key_algorithm(attributes, psa_get_key_algorithm(&old_attributes));
break;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
default:
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
psa_set_key_usage_flags(attributes, more_usage);
psa_set_key_enrollment_algorithm(attributes, PSA_ALG_NONE);
return 0;
}
#endif /* MBEDTLS_PSA_CRYPTO_C */
/*
* Helper for mbedtls_pk_sign and mbedtls_pk_verify
*/

View File

@ -2005,9 +2005,9 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
}
#if defined(MBEDTLS_ECP_C)
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
const mbedtls_ecp_keypair *peer_key = mbedtls_pk_ec_ro(*peer_pk);
#endif /* MBEDTLS_ECP_C */
#endif /* !defined(MBEDTLS_PK_USE_PSA_EC_DATA) */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
uint16_t tls_id = 0;