mbedtls_pk_get_psa_attributes: RSA support
Add code and unit tests for MBEDTLS_PK_RSA in mbedtls_pk_get_psa_attributes().
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/library/pk.c b/library/pk.c
index 706d5d3..1485bd7 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -379,6 +379,27 @@
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
+#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)
@@ -386,6 +407,49 @@
mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
switch (pk_type) {
+#if defined(MBEDTLS_RSA_C)
+ case MBEDTLS_PK_RSA:
+ int want_crypt = 0;
+ int want_private = 0;
+ switch (usage) {
+ case PSA_KEY_USAGE_SIGN_MESSAGE:
+ usage |= PSA_KEY_USAGE_VERIFY_MESSAGE;
+ want_private = 1;
+ break;
+ case PSA_KEY_USAGE_SIGN_HASH:
+ usage |= PSA_KEY_USAGE_VERIFY_HASH;
+ want_private = 1;
+ break;
+ case PSA_KEY_USAGE_DECRYPT:
+ usage |= PSA_KEY_USAGE_ENCRYPT;
+ want_private = 1;
+ want_crypt = 1;
+ break;
+ case PSA_KEY_USAGE_VERIFY_MESSAGE:
+ case PSA_KEY_USAGE_VERIFY_HASH:
+ break;
+ 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_mpi_bitlen(&rsa->N));
+ psa_set_key_algorithm(attributes,
+ psa_algorithm_for_rsa(rsa, want_crypt));
+ break;
+#endif /* MBEDTLS_RSA_C */
+
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
case MBEDTLS_PK_RSA_ALT:
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;