1817466cbSJens Wiklander /* 2817466cbSJens Wiklander * Public Key abstraction layer 3817466cbSJens Wiklander * 47901324dSJerome Forissier * Copyright The Mbed TLS Contributors 5b0563631STom Van Eyck * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6817466cbSJens Wiklander */ 7817466cbSJens Wiklander 87901324dSJerome Forissier #include "common.h" 9817466cbSJens Wiklander 10817466cbSJens Wiklander #if defined(MBEDTLS_PK_C) 11817466cbSJens Wiklander #include "mbedtls/pk.h" 1232b31808SJens Wiklander #include "pk_wrap.h" 1332b31808SJens Wiklander #include "pkwrite.h" 14b0563631STom Van Eyck #include "pk_internal.h" 15817466cbSJens Wiklander 163d3b0591SJens Wiklander #include "mbedtls/platform_util.h" 1711fa71b9SJerome Forissier #include "mbedtls/error.h" 18817466cbSJens Wiklander 19817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 20817466cbSJens Wiklander #include "mbedtls/rsa.h" 21b0563631STom Van Eyck #include "rsa_internal.h" 22817466cbSJens Wiklander #endif 23b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 24817466cbSJens Wiklander #include "mbedtls/ecp.h" 25817466cbSJens Wiklander #endif 26817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 27817466cbSJens Wiklander #include "mbedtls/ecdsa.h" 28817466cbSJens Wiklander #endif 29817466cbSJens Wiklander 30b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_CLIENT) 31b0563631STom Van Eyck #include "psa_util_internal.h" 3211fa71b9SJerome Forissier #include "mbedtls/psa_util.h" 3311fa71b9SJerome Forissier #endif 3411fa71b9SJerome Forissier 35817466cbSJens Wiklander #include <limits.h> 363d3b0591SJens Wiklander #include <stdint.h> 37817466cbSJens Wiklander 38b0563631STom Van Eyck #define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE \ 39b0563631STom Van Eyck (PSA_EXPORT_KEY_PAIR_MAX_SIZE > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) ? \ 40b0563631STom Van Eyck PSA_EXPORT_KEY_PAIR_MAX_SIZE : PSA_EXPORT_PUBLIC_KEY_MAX_SIZE 41b0563631STom Van Eyck 42817466cbSJens Wiklander /* 43817466cbSJens Wiklander * Initialise a mbedtls_pk_context 44817466cbSJens Wiklander */ 45817466cbSJens Wiklander void mbedtls_pk_init(mbedtls_pk_context *ctx) 46817466cbSJens Wiklander { 47817466cbSJens Wiklander ctx->pk_info = NULL; 48817466cbSJens Wiklander ctx->pk_ctx = NULL; 49b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO) 50b0563631STom Van Eyck ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT; 51b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */ 52b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 53b0563631STom Van Eyck memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw)); 54b0563631STom Van Eyck ctx->pub_raw_len = 0; 55b0563631STom Van Eyck ctx->ec_family = 0; 56b0563631STom Van Eyck ctx->ec_bits = 0; 57b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 58817466cbSJens Wiklander } 59817466cbSJens Wiklander 60817466cbSJens Wiklander /* 61817466cbSJens Wiklander * Free (the components of) a mbedtls_pk_context 62817466cbSJens Wiklander */ 63817466cbSJens Wiklander void mbedtls_pk_free(mbedtls_pk_context *ctx) 64817466cbSJens Wiklander { 6532b31808SJens Wiklander if (ctx == NULL) { 66817466cbSJens Wiklander return; 6732b31808SJens Wiklander } 68817466cbSJens Wiklander 69b0563631STom Van Eyck if ((ctx->pk_info != NULL) && (ctx->pk_info->ctx_free_func != NULL)) { 70817466cbSJens Wiklander ctx->pk_info->ctx_free_func(ctx->pk_ctx); 7132b31808SJens Wiklander } 72817466cbSJens Wiklander 73b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 74b0563631STom Van Eyck /* The ownership of the priv_id key for opaque keys is external of the PK 75b0563631STom Van Eyck * module. It's the user responsibility to clear it after use. */ 76b0563631STom Van Eyck if ((ctx->pk_info != NULL) && (ctx->pk_info->type != MBEDTLS_PK_OPAQUE)) { 77b0563631STom Van Eyck psa_destroy_key(ctx->priv_id); 78b0563631STom Van Eyck } 79b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 80b0563631STom Van Eyck 813d3b0591SJens Wiklander mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context)); 82817466cbSJens Wiklander } 83817466cbSJens Wiklander 843d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 853d3b0591SJens Wiklander /* 863d3b0591SJens Wiklander * Initialize a restart context 873d3b0591SJens Wiklander */ 883d3b0591SJens Wiklander void mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx) 893d3b0591SJens Wiklander { 903d3b0591SJens Wiklander ctx->pk_info = NULL; 913d3b0591SJens Wiklander ctx->rs_ctx = NULL; 923d3b0591SJens Wiklander } 933d3b0591SJens Wiklander 943d3b0591SJens Wiklander /* 953d3b0591SJens Wiklander * Free the components of a restart context 963d3b0591SJens Wiklander */ 973d3b0591SJens Wiklander void mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx) 983d3b0591SJens Wiklander { 993d3b0591SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL || 10032b31808SJens Wiklander ctx->pk_info->rs_free_func == NULL) { 1013d3b0591SJens Wiklander return; 1023d3b0591SJens Wiklander } 1033d3b0591SJens Wiklander 1043d3b0591SJens Wiklander ctx->pk_info->rs_free_func(ctx->rs_ctx); 1053d3b0591SJens Wiklander 1063d3b0591SJens Wiklander ctx->pk_info = NULL; 1073d3b0591SJens Wiklander ctx->rs_ctx = NULL; 1083d3b0591SJens Wiklander } 1093d3b0591SJens Wiklander #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 1103d3b0591SJens Wiklander 111817466cbSJens Wiklander /* 112817466cbSJens Wiklander * Get pk_info structure from type 113817466cbSJens Wiklander */ 114817466cbSJens Wiklander const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type) 115817466cbSJens Wiklander { 116817466cbSJens Wiklander switch (pk_type) { 117817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 118817466cbSJens Wiklander case MBEDTLS_PK_RSA: 11932b31808SJens Wiklander return &mbedtls_rsa_info; 120b0563631STom Van Eyck #endif /* MBEDTLS_RSA_C */ 121b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 122817466cbSJens Wiklander case MBEDTLS_PK_ECKEY: 12332b31808SJens Wiklander return &mbedtls_eckey_info; 124817466cbSJens Wiklander case MBEDTLS_PK_ECKEY_DH: 12532b31808SJens Wiklander return &mbedtls_eckeydh_info; 126b0563631STom Van Eyck #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 12732b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SOME) 128817466cbSJens Wiklander case MBEDTLS_PK_ECDSA: 12932b31808SJens Wiklander return &mbedtls_ecdsa_info; 130b0563631STom Van Eyck #endif /* MBEDTLS_PK_CAN_ECDSA_SOME */ 131817466cbSJens Wiklander /* MBEDTLS_PK_RSA_ALT omitted on purpose */ 132817466cbSJens Wiklander default: 13332b31808SJens Wiklander return NULL; 134817466cbSJens Wiklander } 135817466cbSJens Wiklander } 136817466cbSJens Wiklander 137817466cbSJens Wiklander /* 138817466cbSJens Wiklander * Initialise context 139817466cbSJens Wiklander */ 140817466cbSJens Wiklander int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info) 141817466cbSJens Wiklander { 14232b31808SJens Wiklander if (info == NULL || ctx->pk_info != NULL) { 14332b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 14432b31808SJens Wiklander } 145817466cbSJens Wiklander 146b0563631STom Van Eyck if ((info->ctx_alloc_func != NULL) && 147b0563631STom Van Eyck ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)) { 14832b31808SJens Wiklander return MBEDTLS_ERR_PK_ALLOC_FAILED; 14932b31808SJens Wiklander } 150817466cbSJens Wiklander 151817466cbSJens Wiklander ctx->pk_info = info; 152817466cbSJens Wiklander 15332b31808SJens Wiklander return 0; 154817466cbSJens Wiklander } 155817466cbSJens Wiklander 15611fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 15711fa71b9SJerome Forissier /* 15811fa71b9SJerome Forissier * Initialise a PSA-wrapping context 15911fa71b9SJerome Forissier */ 1607901324dSJerome Forissier int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, 16132b31808SJens Wiklander const mbedtls_svc_key_id_t key) 16211fa71b9SJerome Forissier { 16332b31808SJens Wiklander const mbedtls_pk_info_t *info = NULL; 16411fa71b9SJerome Forissier psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 16511fa71b9SJerome Forissier psa_key_type_t type; 16611fa71b9SJerome Forissier 16732b31808SJens Wiklander if (ctx == NULL || ctx->pk_info != NULL) { 16832b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 16932b31808SJens Wiklander } 17011fa71b9SJerome Forissier 17132b31808SJens Wiklander if (PSA_SUCCESS != psa_get_key_attributes(key, &attributes)) { 17232b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 17332b31808SJens Wiklander } 17411fa71b9SJerome Forissier type = psa_get_key_type(&attributes); 17511fa71b9SJerome Forissier psa_reset_key_attributes(&attributes); 17611fa71b9SJerome Forissier 177b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 17832b31808SJens Wiklander if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) { 179b0563631STom Van Eyck info = &mbedtls_ecdsa_opaque_info; 180b0563631STom Van Eyck } else 181b0563631STom Van Eyck #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 182b0563631STom Van Eyck if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) { 183b0563631STom Van Eyck info = &mbedtls_rsa_opaque_info; 18432b31808SJens Wiklander } else { 18532b31808SJens Wiklander return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 18632b31808SJens Wiklander } 18711fa71b9SJerome Forissier 18811fa71b9SJerome Forissier ctx->pk_info = info; 189b0563631STom Van Eyck ctx->priv_id = key; 19011fa71b9SJerome Forissier 19132b31808SJens Wiklander return 0; 19211fa71b9SJerome Forissier } 19311fa71b9SJerome Forissier #endif /* MBEDTLS_USE_PSA_CRYPTO */ 19411fa71b9SJerome Forissier 195817466cbSJens Wiklander #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 196817466cbSJens Wiklander /* 197817466cbSJens Wiklander * Initialize an RSA-alt context 198817466cbSJens Wiklander */ 199817466cbSJens Wiklander int mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key, 200817466cbSJens Wiklander mbedtls_pk_rsa_alt_decrypt_func decrypt_func, 201817466cbSJens Wiklander mbedtls_pk_rsa_alt_sign_func sign_func, 202817466cbSJens Wiklander mbedtls_pk_rsa_alt_key_len_func key_len_func) 203817466cbSJens Wiklander { 204817466cbSJens Wiklander mbedtls_rsa_alt_context *rsa_alt; 205817466cbSJens Wiklander const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info; 206817466cbSJens Wiklander 20732b31808SJens Wiklander if (ctx->pk_info != NULL) { 20832b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 20932b31808SJens Wiklander } 210817466cbSJens Wiklander 21132b31808SJens Wiklander if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) { 21232b31808SJens Wiklander return MBEDTLS_ERR_PK_ALLOC_FAILED; 21332b31808SJens Wiklander } 214817466cbSJens Wiklander 215817466cbSJens Wiklander ctx->pk_info = info; 216817466cbSJens Wiklander 217817466cbSJens Wiklander rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx; 218817466cbSJens Wiklander 219817466cbSJens Wiklander rsa_alt->key = key; 220817466cbSJens Wiklander rsa_alt->decrypt_func = decrypt_func; 221817466cbSJens Wiklander rsa_alt->sign_func = sign_func; 222817466cbSJens Wiklander rsa_alt->key_len_func = key_len_func; 223817466cbSJens Wiklander 22432b31808SJens Wiklander return 0; 225817466cbSJens Wiklander } 226817466cbSJens Wiklander #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ 227817466cbSJens Wiklander 228817466cbSJens Wiklander /* 229817466cbSJens Wiklander * Tell if a PK can do the operations of the given type 230817466cbSJens Wiklander */ 231817466cbSJens Wiklander int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type) 232817466cbSJens Wiklander { 2333d3b0591SJens Wiklander /* A context with null pk_info is not set up yet and can't do anything. 2343d3b0591SJens Wiklander * For backward compatibility, also accept NULL instead of a context 2353d3b0591SJens Wiklander * pointer. */ 23632b31808SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL) { 23732b31808SJens Wiklander return 0; 238817466cbSJens Wiklander } 239817466cbSJens Wiklander 24032b31808SJens Wiklander return ctx->pk_info->can_do(type); 24132b31808SJens Wiklander } 24232b31808SJens Wiklander 24332b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 24432b31808SJens Wiklander /* 24532b31808SJens Wiklander * Tell if a PK can do the operations of the given PSA algorithm 24632b31808SJens Wiklander */ 24732b31808SJens Wiklander int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg, 24832b31808SJens Wiklander psa_key_usage_t usage) 24932b31808SJens Wiklander { 25032b31808SJens Wiklander psa_key_usage_t key_usage; 25132b31808SJens Wiklander 25232b31808SJens Wiklander /* A context with null pk_info is not set up yet and can't do anything. 25332b31808SJens Wiklander * For backward compatibility, also accept NULL instead of a context 25432b31808SJens Wiklander * pointer. */ 25532b31808SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL) { 25632b31808SJens Wiklander return 0; 25732b31808SJens Wiklander } 25832b31808SJens Wiklander 25932b31808SJens Wiklander /* Filter out non allowed algorithms */ 26032b31808SJens Wiklander if (PSA_ALG_IS_ECDSA(alg) == 0 && 26132b31808SJens Wiklander PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) == 0 && 26232b31808SJens Wiklander PSA_ALG_IS_RSA_PSS(alg) == 0 && 26332b31808SJens Wiklander alg != PSA_ALG_RSA_PKCS1V15_CRYPT && 26432b31808SJens Wiklander PSA_ALG_IS_ECDH(alg) == 0) { 26532b31808SJens Wiklander return 0; 26632b31808SJens Wiklander } 26732b31808SJens Wiklander 26832b31808SJens Wiklander /* Filter out non allowed usage flags */ 26932b31808SJens Wiklander if (usage == 0 || 27032b31808SJens Wiklander (usage & ~(PSA_KEY_USAGE_SIGN_HASH | 27132b31808SJens Wiklander PSA_KEY_USAGE_DECRYPT | 27232b31808SJens Wiklander PSA_KEY_USAGE_DERIVE)) != 0) { 27332b31808SJens Wiklander return 0; 27432b31808SJens Wiklander } 27532b31808SJens Wiklander 27632b31808SJens Wiklander /* Wildcard hash is not allowed */ 27732b31808SJens Wiklander if (PSA_ALG_IS_SIGN_HASH(alg) && 27832b31808SJens Wiklander PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH) { 27932b31808SJens Wiklander return 0; 28032b31808SJens Wiklander } 28132b31808SJens Wiklander 28232b31808SJens Wiklander if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_OPAQUE) { 28332b31808SJens Wiklander mbedtls_pk_type_t type; 28432b31808SJens Wiklander 28532b31808SJens Wiklander if (PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_ECDH(alg)) { 28632b31808SJens Wiklander type = MBEDTLS_PK_ECKEY; 28732b31808SJens Wiklander } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || 28832b31808SJens Wiklander alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { 28932b31808SJens Wiklander type = MBEDTLS_PK_RSA; 29032b31808SJens Wiklander } else if (PSA_ALG_IS_RSA_PSS(alg)) { 29132b31808SJens Wiklander type = MBEDTLS_PK_RSASSA_PSS; 29232b31808SJens Wiklander } else { 29332b31808SJens Wiklander return 0; 29432b31808SJens Wiklander } 29532b31808SJens Wiklander 29632b31808SJens Wiklander if (ctx->pk_info->can_do(type) == 0) { 29732b31808SJens Wiklander return 0; 29832b31808SJens Wiklander } 29932b31808SJens Wiklander 30032b31808SJens Wiklander switch (type) { 30132b31808SJens Wiklander case MBEDTLS_PK_ECKEY: 30232b31808SJens Wiklander key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE; 30332b31808SJens Wiklander break; 30432b31808SJens Wiklander case MBEDTLS_PK_RSA: 30532b31808SJens Wiklander case MBEDTLS_PK_RSASSA_PSS: 30632b31808SJens Wiklander key_usage = PSA_KEY_USAGE_SIGN_HASH | 30732b31808SJens Wiklander PSA_KEY_USAGE_SIGN_MESSAGE | 30832b31808SJens Wiklander PSA_KEY_USAGE_DECRYPT; 30932b31808SJens Wiklander break; 31032b31808SJens Wiklander default: 31132b31808SJens Wiklander /* Should never happen */ 31232b31808SJens Wiklander return 0; 31332b31808SJens Wiklander } 31432b31808SJens Wiklander 31532b31808SJens Wiklander return (key_usage & usage) == usage; 31632b31808SJens Wiklander } 31732b31808SJens Wiklander 31832b31808SJens Wiklander psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 31932b31808SJens Wiklander psa_status_t status; 32032b31808SJens Wiklander 321b0563631STom Van Eyck status = psa_get_key_attributes(ctx->priv_id, &attributes); 32232b31808SJens Wiklander if (status != PSA_SUCCESS) { 32332b31808SJens Wiklander return 0; 32432b31808SJens Wiklander } 32532b31808SJens Wiklander 326b0563631STom Van Eyck psa_algorithm_t key_alg = psa_get_key_algorithm(&attributes); 327b0563631STom Van Eyck /* Key's enrollment is available only when an Mbed TLS implementation of PSA 328b0563631STom Van Eyck * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined. 329b0563631STom Van Eyck * Even though we don't officially support using other implementations of PSA 330b0563631STom Van Eyck * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations 331b0563631STom Van Eyck * separated. */ 332b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_C) 333b0563631STom Van Eyck psa_algorithm_t key_alg2 = psa_get_key_enrollment_algorithm(&attributes); 334b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_C */ 33532b31808SJens Wiklander key_usage = psa_get_key_usage_flags(&attributes); 33632b31808SJens Wiklander psa_reset_key_attributes(&attributes); 33732b31808SJens Wiklander 33832b31808SJens Wiklander if ((key_usage & usage) != usage) { 33932b31808SJens Wiklander return 0; 34032b31808SJens Wiklander } 34132b31808SJens Wiklander 34232b31808SJens Wiklander /* 343b0563631STom Van Eyck * Common case: the key alg [or alg2] only allows alg. 34432b31808SJens Wiklander * This will match PSA_ALG_RSA_PKCS1V15_CRYPT & PSA_ALG_IS_ECDH 34532b31808SJens Wiklander * directly. 34632b31808SJens Wiklander * This would also match ECDSA/RSA_PKCS1V15_SIGN/RSA_PSS with 347b0563631STom Van Eyck * a fixed hash on key_alg [or key_alg2]. 34832b31808SJens Wiklander */ 349b0563631STom Van Eyck if (alg == key_alg) { 35032b31808SJens Wiklander return 1; 35132b31808SJens Wiklander } 352b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_C) 353b0563631STom Van Eyck if (alg == key_alg2) { 354b0563631STom Van Eyck return 1; 355b0563631STom Van Eyck } 356b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_C */ 35732b31808SJens Wiklander 35832b31808SJens Wiklander /* 359b0563631STom Van Eyck * If key_alg [or key_alg2] is a hash-and-sign with a wildcard for the hash, 36032b31808SJens Wiklander * and alg is the same hash-and-sign family with any hash, 36132b31808SJens Wiklander * then alg is compliant with this key alg 36232b31808SJens Wiklander */ 36332b31808SJens Wiklander if (PSA_ALG_IS_SIGN_HASH(alg)) { 36432b31808SJens Wiklander if (PSA_ALG_IS_SIGN_HASH(key_alg) && 36532b31808SJens Wiklander PSA_ALG_SIGN_GET_HASH(key_alg) == PSA_ALG_ANY_HASH && 36632b31808SJens Wiklander (alg & ~PSA_ALG_HASH_MASK) == (key_alg & ~PSA_ALG_HASH_MASK)) { 36732b31808SJens Wiklander return 1; 36832b31808SJens Wiklander } 369b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_C) 37032b31808SJens Wiklander if (PSA_ALG_IS_SIGN_HASH(key_alg2) && 37132b31808SJens Wiklander PSA_ALG_SIGN_GET_HASH(key_alg2) == PSA_ALG_ANY_HASH && 37232b31808SJens Wiklander (alg & ~PSA_ALG_HASH_MASK) == (key_alg2 & ~PSA_ALG_HASH_MASK)) { 37332b31808SJens Wiklander return 1; 37432b31808SJens Wiklander } 375b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_C */ 37632b31808SJens Wiklander } 37732b31808SJens Wiklander 37832b31808SJens Wiklander return 0; 37932b31808SJens Wiklander } 38032b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 38132b31808SJens Wiklander 382b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_CLIENT) 383b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) 384b0563631STom Van Eyck static psa_algorithm_t psa_algorithm_for_rsa(const mbedtls_rsa_context *rsa, 385b0563631STom Van Eyck int want_crypt) 386b0563631STom Van Eyck { 387b0563631STom Van Eyck if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) { 388b0563631STom Van Eyck if (want_crypt) { 389b0563631STom Van Eyck mbedtls_md_type_t md_type = (mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa); 390b0563631STom Van Eyck return PSA_ALG_RSA_OAEP(mbedtls_md_psa_alg_from_type(md_type)); 391b0563631STom Van Eyck } else { 392b0563631STom Van Eyck return PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH); 393b0563631STom Van Eyck } 394b0563631STom Van Eyck } else { 395b0563631STom Van Eyck if (want_crypt) { 396b0563631STom Van Eyck return PSA_ALG_RSA_PKCS1V15_CRYPT; 397b0563631STom Van Eyck } else { 398b0563631STom Van Eyck return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH); 399b0563631STom Van Eyck } 400b0563631STom Van Eyck } 401b0563631STom Van Eyck } 402b0563631STom Van Eyck #endif /* MBEDTLS_RSA_C */ 403b0563631STom Van Eyck 404b0563631STom Van Eyck int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk, 405b0563631STom Van Eyck psa_key_usage_t usage, 406b0563631STom Van Eyck psa_key_attributes_t *attributes) 407b0563631STom Van Eyck { 408b0563631STom Van Eyck mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk); 409b0563631STom Van Eyck 410b0563631STom Van Eyck psa_key_usage_t more_usage = usage; 411b0563631STom Van Eyck if (usage == PSA_KEY_USAGE_SIGN_MESSAGE) { 412b0563631STom Van Eyck more_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE; 413b0563631STom Van Eyck } else if (usage == PSA_KEY_USAGE_SIGN_HASH) { 414b0563631STom Van Eyck more_usage |= PSA_KEY_USAGE_VERIFY_HASH; 415b0563631STom Van Eyck } else if (usage == PSA_KEY_USAGE_DECRYPT) { 416b0563631STom Van Eyck more_usage |= PSA_KEY_USAGE_ENCRYPT; 417b0563631STom Van Eyck } 418b0563631STom Van Eyck more_usage |= PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY; 419b0563631STom Van Eyck 420b0563631STom Van Eyck int want_private = !(usage == PSA_KEY_USAGE_VERIFY_MESSAGE || 421b0563631STom Van Eyck usage == PSA_KEY_USAGE_VERIFY_HASH || 422b0563631STom Van Eyck usage == PSA_KEY_USAGE_ENCRYPT); 423b0563631STom Van Eyck 424b0563631STom Van Eyck switch (pk_type) { 425b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) 426b0563631STom Van Eyck case MBEDTLS_PK_RSA: 427b0563631STom Van Eyck { 428b0563631STom Van Eyck int want_crypt = 0; /* 0: sign/verify; 1: encrypt/decrypt */ 429b0563631STom Van Eyck switch (usage) { 430b0563631STom Van Eyck case PSA_KEY_USAGE_SIGN_MESSAGE: 431b0563631STom Van Eyck case PSA_KEY_USAGE_SIGN_HASH: 432b0563631STom Van Eyck case PSA_KEY_USAGE_VERIFY_MESSAGE: 433b0563631STom Van Eyck case PSA_KEY_USAGE_VERIFY_HASH: 434b0563631STom Van Eyck /* Nothing to do. */ 435b0563631STom Van Eyck break; 436b0563631STom Van Eyck case PSA_KEY_USAGE_DECRYPT: 437b0563631STom Van Eyck case PSA_KEY_USAGE_ENCRYPT: 438b0563631STom Van Eyck want_crypt = 1; 439b0563631STom Van Eyck break; 440b0563631STom Van Eyck default: 441b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 442b0563631STom Van Eyck } 443b0563631STom Van Eyck /* Detect the presence of a private key in a way that works both 444b0563631STom Van Eyck * in CRT and non-CRT configurations. */ 445b0563631STom Van Eyck mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk); 446b0563631STom Van Eyck int has_private = (mbedtls_rsa_check_privkey(rsa) == 0); 447b0563631STom Van Eyck if (want_private && !has_private) { 448b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 449b0563631STom Van Eyck } 450b0563631STom Van Eyck psa_set_key_type(attributes, (want_private ? 451b0563631STom Van Eyck PSA_KEY_TYPE_RSA_KEY_PAIR : 452b0563631STom Van Eyck PSA_KEY_TYPE_RSA_PUBLIC_KEY)); 453b0563631STom Van Eyck psa_set_key_bits(attributes, mbedtls_pk_get_bitlen(pk)); 454b0563631STom Van Eyck psa_set_key_algorithm(attributes, 455b0563631STom Van Eyck psa_algorithm_for_rsa(rsa, want_crypt)); 456b0563631STom Van Eyck break; 457b0563631STom Van Eyck } 458b0563631STom Van Eyck #endif /* MBEDTLS_RSA_C */ 459b0563631STom Van Eyck 460b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 461b0563631STom Van Eyck case MBEDTLS_PK_ECKEY: 462b0563631STom Van Eyck case MBEDTLS_PK_ECKEY_DH: 463b0563631STom Van Eyck case MBEDTLS_PK_ECDSA: 464b0563631STom Van Eyck { 465b0563631STom Van Eyck int sign_ok = (pk_type != MBEDTLS_PK_ECKEY_DH); 466b0563631STom Van Eyck int derive_ok = (pk_type != MBEDTLS_PK_ECDSA); 467b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 468b0563631STom Van Eyck psa_ecc_family_t family = pk->ec_family; 469b0563631STom Van Eyck size_t bits = pk->ec_bits; 470b0563631STom Van Eyck int has_private = 0; 471b0563631STom Van Eyck if (pk->priv_id != MBEDTLS_SVC_KEY_ID_INIT) { 472b0563631STom Van Eyck has_private = 1; 473b0563631STom Van Eyck } 474b0563631STom Van Eyck #else 475b0563631STom Van Eyck const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); 476b0563631STom Van Eyck int has_private = (ec->d.n != 0); 477b0563631STom Van Eyck size_t bits = 0; 478b0563631STom Van Eyck psa_ecc_family_t family = 479b0563631STom Van Eyck mbedtls_ecc_group_to_psa(ec->grp.id, &bits); 480b0563631STom Van Eyck #endif 481b0563631STom Van Eyck psa_algorithm_t alg = 0; 482b0563631STom Van Eyck switch (usage) { 483b0563631STom Van Eyck case PSA_KEY_USAGE_SIGN_MESSAGE: 484b0563631STom Van Eyck case PSA_KEY_USAGE_SIGN_HASH: 485b0563631STom Van Eyck case PSA_KEY_USAGE_VERIFY_MESSAGE: 486b0563631STom Van Eyck case PSA_KEY_USAGE_VERIFY_HASH: 487b0563631STom Van Eyck if (!sign_ok) { 488b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 489b0563631STom Van Eyck } 490b0563631STom Van Eyck #if defined(MBEDTLS_ECDSA_DETERMINISTIC) 491b0563631STom Van Eyck alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH); 492b0563631STom Van Eyck #else 493b0563631STom Van Eyck alg = PSA_ALG_ECDSA(PSA_ALG_ANY_HASH); 494b0563631STom Van Eyck #endif 495b0563631STom Van Eyck break; 496b0563631STom Van Eyck case PSA_KEY_USAGE_DERIVE: 497b0563631STom Van Eyck alg = PSA_ALG_ECDH; 498b0563631STom Van Eyck if (!derive_ok) { 499b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 500b0563631STom Van Eyck } 501b0563631STom Van Eyck break; 502b0563631STom Van Eyck default: 503b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 504b0563631STom Van Eyck } 505b0563631STom Van Eyck if (want_private && !has_private) { 506b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 507b0563631STom Van Eyck } 508b0563631STom Van Eyck psa_set_key_type(attributes, (want_private ? 509b0563631STom Van Eyck PSA_KEY_TYPE_ECC_KEY_PAIR(family) : 510b0563631STom Van Eyck PSA_KEY_TYPE_ECC_PUBLIC_KEY(family))); 511b0563631STom Van Eyck psa_set_key_bits(attributes, bits); 512b0563631STom Van Eyck psa_set_key_algorithm(attributes, alg); 513b0563631STom Van Eyck break; 514b0563631STom Van Eyck } 515b0563631STom Van Eyck #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 516b0563631STom Van Eyck 517b0563631STom Van Eyck #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 518b0563631STom Van Eyck case MBEDTLS_PK_RSA_ALT: 519b0563631STom Van Eyck return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 520b0563631STom Van Eyck #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ 521b0563631STom Van Eyck 522b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO) 523b0563631STom Van Eyck case MBEDTLS_PK_OPAQUE: 524b0563631STom Van Eyck { 525b0563631STom Van Eyck psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; 526b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 527b0563631STom Van Eyck status = psa_get_key_attributes(pk->priv_id, &old_attributes); 528b0563631STom Van Eyck if (status != PSA_SUCCESS) { 529b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 530b0563631STom Van Eyck } 531b0563631STom Van Eyck psa_key_type_t old_type = psa_get_key_type(&old_attributes); 532b0563631STom Van Eyck switch (usage) { 533b0563631STom Van Eyck case PSA_KEY_USAGE_SIGN_MESSAGE: 534b0563631STom Van Eyck case PSA_KEY_USAGE_SIGN_HASH: 535b0563631STom Van Eyck case PSA_KEY_USAGE_VERIFY_MESSAGE: 536b0563631STom Van Eyck case PSA_KEY_USAGE_VERIFY_HASH: 537b0563631STom Van Eyck if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type) || 538b0563631STom Van Eyck old_type == PSA_KEY_TYPE_RSA_KEY_PAIR)) { 539b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 540b0563631STom Van Eyck } 541b0563631STom Van Eyck break; 542b0563631STom Van Eyck case PSA_KEY_USAGE_DECRYPT: 543b0563631STom Van Eyck case PSA_KEY_USAGE_ENCRYPT: 544b0563631STom Van Eyck if (old_type != PSA_KEY_TYPE_RSA_KEY_PAIR) { 545b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 546b0563631STom Van Eyck } 547b0563631STom Van Eyck break; 548b0563631STom Van Eyck case PSA_KEY_USAGE_DERIVE: 549b0563631STom Van Eyck if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type))) { 550b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 551b0563631STom Van Eyck } 552b0563631STom Van Eyck break; 553b0563631STom Van Eyck default: 554b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 555b0563631STom Van Eyck } 556b0563631STom Van Eyck psa_key_type_t new_type = old_type; 557b0563631STom Van Eyck /* Opaque keys are always key pairs, so we don't need a check 558b0563631STom Van Eyck * on the input if the required usage is private. We just need 559b0563631STom Van Eyck * to adjust the type correctly if the required usage is public. */ 560b0563631STom Van Eyck if (!want_private) { 561b0563631STom Van Eyck new_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(new_type); 562b0563631STom Van Eyck } 563b0563631STom Van Eyck more_usage = psa_get_key_usage_flags(&old_attributes); 564b0563631STom Van Eyck if ((usage & more_usage) == 0) { 565b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 566b0563631STom Van Eyck } 567b0563631STom Van Eyck psa_set_key_type(attributes, new_type); 568b0563631STom Van Eyck psa_set_key_bits(attributes, psa_get_key_bits(&old_attributes)); 569b0563631STom Van Eyck psa_set_key_algorithm(attributes, psa_get_key_algorithm(&old_attributes)); 570b0563631STom Van Eyck break; 571b0563631STom Van Eyck } 572b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */ 573b0563631STom Van Eyck 574b0563631STom Van Eyck default: 575b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 576b0563631STom Van Eyck } 577b0563631STom Van Eyck 578b0563631STom Van Eyck psa_set_key_usage_flags(attributes, more_usage); 579b0563631STom Van Eyck /* Key's enrollment is available only when an Mbed TLS implementation of PSA 580b0563631STom Van Eyck * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined. 581b0563631STom Van Eyck * Even though we don't officially support using other implementations of PSA 582b0563631STom Van Eyck * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations 583b0563631STom Van Eyck * separated. */ 584b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_C) 585b0563631STom Van Eyck psa_set_key_enrollment_algorithm(attributes, PSA_ALG_NONE); 586b0563631STom Van Eyck #endif 587b0563631STom Van Eyck 588b0563631STom Van Eyck return 0; 589b0563631STom Van Eyck } 590b0563631STom Van Eyck 591b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) || defined(MBEDTLS_USE_PSA_CRYPTO) 592b0563631STom Van Eyck static psa_status_t export_import_into_psa(mbedtls_svc_key_id_t old_key_id, 593b0563631STom Van Eyck const psa_key_attributes_t *attributes, 594b0563631STom Van Eyck mbedtls_svc_key_id_t *new_key_id) 595b0563631STom Van Eyck { 596b0563631STom Van Eyck unsigned char key_buffer[PSA_EXPORT_KEY_PAIR_MAX_SIZE]; 597b0563631STom Van Eyck size_t key_length = 0; 598b0563631STom Van Eyck psa_status_t status = psa_export_key(old_key_id, 599b0563631STom Van Eyck key_buffer, sizeof(key_buffer), 600b0563631STom Van Eyck &key_length); 601b0563631STom Van Eyck if (status != PSA_SUCCESS) { 602b0563631STom Van Eyck return status; 603b0563631STom Van Eyck } 604b0563631STom Van Eyck status = psa_import_key(attributes, key_buffer, key_length, new_key_id); 605b0563631STom Van Eyck mbedtls_platform_zeroize(key_buffer, key_length); 606b0563631STom Van Eyck return status; 607b0563631STom Van Eyck } 608b0563631STom Van Eyck 609b0563631STom Van Eyck static int copy_into_psa(mbedtls_svc_key_id_t old_key_id, 610b0563631STom Van Eyck const psa_key_attributes_t *attributes, 611b0563631STom Van Eyck mbedtls_svc_key_id_t *new_key_id) 612b0563631STom Van Eyck { 613b0563631STom Van Eyck /* Normally, we prefer copying: it's more efficient and works even 614b0563631STom Van Eyck * for non-exportable keys. */ 615b0563631STom Van Eyck psa_status_t status = psa_copy_key(old_key_id, attributes, new_key_id); 616b0563631STom Van Eyck if (status == PSA_ERROR_NOT_PERMITTED /*missing COPY usage*/ || 617b0563631STom Van Eyck status == PSA_ERROR_INVALID_ARGUMENT /*incompatible policy*/) { 618b0563631STom Van Eyck /* There are edge cases where copying won't work, but export+import 619b0563631STom Van Eyck * might: 620b0563631STom Van Eyck * - If the old key does not allow PSA_KEY_USAGE_COPY. 621b0563631STom Van Eyck * - If the old key's usage does not allow what attributes wants. 622b0563631STom Van Eyck * Because the key was intended for use in the pk module, and may 623b0563631STom Van Eyck * have had a policy chosen solely for what pk needs rather than 624b0563631STom Van Eyck * based on a detailed understanding of PSA policies, we are a bit 625b0563631STom Van Eyck * more liberal than psa_copy_key() here. 626b0563631STom Van Eyck */ 627b0563631STom Van Eyck /* Here we need to check that the types match, otherwise we risk 628b0563631STom Van Eyck * importing nonsensical data. */ 629b0563631STom Van Eyck psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; 630b0563631STom Van Eyck status = psa_get_key_attributes(old_key_id, &old_attributes); 631b0563631STom Van Eyck if (status != PSA_SUCCESS) { 632b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 633b0563631STom Van Eyck } 634b0563631STom Van Eyck psa_key_type_t old_type = psa_get_key_type(&old_attributes); 635b0563631STom Van Eyck psa_reset_key_attributes(&old_attributes); 636b0563631STom Van Eyck if (old_type != psa_get_key_type(attributes)) { 637b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 638b0563631STom Van Eyck } 639b0563631STom Van Eyck status = export_import_into_psa(old_key_id, attributes, new_key_id); 640b0563631STom Van Eyck } 641b0563631STom Van Eyck return PSA_PK_TO_MBEDTLS_ERR(status); 642b0563631STom Van Eyck } 643b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_USE_PSA_CRYPTO */ 644b0563631STom Van Eyck 645b0563631STom Van Eyck static int import_pair_into_psa(const mbedtls_pk_context *pk, 646b0563631STom Van Eyck const psa_key_attributes_t *attributes, 647b0563631STom Van Eyck mbedtls_svc_key_id_t *key_id) 648b0563631STom Van Eyck { 649b0563631STom Van Eyck switch (mbedtls_pk_get_type(pk)) { 650b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) 651b0563631STom Van Eyck case MBEDTLS_PK_RSA: 652b0563631STom Van Eyck { 653b0563631STom Van Eyck if (psa_get_key_type(attributes) != PSA_KEY_TYPE_RSA_KEY_PAIR) { 654b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 655b0563631STom Van Eyck } 656b0563631STom Van Eyck unsigned char key_buffer[ 657b0563631STom Van Eyck PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)]; 658b0563631STom Van Eyck unsigned char *const key_end = key_buffer + sizeof(key_buffer); 659b0563631STom Van Eyck unsigned char *key_data = key_end; 660b0563631STom Van Eyck int ret = mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), 661b0563631STom Van Eyck key_buffer, &key_data); 662b0563631STom Van Eyck if (ret < 0) { 663b0563631STom Van Eyck return ret; 664b0563631STom Van Eyck } 665b0563631STom Van Eyck size_t key_length = key_end - key_data; 666b0563631STom Van Eyck ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, 667b0563631STom Van Eyck key_data, key_length, 668b0563631STom Van Eyck key_id)); 669b0563631STom Van Eyck mbedtls_platform_zeroize(key_data, key_length); 670b0563631STom Van Eyck return ret; 671b0563631STom Van Eyck } 672b0563631STom Van Eyck #endif /* MBEDTLS_RSA_C */ 673b0563631STom Van Eyck 674b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 675b0563631STom Van Eyck case MBEDTLS_PK_ECKEY: 676b0563631STom Van Eyck case MBEDTLS_PK_ECKEY_DH: 677b0563631STom Van Eyck case MBEDTLS_PK_ECDSA: 678b0563631STom Van Eyck { 679b0563631STom Van Eyck /* We need to check the curve family, otherwise the import could 680b0563631STom Van Eyck * succeed with nonsensical data. 681b0563631STom Van Eyck * We don't check the bit-size: it's optional in attributes, 682b0563631STom Van Eyck * and if it's specified, psa_import_key() will know from the key 683b0563631STom Van Eyck * data length and will check that the bit-size matches. */ 684b0563631STom Van Eyck psa_key_type_t to_type = psa_get_key_type(attributes); 685b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 686b0563631STom Van Eyck psa_ecc_family_t from_family = pk->ec_family; 687b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */ 688b0563631STom Van Eyck const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); 689b0563631STom Van Eyck size_t from_bits = 0; 690b0563631STom Van Eyck psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id, 691b0563631STom Van Eyck &from_bits); 692b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 693b0563631STom Van Eyck if (to_type != PSA_KEY_TYPE_ECC_KEY_PAIR(from_family)) { 694b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 695b0563631STom Van Eyck } 696b0563631STom Van Eyck 697b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 698b0563631STom Van Eyck if (mbedtls_svc_key_id_is_null(pk->priv_id)) { 699b0563631STom Van Eyck /* We have a public key and want a key pair. */ 700b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 701b0563631STom Van Eyck } 702b0563631STom Van Eyck return copy_into_psa(pk->priv_id, attributes, key_id); 703b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */ 704b0563631STom Van Eyck if (ec->d.n == 0) { 705b0563631STom Van Eyck /* Private key not set. Assume the input is a public key only. 706b0563631STom Van Eyck * (The other possibility is that it's an incomplete object 707b0563631STom Van Eyck * where the group is set but neither the public key nor 708b0563631STom Van Eyck * the private key. This is not possible through ecp.h 709b0563631STom Van Eyck * functions, so we don't bother reporting a more suitable 710b0563631STom Van Eyck * error in that case.) */ 711b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 712b0563631STom Van Eyck } 713b0563631STom Van Eyck unsigned char key_buffer[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; 714b0563631STom Van Eyck size_t key_length = 0; 715b0563631STom Van Eyck int ret = mbedtls_ecp_write_key_ext(ec, &key_length, 716b0563631STom Van Eyck key_buffer, sizeof(key_buffer)); 717b0563631STom Van Eyck if (ret < 0) { 718b0563631STom Van Eyck return ret; 719b0563631STom Van Eyck } 720b0563631STom Van Eyck ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, 721b0563631STom Van Eyck key_buffer, key_length, 722b0563631STom Van Eyck key_id)); 723b0563631STom Van Eyck mbedtls_platform_zeroize(key_buffer, key_length); 724b0563631STom Van Eyck return ret; 725b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 726b0563631STom Van Eyck } 727b0563631STom Van Eyck #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 728b0563631STom Van Eyck 729b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO) 730b0563631STom Van Eyck case MBEDTLS_PK_OPAQUE: 731b0563631STom Van Eyck return copy_into_psa(pk->priv_id, attributes, key_id); 732b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */ 733b0563631STom Van Eyck 734b0563631STom Van Eyck default: 735b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 736b0563631STom Van Eyck } 737b0563631STom Van Eyck } 738b0563631STom Van Eyck 739b0563631STom Van Eyck static int import_public_into_psa(const mbedtls_pk_context *pk, 740b0563631STom Van Eyck const psa_key_attributes_t *attributes, 741b0563631STom Van Eyck mbedtls_svc_key_id_t *key_id) 742b0563631STom Van Eyck { 743b0563631STom Van Eyck psa_key_type_t psa_type = psa_get_key_type(attributes); 744b0563631STom Van Eyck 745b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) || \ 746b0563631STom Van Eyck (defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)) || \ 747b0563631STom Van Eyck defined(MBEDTLS_USE_PSA_CRYPTO) 748b0563631STom Van Eyck unsigned char key_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; 749b0563631STom Van Eyck #endif 750b0563631STom Van Eyck unsigned char *key_data = NULL; 751b0563631STom Van Eyck size_t key_length = 0; 752b0563631STom Van Eyck 753b0563631STom Van Eyck switch (mbedtls_pk_get_type(pk)) { 754b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) 755b0563631STom Van Eyck case MBEDTLS_PK_RSA: 756b0563631STom Van Eyck { 757b0563631STom Van Eyck if (psa_type != PSA_KEY_TYPE_RSA_PUBLIC_KEY) { 758b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 759b0563631STom Van Eyck } 760b0563631STom Van Eyck unsigned char *const key_end = key_buffer + sizeof(key_buffer); 761b0563631STom Van Eyck key_data = key_end; 762b0563631STom Van Eyck int ret = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*pk), 763b0563631STom Van Eyck key_buffer, &key_data); 764b0563631STom Van Eyck if (ret < 0) { 765b0563631STom Van Eyck return ret; 766b0563631STom Van Eyck } 767b0563631STom Van Eyck key_length = (size_t) ret; 768b0563631STom Van Eyck break; 769b0563631STom Van Eyck } 770b0563631STom Van Eyck #endif /*MBEDTLS_RSA_C */ 771b0563631STom Van Eyck 772b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 773b0563631STom Van Eyck case MBEDTLS_PK_ECKEY: 774b0563631STom Van Eyck case MBEDTLS_PK_ECKEY_DH: 775b0563631STom Van Eyck case MBEDTLS_PK_ECDSA: 776b0563631STom Van Eyck { 777b0563631STom Van Eyck /* We need to check the curve family, otherwise the import could 778b0563631STom Van Eyck * succeed with nonsensical data. 779b0563631STom Van Eyck * We don't check the bit-size: it's optional in attributes, 780b0563631STom Van Eyck * and if it's specified, psa_import_key() will know from the key 781b0563631STom Van Eyck * data length and will check that the bit-size matches. */ 782b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 783b0563631STom Van Eyck if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family)) { 784b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 785b0563631STom Van Eyck } 786b0563631STom Van Eyck key_data = (unsigned char *) pk->pub_raw; 787b0563631STom Van Eyck key_length = pk->pub_raw_len; 788b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */ 789b0563631STom Van Eyck const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); 790b0563631STom Van Eyck size_t from_bits = 0; 791b0563631STom Van Eyck psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id, 792b0563631STom Van Eyck &from_bits); 793b0563631STom Van Eyck if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(from_family)) { 794b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 795b0563631STom Van Eyck } 796b0563631STom Van Eyck int ret = mbedtls_ecp_write_public_key( 797b0563631STom Van Eyck ec, MBEDTLS_ECP_PF_UNCOMPRESSED, 798b0563631STom Van Eyck &key_length, key_buffer, sizeof(key_buffer)); 799b0563631STom Van Eyck if (ret < 0) { 800b0563631STom Van Eyck return ret; 801b0563631STom Van Eyck } 802b0563631STom Van Eyck key_data = key_buffer; 803b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 804b0563631STom Van Eyck break; 805b0563631STom Van Eyck } 806b0563631STom Van Eyck #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 807b0563631STom Van Eyck 808b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO) 809b0563631STom Van Eyck case MBEDTLS_PK_OPAQUE: 810b0563631STom Van Eyck { 811b0563631STom Van Eyck psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; 812b0563631STom Van Eyck psa_status_t status = 813b0563631STom Van Eyck psa_get_key_attributes(pk->priv_id, &old_attributes); 814b0563631STom Van Eyck if (status != PSA_SUCCESS) { 815b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 816b0563631STom Van Eyck } 817b0563631STom Van Eyck psa_key_type_t old_type = psa_get_key_type(&old_attributes); 818b0563631STom Van Eyck psa_reset_key_attributes(&old_attributes); 819b0563631STom Van Eyck if (psa_type != PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(old_type)) { 820b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 821b0563631STom Van Eyck } 822b0563631STom Van Eyck status = psa_export_public_key(pk->priv_id, 823b0563631STom Van Eyck key_buffer, sizeof(key_buffer), 824b0563631STom Van Eyck &key_length); 825b0563631STom Van Eyck if (status != PSA_SUCCESS) { 826b0563631STom Van Eyck return PSA_PK_TO_MBEDTLS_ERR(status); 827b0563631STom Van Eyck } 828b0563631STom Van Eyck key_data = key_buffer; 829b0563631STom Van Eyck break; 830b0563631STom Van Eyck } 831b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */ 832b0563631STom Van Eyck 833b0563631STom Van Eyck default: 834b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 835b0563631STom Van Eyck } 836b0563631STom Van Eyck 837b0563631STom Van Eyck return PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, 838b0563631STom Van Eyck key_data, key_length, 839b0563631STom Van Eyck key_id)); 840b0563631STom Van Eyck } 841b0563631STom Van Eyck 842b0563631STom Van Eyck int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, 843b0563631STom Van Eyck const psa_key_attributes_t *attributes, 844b0563631STom Van Eyck mbedtls_svc_key_id_t *key_id) 845b0563631STom Van Eyck { 846b0563631STom Van Eyck /* Set the output immediately so that it won't contain garbage even 847b0563631STom Van Eyck * if we error out before calling psa_import_key(). */ 848b0563631STom Van Eyck *key_id = MBEDTLS_SVC_KEY_ID_INIT; 849b0563631STom Van Eyck 850b0563631STom Van Eyck #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 851b0563631STom Van Eyck if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA_ALT) { 852b0563631STom Van Eyck return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 853b0563631STom Van Eyck } 854b0563631STom Van Eyck #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ 855b0563631STom Van Eyck 856b0563631STom Van Eyck int want_public = PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(attributes)); 857b0563631STom Van Eyck if (want_public) { 858b0563631STom Van Eyck return import_public_into_psa(pk, attributes, key_id); 859b0563631STom Van Eyck } else { 860b0563631STom Van Eyck return import_pair_into_psa(pk, attributes, key_id); 861b0563631STom Van Eyck } 862b0563631STom Van Eyck } 863b0563631STom Van Eyck 864b0563631STom Van Eyck static int copy_from_psa(mbedtls_svc_key_id_t key_id, 865b0563631STom Van Eyck mbedtls_pk_context *pk, 866b0563631STom Van Eyck int public_only) 867b0563631STom Van Eyck { 868b0563631STom Van Eyck psa_status_t status; 869b0563631STom Van Eyck psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; 870b0563631STom Van Eyck psa_key_type_t key_type; 871b0563631STom Van Eyck size_t key_bits; 872b0563631STom Van Eyck /* Use a buffer size large enough to contain either a key pair or public key. */ 873b0563631STom Van Eyck unsigned char exp_key[PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE]; 874b0563631STom Van Eyck size_t exp_key_len; 875b0563631STom Van Eyck int ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; 876b0563631STom Van Eyck 877b0563631STom Van Eyck if (pk == NULL) { 878b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 879b0563631STom Van Eyck } 880b0563631STom Van Eyck 881b0563631STom Van Eyck status = psa_get_key_attributes(key_id, &key_attr); 882b0563631STom Van Eyck if (status != PSA_SUCCESS) { 883b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 884b0563631STom Van Eyck } 885b0563631STom Van Eyck 886b0563631STom Van Eyck if (public_only) { 887b0563631STom Van Eyck status = psa_export_public_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); 888b0563631STom Van Eyck } else { 889b0563631STom Van Eyck status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); 890b0563631STom Van Eyck } 891b0563631STom Van Eyck if (status != PSA_SUCCESS) { 892b0563631STom Van Eyck ret = PSA_PK_TO_MBEDTLS_ERR(status); 893b0563631STom Van Eyck goto exit; 894b0563631STom Van Eyck } 895b0563631STom Van Eyck 896b0563631STom Van Eyck key_type = psa_get_key_type(&key_attr); 897b0563631STom Van Eyck if (public_only) { 898b0563631STom Van Eyck key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type); 899b0563631STom Van Eyck } 900b0563631STom Van Eyck key_bits = psa_get_key_bits(&key_attr); 901b0563631STom Van Eyck 902b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) 903b0563631STom Van Eyck if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) || 904b0563631STom Van Eyck (key_type == PSA_KEY_TYPE_RSA_PUBLIC_KEY)) { 905b0563631STom Van Eyck 906b0563631STom Van Eyck ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); 907b0563631STom Van Eyck if (ret != 0) { 908b0563631STom Van Eyck goto exit; 909b0563631STom Van Eyck } 910b0563631STom Van Eyck 911b0563631STom Van Eyck if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { 912b0563631STom Van Eyck ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); 913b0563631STom Van Eyck } else { 914b0563631STom Van Eyck ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); 915b0563631STom Van Eyck } 916b0563631STom Van Eyck if (ret != 0) { 917b0563631STom Van Eyck goto exit; 918b0563631STom Van Eyck } 919b0563631STom Van Eyck 920*cb034002SJerome Forissier psa_algorithm_t alg_type = psa_get_key_algorithm(&key_attr); 921b0563631STom Van Eyck mbedtls_md_type_t md_type = MBEDTLS_MD_NONE; 922b0563631STom Van Eyck if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) { 923b0563631STom Van Eyck md_type = mbedtls_md_type_from_psa_alg(alg_type); 924b0563631STom Van Eyck } 925b0563631STom Van Eyck 926b0563631STom Van Eyck if (PSA_ALG_IS_RSA_OAEP(alg_type) || PSA_ALG_IS_RSA_PSS(alg_type)) { 927b0563631STom Van Eyck ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V21, md_type); 928b0563631STom Van Eyck } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) || 929b0563631STom Van Eyck alg_type == PSA_ALG_RSA_PKCS1V15_CRYPT) { 930b0563631STom Van Eyck ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V15, md_type); 931b0563631STom Van Eyck } 932b0563631STom Van Eyck if (ret != 0) { 933b0563631STom Van Eyck goto exit; 934b0563631STom Van Eyck } 935b0563631STom Van Eyck } else 936b0563631STom Van Eyck #endif /* MBEDTLS_RSA_C */ 937b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 938b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) || 939b0563631STom Van Eyck PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) { 940b0563631STom Van Eyck mbedtls_ecp_group_id grp_id; 941b0563631STom Van Eyck 942b0563631STom Van Eyck ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); 943b0563631STom Van Eyck if (ret != 0) { 944b0563631STom Van Eyck goto exit; 945b0563631STom Van Eyck } 946b0563631STom Van Eyck 947b0563631STom Van Eyck grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type), key_bits); 948b0563631STom Van Eyck ret = mbedtls_pk_ecc_set_group(pk, grp_id); 949b0563631STom Van Eyck if (ret != 0) { 950b0563631STom Van Eyck goto exit; 951b0563631STom Van Eyck } 952b0563631STom Van Eyck 953b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) { 954b0563631STom Van Eyck ret = mbedtls_pk_ecc_set_key(pk, exp_key, exp_key_len); 955b0563631STom Van Eyck if (ret != 0) { 956b0563631STom Van Eyck goto exit; 957b0563631STom Van Eyck } 958b0563631STom Van Eyck ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, exp_key, exp_key_len, 959b0563631STom Van Eyck mbedtls_psa_get_random, 960b0563631STom Van Eyck MBEDTLS_PSA_RANDOM_STATE); 961b0563631STom Van Eyck } else { 962b0563631STom Van Eyck ret = mbedtls_pk_ecc_set_pubkey(pk, exp_key, exp_key_len); 963b0563631STom Van Eyck } 964b0563631STom Van Eyck if (ret != 0) { 965b0563631STom Van Eyck goto exit; 966b0563631STom Van Eyck } 967b0563631STom Van Eyck } else 968b0563631STom Van Eyck #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 969b0563631STom Van Eyck { 970*cb034002SJerome Forissier (void) key_bits; 971b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 972b0563631STom Van Eyck } 973b0563631STom Van Eyck 974b0563631STom Van Eyck exit: 975b0563631STom Van Eyck psa_reset_key_attributes(&key_attr); 976b0563631STom Van Eyck mbedtls_platform_zeroize(exp_key, sizeof(exp_key)); 977b0563631STom Van Eyck 978b0563631STom Van Eyck return ret; 979b0563631STom Van Eyck } 980b0563631STom Van Eyck 981b0563631STom Van Eyck int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, 982b0563631STom Van Eyck mbedtls_pk_context *pk) 983b0563631STom Van Eyck { 984b0563631STom Van Eyck return copy_from_psa(key_id, pk, 0); 985b0563631STom Van Eyck } 986b0563631STom Van Eyck 987b0563631STom Van Eyck int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, 988b0563631STom Van Eyck mbedtls_pk_context *pk) 989b0563631STom Van Eyck { 990b0563631STom Van Eyck return copy_from_psa(key_id, pk, 1); 991b0563631STom Van Eyck } 992b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ 993b0563631STom Van Eyck 994817466cbSJens Wiklander /* 995817466cbSJens Wiklander * Helper for mbedtls_pk_sign and mbedtls_pk_verify 996817466cbSJens Wiklander */ 997817466cbSJens Wiklander static inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len) 998817466cbSJens Wiklander { 99932b31808SJens Wiklander if (*hash_len != 0) { 100032b31808SJens Wiklander return 0; 100132b31808SJens Wiklander } 1002817466cbSJens Wiklander 1003b0563631STom Van Eyck *hash_len = mbedtls_md_get_size_from_type(md_alg); 1004817466cbSJens Wiklander 100532b31808SJens Wiklander if (*hash_len == 0) { 100632b31808SJens Wiklander return -1; 100732b31808SJens Wiklander } 1008817466cbSJens Wiklander 100932b31808SJens Wiklander return 0; 1010817466cbSJens Wiklander } 1011817466cbSJens Wiklander 10123d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 10133d3b0591SJens Wiklander /* 10143d3b0591SJens Wiklander * Helper to set up a restart context if needed 10153d3b0591SJens Wiklander */ 10163d3b0591SJens Wiklander static int pk_restart_setup(mbedtls_pk_restart_ctx *ctx, 10173d3b0591SJens Wiklander const mbedtls_pk_info_t *info) 10183d3b0591SJens Wiklander { 10193d3b0591SJens Wiklander /* Don't do anything if already set up or invalid */ 102032b31808SJens Wiklander if (ctx == NULL || ctx->pk_info != NULL) { 102132b31808SJens Wiklander return 0; 102232b31808SJens Wiklander } 10233d3b0591SJens Wiklander 10243d3b0591SJens Wiklander /* Should never happen when we're called */ 102532b31808SJens Wiklander if (info->rs_alloc_func == NULL || info->rs_free_func == NULL) { 102632b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 102732b31808SJens Wiklander } 10283d3b0591SJens Wiklander 102932b31808SJens Wiklander if ((ctx->rs_ctx = info->rs_alloc_func()) == NULL) { 103032b31808SJens Wiklander return MBEDTLS_ERR_PK_ALLOC_FAILED; 103132b31808SJens Wiklander } 10323d3b0591SJens Wiklander 10333d3b0591SJens Wiklander ctx->pk_info = info; 10343d3b0591SJens Wiklander 103532b31808SJens Wiklander return 0; 10363d3b0591SJens Wiklander } 10373d3b0591SJens Wiklander #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 10383d3b0591SJens Wiklander 10393d3b0591SJens Wiklander /* 10403d3b0591SJens Wiklander * Verify a signature (restartable) 10413d3b0591SJens Wiklander */ 10423d3b0591SJens Wiklander int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx, 10433d3b0591SJens Wiklander mbedtls_md_type_t md_alg, 10443d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 10453d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 10463d3b0591SJens Wiklander mbedtls_pk_restart_ctx *rs_ctx) 10473d3b0591SJens Wiklander { 104832b31808SJens Wiklander if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { 104932b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 105032b31808SJens Wiklander } 10513d3b0591SJens Wiklander 10523d3b0591SJens Wiklander if (ctx->pk_info == NULL || 105332b31808SJens Wiklander pk_hashlen_helper(md_alg, &hash_len) != 0) { 105432b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 105532b31808SJens Wiklander } 10563d3b0591SJens Wiklander 10573d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 10583d3b0591SJens Wiklander /* optimization: use non-restartable version if restart disabled */ 10593d3b0591SJens Wiklander if (rs_ctx != NULL && 10603d3b0591SJens Wiklander mbedtls_ecp_restart_is_enabled() && 106132b31808SJens Wiklander ctx->pk_info->verify_rs_func != NULL) { 106211fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 10633d3b0591SJens Wiklander 106432b31808SJens Wiklander if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) { 106532b31808SJens Wiklander return ret; 106632b31808SJens Wiklander } 10673d3b0591SJens Wiklander 1068b0563631STom Van Eyck ret = ctx->pk_info->verify_rs_func(ctx, 10693d3b0591SJens Wiklander md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx); 10703d3b0591SJens Wiklander 107132b31808SJens Wiklander if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) { 10723d3b0591SJens Wiklander mbedtls_pk_restart_free(rs_ctx); 107332b31808SJens Wiklander } 10743d3b0591SJens Wiklander 107532b31808SJens Wiklander return ret; 10763d3b0591SJens Wiklander } 10773d3b0591SJens Wiklander #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 10783d3b0591SJens Wiklander (void) rs_ctx; 10793d3b0591SJens Wiklander #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 10803d3b0591SJens Wiklander 108132b31808SJens Wiklander if (ctx->pk_info->verify_func == NULL) { 108232b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 108332b31808SJens Wiklander } 10843d3b0591SJens Wiklander 1085b0563631STom Van Eyck return ctx->pk_info->verify_func(ctx, md_alg, hash, hash_len, 108632b31808SJens Wiklander sig, sig_len); 10873d3b0591SJens Wiklander } 10883d3b0591SJens Wiklander 1089817466cbSJens Wiklander /* 1090817466cbSJens Wiklander * Verify a signature 1091817466cbSJens Wiklander */ 1092817466cbSJens Wiklander int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, 1093817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 1094817466cbSJens Wiklander const unsigned char *sig, size_t sig_len) 1095817466cbSJens Wiklander { 109632b31808SJens Wiklander return mbedtls_pk_verify_restartable(ctx, md_alg, hash, hash_len, 109732b31808SJens Wiklander sig, sig_len, NULL); 1098817466cbSJens Wiklander } 1099817466cbSJens Wiklander 1100817466cbSJens Wiklander /* 1101817466cbSJens Wiklander * Verify a signature with options 1102817466cbSJens Wiklander */ 1103817466cbSJens Wiklander int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options, 1104817466cbSJens Wiklander mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, 1105817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 1106817466cbSJens Wiklander const unsigned char *sig, size_t sig_len) 1107817466cbSJens Wiklander { 110832b31808SJens Wiklander if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { 110932b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 111032b31808SJens Wiklander } 11113d3b0591SJens Wiklander 111232b31808SJens Wiklander if (ctx->pk_info == NULL) { 111332b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 111432b31808SJens Wiklander } 1115817466cbSJens Wiklander 111632b31808SJens Wiklander if (!mbedtls_pk_can_do(ctx, type)) { 111732b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 111832b31808SJens Wiklander } 1119817466cbSJens Wiklander 112032b31808SJens Wiklander if (type != MBEDTLS_PK_RSASSA_PSS) { 112132b31808SJens Wiklander /* General case: no options */ 112232b31808SJens Wiklander if (options != NULL) { 112332b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 112432b31808SJens Wiklander } 112532b31808SJens Wiklander 112632b31808SJens Wiklander return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len); 112732b31808SJens Wiklander } 112832b31808SJens Wiklander 1129b0563631STom Van Eyck /* Ensure the PK context is of the right type otherwise mbedtls_pk_rsa() 1130b0563631STom Van Eyck * below would return a NULL pointer. */ 1131b0563631STom Van Eyck if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_RSA) { 1132b0563631STom Van Eyck return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 1133b0563631STom Van Eyck } 1134b0563631STom Van Eyck 1135817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) 113611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1137817466cbSJens Wiklander const mbedtls_pk_rsassa_pss_options *pss_opts; 1138817466cbSJens Wiklander 1139b0563631STom Van Eyck #if SIZE_MAX > UINT_MAX 114032b31808SJens Wiklander if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) { 114132b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 114232b31808SJens Wiklander } 1143b0563631STom Van Eyck #endif 1144817466cbSJens Wiklander 114532b31808SJens Wiklander if (options == NULL) { 114632b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 114732b31808SJens Wiklander } 1148817466cbSJens Wiklander 1149817466cbSJens Wiklander pss_opts = (const mbedtls_pk_rsassa_pss_options *) options; 1150817466cbSJens Wiklander 115132b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 115232b31808SJens Wiklander if (pss_opts->mgf1_hash_id == md_alg) { 115332b31808SJens Wiklander unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES]; 115432b31808SJens Wiklander unsigned char *p; 115532b31808SJens Wiklander int key_len; 115632b31808SJens Wiklander size_t signature_length; 115732b31808SJens Wiklander psa_status_t status = PSA_ERROR_DATA_CORRUPT; 115832b31808SJens Wiklander psa_status_t destruction_status = PSA_ERROR_DATA_CORRUPT; 115932b31808SJens Wiklander 1160b0563631STom Van Eyck psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 116132b31808SJens Wiklander mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; 116232b31808SJens Wiklander psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 116332b31808SJens Wiklander psa_algorithm_t psa_sig_alg = PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg); 116432b31808SJens Wiklander p = buf + sizeof(buf); 1165b0563631STom Van Eyck key_len = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*ctx), buf, &p); 116632b31808SJens Wiklander 116732b31808SJens Wiklander if (key_len < 0) { 116832b31808SJens Wiklander return key_len; 116932b31808SJens Wiklander } 117032b31808SJens Wiklander 117132b31808SJens Wiklander psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY); 117232b31808SJens Wiklander psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); 117332b31808SJens Wiklander psa_set_key_algorithm(&attributes, psa_sig_alg); 117432b31808SJens Wiklander 117532b31808SJens Wiklander status = psa_import_key(&attributes, 117632b31808SJens Wiklander buf + sizeof(buf) - key_len, key_len, 117732b31808SJens Wiklander &key_id); 117832b31808SJens Wiklander if (status != PSA_SUCCESS) { 117932b31808SJens Wiklander psa_destroy_key(key_id); 118032b31808SJens Wiklander return PSA_PK_TO_MBEDTLS_ERR(status); 118132b31808SJens Wiklander } 118232b31808SJens Wiklander 118332b31808SJens Wiklander /* This function requires returning MBEDTLS_ERR_PK_SIG_LEN_MISMATCH 118432b31808SJens Wiklander * on a valid signature with trailing data in a buffer, but 118532b31808SJens Wiklander * mbedtls_psa_rsa_verify_hash requires the sig_len to be exact, 118632b31808SJens Wiklander * so for this reason the passed sig_len is overwritten. Smaller 118732b31808SJens Wiklander * signature lengths should not be accepted for verification. */ 118832b31808SJens Wiklander signature_length = sig_len > mbedtls_pk_get_len(ctx) ? 118932b31808SJens Wiklander mbedtls_pk_get_len(ctx) : sig_len; 119032b31808SJens Wiklander status = psa_verify_hash(key_id, psa_sig_alg, hash, 119132b31808SJens Wiklander hash_len, sig, signature_length); 119232b31808SJens Wiklander destruction_status = psa_destroy_key(key_id); 119332b31808SJens Wiklander 119432b31808SJens Wiklander if (status == PSA_SUCCESS && sig_len > mbedtls_pk_get_len(ctx)) { 119532b31808SJens Wiklander return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; 119632b31808SJens Wiklander } 119732b31808SJens Wiklander 119832b31808SJens Wiklander if (status == PSA_SUCCESS) { 119932b31808SJens Wiklander status = destruction_status; 120032b31808SJens Wiklander } 120132b31808SJens Wiklander 120232b31808SJens Wiklander return PSA_PK_RSA_TO_MBEDTLS_ERR(status); 120332b31808SJens Wiklander } else 1204b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */ 120532b31808SJens Wiklander { 120632b31808SJens Wiklander if (sig_len < mbedtls_pk_get_len(ctx)) { 120732b31808SJens Wiklander return MBEDTLS_ERR_RSA_VERIFY_FAILED; 120832b31808SJens Wiklander } 1209817466cbSJens Wiklander 1210817466cbSJens Wiklander ret = mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_pk_rsa(*ctx), 1211817466cbSJens Wiklander md_alg, (unsigned int) hash_len, hash, 1212817466cbSJens Wiklander pss_opts->mgf1_hash_id, 1213817466cbSJens Wiklander pss_opts->expected_salt_len, 1214817466cbSJens Wiklander sig); 121532b31808SJens Wiklander if (ret != 0) { 121632b31808SJens Wiklander return ret; 1217817466cbSJens Wiklander } 1218817466cbSJens Wiklander 121932b31808SJens Wiklander if (sig_len > mbedtls_pk_get_len(ctx)) { 122032b31808SJens Wiklander return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; 122132b31808SJens Wiklander } 1222817466cbSJens Wiklander 122332b31808SJens Wiklander return 0; 122432b31808SJens Wiklander } 122532b31808SJens Wiklander #else 122632b31808SJens Wiklander return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 122732b31808SJens Wiklander #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ 1228817466cbSJens Wiklander } 1229817466cbSJens Wiklander 1230817466cbSJens Wiklander /* 12313d3b0591SJens Wiklander * Make a signature (restartable) 12323d3b0591SJens Wiklander */ 12333d3b0591SJens Wiklander int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx, 12343d3b0591SJens Wiklander mbedtls_md_type_t md_alg, 12353d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 123632b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 12373d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 12383d3b0591SJens Wiklander mbedtls_pk_restart_ctx *rs_ctx) 12393d3b0591SJens Wiklander { 124032b31808SJens Wiklander if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { 124132b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 124232b31808SJens Wiklander } 12433d3b0591SJens Wiklander 124432b31808SJens Wiklander if (ctx->pk_info == NULL || pk_hashlen_helper(md_alg, &hash_len) != 0) { 124532b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 124632b31808SJens Wiklander } 12473d3b0591SJens Wiklander 12483d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 12493d3b0591SJens Wiklander /* optimization: use non-restartable version if restart disabled */ 12503d3b0591SJens Wiklander if (rs_ctx != NULL && 12513d3b0591SJens Wiklander mbedtls_ecp_restart_is_enabled() && 125232b31808SJens Wiklander ctx->pk_info->sign_rs_func != NULL) { 125311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 12543d3b0591SJens Wiklander 125532b31808SJens Wiklander if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) { 125632b31808SJens Wiklander return ret; 125732b31808SJens Wiklander } 12583d3b0591SJens Wiklander 1259b0563631STom Van Eyck ret = ctx->pk_info->sign_rs_func(ctx, md_alg, 126032b31808SJens Wiklander hash, hash_len, 126132b31808SJens Wiklander sig, sig_size, sig_len, 126232b31808SJens Wiklander f_rng, p_rng, rs_ctx->rs_ctx); 12633d3b0591SJens Wiklander 126432b31808SJens Wiklander if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) { 12653d3b0591SJens Wiklander mbedtls_pk_restart_free(rs_ctx); 126632b31808SJens Wiklander } 12673d3b0591SJens Wiklander 126832b31808SJens Wiklander return ret; 12693d3b0591SJens Wiklander } 12703d3b0591SJens Wiklander #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 12713d3b0591SJens Wiklander (void) rs_ctx; 12723d3b0591SJens Wiklander #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 12733d3b0591SJens Wiklander 127432b31808SJens Wiklander if (ctx->pk_info->sign_func == NULL) { 127532b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 127632b31808SJens Wiklander } 12773d3b0591SJens Wiklander 1278b0563631STom Van Eyck return ctx->pk_info->sign_func(ctx, md_alg, 127932b31808SJens Wiklander hash, hash_len, 128032b31808SJens Wiklander sig, sig_size, sig_len, 128132b31808SJens Wiklander f_rng, p_rng); 12823d3b0591SJens Wiklander } 12833d3b0591SJens Wiklander 12843d3b0591SJens Wiklander /* 1285817466cbSJens Wiklander * Make a signature 1286817466cbSJens Wiklander */ 1287817466cbSJens Wiklander int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, 1288817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 128932b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 1290817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 1291817466cbSJens Wiklander { 129232b31808SJens Wiklander return mbedtls_pk_sign_restartable(ctx, md_alg, hash, hash_len, 129332b31808SJens Wiklander sig, sig_size, sig_len, 129432b31808SJens Wiklander f_rng, p_rng, NULL); 1295817466cbSJens Wiklander } 1296817466cbSJens Wiklander 129732b31808SJens Wiklander /* 129832b31808SJens Wiklander * Make a signature given a signature type. 129932b31808SJens Wiklander */ 130032b31808SJens Wiklander int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, 130132b31808SJens Wiklander mbedtls_pk_context *ctx, 130232b31808SJens Wiklander mbedtls_md_type_t md_alg, 130332b31808SJens Wiklander const unsigned char *hash, size_t hash_len, 130432b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 130532b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 130632b31808SJens Wiklander void *p_rng) 130732b31808SJens Wiklander { 130832b31808SJens Wiklander if (ctx->pk_info == NULL) { 130932b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 131032b31808SJens Wiklander } 131132b31808SJens Wiklander 131232b31808SJens Wiklander if (!mbedtls_pk_can_do(ctx, pk_type)) { 131332b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 131432b31808SJens Wiklander } 131532b31808SJens Wiklander 131632b31808SJens Wiklander if (pk_type != MBEDTLS_PK_RSASSA_PSS) { 131732b31808SJens Wiklander return mbedtls_pk_sign(ctx, md_alg, hash, hash_len, 131832b31808SJens Wiklander sig, sig_size, sig_len, f_rng, p_rng); 131932b31808SJens Wiklander } 132032b31808SJens Wiklander 1321b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) 1322b0563631STom Van Eyck 1323b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO) 1324b0563631STom Van Eyck const psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 132532b31808SJens Wiklander if (psa_md_alg == 0) { 132632b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 132732b31808SJens Wiklander } 132832b31808SJens Wiklander 132932b31808SJens Wiklander if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) { 133032b31808SJens Wiklander psa_status_t status; 133132b31808SJens Wiklander 1332*cb034002SJerome Forissier /* PSA_ALG_RSA_PSS() behaves the same as PSA_ALG_RSA_PSS_ANY_SALT() when 1333*cb034002SJerome Forissier * performing a signature, but they are encoded differently. Instead of 1334*cb034002SJerome Forissier * extracting the proper one from the wrapped key policy, just try both. */ 1335*cb034002SJerome Forissier status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg), 133632b31808SJens Wiklander hash, hash_len, 133732b31808SJens Wiklander sig, sig_size, sig_len); 1338*cb034002SJerome Forissier if (status == PSA_ERROR_NOT_PERMITTED) { 1339*cb034002SJerome Forissier status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg), 1340*cb034002SJerome Forissier hash, hash_len, 1341*cb034002SJerome Forissier sig, sig_size, sig_len); 1342*cb034002SJerome Forissier } 134332b31808SJens Wiklander return PSA_PK_RSA_TO_MBEDTLS_ERR(status); 134432b31808SJens Wiklander } 134532b31808SJens Wiklander 134632b31808SJens Wiklander return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PSS(psa_md_alg), 134732b31808SJens Wiklander ctx->pk_ctx, hash, hash_len, 134832b31808SJens Wiklander sig, sig_size, sig_len); 1349b0563631STom Van Eyck #else /* MBEDTLS_USE_PSA_CRYPTO */ 135032b31808SJens Wiklander 1351b0563631STom Van Eyck if (sig_size < mbedtls_pk_get_len(ctx)) { 1352b0563631STom Van Eyck return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; 135332b31808SJens Wiklander } 1354b0563631STom Van Eyck 1355b0563631STom Van Eyck if (pk_hashlen_helper(md_alg, &hash_len) != 0) { 1356b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1357b0563631STom Van Eyck } 1358b0563631STom Van Eyck 1359b0563631STom Van Eyck mbedtls_rsa_context *const rsa_ctx = mbedtls_pk_rsa(*ctx); 1360b0563631STom Van Eyck 1361b0563631STom Van Eyck const int ret = mbedtls_rsa_rsassa_pss_sign_no_mode_check(rsa_ctx, f_rng, p_rng, md_alg, 1362b0563631STom Van Eyck (unsigned int) hash_len, hash, sig); 1363b0563631STom Van Eyck if (ret == 0) { 1364b0563631STom Van Eyck *sig_len = rsa_ctx->len; 1365b0563631STom Van Eyck } 1366b0563631STom Van Eyck return ret; 1367b0563631STom Van Eyck 1368b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */ 1369b0563631STom Van Eyck 1370b0563631STom Van Eyck #else 1371b0563631STom Van Eyck return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 1372b0563631STom Van Eyck #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ 1373b0563631STom Van Eyck } 137432b31808SJens Wiklander 1375817466cbSJens Wiklander /* 1376817466cbSJens Wiklander * Decrypt message 1377817466cbSJens Wiklander */ 1378817466cbSJens Wiklander int mbedtls_pk_decrypt(mbedtls_pk_context *ctx, 1379817466cbSJens Wiklander const unsigned char *input, size_t ilen, 1380817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 1381817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 1382817466cbSJens Wiklander { 138332b31808SJens Wiklander if (ctx->pk_info == NULL) { 138432b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 138532b31808SJens Wiklander } 13863d3b0591SJens Wiklander 138732b31808SJens Wiklander if (ctx->pk_info->decrypt_func == NULL) { 138832b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 138932b31808SJens Wiklander } 1390817466cbSJens Wiklander 1391b0563631STom Van Eyck return ctx->pk_info->decrypt_func(ctx, input, ilen, 139232b31808SJens Wiklander output, olen, osize, f_rng, p_rng); 1393817466cbSJens Wiklander } 1394817466cbSJens Wiklander 1395817466cbSJens Wiklander /* 1396817466cbSJens Wiklander * Encrypt message 1397817466cbSJens Wiklander */ 1398817466cbSJens Wiklander int mbedtls_pk_encrypt(mbedtls_pk_context *ctx, 1399817466cbSJens Wiklander const unsigned char *input, size_t ilen, 1400817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 1401817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 1402817466cbSJens Wiklander { 140332b31808SJens Wiklander if (ctx->pk_info == NULL) { 140432b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 140532b31808SJens Wiklander } 14063d3b0591SJens Wiklander 140732b31808SJens Wiklander if (ctx->pk_info->encrypt_func == NULL) { 140832b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 140932b31808SJens Wiklander } 1410817466cbSJens Wiklander 1411b0563631STom Van Eyck return ctx->pk_info->encrypt_func(ctx, input, ilen, 141232b31808SJens Wiklander output, olen, osize, f_rng, p_rng); 1413817466cbSJens Wiklander } 1414817466cbSJens Wiklander 1415817466cbSJens Wiklander /* 1416817466cbSJens Wiklander * Check public-private key pair 1417817466cbSJens Wiklander */ 141832b31808SJens Wiklander int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, 141932b31808SJens Wiklander const mbedtls_pk_context *prv, 142032b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 142132b31808SJens Wiklander void *p_rng) 1422817466cbSJens Wiklander { 14233d3b0591SJens Wiklander if (pub->pk_info == NULL || 142432b31808SJens Wiklander prv->pk_info == NULL) { 142532b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1426817466cbSJens Wiklander } 1427817466cbSJens Wiklander 142832b31808SJens Wiklander if (f_rng == NULL) { 142932b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1430817466cbSJens Wiklander } 1431817466cbSJens Wiklander 143232b31808SJens Wiklander if (prv->pk_info->check_pair_func == NULL) { 143332b31808SJens Wiklander return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 143432b31808SJens Wiklander } 143532b31808SJens Wiklander 143632b31808SJens Wiklander if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) { 143732b31808SJens Wiklander if (pub->pk_info->type != MBEDTLS_PK_RSA) { 143832b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 143932b31808SJens Wiklander } 144032b31808SJens Wiklander } else { 1441b0563631STom Van Eyck if ((prv->pk_info->type != MBEDTLS_PK_OPAQUE) && 1442b0563631STom Van Eyck (pub->pk_info != prv->pk_info)) { 144332b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 144432b31808SJens Wiklander } 144532b31808SJens Wiklander } 144632b31808SJens Wiklander 1447b0563631STom Van Eyck return prv->pk_info->check_pair_func((mbedtls_pk_context *) pub, 1448b0563631STom Van Eyck (mbedtls_pk_context *) prv, 1449b0563631STom Van Eyck f_rng, p_rng); 1450817466cbSJens Wiklander } 1451817466cbSJens Wiklander 1452817466cbSJens Wiklander /* 1453817466cbSJens Wiklander * Get key size in bits 1454817466cbSJens Wiklander */ 1455817466cbSJens Wiklander size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx) 1456817466cbSJens Wiklander { 14573d3b0591SJens Wiklander /* For backward compatibility, accept NULL or a context that 14583d3b0591SJens Wiklander * isn't set up yet, and return a fake value that should be safe. */ 145932b31808SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL) { 146032b31808SJens Wiklander return 0; 146132b31808SJens Wiklander } 1462817466cbSJens Wiklander 1463b0563631STom Van Eyck return ctx->pk_info->get_bitlen((mbedtls_pk_context *) ctx); 1464817466cbSJens Wiklander } 1465817466cbSJens Wiklander 1466817466cbSJens Wiklander /* 1467817466cbSJens Wiklander * Export debug information 1468817466cbSJens Wiklander */ 1469817466cbSJens Wiklander int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items) 1470817466cbSJens Wiklander { 147132b31808SJens Wiklander if (ctx->pk_info == NULL) { 147232b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 147332b31808SJens Wiklander } 1474817466cbSJens Wiklander 147532b31808SJens Wiklander if (ctx->pk_info->debug_func == NULL) { 147632b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 147732b31808SJens Wiklander } 1478817466cbSJens Wiklander 1479b0563631STom Van Eyck ctx->pk_info->debug_func((mbedtls_pk_context *) ctx, items); 148032b31808SJens Wiklander return 0; 1481817466cbSJens Wiklander } 1482817466cbSJens Wiklander 1483817466cbSJens Wiklander /* 1484817466cbSJens Wiklander * Access the PK type name 1485817466cbSJens Wiklander */ 1486817466cbSJens Wiklander const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx) 1487817466cbSJens Wiklander { 148832b31808SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL) { 148932b31808SJens Wiklander return "invalid PK"; 149032b31808SJens Wiklander } 1491817466cbSJens Wiklander 149232b31808SJens Wiklander return ctx->pk_info->name; 1493817466cbSJens Wiklander } 1494817466cbSJens Wiklander 1495817466cbSJens Wiklander /* 1496817466cbSJens Wiklander * Access the PK type 1497817466cbSJens Wiklander */ 1498817466cbSJens Wiklander mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) 1499817466cbSJens Wiklander { 150032b31808SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL) { 150132b31808SJens Wiklander return MBEDTLS_PK_NONE; 150232b31808SJens Wiklander } 1503817466cbSJens Wiklander 150432b31808SJens Wiklander return ctx->pk_info->type; 1505817466cbSJens Wiklander } 1506817466cbSJens Wiklander 1507817466cbSJens Wiklander #endif /* MBEDTLS_PK_C */ 1508