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:
205
library/pk.c
205
library/pk.c
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user