1817466cbSJens Wiklander /* 2817466cbSJens Wiklander * Public Key abstraction layer 3817466cbSJens Wiklander * 47901324dSJerome Forissier * Copyright The Mbed TLS Contributors 5*b0563631STom 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" 14*b0563631STom 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" 21*b0563631STom Van Eyck #include "rsa_internal.h" 22817466cbSJens Wiklander #endif 23*b0563631STom 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 30*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_CLIENT) 31*b0563631STom 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 38*b0563631STom Van Eyck #define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE \ 39*b0563631STom Van Eyck (PSA_EXPORT_KEY_PAIR_MAX_SIZE > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) ? \ 40*b0563631STom Van Eyck PSA_EXPORT_KEY_PAIR_MAX_SIZE : PSA_EXPORT_PUBLIC_KEY_MAX_SIZE 41*b0563631STom 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; 49*b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO) 50*b0563631STom Van Eyck ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT; 51*b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */ 52*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 53*b0563631STom Van Eyck memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw)); 54*b0563631STom Van Eyck ctx->pub_raw_len = 0; 55*b0563631STom Van Eyck ctx->ec_family = 0; 56*b0563631STom Van Eyck ctx->ec_bits = 0; 57*b0563631STom 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 69*b0563631STom 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 73*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 74*b0563631STom Van Eyck /* The ownership of the priv_id key for opaque keys is external of the PK 75*b0563631STom Van Eyck * module. It's the user responsibility to clear it after use. */ 76*b0563631STom Van Eyck if ((ctx->pk_info != NULL) && (ctx->pk_info->type != MBEDTLS_PK_OPAQUE)) { 77*b0563631STom Van Eyck psa_destroy_key(ctx->priv_id); 78*b0563631STom Van Eyck } 79*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 80*b0563631STom 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; 120*b0563631STom Van Eyck #endif /* MBEDTLS_RSA_C */ 121*b0563631STom 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; 126*b0563631STom 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; 130*b0563631STom 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 146*b0563631STom Van Eyck if ((info->ctx_alloc_func != NULL) && 147*b0563631STom 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 177*b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 17832b31808SJens Wiklander if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) { 179*b0563631STom Van Eyck info = &mbedtls_ecdsa_opaque_info; 180*b0563631STom Van Eyck } else 181*b0563631STom Van Eyck #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 182*b0563631STom Van Eyck if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) { 183*b0563631STom 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; 189*b0563631STom 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 321*b0563631STom 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 326*b0563631STom Van Eyck psa_algorithm_t key_alg = psa_get_key_algorithm(&attributes); 327*b0563631STom Van Eyck /* Key's enrollment is available only when an Mbed TLS implementation of PSA 328*b0563631STom Van Eyck * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined. 329*b0563631STom Van Eyck * Even though we don't officially support using other implementations of PSA 330*b0563631STom Van Eyck * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations 331*b0563631STom Van Eyck * separated. */ 332*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_C) 333*b0563631STom Van Eyck psa_algorithm_t key_alg2 = psa_get_key_enrollment_algorithm(&attributes); 334*b0563631STom 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 /* 343*b0563631STom 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 347*b0563631STom Van Eyck * a fixed hash on key_alg [or key_alg2]. 34832b31808SJens Wiklander */ 349*b0563631STom Van Eyck if (alg == key_alg) { 35032b31808SJens Wiklander return 1; 35132b31808SJens Wiklander } 352*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_C) 353*b0563631STom Van Eyck if (alg == key_alg2) { 354*b0563631STom Van Eyck return 1; 355*b0563631STom Van Eyck } 356*b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_C */ 35732b31808SJens Wiklander 35832b31808SJens Wiklander /* 359*b0563631STom 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 } 369*b0563631STom 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 } 375*b0563631STom 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 382*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_CLIENT) 383*b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) 384*b0563631STom Van Eyck static psa_algorithm_t psa_algorithm_for_rsa(const mbedtls_rsa_context *rsa, 385*b0563631STom Van Eyck int want_crypt) 386*b0563631STom Van Eyck { 387*b0563631STom Van Eyck if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) { 388*b0563631STom Van Eyck if (want_crypt) { 389*b0563631STom Van Eyck mbedtls_md_type_t md_type = (mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa); 390*b0563631STom Van Eyck return PSA_ALG_RSA_OAEP(mbedtls_md_psa_alg_from_type(md_type)); 391*b0563631STom Van Eyck } else { 392*b0563631STom Van Eyck return PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH); 393*b0563631STom Van Eyck } 394*b0563631STom Van Eyck } else { 395*b0563631STom Van Eyck if (want_crypt) { 396*b0563631STom Van Eyck return PSA_ALG_RSA_PKCS1V15_CRYPT; 397*b0563631STom Van Eyck } else { 398*b0563631STom Van Eyck return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH); 399*b0563631STom Van Eyck } 400*b0563631STom Van Eyck } 401*b0563631STom Van Eyck } 402*b0563631STom Van Eyck #endif /* MBEDTLS_RSA_C */ 403*b0563631STom Van Eyck 404*b0563631STom Van Eyck int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk, 405*b0563631STom Van Eyck psa_key_usage_t usage, 406*b0563631STom Van Eyck psa_key_attributes_t *attributes) 407*b0563631STom Van Eyck { 408*b0563631STom Van Eyck mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk); 409*b0563631STom Van Eyck 410*b0563631STom Van Eyck psa_key_usage_t more_usage = usage; 411*b0563631STom Van Eyck if (usage == PSA_KEY_USAGE_SIGN_MESSAGE) { 412*b0563631STom Van Eyck more_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE; 413*b0563631STom Van Eyck } else if (usage == PSA_KEY_USAGE_SIGN_HASH) { 414*b0563631STom Van Eyck more_usage |= PSA_KEY_USAGE_VERIFY_HASH; 415*b0563631STom Van Eyck } else if (usage == PSA_KEY_USAGE_DECRYPT) { 416*b0563631STom Van Eyck more_usage |= PSA_KEY_USAGE_ENCRYPT; 417*b0563631STom Van Eyck } 418*b0563631STom Van Eyck more_usage |= PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY; 419*b0563631STom Van Eyck 420*b0563631STom Van Eyck int want_private = !(usage == PSA_KEY_USAGE_VERIFY_MESSAGE || 421*b0563631STom Van Eyck usage == PSA_KEY_USAGE_VERIFY_HASH || 422*b0563631STom Van Eyck usage == PSA_KEY_USAGE_ENCRYPT); 423*b0563631STom Van Eyck 424*b0563631STom Van Eyck switch (pk_type) { 425*b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) 426*b0563631STom Van Eyck case MBEDTLS_PK_RSA: 427*b0563631STom Van Eyck { 428*b0563631STom Van Eyck int want_crypt = 0; /* 0: sign/verify; 1: encrypt/decrypt */ 429*b0563631STom Van Eyck switch (usage) { 430*b0563631STom Van Eyck case PSA_KEY_USAGE_SIGN_MESSAGE: 431*b0563631STom Van Eyck case PSA_KEY_USAGE_SIGN_HASH: 432*b0563631STom Van Eyck case PSA_KEY_USAGE_VERIFY_MESSAGE: 433*b0563631STom Van Eyck case PSA_KEY_USAGE_VERIFY_HASH: 434*b0563631STom Van Eyck /* Nothing to do. */ 435*b0563631STom Van Eyck break; 436*b0563631STom Van Eyck case PSA_KEY_USAGE_DECRYPT: 437*b0563631STom Van Eyck case PSA_KEY_USAGE_ENCRYPT: 438*b0563631STom Van Eyck want_crypt = 1; 439*b0563631STom Van Eyck break; 440*b0563631STom Van Eyck default: 441*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 442*b0563631STom Van Eyck } 443*b0563631STom Van Eyck /* Detect the presence of a private key in a way that works both 444*b0563631STom Van Eyck * in CRT and non-CRT configurations. */ 445*b0563631STom Van Eyck mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk); 446*b0563631STom Van Eyck int has_private = (mbedtls_rsa_check_privkey(rsa) == 0); 447*b0563631STom Van Eyck if (want_private && !has_private) { 448*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 449*b0563631STom Van Eyck } 450*b0563631STom Van Eyck psa_set_key_type(attributes, (want_private ? 451*b0563631STom Van Eyck PSA_KEY_TYPE_RSA_KEY_PAIR : 452*b0563631STom Van Eyck PSA_KEY_TYPE_RSA_PUBLIC_KEY)); 453*b0563631STom Van Eyck psa_set_key_bits(attributes, mbedtls_pk_get_bitlen(pk)); 454*b0563631STom Van Eyck psa_set_key_algorithm(attributes, 455*b0563631STom Van Eyck psa_algorithm_for_rsa(rsa, want_crypt)); 456*b0563631STom Van Eyck break; 457*b0563631STom Van Eyck } 458*b0563631STom Van Eyck #endif /* MBEDTLS_RSA_C */ 459*b0563631STom Van Eyck 460*b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 461*b0563631STom Van Eyck case MBEDTLS_PK_ECKEY: 462*b0563631STom Van Eyck case MBEDTLS_PK_ECKEY_DH: 463*b0563631STom Van Eyck case MBEDTLS_PK_ECDSA: 464*b0563631STom Van Eyck { 465*b0563631STom Van Eyck int sign_ok = (pk_type != MBEDTLS_PK_ECKEY_DH); 466*b0563631STom Van Eyck int derive_ok = (pk_type != MBEDTLS_PK_ECDSA); 467*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 468*b0563631STom Van Eyck psa_ecc_family_t family = pk->ec_family; 469*b0563631STom Van Eyck size_t bits = pk->ec_bits; 470*b0563631STom Van Eyck int has_private = 0; 471*b0563631STom Van Eyck if (pk->priv_id != MBEDTLS_SVC_KEY_ID_INIT) { 472*b0563631STom Van Eyck has_private = 1; 473*b0563631STom Van Eyck } 474*b0563631STom Van Eyck #else 475*b0563631STom Van Eyck const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); 476*b0563631STom Van Eyck int has_private = (ec->d.n != 0); 477*b0563631STom Van Eyck size_t bits = 0; 478*b0563631STom Van Eyck psa_ecc_family_t family = 479*b0563631STom Van Eyck mbedtls_ecc_group_to_psa(ec->grp.id, &bits); 480*b0563631STom Van Eyck #endif 481*b0563631STom Van Eyck psa_algorithm_t alg = 0; 482*b0563631STom Van Eyck switch (usage) { 483*b0563631STom Van Eyck case PSA_KEY_USAGE_SIGN_MESSAGE: 484*b0563631STom Van Eyck case PSA_KEY_USAGE_SIGN_HASH: 485*b0563631STom Van Eyck case PSA_KEY_USAGE_VERIFY_MESSAGE: 486*b0563631STom Van Eyck case PSA_KEY_USAGE_VERIFY_HASH: 487*b0563631STom Van Eyck if (!sign_ok) { 488*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 489*b0563631STom Van Eyck } 490*b0563631STom Van Eyck #if defined(MBEDTLS_ECDSA_DETERMINISTIC) 491*b0563631STom Van Eyck alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH); 492*b0563631STom Van Eyck #else 493*b0563631STom Van Eyck alg = PSA_ALG_ECDSA(PSA_ALG_ANY_HASH); 494*b0563631STom Van Eyck #endif 495*b0563631STom Van Eyck break; 496*b0563631STom Van Eyck case PSA_KEY_USAGE_DERIVE: 497*b0563631STom Van Eyck alg = PSA_ALG_ECDH; 498*b0563631STom Van Eyck if (!derive_ok) { 499*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 500*b0563631STom Van Eyck } 501*b0563631STom Van Eyck break; 502*b0563631STom Van Eyck default: 503*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 504*b0563631STom Van Eyck } 505*b0563631STom Van Eyck if (want_private && !has_private) { 506*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 507*b0563631STom Van Eyck } 508*b0563631STom Van Eyck psa_set_key_type(attributes, (want_private ? 509*b0563631STom Van Eyck PSA_KEY_TYPE_ECC_KEY_PAIR(family) : 510*b0563631STom Van Eyck PSA_KEY_TYPE_ECC_PUBLIC_KEY(family))); 511*b0563631STom Van Eyck psa_set_key_bits(attributes, bits); 512*b0563631STom Van Eyck psa_set_key_algorithm(attributes, alg); 513*b0563631STom Van Eyck break; 514*b0563631STom Van Eyck } 515*b0563631STom Van Eyck #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 516*b0563631STom Van Eyck 517*b0563631STom Van Eyck #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 518*b0563631STom Van Eyck case MBEDTLS_PK_RSA_ALT: 519*b0563631STom Van Eyck return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 520*b0563631STom Van Eyck #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ 521*b0563631STom Van Eyck 522*b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO) 523*b0563631STom Van Eyck case MBEDTLS_PK_OPAQUE: 524*b0563631STom Van Eyck { 525*b0563631STom Van Eyck psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; 526*b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 527*b0563631STom Van Eyck status = psa_get_key_attributes(pk->priv_id, &old_attributes); 528*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 529*b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 530*b0563631STom Van Eyck } 531*b0563631STom Van Eyck psa_key_type_t old_type = psa_get_key_type(&old_attributes); 532*b0563631STom Van Eyck switch (usage) { 533*b0563631STom Van Eyck case PSA_KEY_USAGE_SIGN_MESSAGE: 534*b0563631STom Van Eyck case PSA_KEY_USAGE_SIGN_HASH: 535*b0563631STom Van Eyck case PSA_KEY_USAGE_VERIFY_MESSAGE: 536*b0563631STom Van Eyck case PSA_KEY_USAGE_VERIFY_HASH: 537*b0563631STom Van Eyck if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type) || 538*b0563631STom Van Eyck old_type == PSA_KEY_TYPE_RSA_KEY_PAIR)) { 539*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 540*b0563631STom Van Eyck } 541*b0563631STom Van Eyck break; 542*b0563631STom Van Eyck case PSA_KEY_USAGE_DECRYPT: 543*b0563631STom Van Eyck case PSA_KEY_USAGE_ENCRYPT: 544*b0563631STom Van Eyck if (old_type != PSA_KEY_TYPE_RSA_KEY_PAIR) { 545*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 546*b0563631STom Van Eyck } 547*b0563631STom Van Eyck break; 548*b0563631STom Van Eyck case PSA_KEY_USAGE_DERIVE: 549*b0563631STom Van Eyck if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type))) { 550*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 551*b0563631STom Van Eyck } 552*b0563631STom Van Eyck break; 553*b0563631STom Van Eyck default: 554*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 555*b0563631STom Van Eyck } 556*b0563631STom Van Eyck psa_key_type_t new_type = old_type; 557*b0563631STom Van Eyck /* Opaque keys are always key pairs, so we don't need a check 558*b0563631STom Van Eyck * on the input if the required usage is private. We just need 559*b0563631STom Van Eyck * to adjust the type correctly if the required usage is public. */ 560*b0563631STom Van Eyck if (!want_private) { 561*b0563631STom Van Eyck new_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(new_type); 562*b0563631STom Van Eyck } 563*b0563631STom Van Eyck more_usage = psa_get_key_usage_flags(&old_attributes); 564*b0563631STom Van Eyck if ((usage & more_usage) == 0) { 565*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 566*b0563631STom Van Eyck } 567*b0563631STom Van Eyck psa_set_key_type(attributes, new_type); 568*b0563631STom Van Eyck psa_set_key_bits(attributes, psa_get_key_bits(&old_attributes)); 569*b0563631STom Van Eyck psa_set_key_algorithm(attributes, psa_get_key_algorithm(&old_attributes)); 570*b0563631STom Van Eyck break; 571*b0563631STom Van Eyck } 572*b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */ 573*b0563631STom Van Eyck 574*b0563631STom Van Eyck default: 575*b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 576*b0563631STom Van Eyck } 577*b0563631STom Van Eyck 578*b0563631STom Van Eyck psa_set_key_usage_flags(attributes, more_usage); 579*b0563631STom Van Eyck /* Key's enrollment is available only when an Mbed TLS implementation of PSA 580*b0563631STom Van Eyck * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined. 581*b0563631STom Van Eyck * Even though we don't officially support using other implementations of PSA 582*b0563631STom Van Eyck * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations 583*b0563631STom Van Eyck * separated. */ 584*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_C) 585*b0563631STom Van Eyck psa_set_key_enrollment_algorithm(attributes, PSA_ALG_NONE); 586*b0563631STom Van Eyck #endif 587*b0563631STom Van Eyck 588*b0563631STom Van Eyck return 0; 589*b0563631STom Van Eyck } 590*b0563631STom Van Eyck 591*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) || defined(MBEDTLS_USE_PSA_CRYPTO) 592*b0563631STom Van Eyck static psa_status_t export_import_into_psa(mbedtls_svc_key_id_t old_key_id, 593*b0563631STom Van Eyck const psa_key_attributes_t *attributes, 594*b0563631STom Van Eyck mbedtls_svc_key_id_t *new_key_id) 595*b0563631STom Van Eyck { 596*b0563631STom Van Eyck unsigned char key_buffer[PSA_EXPORT_KEY_PAIR_MAX_SIZE]; 597*b0563631STom Van Eyck size_t key_length = 0; 598*b0563631STom Van Eyck psa_status_t status = psa_export_key(old_key_id, 599*b0563631STom Van Eyck key_buffer, sizeof(key_buffer), 600*b0563631STom Van Eyck &key_length); 601*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 602*b0563631STom Van Eyck return status; 603*b0563631STom Van Eyck } 604*b0563631STom Van Eyck status = psa_import_key(attributes, key_buffer, key_length, new_key_id); 605*b0563631STom Van Eyck mbedtls_platform_zeroize(key_buffer, key_length); 606*b0563631STom Van Eyck return status; 607*b0563631STom Van Eyck } 608*b0563631STom Van Eyck 609*b0563631STom Van Eyck static int copy_into_psa(mbedtls_svc_key_id_t old_key_id, 610*b0563631STom Van Eyck const psa_key_attributes_t *attributes, 611*b0563631STom Van Eyck mbedtls_svc_key_id_t *new_key_id) 612*b0563631STom Van Eyck { 613*b0563631STom Van Eyck /* Normally, we prefer copying: it's more efficient and works even 614*b0563631STom Van Eyck * for non-exportable keys. */ 615*b0563631STom Van Eyck psa_status_t status = psa_copy_key(old_key_id, attributes, new_key_id); 616*b0563631STom Van Eyck if (status == PSA_ERROR_NOT_PERMITTED /*missing COPY usage*/ || 617*b0563631STom Van Eyck status == PSA_ERROR_INVALID_ARGUMENT /*incompatible policy*/) { 618*b0563631STom Van Eyck /* There are edge cases where copying won't work, but export+import 619*b0563631STom Van Eyck * might: 620*b0563631STom Van Eyck * - If the old key does not allow PSA_KEY_USAGE_COPY. 621*b0563631STom Van Eyck * - If the old key's usage does not allow what attributes wants. 622*b0563631STom Van Eyck * Because the key was intended for use in the pk module, and may 623*b0563631STom Van Eyck * have had a policy chosen solely for what pk needs rather than 624*b0563631STom Van Eyck * based on a detailed understanding of PSA policies, we are a bit 625*b0563631STom Van Eyck * more liberal than psa_copy_key() here. 626*b0563631STom Van Eyck */ 627*b0563631STom Van Eyck /* Here we need to check that the types match, otherwise we risk 628*b0563631STom Van Eyck * importing nonsensical data. */ 629*b0563631STom Van Eyck psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; 630*b0563631STom Van Eyck status = psa_get_key_attributes(old_key_id, &old_attributes); 631*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 632*b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 633*b0563631STom Van Eyck } 634*b0563631STom Van Eyck psa_key_type_t old_type = psa_get_key_type(&old_attributes); 635*b0563631STom Van Eyck psa_reset_key_attributes(&old_attributes); 636*b0563631STom Van Eyck if (old_type != psa_get_key_type(attributes)) { 637*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 638*b0563631STom Van Eyck } 639*b0563631STom Van Eyck status = export_import_into_psa(old_key_id, attributes, new_key_id); 640*b0563631STom Van Eyck } 641*b0563631STom Van Eyck return PSA_PK_TO_MBEDTLS_ERR(status); 642*b0563631STom Van Eyck } 643*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_USE_PSA_CRYPTO */ 644*b0563631STom Van Eyck 645*b0563631STom Van Eyck static int import_pair_into_psa(const mbedtls_pk_context *pk, 646*b0563631STom Van Eyck const psa_key_attributes_t *attributes, 647*b0563631STom Van Eyck mbedtls_svc_key_id_t *key_id) 648*b0563631STom Van Eyck { 649*b0563631STom Van Eyck switch (mbedtls_pk_get_type(pk)) { 650*b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) 651*b0563631STom Van Eyck case MBEDTLS_PK_RSA: 652*b0563631STom Van Eyck { 653*b0563631STom Van Eyck if (psa_get_key_type(attributes) != PSA_KEY_TYPE_RSA_KEY_PAIR) { 654*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 655*b0563631STom Van Eyck } 656*b0563631STom Van Eyck unsigned char key_buffer[ 657*b0563631STom Van Eyck PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)]; 658*b0563631STom Van Eyck unsigned char *const key_end = key_buffer + sizeof(key_buffer); 659*b0563631STom Van Eyck unsigned char *key_data = key_end; 660*b0563631STom Van Eyck int ret = mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), 661*b0563631STom Van Eyck key_buffer, &key_data); 662*b0563631STom Van Eyck if (ret < 0) { 663*b0563631STom Van Eyck return ret; 664*b0563631STom Van Eyck } 665*b0563631STom Van Eyck size_t key_length = key_end - key_data; 666*b0563631STom Van Eyck ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, 667*b0563631STom Van Eyck key_data, key_length, 668*b0563631STom Van Eyck key_id)); 669*b0563631STom Van Eyck mbedtls_platform_zeroize(key_data, key_length); 670*b0563631STom Van Eyck return ret; 671*b0563631STom Van Eyck } 672*b0563631STom Van Eyck #endif /* MBEDTLS_RSA_C */ 673*b0563631STom Van Eyck 674*b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 675*b0563631STom Van Eyck case MBEDTLS_PK_ECKEY: 676*b0563631STom Van Eyck case MBEDTLS_PK_ECKEY_DH: 677*b0563631STom Van Eyck case MBEDTLS_PK_ECDSA: 678*b0563631STom Van Eyck { 679*b0563631STom Van Eyck /* We need to check the curve family, otherwise the import could 680*b0563631STom Van Eyck * succeed with nonsensical data. 681*b0563631STom Van Eyck * We don't check the bit-size: it's optional in attributes, 682*b0563631STom Van Eyck * and if it's specified, psa_import_key() will know from the key 683*b0563631STom Van Eyck * data length and will check that the bit-size matches. */ 684*b0563631STom Van Eyck psa_key_type_t to_type = psa_get_key_type(attributes); 685*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 686*b0563631STom Van Eyck psa_ecc_family_t from_family = pk->ec_family; 687*b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */ 688*b0563631STom Van Eyck const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); 689*b0563631STom Van Eyck size_t from_bits = 0; 690*b0563631STom Van Eyck psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id, 691*b0563631STom Van Eyck &from_bits); 692*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 693*b0563631STom Van Eyck if (to_type != PSA_KEY_TYPE_ECC_KEY_PAIR(from_family)) { 694*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 695*b0563631STom Van Eyck } 696*b0563631STom Van Eyck 697*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 698*b0563631STom Van Eyck if (mbedtls_svc_key_id_is_null(pk->priv_id)) { 699*b0563631STom Van Eyck /* We have a public key and want a key pair. */ 700*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 701*b0563631STom Van Eyck } 702*b0563631STom Van Eyck return copy_into_psa(pk->priv_id, attributes, key_id); 703*b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */ 704*b0563631STom Van Eyck if (ec->d.n == 0) { 705*b0563631STom Van Eyck /* Private key not set. Assume the input is a public key only. 706*b0563631STom Van Eyck * (The other possibility is that it's an incomplete object 707*b0563631STom Van Eyck * where the group is set but neither the public key nor 708*b0563631STom Van Eyck * the private key. This is not possible through ecp.h 709*b0563631STom Van Eyck * functions, so we don't bother reporting a more suitable 710*b0563631STom Van Eyck * error in that case.) */ 711*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 712*b0563631STom Van Eyck } 713*b0563631STom Van Eyck unsigned char key_buffer[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; 714*b0563631STom Van Eyck size_t key_length = 0; 715*b0563631STom Van Eyck int ret = mbedtls_ecp_write_key_ext(ec, &key_length, 716*b0563631STom Van Eyck key_buffer, sizeof(key_buffer)); 717*b0563631STom Van Eyck if (ret < 0) { 718*b0563631STom Van Eyck return ret; 719*b0563631STom Van Eyck } 720*b0563631STom Van Eyck ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, 721*b0563631STom Van Eyck key_buffer, key_length, 722*b0563631STom Van Eyck key_id)); 723*b0563631STom Van Eyck mbedtls_platform_zeroize(key_buffer, key_length); 724*b0563631STom Van Eyck return ret; 725*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 726*b0563631STom Van Eyck } 727*b0563631STom Van Eyck #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 728*b0563631STom Van Eyck 729*b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO) 730*b0563631STom Van Eyck case MBEDTLS_PK_OPAQUE: 731*b0563631STom Van Eyck return copy_into_psa(pk->priv_id, attributes, key_id); 732*b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */ 733*b0563631STom Van Eyck 734*b0563631STom Van Eyck default: 735*b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 736*b0563631STom Van Eyck } 737*b0563631STom Van Eyck } 738*b0563631STom Van Eyck 739*b0563631STom Van Eyck static int import_public_into_psa(const mbedtls_pk_context *pk, 740*b0563631STom Van Eyck const psa_key_attributes_t *attributes, 741*b0563631STom Van Eyck mbedtls_svc_key_id_t *key_id) 742*b0563631STom Van Eyck { 743*b0563631STom Van Eyck psa_key_type_t psa_type = psa_get_key_type(attributes); 744*b0563631STom Van Eyck 745*b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) || \ 746*b0563631STom Van Eyck (defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)) || \ 747*b0563631STom Van Eyck defined(MBEDTLS_USE_PSA_CRYPTO) 748*b0563631STom Van Eyck unsigned char key_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; 749*b0563631STom Van Eyck #endif 750*b0563631STom Van Eyck unsigned char *key_data = NULL; 751*b0563631STom Van Eyck size_t key_length = 0; 752*b0563631STom Van Eyck 753*b0563631STom Van Eyck switch (mbedtls_pk_get_type(pk)) { 754*b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) 755*b0563631STom Van Eyck case MBEDTLS_PK_RSA: 756*b0563631STom Van Eyck { 757*b0563631STom Van Eyck if (psa_type != PSA_KEY_TYPE_RSA_PUBLIC_KEY) { 758*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 759*b0563631STom Van Eyck } 760*b0563631STom Van Eyck unsigned char *const key_end = key_buffer + sizeof(key_buffer); 761*b0563631STom Van Eyck key_data = key_end; 762*b0563631STom Van Eyck int ret = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*pk), 763*b0563631STom Van Eyck key_buffer, &key_data); 764*b0563631STom Van Eyck if (ret < 0) { 765*b0563631STom Van Eyck return ret; 766*b0563631STom Van Eyck } 767*b0563631STom Van Eyck key_length = (size_t) ret; 768*b0563631STom Van Eyck break; 769*b0563631STom Van Eyck } 770*b0563631STom Van Eyck #endif /*MBEDTLS_RSA_C */ 771*b0563631STom Van Eyck 772*b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 773*b0563631STom Van Eyck case MBEDTLS_PK_ECKEY: 774*b0563631STom Van Eyck case MBEDTLS_PK_ECKEY_DH: 775*b0563631STom Van Eyck case MBEDTLS_PK_ECDSA: 776*b0563631STom Van Eyck { 777*b0563631STom Van Eyck /* We need to check the curve family, otherwise the import could 778*b0563631STom Van Eyck * succeed with nonsensical data. 779*b0563631STom Van Eyck * We don't check the bit-size: it's optional in attributes, 780*b0563631STom Van Eyck * and if it's specified, psa_import_key() will know from the key 781*b0563631STom Van Eyck * data length and will check that the bit-size matches. */ 782*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 783*b0563631STom Van Eyck if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family)) { 784*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 785*b0563631STom Van Eyck } 786*b0563631STom Van Eyck key_data = (unsigned char *) pk->pub_raw; 787*b0563631STom Van Eyck key_length = pk->pub_raw_len; 788*b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */ 789*b0563631STom Van Eyck const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); 790*b0563631STom Van Eyck size_t from_bits = 0; 791*b0563631STom Van Eyck psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id, 792*b0563631STom Van Eyck &from_bits); 793*b0563631STom Van Eyck if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(from_family)) { 794*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 795*b0563631STom Van Eyck } 796*b0563631STom Van Eyck int ret = mbedtls_ecp_write_public_key( 797*b0563631STom Van Eyck ec, MBEDTLS_ECP_PF_UNCOMPRESSED, 798*b0563631STom Van Eyck &key_length, key_buffer, sizeof(key_buffer)); 799*b0563631STom Van Eyck if (ret < 0) { 800*b0563631STom Van Eyck return ret; 801*b0563631STom Van Eyck } 802*b0563631STom Van Eyck key_data = key_buffer; 803*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 804*b0563631STom Van Eyck break; 805*b0563631STom Van Eyck } 806*b0563631STom Van Eyck #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 807*b0563631STom Van Eyck 808*b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO) 809*b0563631STom Van Eyck case MBEDTLS_PK_OPAQUE: 810*b0563631STom Van Eyck { 811*b0563631STom Van Eyck psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; 812*b0563631STom Van Eyck psa_status_t status = 813*b0563631STom Van Eyck psa_get_key_attributes(pk->priv_id, &old_attributes); 814*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 815*b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 816*b0563631STom Van Eyck } 817*b0563631STom Van Eyck psa_key_type_t old_type = psa_get_key_type(&old_attributes); 818*b0563631STom Van Eyck psa_reset_key_attributes(&old_attributes); 819*b0563631STom Van Eyck if (psa_type != PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(old_type)) { 820*b0563631STom Van Eyck return MBEDTLS_ERR_PK_TYPE_MISMATCH; 821*b0563631STom Van Eyck } 822*b0563631STom Van Eyck status = psa_export_public_key(pk->priv_id, 823*b0563631STom Van Eyck key_buffer, sizeof(key_buffer), 824*b0563631STom Van Eyck &key_length); 825*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 826*b0563631STom Van Eyck return PSA_PK_TO_MBEDTLS_ERR(status); 827*b0563631STom Van Eyck } 828*b0563631STom Van Eyck key_data = key_buffer; 829*b0563631STom Van Eyck break; 830*b0563631STom Van Eyck } 831*b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */ 832*b0563631STom Van Eyck 833*b0563631STom Van Eyck default: 834*b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 835*b0563631STom Van Eyck } 836*b0563631STom Van Eyck 837*b0563631STom Van Eyck return PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, 838*b0563631STom Van Eyck key_data, key_length, 839*b0563631STom Van Eyck key_id)); 840*b0563631STom Van Eyck } 841*b0563631STom Van Eyck 842*b0563631STom Van Eyck int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, 843*b0563631STom Van Eyck const psa_key_attributes_t *attributes, 844*b0563631STom Van Eyck mbedtls_svc_key_id_t *key_id) 845*b0563631STom Van Eyck { 846*b0563631STom Van Eyck /* Set the output immediately so that it won't contain garbage even 847*b0563631STom Van Eyck * if we error out before calling psa_import_key(). */ 848*b0563631STom Van Eyck *key_id = MBEDTLS_SVC_KEY_ID_INIT; 849*b0563631STom Van Eyck 850*b0563631STom Van Eyck #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 851*b0563631STom Van Eyck if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA_ALT) { 852*b0563631STom Van Eyck return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 853*b0563631STom Van Eyck } 854*b0563631STom Van Eyck #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ 855*b0563631STom Van Eyck 856*b0563631STom Van Eyck int want_public = PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(attributes)); 857*b0563631STom Van Eyck if (want_public) { 858*b0563631STom Van Eyck return import_public_into_psa(pk, attributes, key_id); 859*b0563631STom Van Eyck } else { 860*b0563631STom Van Eyck return import_pair_into_psa(pk, attributes, key_id); 861*b0563631STom Van Eyck } 862*b0563631STom Van Eyck } 863*b0563631STom Van Eyck 864*b0563631STom Van Eyck static int copy_from_psa(mbedtls_svc_key_id_t key_id, 865*b0563631STom Van Eyck mbedtls_pk_context *pk, 866*b0563631STom Van Eyck int public_only) 867*b0563631STom Van Eyck { 868*b0563631STom Van Eyck psa_status_t status; 869*b0563631STom Van Eyck psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; 870*b0563631STom Van Eyck psa_key_type_t key_type; 871*b0563631STom Van Eyck psa_algorithm_t alg_type; 872*b0563631STom Van Eyck size_t key_bits; 873*b0563631STom Van Eyck /* Use a buffer size large enough to contain either a key pair or public key. */ 874*b0563631STom Van Eyck unsigned char exp_key[PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE]; 875*b0563631STom Van Eyck size_t exp_key_len; 876*b0563631STom Van Eyck int ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; 877*b0563631STom Van Eyck 878*b0563631STom Van Eyck if (pk == NULL) { 879*b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 880*b0563631STom Van Eyck } 881*b0563631STom Van Eyck 882*b0563631STom Van Eyck status = psa_get_key_attributes(key_id, &key_attr); 883*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 884*b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 885*b0563631STom Van Eyck } 886*b0563631STom Van Eyck 887*b0563631STom Van Eyck if (public_only) { 888*b0563631STom Van Eyck status = psa_export_public_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); 889*b0563631STom Van Eyck } else { 890*b0563631STom Van Eyck status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); 891*b0563631STom Van Eyck } 892*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 893*b0563631STom Van Eyck ret = PSA_PK_TO_MBEDTLS_ERR(status); 894*b0563631STom Van Eyck goto exit; 895*b0563631STom Van Eyck } 896*b0563631STom Van Eyck 897*b0563631STom Van Eyck key_type = psa_get_key_type(&key_attr); 898*b0563631STom Van Eyck if (public_only) { 899*b0563631STom Van Eyck key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type); 900*b0563631STom Van Eyck } 901*b0563631STom Van Eyck key_bits = psa_get_key_bits(&key_attr); 902*b0563631STom Van Eyck alg_type = psa_get_key_algorithm(&key_attr); 903*b0563631STom Van Eyck 904*b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) 905*b0563631STom Van Eyck if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) || 906*b0563631STom Van Eyck (key_type == PSA_KEY_TYPE_RSA_PUBLIC_KEY)) { 907*b0563631STom Van Eyck 908*b0563631STom Van Eyck ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); 909*b0563631STom Van Eyck if (ret != 0) { 910*b0563631STom Van Eyck goto exit; 911*b0563631STom Van Eyck } 912*b0563631STom Van Eyck 913*b0563631STom Van Eyck if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { 914*b0563631STom Van Eyck ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); 915*b0563631STom Van Eyck } else { 916*b0563631STom Van Eyck ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); 917*b0563631STom Van Eyck } 918*b0563631STom Van Eyck if (ret != 0) { 919*b0563631STom Van Eyck goto exit; 920*b0563631STom Van Eyck } 921*b0563631STom Van Eyck 922*b0563631STom Van Eyck mbedtls_md_type_t md_type = MBEDTLS_MD_NONE; 923*b0563631STom Van Eyck if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) { 924*b0563631STom Van Eyck md_type = mbedtls_md_type_from_psa_alg(alg_type); 925*b0563631STom Van Eyck } 926*b0563631STom Van Eyck 927*b0563631STom Van Eyck if (PSA_ALG_IS_RSA_OAEP(alg_type) || PSA_ALG_IS_RSA_PSS(alg_type)) { 928*b0563631STom Van Eyck ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V21, md_type); 929*b0563631STom Van Eyck } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) || 930*b0563631STom Van Eyck alg_type == PSA_ALG_RSA_PKCS1V15_CRYPT) { 931*b0563631STom Van Eyck ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V15, md_type); 932*b0563631STom Van Eyck } 933*b0563631STom Van Eyck if (ret != 0) { 934*b0563631STom Van Eyck goto exit; 935*b0563631STom Van Eyck } 936*b0563631STom Van Eyck } else 937*b0563631STom Van Eyck #endif /* MBEDTLS_RSA_C */ 938*b0563631STom Van Eyck #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 939*b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) || 940*b0563631STom Van Eyck PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) { 941*b0563631STom Van Eyck mbedtls_ecp_group_id grp_id; 942*b0563631STom Van Eyck 943*b0563631STom Van Eyck ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); 944*b0563631STom Van Eyck if (ret != 0) { 945*b0563631STom Van Eyck goto exit; 946*b0563631STom Van Eyck } 947*b0563631STom Van Eyck 948*b0563631STom Van Eyck grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type), key_bits); 949*b0563631STom Van Eyck ret = mbedtls_pk_ecc_set_group(pk, grp_id); 950*b0563631STom Van Eyck if (ret != 0) { 951*b0563631STom Van Eyck goto exit; 952*b0563631STom Van Eyck } 953*b0563631STom Van Eyck 954*b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) { 955*b0563631STom Van Eyck ret = mbedtls_pk_ecc_set_key(pk, exp_key, exp_key_len); 956*b0563631STom Van Eyck if (ret != 0) { 957*b0563631STom Van Eyck goto exit; 958*b0563631STom Van Eyck } 959*b0563631STom Van Eyck ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, exp_key, exp_key_len, 960*b0563631STom Van Eyck mbedtls_psa_get_random, 961*b0563631STom Van Eyck MBEDTLS_PSA_RANDOM_STATE); 962*b0563631STom Van Eyck } else { 963*b0563631STom Van Eyck ret = mbedtls_pk_ecc_set_pubkey(pk, exp_key, exp_key_len); 964*b0563631STom Van Eyck } 965*b0563631STom Van Eyck if (ret != 0) { 966*b0563631STom Van Eyck goto exit; 967*b0563631STom Van Eyck } 968*b0563631STom Van Eyck } else 969*b0563631STom Van Eyck #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 970*b0563631STom Van Eyck { 971*b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 972*b0563631STom Van Eyck } 973*b0563631STom Van Eyck 974*b0563631STom Van Eyck exit: 975*b0563631STom Van Eyck psa_reset_key_attributes(&key_attr); 976*b0563631STom Van Eyck mbedtls_platform_zeroize(exp_key, sizeof(exp_key)); 977*b0563631STom Van Eyck 978*b0563631STom Van Eyck return ret; 979*b0563631STom Van Eyck } 980*b0563631STom Van Eyck 981*b0563631STom Van Eyck int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, 982*b0563631STom Van Eyck mbedtls_pk_context *pk) 983*b0563631STom Van Eyck { 984*b0563631STom Van Eyck return copy_from_psa(key_id, pk, 0); 985*b0563631STom Van Eyck } 986*b0563631STom Van Eyck 987*b0563631STom Van Eyck int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, 988*b0563631STom Van Eyck mbedtls_pk_context *pk) 989*b0563631STom Van Eyck { 990*b0563631STom Van Eyck return copy_from_psa(key_id, pk, 1); 991*b0563631STom Van Eyck } 992*b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ 993*b0563631STom 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 1003*b0563631STom 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 1068*b0563631STom 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 1085*b0563631STom 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 1129*b0563631STom Van Eyck /* Ensure the PK context is of the right type otherwise mbedtls_pk_rsa() 1130*b0563631STom Van Eyck * below would return a NULL pointer. */ 1131*b0563631STom Van Eyck if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_RSA) { 1132*b0563631STom Van Eyck return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 1133*b0563631STom Van Eyck } 1134*b0563631STom 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 1139*b0563631STom 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 } 1143*b0563631STom 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 1160*b0563631STom 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); 1165*b0563631STom 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 1204*b0563631STom 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 1259*b0563631STom 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 1278*b0563631STom 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 1321*b0563631STom Van Eyck #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) 1322*b0563631STom Van Eyck 1323*b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO) 1324*b0563631STom 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) { 1330*b0563631STom Van Eyck psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; 1331*b0563631STom Van Eyck psa_algorithm_t psa_alg, sign_alg; 1332*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_C) 1333*b0563631STom Van Eyck psa_algorithm_t psa_enrollment_alg; 1334*b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_C */ 133532b31808SJens Wiklander psa_status_t status; 133632b31808SJens Wiklander 1337*b0563631STom Van Eyck status = psa_get_key_attributes(ctx->priv_id, &key_attr); 1338*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 1339*b0563631STom Van Eyck return PSA_PK_RSA_TO_MBEDTLS_ERR(status); 1340*b0563631STom Van Eyck } 1341*b0563631STom Van Eyck psa_alg = psa_get_key_algorithm(&key_attr); 1342*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_C) 1343*b0563631STom Van Eyck psa_enrollment_alg = psa_get_key_enrollment_algorithm(&key_attr); 1344*b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_C */ 1345*b0563631STom Van Eyck psa_reset_key_attributes(&key_attr); 1346*b0563631STom Van Eyck 1347*b0563631STom Van Eyck /* Since we're PK type is MBEDTLS_PK_RSASSA_PSS at least one between 1348*b0563631STom Van Eyck * alg and enrollment alg should be of type RSA_PSS. */ 1349*b0563631STom Van Eyck if (PSA_ALG_IS_RSA_PSS(psa_alg)) { 1350*b0563631STom Van Eyck sign_alg = psa_alg; 1351*b0563631STom Van Eyck } 1352*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_C) 1353*b0563631STom Van Eyck else if (PSA_ALG_IS_RSA_PSS(psa_enrollment_alg)) { 1354*b0563631STom Van Eyck sign_alg = psa_enrollment_alg; 1355*b0563631STom Van Eyck } 1356*b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_C */ 1357*b0563631STom Van Eyck else { 1358*b0563631STom Van Eyck /* The opaque key has no RSA PSS algorithm associated. */ 1359*b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1360*b0563631STom Van Eyck } 1361*b0563631STom Van Eyck /* Adjust the hashing algorithm. */ 1362*b0563631STom Van Eyck sign_alg = (sign_alg & ~PSA_ALG_HASH_MASK) | PSA_ALG_GET_HASH(psa_md_alg); 1363*b0563631STom Van Eyck 1364*b0563631STom Van Eyck status = psa_sign_hash(ctx->priv_id, sign_alg, 136532b31808SJens Wiklander hash, hash_len, 136632b31808SJens Wiklander sig, sig_size, sig_len); 136732b31808SJens Wiklander return PSA_PK_RSA_TO_MBEDTLS_ERR(status); 136832b31808SJens Wiklander } 136932b31808SJens Wiklander 137032b31808SJens Wiklander return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PSS(psa_md_alg), 137132b31808SJens Wiklander ctx->pk_ctx, hash, hash_len, 137232b31808SJens Wiklander sig, sig_size, sig_len); 1373*b0563631STom Van Eyck #else /* MBEDTLS_USE_PSA_CRYPTO */ 137432b31808SJens Wiklander 1375*b0563631STom Van Eyck if (sig_size < mbedtls_pk_get_len(ctx)) { 1376*b0563631STom Van Eyck return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; 137732b31808SJens Wiklander } 1378*b0563631STom Van Eyck 1379*b0563631STom Van Eyck if (pk_hashlen_helper(md_alg, &hash_len) != 0) { 1380*b0563631STom Van Eyck return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1381*b0563631STom Van Eyck } 1382*b0563631STom Van Eyck 1383*b0563631STom Van Eyck mbedtls_rsa_context *const rsa_ctx = mbedtls_pk_rsa(*ctx); 1384*b0563631STom Van Eyck 1385*b0563631STom Van Eyck const int ret = mbedtls_rsa_rsassa_pss_sign_no_mode_check(rsa_ctx, f_rng, p_rng, md_alg, 1386*b0563631STom Van Eyck (unsigned int) hash_len, hash, sig); 1387*b0563631STom Van Eyck if (ret == 0) { 1388*b0563631STom Van Eyck *sig_len = rsa_ctx->len; 1389*b0563631STom Van Eyck } 1390*b0563631STom Van Eyck return ret; 1391*b0563631STom Van Eyck 1392*b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */ 1393*b0563631STom Van Eyck 1394*b0563631STom Van Eyck #else 1395*b0563631STom Van Eyck return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 1396*b0563631STom Van Eyck #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ 1397*b0563631STom Van Eyck } 139832b31808SJens Wiklander 1399817466cbSJens Wiklander /* 1400817466cbSJens Wiklander * Decrypt message 1401817466cbSJens Wiklander */ 1402817466cbSJens Wiklander int mbedtls_pk_decrypt(mbedtls_pk_context *ctx, 1403817466cbSJens Wiklander const unsigned char *input, size_t ilen, 1404817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 1405817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 1406817466cbSJens Wiklander { 140732b31808SJens Wiklander if (ctx->pk_info == NULL) { 140832b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 140932b31808SJens Wiklander } 14103d3b0591SJens Wiklander 141132b31808SJens Wiklander if (ctx->pk_info->decrypt_func == NULL) { 141232b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 141332b31808SJens Wiklander } 1414817466cbSJens Wiklander 1415*b0563631STom Van Eyck return ctx->pk_info->decrypt_func(ctx, input, ilen, 141632b31808SJens Wiklander output, olen, osize, f_rng, p_rng); 1417817466cbSJens Wiklander } 1418817466cbSJens Wiklander 1419817466cbSJens Wiklander /* 1420817466cbSJens Wiklander * Encrypt message 1421817466cbSJens Wiklander */ 1422817466cbSJens Wiklander int mbedtls_pk_encrypt(mbedtls_pk_context *ctx, 1423817466cbSJens Wiklander const unsigned char *input, size_t ilen, 1424817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 1425817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 1426817466cbSJens Wiklander { 142732b31808SJens Wiklander if (ctx->pk_info == NULL) { 142832b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 142932b31808SJens Wiklander } 14303d3b0591SJens Wiklander 143132b31808SJens Wiklander if (ctx->pk_info->encrypt_func == NULL) { 143232b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 143332b31808SJens Wiklander } 1434817466cbSJens Wiklander 1435*b0563631STom Van Eyck return ctx->pk_info->encrypt_func(ctx, input, ilen, 143632b31808SJens Wiklander output, olen, osize, f_rng, p_rng); 1437817466cbSJens Wiklander } 1438817466cbSJens Wiklander 1439817466cbSJens Wiklander /* 1440817466cbSJens Wiklander * Check public-private key pair 1441817466cbSJens Wiklander */ 144232b31808SJens Wiklander int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, 144332b31808SJens Wiklander const mbedtls_pk_context *prv, 144432b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 144532b31808SJens Wiklander void *p_rng) 1446817466cbSJens Wiklander { 14473d3b0591SJens Wiklander if (pub->pk_info == NULL || 144832b31808SJens Wiklander prv->pk_info == NULL) { 144932b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1450817466cbSJens Wiklander } 1451817466cbSJens Wiklander 145232b31808SJens Wiklander if (f_rng == NULL) { 145332b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1454817466cbSJens Wiklander } 1455817466cbSJens Wiklander 145632b31808SJens Wiklander if (prv->pk_info->check_pair_func == NULL) { 145732b31808SJens Wiklander return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 145832b31808SJens Wiklander } 145932b31808SJens Wiklander 146032b31808SJens Wiklander if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) { 146132b31808SJens Wiklander if (pub->pk_info->type != MBEDTLS_PK_RSA) { 146232b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 146332b31808SJens Wiklander } 146432b31808SJens Wiklander } else { 1465*b0563631STom Van Eyck if ((prv->pk_info->type != MBEDTLS_PK_OPAQUE) && 1466*b0563631STom Van Eyck (pub->pk_info != prv->pk_info)) { 146732b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 146832b31808SJens Wiklander } 146932b31808SJens Wiklander } 147032b31808SJens Wiklander 1471*b0563631STom Van Eyck return prv->pk_info->check_pair_func((mbedtls_pk_context *) pub, 1472*b0563631STom Van Eyck (mbedtls_pk_context *) prv, 1473*b0563631STom Van Eyck f_rng, p_rng); 1474817466cbSJens Wiklander } 1475817466cbSJens Wiklander 1476817466cbSJens Wiklander /* 1477817466cbSJens Wiklander * Get key size in bits 1478817466cbSJens Wiklander */ 1479817466cbSJens Wiklander size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx) 1480817466cbSJens Wiklander { 14813d3b0591SJens Wiklander /* For backward compatibility, accept NULL or a context that 14823d3b0591SJens Wiklander * isn't set up yet, and return a fake value that should be safe. */ 148332b31808SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL) { 148432b31808SJens Wiklander return 0; 148532b31808SJens Wiklander } 1486817466cbSJens Wiklander 1487*b0563631STom Van Eyck return ctx->pk_info->get_bitlen((mbedtls_pk_context *) ctx); 1488817466cbSJens Wiklander } 1489817466cbSJens Wiklander 1490817466cbSJens Wiklander /* 1491817466cbSJens Wiklander * Export debug information 1492817466cbSJens Wiklander */ 1493817466cbSJens Wiklander int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items) 1494817466cbSJens Wiklander { 149532b31808SJens Wiklander if (ctx->pk_info == NULL) { 149632b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 149732b31808SJens Wiklander } 1498817466cbSJens Wiklander 149932b31808SJens Wiklander if (ctx->pk_info->debug_func == NULL) { 150032b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 150132b31808SJens Wiklander } 1502817466cbSJens Wiklander 1503*b0563631STom Van Eyck ctx->pk_info->debug_func((mbedtls_pk_context *) ctx, items); 150432b31808SJens Wiklander return 0; 1505817466cbSJens Wiklander } 1506817466cbSJens Wiklander 1507817466cbSJens Wiklander /* 1508817466cbSJens Wiklander * Access the PK type name 1509817466cbSJens Wiklander */ 1510817466cbSJens Wiklander const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx) 1511817466cbSJens Wiklander { 151232b31808SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL) { 151332b31808SJens Wiklander return "invalid PK"; 151432b31808SJens Wiklander } 1515817466cbSJens Wiklander 151632b31808SJens Wiklander return ctx->pk_info->name; 1517817466cbSJens Wiklander } 1518817466cbSJens Wiklander 1519817466cbSJens Wiklander /* 1520817466cbSJens Wiklander * Access the PK type 1521817466cbSJens Wiklander */ 1522817466cbSJens Wiklander mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) 1523817466cbSJens Wiklander { 152432b31808SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL) { 152532b31808SJens Wiklander return MBEDTLS_PK_NONE; 152632b31808SJens Wiklander } 1527817466cbSJens Wiklander 152832b31808SJens Wiklander return ctx->pk_info->type; 1529817466cbSJens Wiklander } 1530817466cbSJens Wiklander 1531817466cbSJens Wiklander #endif /* MBEDTLS_PK_C */ 1532