1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * Public Key abstraction layer 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 5a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6a8e1175bSopenharmony_ci */ 7a8e1175bSopenharmony_ci 8a8e1175bSopenharmony_ci#include "common.h" 9a8e1175bSopenharmony_ci 10a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_C) 11a8e1175bSopenharmony_ci#include "mbedtls/pk.h" 12a8e1175bSopenharmony_ci#include "pk_wrap.h" 13a8e1175bSopenharmony_ci#include "pkwrite.h" 14a8e1175bSopenharmony_ci#include "pk_internal.h" 15a8e1175bSopenharmony_ci 16a8e1175bSopenharmony_ci#include "mbedtls/platform_util.h" 17a8e1175bSopenharmony_ci#include "mbedtls/error.h" 18a8e1175bSopenharmony_ci 19a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) 20a8e1175bSopenharmony_ci#include "mbedtls/rsa.h" 21a8e1175bSopenharmony_ci#include "rsa_internal.h" 22a8e1175bSopenharmony_ci#endif 23a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 24a8e1175bSopenharmony_ci#include "mbedtls/ecp.h" 25a8e1175bSopenharmony_ci#endif 26a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) 27a8e1175bSopenharmony_ci#include "mbedtls/ecdsa.h" 28a8e1175bSopenharmony_ci#endif 29a8e1175bSopenharmony_ci 30a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) 31a8e1175bSopenharmony_ci#include "psa_util_internal.h" 32a8e1175bSopenharmony_ci#include "mbedtls/psa_util.h" 33a8e1175bSopenharmony_ci#endif 34a8e1175bSopenharmony_ci 35a8e1175bSopenharmony_ci#include <limits.h> 36a8e1175bSopenharmony_ci#include <stdint.h> 37a8e1175bSopenharmony_ci 38a8e1175bSopenharmony_ci#define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE \ 39a8e1175bSopenharmony_ci (PSA_EXPORT_KEY_PAIR_MAX_SIZE > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) ? \ 40a8e1175bSopenharmony_ci PSA_EXPORT_KEY_PAIR_MAX_SIZE : PSA_EXPORT_PUBLIC_KEY_MAX_SIZE 41a8e1175bSopenharmony_ci 42a8e1175bSopenharmony_ci/* 43a8e1175bSopenharmony_ci * Initialise a mbedtls_pk_context 44a8e1175bSopenharmony_ci */ 45a8e1175bSopenharmony_civoid mbedtls_pk_init(mbedtls_pk_context *ctx) 46a8e1175bSopenharmony_ci{ 47a8e1175bSopenharmony_ci ctx->pk_info = NULL; 48a8e1175bSopenharmony_ci ctx->pk_ctx = NULL; 49a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 50a8e1175bSopenharmony_ci ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT; 51a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 52a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 53a8e1175bSopenharmony_ci memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw)); 54a8e1175bSopenharmony_ci ctx->pub_raw_len = 0; 55a8e1175bSopenharmony_ci ctx->ec_family = 0; 56a8e1175bSopenharmony_ci ctx->ec_bits = 0; 57a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 58a8e1175bSopenharmony_ci} 59a8e1175bSopenharmony_ci 60a8e1175bSopenharmony_ci/* 61a8e1175bSopenharmony_ci * Free (the components of) a mbedtls_pk_context 62a8e1175bSopenharmony_ci */ 63a8e1175bSopenharmony_civoid mbedtls_pk_free(mbedtls_pk_context *ctx) 64a8e1175bSopenharmony_ci{ 65a8e1175bSopenharmony_ci if (ctx == NULL) { 66a8e1175bSopenharmony_ci return; 67a8e1175bSopenharmony_ci } 68a8e1175bSopenharmony_ci 69a8e1175bSopenharmony_ci if ((ctx->pk_info != NULL) && (ctx->pk_info->ctx_free_func != NULL)) { 70a8e1175bSopenharmony_ci ctx->pk_info->ctx_free_func(ctx->pk_ctx); 71a8e1175bSopenharmony_ci } 72a8e1175bSopenharmony_ci 73a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 74a8e1175bSopenharmony_ci /* The ownership of the priv_id key for opaque keys is external of the PK 75a8e1175bSopenharmony_ci * module. It's the user responsibility to clear it after use. */ 76a8e1175bSopenharmony_ci if ((ctx->pk_info != NULL) && (ctx->pk_info->type != MBEDTLS_PK_OPAQUE)) { 77a8e1175bSopenharmony_ci psa_destroy_key(ctx->priv_id); 78a8e1175bSopenharmony_ci } 79a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 80a8e1175bSopenharmony_ci 81a8e1175bSopenharmony_ci mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context)); 82a8e1175bSopenharmony_ci} 83a8e1175bSopenharmony_ci 84a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 85a8e1175bSopenharmony_ci/* 86a8e1175bSopenharmony_ci * Initialize a restart context 87a8e1175bSopenharmony_ci */ 88a8e1175bSopenharmony_civoid mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx) 89a8e1175bSopenharmony_ci{ 90a8e1175bSopenharmony_ci ctx->pk_info = NULL; 91a8e1175bSopenharmony_ci ctx->rs_ctx = NULL; 92a8e1175bSopenharmony_ci} 93a8e1175bSopenharmony_ci 94a8e1175bSopenharmony_ci/* 95a8e1175bSopenharmony_ci * Free the components of a restart context 96a8e1175bSopenharmony_ci */ 97a8e1175bSopenharmony_civoid mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx) 98a8e1175bSopenharmony_ci{ 99a8e1175bSopenharmony_ci if (ctx == NULL || ctx->pk_info == NULL || 100a8e1175bSopenharmony_ci ctx->pk_info->rs_free_func == NULL) { 101a8e1175bSopenharmony_ci return; 102a8e1175bSopenharmony_ci } 103a8e1175bSopenharmony_ci 104a8e1175bSopenharmony_ci ctx->pk_info->rs_free_func(ctx->rs_ctx); 105a8e1175bSopenharmony_ci 106a8e1175bSopenharmony_ci ctx->pk_info = NULL; 107a8e1175bSopenharmony_ci ctx->rs_ctx = NULL; 108a8e1175bSopenharmony_ci} 109a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 110a8e1175bSopenharmony_ci 111a8e1175bSopenharmony_ci/* 112a8e1175bSopenharmony_ci * Get pk_info structure from type 113a8e1175bSopenharmony_ci */ 114a8e1175bSopenharmony_ciconst mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type) 115a8e1175bSopenharmony_ci{ 116a8e1175bSopenharmony_ci switch (pk_type) { 117a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) 118a8e1175bSopenharmony_ci case MBEDTLS_PK_RSA: 119a8e1175bSopenharmony_ci return &mbedtls_rsa_info; 120a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */ 121a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 122a8e1175bSopenharmony_ci case MBEDTLS_PK_ECKEY: 123a8e1175bSopenharmony_ci return &mbedtls_eckey_info; 124a8e1175bSopenharmony_ci case MBEDTLS_PK_ECKEY_DH: 125a8e1175bSopenharmony_ci return &mbedtls_eckeydh_info; 126a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 127a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_CAN_ECDSA_SOME) 128a8e1175bSopenharmony_ci case MBEDTLS_PK_ECDSA: 129a8e1175bSopenharmony_ci return &mbedtls_ecdsa_info; 130a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_CAN_ECDSA_SOME */ 131a8e1175bSopenharmony_ci /* MBEDTLS_PK_RSA_ALT omitted on purpose */ 132a8e1175bSopenharmony_ci default: 133a8e1175bSopenharmony_ci return NULL; 134a8e1175bSopenharmony_ci } 135a8e1175bSopenharmony_ci} 136a8e1175bSopenharmony_ci 137a8e1175bSopenharmony_ci/* 138a8e1175bSopenharmony_ci * Initialise context 139a8e1175bSopenharmony_ci */ 140a8e1175bSopenharmony_ciint mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info) 141a8e1175bSopenharmony_ci{ 142a8e1175bSopenharmony_ci if (info == NULL || ctx->pk_info != NULL) { 143a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 144a8e1175bSopenharmony_ci } 145a8e1175bSopenharmony_ci 146a8e1175bSopenharmony_ci if ((info->ctx_alloc_func != NULL) && 147a8e1175bSopenharmony_ci ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)) { 148a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_ALLOC_FAILED; 149a8e1175bSopenharmony_ci } 150a8e1175bSopenharmony_ci 151a8e1175bSopenharmony_ci ctx->pk_info = info; 152a8e1175bSopenharmony_ci 153a8e1175bSopenharmony_ci return 0; 154a8e1175bSopenharmony_ci} 155a8e1175bSopenharmony_ci 156a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 157a8e1175bSopenharmony_ci/* 158a8e1175bSopenharmony_ci * Initialise a PSA-wrapping context 159a8e1175bSopenharmony_ci */ 160a8e1175bSopenharmony_ciint mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, 161a8e1175bSopenharmony_ci const mbedtls_svc_key_id_t key) 162a8e1175bSopenharmony_ci{ 163a8e1175bSopenharmony_ci const mbedtls_pk_info_t *info = NULL; 164a8e1175bSopenharmony_ci psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 165a8e1175bSopenharmony_ci psa_key_type_t type; 166a8e1175bSopenharmony_ci 167a8e1175bSopenharmony_ci if (ctx == NULL || ctx->pk_info != NULL) { 168a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 169a8e1175bSopenharmony_ci } 170a8e1175bSopenharmony_ci 171a8e1175bSopenharmony_ci if (PSA_SUCCESS != psa_get_key_attributes(key, &attributes)) { 172a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 173a8e1175bSopenharmony_ci } 174a8e1175bSopenharmony_ci type = psa_get_key_type(&attributes); 175a8e1175bSopenharmony_ci psa_reset_key_attributes(&attributes); 176a8e1175bSopenharmony_ci 177a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 178a8e1175bSopenharmony_ci if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) { 179a8e1175bSopenharmony_ci info = &mbedtls_ecdsa_opaque_info; 180a8e1175bSopenharmony_ci } else 181a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 182a8e1175bSopenharmony_ci if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) { 183a8e1175bSopenharmony_ci info = &mbedtls_rsa_opaque_info; 184a8e1175bSopenharmony_ci } else { 185a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 186a8e1175bSopenharmony_ci } 187a8e1175bSopenharmony_ci 188a8e1175bSopenharmony_ci ctx->pk_info = info; 189a8e1175bSopenharmony_ci ctx->priv_id = key; 190a8e1175bSopenharmony_ci 191a8e1175bSopenharmony_ci return 0; 192a8e1175bSopenharmony_ci} 193a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 194a8e1175bSopenharmony_ci 195a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 196a8e1175bSopenharmony_ci/* 197a8e1175bSopenharmony_ci * Initialize an RSA-alt context 198a8e1175bSopenharmony_ci */ 199a8e1175bSopenharmony_ciint mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key, 200a8e1175bSopenharmony_ci mbedtls_pk_rsa_alt_decrypt_func decrypt_func, 201a8e1175bSopenharmony_ci mbedtls_pk_rsa_alt_sign_func sign_func, 202a8e1175bSopenharmony_ci mbedtls_pk_rsa_alt_key_len_func key_len_func) 203a8e1175bSopenharmony_ci{ 204a8e1175bSopenharmony_ci mbedtls_rsa_alt_context *rsa_alt; 205a8e1175bSopenharmony_ci const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info; 206a8e1175bSopenharmony_ci 207a8e1175bSopenharmony_ci if (ctx->pk_info != NULL) { 208a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 209a8e1175bSopenharmony_ci } 210a8e1175bSopenharmony_ci 211a8e1175bSopenharmony_ci if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) { 212a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_ALLOC_FAILED; 213a8e1175bSopenharmony_ci } 214a8e1175bSopenharmony_ci 215a8e1175bSopenharmony_ci ctx->pk_info = info; 216a8e1175bSopenharmony_ci 217a8e1175bSopenharmony_ci rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx; 218a8e1175bSopenharmony_ci 219a8e1175bSopenharmony_ci rsa_alt->key = key; 220a8e1175bSopenharmony_ci rsa_alt->decrypt_func = decrypt_func; 221a8e1175bSopenharmony_ci rsa_alt->sign_func = sign_func; 222a8e1175bSopenharmony_ci rsa_alt->key_len_func = key_len_func; 223a8e1175bSopenharmony_ci 224a8e1175bSopenharmony_ci return 0; 225a8e1175bSopenharmony_ci} 226a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ 227a8e1175bSopenharmony_ci 228a8e1175bSopenharmony_ci/* 229a8e1175bSopenharmony_ci * Tell if a PK can do the operations of the given type 230a8e1175bSopenharmony_ci */ 231a8e1175bSopenharmony_ciint mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type) 232a8e1175bSopenharmony_ci{ 233a8e1175bSopenharmony_ci /* A context with null pk_info is not set up yet and can't do anything. 234a8e1175bSopenharmony_ci * For backward compatibility, also accept NULL instead of a context 235a8e1175bSopenharmony_ci * pointer. */ 236a8e1175bSopenharmony_ci if (ctx == NULL || ctx->pk_info == NULL) { 237a8e1175bSopenharmony_ci return 0; 238a8e1175bSopenharmony_ci } 239a8e1175bSopenharmony_ci 240a8e1175bSopenharmony_ci return ctx->pk_info->can_do(type); 241a8e1175bSopenharmony_ci} 242a8e1175bSopenharmony_ci 243a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 244a8e1175bSopenharmony_ci/* 245a8e1175bSopenharmony_ci * Tell if a PK can do the operations of the given PSA algorithm 246a8e1175bSopenharmony_ci */ 247a8e1175bSopenharmony_ciint mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg, 248a8e1175bSopenharmony_ci psa_key_usage_t usage) 249a8e1175bSopenharmony_ci{ 250a8e1175bSopenharmony_ci psa_key_usage_t key_usage; 251a8e1175bSopenharmony_ci 252a8e1175bSopenharmony_ci /* A context with null pk_info is not set up yet and can't do anything. 253a8e1175bSopenharmony_ci * For backward compatibility, also accept NULL instead of a context 254a8e1175bSopenharmony_ci * pointer. */ 255a8e1175bSopenharmony_ci if (ctx == NULL || ctx->pk_info == NULL) { 256a8e1175bSopenharmony_ci return 0; 257a8e1175bSopenharmony_ci } 258a8e1175bSopenharmony_ci 259a8e1175bSopenharmony_ci /* Filter out non allowed algorithms */ 260a8e1175bSopenharmony_ci if (PSA_ALG_IS_ECDSA(alg) == 0 && 261a8e1175bSopenharmony_ci PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) == 0 && 262a8e1175bSopenharmony_ci PSA_ALG_IS_RSA_PSS(alg) == 0 && 263a8e1175bSopenharmony_ci alg != PSA_ALG_RSA_PKCS1V15_CRYPT && 264a8e1175bSopenharmony_ci PSA_ALG_IS_ECDH(alg) == 0) { 265a8e1175bSopenharmony_ci return 0; 266a8e1175bSopenharmony_ci } 267a8e1175bSopenharmony_ci 268a8e1175bSopenharmony_ci /* Filter out non allowed usage flags */ 269a8e1175bSopenharmony_ci if (usage == 0 || 270a8e1175bSopenharmony_ci (usage & ~(PSA_KEY_USAGE_SIGN_HASH | 271a8e1175bSopenharmony_ci PSA_KEY_USAGE_DECRYPT | 272a8e1175bSopenharmony_ci PSA_KEY_USAGE_DERIVE)) != 0) { 273a8e1175bSopenharmony_ci return 0; 274a8e1175bSopenharmony_ci } 275a8e1175bSopenharmony_ci 276a8e1175bSopenharmony_ci /* Wildcard hash is not allowed */ 277a8e1175bSopenharmony_ci if (PSA_ALG_IS_SIGN_HASH(alg) && 278a8e1175bSopenharmony_ci PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH) { 279a8e1175bSopenharmony_ci return 0; 280a8e1175bSopenharmony_ci } 281a8e1175bSopenharmony_ci 282a8e1175bSopenharmony_ci if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_OPAQUE) { 283a8e1175bSopenharmony_ci mbedtls_pk_type_t type; 284a8e1175bSopenharmony_ci 285a8e1175bSopenharmony_ci if (PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_ECDH(alg)) { 286a8e1175bSopenharmony_ci type = MBEDTLS_PK_ECKEY; 287a8e1175bSopenharmony_ci } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || 288a8e1175bSopenharmony_ci alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { 289a8e1175bSopenharmony_ci type = MBEDTLS_PK_RSA; 290a8e1175bSopenharmony_ci } else if (PSA_ALG_IS_RSA_PSS(alg)) { 291a8e1175bSopenharmony_ci type = MBEDTLS_PK_RSASSA_PSS; 292a8e1175bSopenharmony_ci } else { 293a8e1175bSopenharmony_ci return 0; 294a8e1175bSopenharmony_ci } 295a8e1175bSopenharmony_ci 296a8e1175bSopenharmony_ci if (ctx->pk_info->can_do(type) == 0) { 297a8e1175bSopenharmony_ci return 0; 298a8e1175bSopenharmony_ci } 299a8e1175bSopenharmony_ci 300a8e1175bSopenharmony_ci switch (type) { 301a8e1175bSopenharmony_ci case MBEDTLS_PK_ECKEY: 302a8e1175bSopenharmony_ci key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE; 303a8e1175bSopenharmony_ci break; 304a8e1175bSopenharmony_ci case MBEDTLS_PK_RSA: 305a8e1175bSopenharmony_ci case MBEDTLS_PK_RSASSA_PSS: 306a8e1175bSopenharmony_ci key_usage = PSA_KEY_USAGE_SIGN_HASH | 307a8e1175bSopenharmony_ci PSA_KEY_USAGE_SIGN_MESSAGE | 308a8e1175bSopenharmony_ci PSA_KEY_USAGE_DECRYPT; 309a8e1175bSopenharmony_ci break; 310a8e1175bSopenharmony_ci default: 311a8e1175bSopenharmony_ci /* Should never happen */ 312a8e1175bSopenharmony_ci return 0; 313a8e1175bSopenharmony_ci } 314a8e1175bSopenharmony_ci 315a8e1175bSopenharmony_ci return (key_usage & usage) == usage; 316a8e1175bSopenharmony_ci } 317a8e1175bSopenharmony_ci 318a8e1175bSopenharmony_ci psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 319a8e1175bSopenharmony_ci psa_status_t status; 320a8e1175bSopenharmony_ci 321a8e1175bSopenharmony_ci status = psa_get_key_attributes(ctx->priv_id, &attributes); 322a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 323a8e1175bSopenharmony_ci return 0; 324a8e1175bSopenharmony_ci } 325a8e1175bSopenharmony_ci 326a8e1175bSopenharmony_ci psa_algorithm_t key_alg = psa_get_key_algorithm(&attributes); 327a8e1175bSopenharmony_ci /* Key's enrollment is available only when an Mbed TLS implementation of PSA 328a8e1175bSopenharmony_ci * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined. 329a8e1175bSopenharmony_ci * Even though we don't officially support using other implementations of PSA 330a8e1175bSopenharmony_ci * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations 331a8e1175bSopenharmony_ci * separated. */ 332a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C) 333a8e1175bSopenharmony_ci psa_algorithm_t key_alg2 = psa_get_key_enrollment_algorithm(&attributes); 334a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */ 335a8e1175bSopenharmony_ci key_usage = psa_get_key_usage_flags(&attributes); 336a8e1175bSopenharmony_ci psa_reset_key_attributes(&attributes); 337a8e1175bSopenharmony_ci 338a8e1175bSopenharmony_ci if ((key_usage & usage) != usage) { 339a8e1175bSopenharmony_ci return 0; 340a8e1175bSopenharmony_ci } 341a8e1175bSopenharmony_ci 342a8e1175bSopenharmony_ci /* 343a8e1175bSopenharmony_ci * Common case: the key alg [or alg2] only allows alg. 344a8e1175bSopenharmony_ci * This will match PSA_ALG_RSA_PKCS1V15_CRYPT & PSA_ALG_IS_ECDH 345a8e1175bSopenharmony_ci * directly. 346a8e1175bSopenharmony_ci * This would also match ECDSA/RSA_PKCS1V15_SIGN/RSA_PSS with 347a8e1175bSopenharmony_ci * a fixed hash on key_alg [or key_alg2]. 348a8e1175bSopenharmony_ci */ 349a8e1175bSopenharmony_ci if (alg == key_alg) { 350a8e1175bSopenharmony_ci return 1; 351a8e1175bSopenharmony_ci } 352a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C) 353a8e1175bSopenharmony_ci if (alg == key_alg2) { 354a8e1175bSopenharmony_ci return 1; 355a8e1175bSopenharmony_ci } 356a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */ 357a8e1175bSopenharmony_ci 358a8e1175bSopenharmony_ci /* 359a8e1175bSopenharmony_ci * If key_alg [or key_alg2] is a hash-and-sign with a wildcard for the hash, 360a8e1175bSopenharmony_ci * and alg is the same hash-and-sign family with any hash, 361a8e1175bSopenharmony_ci * then alg is compliant with this key alg 362a8e1175bSopenharmony_ci */ 363a8e1175bSopenharmony_ci if (PSA_ALG_IS_SIGN_HASH(alg)) { 364a8e1175bSopenharmony_ci if (PSA_ALG_IS_SIGN_HASH(key_alg) && 365a8e1175bSopenharmony_ci PSA_ALG_SIGN_GET_HASH(key_alg) == PSA_ALG_ANY_HASH && 366a8e1175bSopenharmony_ci (alg & ~PSA_ALG_HASH_MASK) == (key_alg & ~PSA_ALG_HASH_MASK)) { 367a8e1175bSopenharmony_ci return 1; 368a8e1175bSopenharmony_ci } 369a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C) 370a8e1175bSopenharmony_ci if (PSA_ALG_IS_SIGN_HASH(key_alg2) && 371a8e1175bSopenharmony_ci PSA_ALG_SIGN_GET_HASH(key_alg2) == PSA_ALG_ANY_HASH && 372a8e1175bSopenharmony_ci (alg & ~PSA_ALG_HASH_MASK) == (key_alg2 & ~PSA_ALG_HASH_MASK)) { 373a8e1175bSopenharmony_ci return 1; 374a8e1175bSopenharmony_ci } 375a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */ 376a8e1175bSopenharmony_ci } 377a8e1175bSopenharmony_ci 378a8e1175bSopenharmony_ci return 0; 379a8e1175bSopenharmony_ci} 380a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 381a8e1175bSopenharmony_ci 382a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) 383a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) 384a8e1175bSopenharmony_cistatic psa_algorithm_t psa_algorithm_for_rsa(const mbedtls_rsa_context *rsa, 385a8e1175bSopenharmony_ci int want_crypt) 386a8e1175bSopenharmony_ci{ 387a8e1175bSopenharmony_ci if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) { 388a8e1175bSopenharmony_ci if (want_crypt) { 389a8e1175bSopenharmony_ci mbedtls_md_type_t md_type = (mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa); 390a8e1175bSopenharmony_ci return PSA_ALG_RSA_OAEP(mbedtls_md_psa_alg_from_type(md_type)); 391a8e1175bSopenharmony_ci } else { 392a8e1175bSopenharmony_ci return PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH); 393a8e1175bSopenharmony_ci } 394a8e1175bSopenharmony_ci } else { 395a8e1175bSopenharmony_ci if (want_crypt) { 396a8e1175bSopenharmony_ci return PSA_ALG_RSA_PKCS1V15_CRYPT; 397a8e1175bSopenharmony_ci } else { 398a8e1175bSopenharmony_ci return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH); 399a8e1175bSopenharmony_ci } 400a8e1175bSopenharmony_ci } 401a8e1175bSopenharmony_ci} 402a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */ 403a8e1175bSopenharmony_ci 404a8e1175bSopenharmony_ciint mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk, 405a8e1175bSopenharmony_ci psa_key_usage_t usage, 406a8e1175bSopenharmony_ci psa_key_attributes_t *attributes) 407a8e1175bSopenharmony_ci{ 408a8e1175bSopenharmony_ci mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk); 409a8e1175bSopenharmony_ci 410a8e1175bSopenharmony_ci psa_key_usage_t more_usage = usage; 411a8e1175bSopenharmony_ci if (usage == PSA_KEY_USAGE_SIGN_MESSAGE) { 412a8e1175bSopenharmony_ci more_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE; 413a8e1175bSopenharmony_ci } else if (usage == PSA_KEY_USAGE_SIGN_HASH) { 414a8e1175bSopenharmony_ci more_usage |= PSA_KEY_USAGE_VERIFY_HASH; 415a8e1175bSopenharmony_ci } else if (usage == PSA_KEY_USAGE_DECRYPT) { 416a8e1175bSopenharmony_ci more_usage |= PSA_KEY_USAGE_ENCRYPT; 417a8e1175bSopenharmony_ci } 418a8e1175bSopenharmony_ci more_usage |= PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY; 419a8e1175bSopenharmony_ci 420a8e1175bSopenharmony_ci int want_private = !(usage == PSA_KEY_USAGE_VERIFY_MESSAGE || 421a8e1175bSopenharmony_ci usage == PSA_KEY_USAGE_VERIFY_HASH || 422a8e1175bSopenharmony_ci usage == PSA_KEY_USAGE_ENCRYPT); 423a8e1175bSopenharmony_ci 424a8e1175bSopenharmony_ci switch (pk_type) { 425a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) 426a8e1175bSopenharmony_ci case MBEDTLS_PK_RSA: 427a8e1175bSopenharmony_ci { 428a8e1175bSopenharmony_ci int want_crypt = 0; /* 0: sign/verify; 1: encrypt/decrypt */ 429a8e1175bSopenharmony_ci switch (usage) { 430a8e1175bSopenharmony_ci case PSA_KEY_USAGE_SIGN_MESSAGE: 431a8e1175bSopenharmony_ci case PSA_KEY_USAGE_SIGN_HASH: 432a8e1175bSopenharmony_ci case PSA_KEY_USAGE_VERIFY_MESSAGE: 433a8e1175bSopenharmony_ci case PSA_KEY_USAGE_VERIFY_HASH: 434a8e1175bSopenharmony_ci /* Nothing to do. */ 435a8e1175bSopenharmony_ci break; 436a8e1175bSopenharmony_ci case PSA_KEY_USAGE_DECRYPT: 437a8e1175bSopenharmony_ci case PSA_KEY_USAGE_ENCRYPT: 438a8e1175bSopenharmony_ci want_crypt = 1; 439a8e1175bSopenharmony_ci break; 440a8e1175bSopenharmony_ci default: 441a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 442a8e1175bSopenharmony_ci } 443a8e1175bSopenharmony_ci /* Detect the presence of a private key in a way that works both 444a8e1175bSopenharmony_ci * in CRT and non-CRT configurations. */ 445a8e1175bSopenharmony_ci mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk); 446a8e1175bSopenharmony_ci int has_private = (mbedtls_rsa_check_privkey(rsa) == 0); 447a8e1175bSopenharmony_ci if (want_private && !has_private) { 448a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 449a8e1175bSopenharmony_ci } 450a8e1175bSopenharmony_ci psa_set_key_type(attributes, (want_private ? 451a8e1175bSopenharmony_ci PSA_KEY_TYPE_RSA_KEY_PAIR : 452a8e1175bSopenharmony_ci PSA_KEY_TYPE_RSA_PUBLIC_KEY)); 453a8e1175bSopenharmony_ci psa_set_key_bits(attributes, mbedtls_pk_get_bitlen(pk)); 454a8e1175bSopenharmony_ci psa_set_key_algorithm(attributes, 455a8e1175bSopenharmony_ci psa_algorithm_for_rsa(rsa, want_crypt)); 456a8e1175bSopenharmony_ci break; 457a8e1175bSopenharmony_ci } 458a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */ 459a8e1175bSopenharmony_ci 460a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 461a8e1175bSopenharmony_ci case MBEDTLS_PK_ECKEY: 462a8e1175bSopenharmony_ci case MBEDTLS_PK_ECKEY_DH: 463a8e1175bSopenharmony_ci case MBEDTLS_PK_ECDSA: 464a8e1175bSopenharmony_ci { 465a8e1175bSopenharmony_ci int sign_ok = (pk_type != MBEDTLS_PK_ECKEY_DH); 466a8e1175bSopenharmony_ci int derive_ok = (pk_type != MBEDTLS_PK_ECDSA); 467a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 468a8e1175bSopenharmony_ci psa_ecc_family_t family = pk->ec_family; 469a8e1175bSopenharmony_ci size_t bits = pk->ec_bits; 470a8e1175bSopenharmony_ci int has_private = 0; 471a8e1175bSopenharmony_ci if (pk->priv_id != MBEDTLS_SVC_KEY_ID_INIT) { 472a8e1175bSopenharmony_ci has_private = 1; 473a8e1175bSopenharmony_ci } 474a8e1175bSopenharmony_ci#else 475a8e1175bSopenharmony_ci const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); 476a8e1175bSopenharmony_ci int has_private = (ec->d.n != 0); 477a8e1175bSopenharmony_ci size_t bits = 0; 478a8e1175bSopenharmony_ci psa_ecc_family_t family = 479a8e1175bSopenharmony_ci mbedtls_ecc_group_to_psa(ec->grp.id, &bits); 480a8e1175bSopenharmony_ci#endif 481a8e1175bSopenharmony_ci psa_algorithm_t alg = 0; 482a8e1175bSopenharmony_ci switch (usage) { 483a8e1175bSopenharmony_ci case PSA_KEY_USAGE_SIGN_MESSAGE: 484a8e1175bSopenharmony_ci case PSA_KEY_USAGE_SIGN_HASH: 485a8e1175bSopenharmony_ci case PSA_KEY_USAGE_VERIFY_MESSAGE: 486a8e1175bSopenharmony_ci case PSA_KEY_USAGE_VERIFY_HASH: 487a8e1175bSopenharmony_ci if (!sign_ok) { 488a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 489a8e1175bSopenharmony_ci } 490a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_DETERMINISTIC) 491a8e1175bSopenharmony_ci alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH); 492a8e1175bSopenharmony_ci#else 493a8e1175bSopenharmony_ci alg = PSA_ALG_ECDSA(PSA_ALG_ANY_HASH); 494a8e1175bSopenharmony_ci#endif 495a8e1175bSopenharmony_ci break; 496a8e1175bSopenharmony_ci case PSA_KEY_USAGE_DERIVE: 497a8e1175bSopenharmony_ci alg = PSA_ALG_ECDH; 498a8e1175bSopenharmony_ci if (!derive_ok) { 499a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 500a8e1175bSopenharmony_ci } 501a8e1175bSopenharmony_ci break; 502a8e1175bSopenharmony_ci default: 503a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 504a8e1175bSopenharmony_ci } 505a8e1175bSopenharmony_ci if (want_private && !has_private) { 506a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 507a8e1175bSopenharmony_ci } 508a8e1175bSopenharmony_ci psa_set_key_type(attributes, (want_private ? 509a8e1175bSopenharmony_ci PSA_KEY_TYPE_ECC_KEY_PAIR(family) : 510a8e1175bSopenharmony_ci PSA_KEY_TYPE_ECC_PUBLIC_KEY(family))); 511a8e1175bSopenharmony_ci psa_set_key_bits(attributes, bits); 512a8e1175bSopenharmony_ci psa_set_key_algorithm(attributes, alg); 513a8e1175bSopenharmony_ci break; 514a8e1175bSopenharmony_ci } 515a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 516a8e1175bSopenharmony_ci 517a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 518a8e1175bSopenharmony_ci case MBEDTLS_PK_RSA_ALT: 519a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 520a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ 521a8e1175bSopenharmony_ci 522a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 523a8e1175bSopenharmony_ci case MBEDTLS_PK_OPAQUE: 524a8e1175bSopenharmony_ci { 525a8e1175bSopenharmony_ci psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; 526a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 527a8e1175bSopenharmony_ci status = psa_get_key_attributes(pk->priv_id, &old_attributes); 528a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 529a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 530a8e1175bSopenharmony_ci } 531a8e1175bSopenharmony_ci psa_key_type_t old_type = psa_get_key_type(&old_attributes); 532a8e1175bSopenharmony_ci switch (usage) { 533a8e1175bSopenharmony_ci case PSA_KEY_USAGE_SIGN_MESSAGE: 534a8e1175bSopenharmony_ci case PSA_KEY_USAGE_SIGN_HASH: 535a8e1175bSopenharmony_ci case PSA_KEY_USAGE_VERIFY_MESSAGE: 536a8e1175bSopenharmony_ci case PSA_KEY_USAGE_VERIFY_HASH: 537a8e1175bSopenharmony_ci if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type) || 538a8e1175bSopenharmony_ci old_type == PSA_KEY_TYPE_RSA_KEY_PAIR)) { 539a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 540a8e1175bSopenharmony_ci } 541a8e1175bSopenharmony_ci break; 542a8e1175bSopenharmony_ci case PSA_KEY_USAGE_DECRYPT: 543a8e1175bSopenharmony_ci case PSA_KEY_USAGE_ENCRYPT: 544a8e1175bSopenharmony_ci if (old_type != PSA_KEY_TYPE_RSA_KEY_PAIR) { 545a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 546a8e1175bSopenharmony_ci } 547a8e1175bSopenharmony_ci break; 548a8e1175bSopenharmony_ci case PSA_KEY_USAGE_DERIVE: 549a8e1175bSopenharmony_ci if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type))) { 550a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 551a8e1175bSopenharmony_ci } 552a8e1175bSopenharmony_ci break; 553a8e1175bSopenharmony_ci default: 554a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 555a8e1175bSopenharmony_ci } 556a8e1175bSopenharmony_ci psa_key_type_t new_type = old_type; 557a8e1175bSopenharmony_ci /* Opaque keys are always key pairs, so we don't need a check 558a8e1175bSopenharmony_ci * on the input if the required usage is private. We just need 559a8e1175bSopenharmony_ci * to adjust the type correctly if the required usage is public. */ 560a8e1175bSopenharmony_ci if (!want_private) { 561a8e1175bSopenharmony_ci new_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(new_type); 562a8e1175bSopenharmony_ci } 563a8e1175bSopenharmony_ci more_usage = psa_get_key_usage_flags(&old_attributes); 564a8e1175bSopenharmony_ci if ((usage & more_usage) == 0) { 565a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 566a8e1175bSopenharmony_ci } 567a8e1175bSopenharmony_ci psa_set_key_type(attributes, new_type); 568a8e1175bSopenharmony_ci psa_set_key_bits(attributes, psa_get_key_bits(&old_attributes)); 569a8e1175bSopenharmony_ci psa_set_key_algorithm(attributes, psa_get_key_algorithm(&old_attributes)); 570a8e1175bSopenharmony_ci break; 571a8e1175bSopenharmony_ci } 572a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 573a8e1175bSopenharmony_ci 574a8e1175bSopenharmony_ci default: 575a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 576a8e1175bSopenharmony_ci } 577a8e1175bSopenharmony_ci 578a8e1175bSopenharmony_ci psa_set_key_usage_flags(attributes, more_usage); 579a8e1175bSopenharmony_ci /* Key's enrollment is available only when an Mbed TLS implementation of PSA 580a8e1175bSopenharmony_ci * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined. 581a8e1175bSopenharmony_ci * Even though we don't officially support using other implementations of PSA 582a8e1175bSopenharmony_ci * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations 583a8e1175bSopenharmony_ci * separated. */ 584a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C) 585a8e1175bSopenharmony_ci psa_set_key_enrollment_algorithm(attributes, PSA_ALG_NONE); 586a8e1175bSopenharmony_ci#endif 587a8e1175bSopenharmony_ci 588a8e1175bSopenharmony_ci return 0; 589a8e1175bSopenharmony_ci} 590a8e1175bSopenharmony_ci 591a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) || defined(MBEDTLS_USE_PSA_CRYPTO) 592a8e1175bSopenharmony_cistatic psa_status_t export_import_into_psa(mbedtls_svc_key_id_t old_key_id, 593a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 594a8e1175bSopenharmony_ci mbedtls_svc_key_id_t *new_key_id) 595a8e1175bSopenharmony_ci{ 596a8e1175bSopenharmony_ci unsigned char key_buffer[PSA_EXPORT_KEY_PAIR_MAX_SIZE]; 597a8e1175bSopenharmony_ci size_t key_length = 0; 598a8e1175bSopenharmony_ci psa_status_t status = psa_export_key(old_key_id, 599a8e1175bSopenharmony_ci key_buffer, sizeof(key_buffer), 600a8e1175bSopenharmony_ci &key_length); 601a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 602a8e1175bSopenharmony_ci return status; 603a8e1175bSopenharmony_ci } 604a8e1175bSopenharmony_ci status = psa_import_key(attributes, key_buffer, key_length, new_key_id); 605a8e1175bSopenharmony_ci mbedtls_platform_zeroize(key_buffer, key_length); 606a8e1175bSopenharmony_ci return status; 607a8e1175bSopenharmony_ci} 608a8e1175bSopenharmony_ci 609a8e1175bSopenharmony_cistatic int copy_into_psa(mbedtls_svc_key_id_t old_key_id, 610a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 611a8e1175bSopenharmony_ci mbedtls_svc_key_id_t *new_key_id) 612a8e1175bSopenharmony_ci{ 613a8e1175bSopenharmony_ci /* Normally, we prefer copying: it's more efficient and works even 614a8e1175bSopenharmony_ci * for non-exportable keys. */ 615a8e1175bSopenharmony_ci psa_status_t status = psa_copy_key(old_key_id, attributes, new_key_id); 616a8e1175bSopenharmony_ci if (status == PSA_ERROR_NOT_PERMITTED /*missing COPY usage*/ || 617a8e1175bSopenharmony_ci status == PSA_ERROR_INVALID_ARGUMENT /*incompatible policy*/) { 618a8e1175bSopenharmony_ci /* There are edge cases where copying won't work, but export+import 619a8e1175bSopenharmony_ci * might: 620a8e1175bSopenharmony_ci * - If the old key does not allow PSA_KEY_USAGE_COPY. 621a8e1175bSopenharmony_ci * - If the old key's usage does not allow what attributes wants. 622a8e1175bSopenharmony_ci * Because the key was intended for use in the pk module, and may 623a8e1175bSopenharmony_ci * have had a policy chosen solely for what pk needs rather than 624a8e1175bSopenharmony_ci * based on a detailed understanding of PSA policies, we are a bit 625a8e1175bSopenharmony_ci * more liberal than psa_copy_key() here. 626a8e1175bSopenharmony_ci */ 627a8e1175bSopenharmony_ci /* Here we need to check that the types match, otherwise we risk 628a8e1175bSopenharmony_ci * importing nonsensical data. */ 629a8e1175bSopenharmony_ci psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; 630a8e1175bSopenharmony_ci status = psa_get_key_attributes(old_key_id, &old_attributes); 631a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 632a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 633a8e1175bSopenharmony_ci } 634a8e1175bSopenharmony_ci psa_key_type_t old_type = psa_get_key_type(&old_attributes); 635a8e1175bSopenharmony_ci psa_reset_key_attributes(&old_attributes); 636a8e1175bSopenharmony_ci if (old_type != psa_get_key_type(attributes)) { 637a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 638a8e1175bSopenharmony_ci } 639a8e1175bSopenharmony_ci status = export_import_into_psa(old_key_id, attributes, new_key_id); 640a8e1175bSopenharmony_ci } 641a8e1175bSopenharmony_ci return PSA_PK_TO_MBEDTLS_ERR(status); 642a8e1175bSopenharmony_ci} 643a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_USE_PSA_CRYPTO */ 644a8e1175bSopenharmony_ci 645a8e1175bSopenharmony_cistatic int import_pair_into_psa(const mbedtls_pk_context *pk, 646a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 647a8e1175bSopenharmony_ci mbedtls_svc_key_id_t *key_id) 648a8e1175bSopenharmony_ci{ 649a8e1175bSopenharmony_ci switch (mbedtls_pk_get_type(pk)) { 650a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) 651a8e1175bSopenharmony_ci case MBEDTLS_PK_RSA: 652a8e1175bSopenharmony_ci { 653a8e1175bSopenharmony_ci if (psa_get_key_type(attributes) != PSA_KEY_TYPE_RSA_KEY_PAIR) { 654a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 655a8e1175bSopenharmony_ci } 656a8e1175bSopenharmony_ci unsigned char key_buffer[ 657a8e1175bSopenharmony_ci PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)]; 658a8e1175bSopenharmony_ci unsigned char *const key_end = key_buffer + sizeof(key_buffer); 659a8e1175bSopenharmony_ci unsigned char *key_data = key_end; 660a8e1175bSopenharmony_ci int ret = mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), 661a8e1175bSopenharmony_ci key_buffer, &key_data); 662a8e1175bSopenharmony_ci if (ret < 0) { 663a8e1175bSopenharmony_ci return ret; 664a8e1175bSopenharmony_ci } 665a8e1175bSopenharmony_ci size_t key_length = key_end - key_data; 666a8e1175bSopenharmony_ci ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, 667a8e1175bSopenharmony_ci key_data, key_length, 668a8e1175bSopenharmony_ci key_id)); 669a8e1175bSopenharmony_ci mbedtls_platform_zeroize(key_data, key_length); 670a8e1175bSopenharmony_ci return ret; 671a8e1175bSopenharmony_ci } 672a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */ 673a8e1175bSopenharmony_ci 674a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 675a8e1175bSopenharmony_ci case MBEDTLS_PK_ECKEY: 676a8e1175bSopenharmony_ci case MBEDTLS_PK_ECKEY_DH: 677a8e1175bSopenharmony_ci case MBEDTLS_PK_ECDSA: 678a8e1175bSopenharmony_ci { 679a8e1175bSopenharmony_ci /* We need to check the curve family, otherwise the import could 680a8e1175bSopenharmony_ci * succeed with nonsensical data. 681a8e1175bSopenharmony_ci * We don't check the bit-size: it's optional in attributes, 682a8e1175bSopenharmony_ci * and if it's specified, psa_import_key() will know from the key 683a8e1175bSopenharmony_ci * data length and will check that the bit-size matches. */ 684a8e1175bSopenharmony_ci psa_key_type_t to_type = psa_get_key_type(attributes); 685a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 686a8e1175bSopenharmony_ci psa_ecc_family_t from_family = pk->ec_family; 687a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ 688a8e1175bSopenharmony_ci const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); 689a8e1175bSopenharmony_ci size_t from_bits = 0; 690a8e1175bSopenharmony_ci psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id, 691a8e1175bSopenharmony_ci &from_bits); 692a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 693a8e1175bSopenharmony_ci if (to_type != PSA_KEY_TYPE_ECC_KEY_PAIR(from_family)) { 694a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 695a8e1175bSopenharmony_ci } 696a8e1175bSopenharmony_ci 697a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 698a8e1175bSopenharmony_ci if (mbedtls_svc_key_id_is_null(pk->priv_id)) { 699a8e1175bSopenharmony_ci /* We have a public key and want a key pair. */ 700a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 701a8e1175bSopenharmony_ci } 702a8e1175bSopenharmony_ci return copy_into_psa(pk->priv_id, attributes, key_id); 703a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ 704a8e1175bSopenharmony_ci if (ec->d.n == 0) { 705a8e1175bSopenharmony_ci /* Private key not set. Assume the input is a public key only. 706a8e1175bSopenharmony_ci * (The other possibility is that it's an incomplete object 707a8e1175bSopenharmony_ci * where the group is set but neither the public key nor 708a8e1175bSopenharmony_ci * the private key. This is not possible through ecp.h 709a8e1175bSopenharmony_ci * functions, so we don't bother reporting a more suitable 710a8e1175bSopenharmony_ci * error in that case.) */ 711a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 712a8e1175bSopenharmony_ci } 713a8e1175bSopenharmony_ci unsigned char key_buffer[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; 714a8e1175bSopenharmony_ci size_t key_length = 0; 715a8e1175bSopenharmony_ci int ret = mbedtls_ecp_write_key_ext(ec, &key_length, 716a8e1175bSopenharmony_ci key_buffer, sizeof(key_buffer)); 717a8e1175bSopenharmony_ci if (ret < 0) { 718a8e1175bSopenharmony_ci return ret; 719a8e1175bSopenharmony_ci } 720a8e1175bSopenharmony_ci ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, 721a8e1175bSopenharmony_ci key_buffer, key_length, 722a8e1175bSopenharmony_ci key_id)); 723a8e1175bSopenharmony_ci mbedtls_platform_zeroize(key_buffer, key_length); 724a8e1175bSopenharmony_ci return ret; 725a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 726a8e1175bSopenharmony_ci } 727a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 728a8e1175bSopenharmony_ci 729a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 730a8e1175bSopenharmony_ci case MBEDTLS_PK_OPAQUE: 731a8e1175bSopenharmony_ci return copy_into_psa(pk->priv_id, attributes, key_id); 732a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 733a8e1175bSopenharmony_ci 734a8e1175bSopenharmony_ci default: 735a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 736a8e1175bSopenharmony_ci } 737a8e1175bSopenharmony_ci} 738a8e1175bSopenharmony_ci 739a8e1175bSopenharmony_cistatic int import_public_into_psa(const mbedtls_pk_context *pk, 740a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 741a8e1175bSopenharmony_ci mbedtls_svc_key_id_t *key_id) 742a8e1175bSopenharmony_ci{ 743a8e1175bSopenharmony_ci psa_key_type_t psa_type = psa_get_key_type(attributes); 744a8e1175bSopenharmony_ci 745a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) || \ 746a8e1175bSopenharmony_ci (defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)) || \ 747a8e1175bSopenharmony_ci defined(MBEDTLS_USE_PSA_CRYPTO) 748a8e1175bSopenharmony_ci unsigned char key_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; 749a8e1175bSopenharmony_ci#endif 750a8e1175bSopenharmony_ci unsigned char *key_data = NULL; 751a8e1175bSopenharmony_ci size_t key_length = 0; 752a8e1175bSopenharmony_ci 753a8e1175bSopenharmony_ci switch (mbedtls_pk_get_type(pk)) { 754a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) 755a8e1175bSopenharmony_ci case MBEDTLS_PK_RSA: 756a8e1175bSopenharmony_ci { 757a8e1175bSopenharmony_ci if (psa_type != PSA_KEY_TYPE_RSA_PUBLIC_KEY) { 758a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 759a8e1175bSopenharmony_ci } 760a8e1175bSopenharmony_ci unsigned char *const key_end = key_buffer + sizeof(key_buffer); 761a8e1175bSopenharmony_ci key_data = key_end; 762a8e1175bSopenharmony_ci int ret = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*pk), 763a8e1175bSopenharmony_ci key_buffer, &key_data); 764a8e1175bSopenharmony_ci if (ret < 0) { 765a8e1175bSopenharmony_ci return ret; 766a8e1175bSopenharmony_ci } 767a8e1175bSopenharmony_ci key_length = (size_t) ret; 768a8e1175bSopenharmony_ci break; 769a8e1175bSopenharmony_ci } 770a8e1175bSopenharmony_ci#endif /*MBEDTLS_RSA_C */ 771a8e1175bSopenharmony_ci 772a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 773a8e1175bSopenharmony_ci case MBEDTLS_PK_ECKEY: 774a8e1175bSopenharmony_ci case MBEDTLS_PK_ECKEY_DH: 775a8e1175bSopenharmony_ci case MBEDTLS_PK_ECDSA: 776a8e1175bSopenharmony_ci { 777a8e1175bSopenharmony_ci /* We need to check the curve family, otherwise the import could 778a8e1175bSopenharmony_ci * succeed with nonsensical data. 779a8e1175bSopenharmony_ci * We don't check the bit-size: it's optional in attributes, 780a8e1175bSopenharmony_ci * and if it's specified, psa_import_key() will know from the key 781a8e1175bSopenharmony_ci * data length and will check that the bit-size matches. */ 782a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 783a8e1175bSopenharmony_ci if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family)) { 784a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 785a8e1175bSopenharmony_ci } 786a8e1175bSopenharmony_ci key_data = (unsigned char *) pk->pub_raw; 787a8e1175bSopenharmony_ci key_length = pk->pub_raw_len; 788a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ 789a8e1175bSopenharmony_ci const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); 790a8e1175bSopenharmony_ci size_t from_bits = 0; 791a8e1175bSopenharmony_ci psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id, 792a8e1175bSopenharmony_ci &from_bits); 793a8e1175bSopenharmony_ci if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(from_family)) { 794a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 795a8e1175bSopenharmony_ci } 796a8e1175bSopenharmony_ci int ret = mbedtls_ecp_write_public_key( 797a8e1175bSopenharmony_ci ec, MBEDTLS_ECP_PF_UNCOMPRESSED, 798a8e1175bSopenharmony_ci &key_length, key_buffer, sizeof(key_buffer)); 799a8e1175bSopenharmony_ci if (ret < 0) { 800a8e1175bSopenharmony_ci return ret; 801a8e1175bSopenharmony_ci } 802a8e1175bSopenharmony_ci key_data = key_buffer; 803a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 804a8e1175bSopenharmony_ci break; 805a8e1175bSopenharmony_ci } 806a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 807a8e1175bSopenharmony_ci 808a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 809a8e1175bSopenharmony_ci case MBEDTLS_PK_OPAQUE: 810a8e1175bSopenharmony_ci { 811a8e1175bSopenharmony_ci psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; 812a8e1175bSopenharmony_ci psa_status_t status = 813a8e1175bSopenharmony_ci psa_get_key_attributes(pk->priv_id, &old_attributes); 814a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 815a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 816a8e1175bSopenharmony_ci } 817a8e1175bSopenharmony_ci psa_key_type_t old_type = psa_get_key_type(&old_attributes); 818a8e1175bSopenharmony_ci psa_reset_key_attributes(&old_attributes); 819a8e1175bSopenharmony_ci if (psa_type != PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(old_type)) { 820a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 821a8e1175bSopenharmony_ci } 822a8e1175bSopenharmony_ci status = psa_export_public_key(pk->priv_id, 823a8e1175bSopenharmony_ci key_buffer, sizeof(key_buffer), 824a8e1175bSopenharmony_ci &key_length); 825a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 826a8e1175bSopenharmony_ci return PSA_PK_TO_MBEDTLS_ERR(status); 827a8e1175bSopenharmony_ci } 828a8e1175bSopenharmony_ci key_data = key_buffer; 829a8e1175bSopenharmony_ci break; 830a8e1175bSopenharmony_ci } 831a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 832a8e1175bSopenharmony_ci 833a8e1175bSopenharmony_ci default: 834a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 835a8e1175bSopenharmony_ci } 836a8e1175bSopenharmony_ci 837a8e1175bSopenharmony_ci return PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, 838a8e1175bSopenharmony_ci key_data, key_length, 839a8e1175bSopenharmony_ci key_id)); 840a8e1175bSopenharmony_ci} 841a8e1175bSopenharmony_ci 842a8e1175bSopenharmony_ciint mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, 843a8e1175bSopenharmony_ci const psa_key_attributes_t *attributes, 844a8e1175bSopenharmony_ci mbedtls_svc_key_id_t *key_id) 845a8e1175bSopenharmony_ci{ 846a8e1175bSopenharmony_ci /* Set the output immediately so that it won't contain garbage even 847a8e1175bSopenharmony_ci * if we error out before calling psa_import_key(). */ 848a8e1175bSopenharmony_ci *key_id = MBEDTLS_SVC_KEY_ID_INIT; 849a8e1175bSopenharmony_ci 850a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 851a8e1175bSopenharmony_ci if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA_ALT) { 852a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 853a8e1175bSopenharmony_ci } 854a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ 855a8e1175bSopenharmony_ci 856a8e1175bSopenharmony_ci int want_public = PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(attributes)); 857a8e1175bSopenharmony_ci if (want_public) { 858a8e1175bSopenharmony_ci return import_public_into_psa(pk, attributes, key_id); 859a8e1175bSopenharmony_ci } else { 860a8e1175bSopenharmony_ci return import_pair_into_psa(pk, attributes, key_id); 861a8e1175bSopenharmony_ci } 862a8e1175bSopenharmony_ci} 863a8e1175bSopenharmony_ci 864a8e1175bSopenharmony_cistatic int copy_from_psa(mbedtls_svc_key_id_t key_id, 865a8e1175bSopenharmony_ci mbedtls_pk_context *pk, 866a8e1175bSopenharmony_ci int public_only) 867a8e1175bSopenharmony_ci{ 868a8e1175bSopenharmony_ci psa_status_t status; 869a8e1175bSopenharmony_ci psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; 870a8e1175bSopenharmony_ci psa_key_type_t key_type; 871a8e1175bSopenharmony_ci psa_algorithm_t alg_type; 872a8e1175bSopenharmony_ci size_t key_bits; 873a8e1175bSopenharmony_ci /* Use a buffer size large enough to contain either a key pair or public key. */ 874a8e1175bSopenharmony_ci unsigned char exp_key[PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE]; 875a8e1175bSopenharmony_ci size_t exp_key_len; 876a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; 877a8e1175bSopenharmony_ci 878a8e1175bSopenharmony_ci if (pk == NULL) { 879a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 880a8e1175bSopenharmony_ci } 881a8e1175bSopenharmony_ci 882a8e1175bSopenharmony_ci status = psa_get_key_attributes(key_id, &key_attr); 883a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 884a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 885a8e1175bSopenharmony_ci } 886a8e1175bSopenharmony_ci 887a8e1175bSopenharmony_ci if (public_only) { 888a8e1175bSopenharmony_ci status = psa_export_public_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); 889a8e1175bSopenharmony_ci } else { 890a8e1175bSopenharmony_ci status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); 891a8e1175bSopenharmony_ci } 892a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 893a8e1175bSopenharmony_ci ret = PSA_PK_TO_MBEDTLS_ERR(status); 894a8e1175bSopenharmony_ci goto exit; 895a8e1175bSopenharmony_ci } 896a8e1175bSopenharmony_ci 897a8e1175bSopenharmony_ci key_type = psa_get_key_type(&key_attr); 898a8e1175bSopenharmony_ci if (public_only) { 899a8e1175bSopenharmony_ci key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type); 900a8e1175bSopenharmony_ci } 901a8e1175bSopenharmony_ci key_bits = psa_get_key_bits(&key_attr); 902a8e1175bSopenharmony_ci alg_type = psa_get_key_algorithm(&key_attr); 903a8e1175bSopenharmony_ci 904a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) 905a8e1175bSopenharmony_ci if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) || 906a8e1175bSopenharmony_ci (key_type == PSA_KEY_TYPE_RSA_PUBLIC_KEY)) { 907a8e1175bSopenharmony_ci 908a8e1175bSopenharmony_ci ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); 909a8e1175bSopenharmony_ci if (ret != 0) { 910a8e1175bSopenharmony_ci goto exit; 911a8e1175bSopenharmony_ci } 912a8e1175bSopenharmony_ci 913a8e1175bSopenharmony_ci if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { 914a8e1175bSopenharmony_ci ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); 915a8e1175bSopenharmony_ci } else { 916a8e1175bSopenharmony_ci ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); 917a8e1175bSopenharmony_ci } 918a8e1175bSopenharmony_ci if (ret != 0) { 919a8e1175bSopenharmony_ci goto exit; 920a8e1175bSopenharmony_ci } 921a8e1175bSopenharmony_ci 922a8e1175bSopenharmony_ci mbedtls_md_type_t md_type = MBEDTLS_MD_NONE; 923a8e1175bSopenharmony_ci if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) { 924a8e1175bSopenharmony_ci md_type = mbedtls_md_type_from_psa_alg(alg_type); 925a8e1175bSopenharmony_ci } 926a8e1175bSopenharmony_ci 927a8e1175bSopenharmony_ci if (PSA_ALG_IS_RSA_OAEP(alg_type) || PSA_ALG_IS_RSA_PSS(alg_type)) { 928a8e1175bSopenharmony_ci ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V21, md_type); 929a8e1175bSopenharmony_ci } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) || 930a8e1175bSopenharmony_ci alg_type == PSA_ALG_RSA_PKCS1V15_CRYPT) { 931a8e1175bSopenharmony_ci ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V15, md_type); 932a8e1175bSopenharmony_ci } 933a8e1175bSopenharmony_ci if (ret != 0) { 934a8e1175bSopenharmony_ci goto exit; 935a8e1175bSopenharmony_ci } 936a8e1175bSopenharmony_ci } else 937a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */ 938a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) 939a8e1175bSopenharmony_ci if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) || 940a8e1175bSopenharmony_ci PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) { 941a8e1175bSopenharmony_ci mbedtls_ecp_group_id grp_id; 942a8e1175bSopenharmony_ci 943a8e1175bSopenharmony_ci ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); 944a8e1175bSopenharmony_ci if (ret != 0) { 945a8e1175bSopenharmony_ci goto exit; 946a8e1175bSopenharmony_ci } 947a8e1175bSopenharmony_ci 948a8e1175bSopenharmony_ci grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type), key_bits); 949a8e1175bSopenharmony_ci ret = mbedtls_pk_ecc_set_group(pk, grp_id); 950a8e1175bSopenharmony_ci if (ret != 0) { 951a8e1175bSopenharmony_ci goto exit; 952a8e1175bSopenharmony_ci } 953a8e1175bSopenharmony_ci 954a8e1175bSopenharmony_ci if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) { 955a8e1175bSopenharmony_ci ret = mbedtls_pk_ecc_set_key(pk, exp_key, exp_key_len); 956a8e1175bSopenharmony_ci if (ret != 0) { 957a8e1175bSopenharmony_ci goto exit; 958a8e1175bSopenharmony_ci } 959a8e1175bSopenharmony_ci ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, exp_key, exp_key_len, 960a8e1175bSopenharmony_ci mbedtls_psa_get_random, 961a8e1175bSopenharmony_ci MBEDTLS_PSA_RANDOM_STATE); 962a8e1175bSopenharmony_ci } else { 963a8e1175bSopenharmony_ci ret = mbedtls_pk_ecc_set_pubkey(pk, exp_key, exp_key_len); 964a8e1175bSopenharmony_ci } 965a8e1175bSopenharmony_ci if (ret != 0) { 966a8e1175bSopenharmony_ci goto exit; 967a8e1175bSopenharmony_ci } 968a8e1175bSopenharmony_ci } else 969a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ 970a8e1175bSopenharmony_ci { 971a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 972a8e1175bSopenharmony_ci } 973a8e1175bSopenharmony_ci 974a8e1175bSopenharmony_ciexit: 975a8e1175bSopenharmony_ci psa_reset_key_attributes(&key_attr); 976a8e1175bSopenharmony_ci mbedtls_platform_zeroize(exp_key, sizeof(exp_key)); 977a8e1175bSopenharmony_ci 978a8e1175bSopenharmony_ci return ret; 979a8e1175bSopenharmony_ci} 980a8e1175bSopenharmony_ci 981a8e1175bSopenharmony_ciint mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, 982a8e1175bSopenharmony_ci mbedtls_pk_context *pk) 983a8e1175bSopenharmony_ci{ 984a8e1175bSopenharmony_ci return copy_from_psa(key_id, pk, 0); 985a8e1175bSopenharmony_ci} 986a8e1175bSopenharmony_ci 987a8e1175bSopenharmony_ciint mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, 988a8e1175bSopenharmony_ci mbedtls_pk_context *pk) 989a8e1175bSopenharmony_ci{ 990a8e1175bSopenharmony_ci return copy_from_psa(key_id, pk, 1); 991a8e1175bSopenharmony_ci} 992a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ 993a8e1175bSopenharmony_ci 994a8e1175bSopenharmony_ci/* 995a8e1175bSopenharmony_ci * Helper for mbedtls_pk_sign and mbedtls_pk_verify 996a8e1175bSopenharmony_ci */ 997a8e1175bSopenharmony_cistatic inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len) 998a8e1175bSopenharmony_ci{ 999a8e1175bSopenharmony_ci if (*hash_len != 0) { 1000a8e1175bSopenharmony_ci return 0; 1001a8e1175bSopenharmony_ci } 1002a8e1175bSopenharmony_ci 1003a8e1175bSopenharmony_ci *hash_len = mbedtls_md_get_size_from_type(md_alg); 1004a8e1175bSopenharmony_ci 1005a8e1175bSopenharmony_ci if (*hash_len == 0) { 1006a8e1175bSopenharmony_ci return -1; 1007a8e1175bSopenharmony_ci } 1008a8e1175bSopenharmony_ci 1009a8e1175bSopenharmony_ci return 0; 1010a8e1175bSopenharmony_ci} 1011a8e1175bSopenharmony_ci 1012a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 1013a8e1175bSopenharmony_ci/* 1014a8e1175bSopenharmony_ci * Helper to set up a restart context if needed 1015a8e1175bSopenharmony_ci */ 1016a8e1175bSopenharmony_cistatic int pk_restart_setup(mbedtls_pk_restart_ctx *ctx, 1017a8e1175bSopenharmony_ci const mbedtls_pk_info_t *info) 1018a8e1175bSopenharmony_ci{ 1019a8e1175bSopenharmony_ci /* Don't do anything if already set up or invalid */ 1020a8e1175bSopenharmony_ci if (ctx == NULL || ctx->pk_info != NULL) { 1021a8e1175bSopenharmony_ci return 0; 1022a8e1175bSopenharmony_ci } 1023a8e1175bSopenharmony_ci 1024a8e1175bSopenharmony_ci /* Should never happen when we're called */ 1025a8e1175bSopenharmony_ci if (info->rs_alloc_func == NULL || info->rs_free_func == NULL) { 1026a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1027a8e1175bSopenharmony_ci } 1028a8e1175bSopenharmony_ci 1029a8e1175bSopenharmony_ci if ((ctx->rs_ctx = info->rs_alloc_func()) == NULL) { 1030a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_ALLOC_FAILED; 1031a8e1175bSopenharmony_ci } 1032a8e1175bSopenharmony_ci 1033a8e1175bSopenharmony_ci ctx->pk_info = info; 1034a8e1175bSopenharmony_ci 1035a8e1175bSopenharmony_ci return 0; 1036a8e1175bSopenharmony_ci} 1037a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 1038a8e1175bSopenharmony_ci 1039a8e1175bSopenharmony_ci/* 1040a8e1175bSopenharmony_ci * Verify a signature (restartable) 1041a8e1175bSopenharmony_ci */ 1042a8e1175bSopenharmony_ciint mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx, 1043a8e1175bSopenharmony_ci mbedtls_md_type_t md_alg, 1044a8e1175bSopenharmony_ci const unsigned char *hash, size_t hash_len, 1045a8e1175bSopenharmony_ci const unsigned char *sig, size_t sig_len, 1046a8e1175bSopenharmony_ci mbedtls_pk_restart_ctx *rs_ctx) 1047a8e1175bSopenharmony_ci{ 1048a8e1175bSopenharmony_ci if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { 1049a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1050a8e1175bSopenharmony_ci } 1051a8e1175bSopenharmony_ci 1052a8e1175bSopenharmony_ci if (ctx->pk_info == NULL || 1053a8e1175bSopenharmony_ci pk_hashlen_helper(md_alg, &hash_len) != 0) { 1054a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1055a8e1175bSopenharmony_ci } 1056a8e1175bSopenharmony_ci 1057a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 1058a8e1175bSopenharmony_ci /* optimization: use non-restartable version if restart disabled */ 1059a8e1175bSopenharmony_ci if (rs_ctx != NULL && 1060a8e1175bSopenharmony_ci mbedtls_ecp_restart_is_enabled() && 1061a8e1175bSopenharmony_ci ctx->pk_info->verify_rs_func != NULL) { 1062a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1063a8e1175bSopenharmony_ci 1064a8e1175bSopenharmony_ci if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) { 1065a8e1175bSopenharmony_ci return ret; 1066a8e1175bSopenharmony_ci } 1067a8e1175bSopenharmony_ci 1068a8e1175bSopenharmony_ci ret = ctx->pk_info->verify_rs_func(ctx, 1069a8e1175bSopenharmony_ci md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx); 1070a8e1175bSopenharmony_ci 1071a8e1175bSopenharmony_ci if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) { 1072a8e1175bSopenharmony_ci mbedtls_pk_restart_free(rs_ctx); 1073a8e1175bSopenharmony_ci } 1074a8e1175bSopenharmony_ci 1075a8e1175bSopenharmony_ci return ret; 1076a8e1175bSopenharmony_ci } 1077a8e1175bSopenharmony_ci#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 1078a8e1175bSopenharmony_ci (void) rs_ctx; 1079a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 1080a8e1175bSopenharmony_ci 1081a8e1175bSopenharmony_ci if (ctx->pk_info->verify_func == NULL) { 1082a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 1083a8e1175bSopenharmony_ci } 1084a8e1175bSopenharmony_ci 1085a8e1175bSopenharmony_ci return ctx->pk_info->verify_func(ctx, md_alg, hash, hash_len, 1086a8e1175bSopenharmony_ci sig, sig_len); 1087a8e1175bSopenharmony_ci} 1088a8e1175bSopenharmony_ci 1089a8e1175bSopenharmony_ci/* 1090a8e1175bSopenharmony_ci * Verify a signature 1091a8e1175bSopenharmony_ci */ 1092a8e1175bSopenharmony_ciint mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, 1093a8e1175bSopenharmony_ci const unsigned char *hash, size_t hash_len, 1094a8e1175bSopenharmony_ci const unsigned char *sig, size_t sig_len) 1095a8e1175bSopenharmony_ci{ 1096a8e1175bSopenharmony_ci return mbedtls_pk_verify_restartable(ctx, md_alg, hash, hash_len, 1097a8e1175bSopenharmony_ci sig, sig_len, NULL); 1098a8e1175bSopenharmony_ci} 1099a8e1175bSopenharmony_ci 1100a8e1175bSopenharmony_ci/* 1101a8e1175bSopenharmony_ci * Verify a signature with options 1102a8e1175bSopenharmony_ci */ 1103a8e1175bSopenharmony_ciint mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options, 1104a8e1175bSopenharmony_ci mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, 1105a8e1175bSopenharmony_ci const unsigned char *hash, size_t hash_len, 1106a8e1175bSopenharmony_ci const unsigned char *sig, size_t sig_len) 1107a8e1175bSopenharmony_ci{ 1108a8e1175bSopenharmony_ci if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { 1109a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1110a8e1175bSopenharmony_ci } 1111a8e1175bSopenharmony_ci 1112a8e1175bSopenharmony_ci if (ctx->pk_info == NULL) { 1113a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1114a8e1175bSopenharmony_ci } 1115a8e1175bSopenharmony_ci 1116a8e1175bSopenharmony_ci if (!mbedtls_pk_can_do(ctx, type)) { 1117a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 1118a8e1175bSopenharmony_ci } 1119a8e1175bSopenharmony_ci 1120a8e1175bSopenharmony_ci if (type != MBEDTLS_PK_RSASSA_PSS) { 1121a8e1175bSopenharmony_ci /* General case: no options */ 1122a8e1175bSopenharmony_ci if (options != NULL) { 1123a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1124a8e1175bSopenharmony_ci } 1125a8e1175bSopenharmony_ci 1126a8e1175bSopenharmony_ci return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len); 1127a8e1175bSopenharmony_ci } 1128a8e1175bSopenharmony_ci 1129a8e1175bSopenharmony_ci /* Ensure the PK context is of the right type otherwise mbedtls_pk_rsa() 1130a8e1175bSopenharmony_ci * below would return a NULL pointer. */ 1131a8e1175bSopenharmony_ci if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_RSA) { 1132a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 1133a8e1175bSopenharmony_ci } 1134a8e1175bSopenharmony_ci 1135a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) 1136a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1137a8e1175bSopenharmony_ci const mbedtls_pk_rsassa_pss_options *pss_opts; 1138a8e1175bSopenharmony_ci 1139a8e1175bSopenharmony_ci#if SIZE_MAX > UINT_MAX 1140a8e1175bSopenharmony_ci if (md_alg == MBEDTLS_MD_NONE && (int)UINT_MAX < (int)hash_len) { 1141a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1142a8e1175bSopenharmony_ci } 1143a8e1175bSopenharmony_ci#endif 1144a8e1175bSopenharmony_ci 1145a8e1175bSopenharmony_ci if (options == NULL) { 1146a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1147a8e1175bSopenharmony_ci } 1148a8e1175bSopenharmony_ci 1149a8e1175bSopenharmony_ci pss_opts = (const mbedtls_pk_rsassa_pss_options *) options; 1150a8e1175bSopenharmony_ci 1151a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 1152a8e1175bSopenharmony_ci if (pss_opts->mgf1_hash_id == md_alg) { 1153a8e1175bSopenharmony_ci unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES]; 1154a8e1175bSopenharmony_ci unsigned char *p; 1155a8e1175bSopenharmony_ci int key_len; 1156a8e1175bSopenharmony_ci size_t signature_length; 1157a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_DATA_CORRUPT; 1158a8e1175bSopenharmony_ci psa_status_t destruction_status = PSA_ERROR_DATA_CORRUPT; 1159a8e1175bSopenharmony_ci 1160a8e1175bSopenharmony_ci psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 1161a8e1175bSopenharmony_ci mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; 1162a8e1175bSopenharmony_ci psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 1163a8e1175bSopenharmony_ci psa_algorithm_t psa_sig_alg = PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg); 1164a8e1175bSopenharmony_ci p = buf + sizeof(buf); 1165a8e1175bSopenharmony_ci key_len = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*ctx), buf, &p); 1166a8e1175bSopenharmony_ci 1167a8e1175bSopenharmony_ci if (key_len < 0) { 1168a8e1175bSopenharmony_ci return key_len; 1169a8e1175bSopenharmony_ci } 1170a8e1175bSopenharmony_ci 1171a8e1175bSopenharmony_ci psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY); 1172a8e1175bSopenharmony_ci psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); 1173a8e1175bSopenharmony_ci psa_set_key_algorithm(&attributes, psa_sig_alg); 1174a8e1175bSopenharmony_ci 1175a8e1175bSopenharmony_ci status = psa_import_key(&attributes, 1176a8e1175bSopenharmony_ci buf + sizeof(buf) - key_len, key_len, 1177a8e1175bSopenharmony_ci &key_id); 1178a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 1179a8e1175bSopenharmony_ci psa_destroy_key(key_id); 1180a8e1175bSopenharmony_ci return PSA_PK_TO_MBEDTLS_ERR(status); 1181a8e1175bSopenharmony_ci } 1182a8e1175bSopenharmony_ci 1183a8e1175bSopenharmony_ci /* This function requires returning MBEDTLS_ERR_PK_SIG_LEN_MISMATCH 1184a8e1175bSopenharmony_ci * on a valid signature with trailing data in a buffer, but 1185a8e1175bSopenharmony_ci * mbedtls_psa_rsa_verify_hash requires the sig_len to be exact, 1186a8e1175bSopenharmony_ci * so for this reason the passed sig_len is overwritten. Smaller 1187a8e1175bSopenharmony_ci * signature lengths should not be accepted for verification. */ 1188a8e1175bSopenharmony_ci signature_length = sig_len > mbedtls_pk_get_len(ctx) ? 1189a8e1175bSopenharmony_ci mbedtls_pk_get_len(ctx) : sig_len; 1190a8e1175bSopenharmony_ci status = psa_verify_hash(key_id, psa_sig_alg, hash, 1191a8e1175bSopenharmony_ci hash_len, sig, signature_length); 1192a8e1175bSopenharmony_ci destruction_status = psa_destroy_key(key_id); 1193a8e1175bSopenharmony_ci 1194a8e1175bSopenharmony_ci if (status == PSA_SUCCESS && sig_len > mbedtls_pk_get_len(ctx)) { 1195a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; 1196a8e1175bSopenharmony_ci } 1197a8e1175bSopenharmony_ci 1198a8e1175bSopenharmony_ci if (status == PSA_SUCCESS) { 1199a8e1175bSopenharmony_ci status = destruction_status; 1200a8e1175bSopenharmony_ci } 1201a8e1175bSopenharmony_ci 1202a8e1175bSopenharmony_ci return PSA_PK_RSA_TO_MBEDTLS_ERR(status); 1203a8e1175bSopenharmony_ci } else 1204a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 1205a8e1175bSopenharmony_ci { 1206a8e1175bSopenharmony_ci if (sig_len < mbedtls_pk_get_len(ctx)) { 1207a8e1175bSopenharmony_ci return MBEDTLS_ERR_RSA_VERIFY_FAILED; 1208a8e1175bSopenharmony_ci } 1209a8e1175bSopenharmony_ci 1210a8e1175bSopenharmony_ci ret = mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_pk_rsa(*ctx), 1211a8e1175bSopenharmony_ci md_alg, (unsigned int) hash_len, hash, 1212a8e1175bSopenharmony_ci pss_opts->mgf1_hash_id, 1213a8e1175bSopenharmony_ci pss_opts->expected_salt_len, 1214a8e1175bSopenharmony_ci sig); 1215a8e1175bSopenharmony_ci if (ret != 0) { 1216a8e1175bSopenharmony_ci return ret; 1217a8e1175bSopenharmony_ci } 1218a8e1175bSopenharmony_ci 1219a8e1175bSopenharmony_ci if (sig_len > mbedtls_pk_get_len(ctx)) { 1220a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; 1221a8e1175bSopenharmony_ci } 1222a8e1175bSopenharmony_ci 1223a8e1175bSopenharmony_ci return 0; 1224a8e1175bSopenharmony_ci } 1225a8e1175bSopenharmony_ci#else 1226a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 1227a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ 1228a8e1175bSopenharmony_ci} 1229a8e1175bSopenharmony_ci 1230a8e1175bSopenharmony_ci/* 1231a8e1175bSopenharmony_ci * Make a signature (restartable) 1232a8e1175bSopenharmony_ci */ 1233a8e1175bSopenharmony_ciint mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx, 1234a8e1175bSopenharmony_ci mbedtls_md_type_t md_alg, 1235a8e1175bSopenharmony_ci const unsigned char *hash, size_t hash_len, 1236a8e1175bSopenharmony_ci unsigned char *sig, size_t sig_size, size_t *sig_len, 1237a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 1238a8e1175bSopenharmony_ci mbedtls_pk_restart_ctx *rs_ctx) 1239a8e1175bSopenharmony_ci{ 1240a8e1175bSopenharmony_ci if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { 1241a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1242a8e1175bSopenharmony_ci } 1243a8e1175bSopenharmony_ci 1244a8e1175bSopenharmony_ci if (ctx->pk_info == NULL || pk_hashlen_helper(md_alg, &hash_len) != 0) { 1245a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1246a8e1175bSopenharmony_ci } 1247a8e1175bSopenharmony_ci 1248a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 1249a8e1175bSopenharmony_ci /* optimization: use non-restartable version if restart disabled */ 1250a8e1175bSopenharmony_ci if (rs_ctx != NULL && 1251a8e1175bSopenharmony_ci mbedtls_ecp_restart_is_enabled() && 1252a8e1175bSopenharmony_ci ctx->pk_info->sign_rs_func != NULL) { 1253a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1254a8e1175bSopenharmony_ci 1255a8e1175bSopenharmony_ci if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) { 1256a8e1175bSopenharmony_ci return ret; 1257a8e1175bSopenharmony_ci } 1258a8e1175bSopenharmony_ci 1259a8e1175bSopenharmony_ci ret = ctx->pk_info->sign_rs_func(ctx, md_alg, 1260a8e1175bSopenharmony_ci hash, hash_len, 1261a8e1175bSopenharmony_ci sig, sig_size, sig_len, 1262a8e1175bSopenharmony_ci f_rng, p_rng, rs_ctx->rs_ctx); 1263a8e1175bSopenharmony_ci 1264a8e1175bSopenharmony_ci if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) { 1265a8e1175bSopenharmony_ci mbedtls_pk_restart_free(rs_ctx); 1266a8e1175bSopenharmony_ci } 1267a8e1175bSopenharmony_ci 1268a8e1175bSopenharmony_ci return ret; 1269a8e1175bSopenharmony_ci } 1270a8e1175bSopenharmony_ci#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 1271a8e1175bSopenharmony_ci (void) rs_ctx; 1272a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 1273a8e1175bSopenharmony_ci 1274a8e1175bSopenharmony_ci if (ctx->pk_info->sign_func == NULL) { 1275a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 1276a8e1175bSopenharmony_ci } 1277a8e1175bSopenharmony_ci 1278a8e1175bSopenharmony_ci return ctx->pk_info->sign_func(ctx, md_alg, 1279a8e1175bSopenharmony_ci hash, hash_len, 1280a8e1175bSopenharmony_ci sig, sig_size, sig_len, 1281a8e1175bSopenharmony_ci f_rng, p_rng); 1282a8e1175bSopenharmony_ci} 1283a8e1175bSopenharmony_ci 1284a8e1175bSopenharmony_ci/* 1285a8e1175bSopenharmony_ci * Make a signature 1286a8e1175bSopenharmony_ci */ 1287a8e1175bSopenharmony_ciint mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, 1288a8e1175bSopenharmony_ci const unsigned char *hash, size_t hash_len, 1289a8e1175bSopenharmony_ci unsigned char *sig, size_t sig_size, size_t *sig_len, 1290a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 1291a8e1175bSopenharmony_ci{ 1292a8e1175bSopenharmony_ci return mbedtls_pk_sign_restartable(ctx, md_alg, hash, hash_len, 1293a8e1175bSopenharmony_ci sig, sig_size, sig_len, 1294a8e1175bSopenharmony_ci f_rng, p_rng, NULL); 1295a8e1175bSopenharmony_ci} 1296a8e1175bSopenharmony_ci 1297a8e1175bSopenharmony_ci/* 1298a8e1175bSopenharmony_ci * Make a signature given a signature type. 1299a8e1175bSopenharmony_ci */ 1300a8e1175bSopenharmony_ciint mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, 1301a8e1175bSopenharmony_ci mbedtls_pk_context *ctx, 1302a8e1175bSopenharmony_ci mbedtls_md_type_t md_alg, 1303a8e1175bSopenharmony_ci const unsigned char *hash, size_t hash_len, 1304a8e1175bSopenharmony_ci unsigned char *sig, size_t sig_size, size_t *sig_len, 1305a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 1306a8e1175bSopenharmony_ci void *p_rng) 1307a8e1175bSopenharmony_ci{ 1308a8e1175bSopenharmony_ci if (ctx->pk_info == NULL) { 1309a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1310a8e1175bSopenharmony_ci } 1311a8e1175bSopenharmony_ci 1312a8e1175bSopenharmony_ci if (!mbedtls_pk_can_do(ctx, pk_type)) { 1313a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 1314a8e1175bSopenharmony_ci } 1315a8e1175bSopenharmony_ci 1316a8e1175bSopenharmony_ci if (pk_type != MBEDTLS_PK_RSASSA_PSS) { 1317a8e1175bSopenharmony_ci return mbedtls_pk_sign(ctx, md_alg, hash, hash_len, 1318a8e1175bSopenharmony_ci sig, sig_size, sig_len, f_rng, p_rng); 1319a8e1175bSopenharmony_ci } 1320a8e1175bSopenharmony_ci 1321a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) 1322a8e1175bSopenharmony_ci 1323a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 1324a8e1175bSopenharmony_ci const psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 1325a8e1175bSopenharmony_ci if (psa_md_alg == 0) { 1326a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1327a8e1175bSopenharmony_ci } 1328a8e1175bSopenharmony_ci 1329a8e1175bSopenharmony_ci if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) { 1330a8e1175bSopenharmony_ci psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; 1331a8e1175bSopenharmony_ci psa_algorithm_t psa_alg, sign_alg; 1332a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C) 1333a8e1175bSopenharmony_ci psa_algorithm_t psa_enrollment_alg; 1334a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */ 1335a8e1175bSopenharmony_ci psa_status_t status; 1336a8e1175bSopenharmony_ci 1337a8e1175bSopenharmony_ci status = psa_get_key_attributes(ctx->priv_id, &key_attr); 1338a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 1339a8e1175bSopenharmony_ci return PSA_PK_RSA_TO_MBEDTLS_ERR(status); 1340a8e1175bSopenharmony_ci } 1341a8e1175bSopenharmony_ci psa_alg = psa_get_key_algorithm(&key_attr); 1342a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C) 1343a8e1175bSopenharmony_ci psa_enrollment_alg = psa_get_key_enrollment_algorithm(&key_attr); 1344a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */ 1345a8e1175bSopenharmony_ci psa_reset_key_attributes(&key_attr); 1346a8e1175bSopenharmony_ci 1347a8e1175bSopenharmony_ci /* Since we're PK type is MBEDTLS_PK_RSASSA_PSS at least one between 1348a8e1175bSopenharmony_ci * alg and enrollment alg should be of type RSA_PSS. */ 1349a8e1175bSopenharmony_ci if (PSA_ALG_IS_RSA_PSS(psa_alg)) { 1350a8e1175bSopenharmony_ci sign_alg = psa_alg; 1351a8e1175bSopenharmony_ci } 1352a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_C) 1353a8e1175bSopenharmony_ci else if (PSA_ALG_IS_RSA_PSS(psa_enrollment_alg)) { 1354a8e1175bSopenharmony_ci sign_alg = psa_enrollment_alg; 1355a8e1175bSopenharmony_ci } 1356a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_C */ 1357a8e1175bSopenharmony_ci else { 1358a8e1175bSopenharmony_ci /* The opaque key has no RSA PSS algorithm associated. */ 1359a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1360a8e1175bSopenharmony_ci } 1361a8e1175bSopenharmony_ci /* Adjust the hashing algorithm. */ 1362a8e1175bSopenharmony_ci sign_alg = (sign_alg & ~PSA_ALG_HASH_MASK) | PSA_ALG_GET_HASH(psa_md_alg); 1363a8e1175bSopenharmony_ci 1364a8e1175bSopenharmony_ci status = psa_sign_hash(ctx->priv_id, sign_alg, 1365a8e1175bSopenharmony_ci hash, hash_len, 1366a8e1175bSopenharmony_ci sig, sig_size, sig_len); 1367a8e1175bSopenharmony_ci return PSA_PK_RSA_TO_MBEDTLS_ERR(status); 1368a8e1175bSopenharmony_ci } 1369a8e1175bSopenharmony_ci 1370a8e1175bSopenharmony_ci return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PSS(psa_md_alg), 1371a8e1175bSopenharmony_ci ctx->pk_ctx, hash, hash_len, 1372a8e1175bSopenharmony_ci sig, sig_size, sig_len); 1373a8e1175bSopenharmony_ci#else /* MBEDTLS_USE_PSA_CRYPTO */ 1374a8e1175bSopenharmony_ci 1375a8e1175bSopenharmony_ci if (sig_size < mbedtls_pk_get_len(ctx)) { 1376a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; 1377a8e1175bSopenharmony_ci } 1378a8e1175bSopenharmony_ci 1379a8e1175bSopenharmony_ci if (pk_hashlen_helper(md_alg, &hash_len) != 0) { 1380a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1381a8e1175bSopenharmony_ci } 1382a8e1175bSopenharmony_ci 1383a8e1175bSopenharmony_ci mbedtls_rsa_context *const rsa_ctx = mbedtls_pk_rsa(*ctx); 1384a8e1175bSopenharmony_ci 1385a8e1175bSopenharmony_ci const int ret = mbedtls_rsa_rsassa_pss_sign_no_mode_check(rsa_ctx, f_rng, p_rng, md_alg, 1386a8e1175bSopenharmony_ci (unsigned int) hash_len, hash, sig); 1387a8e1175bSopenharmony_ci if (ret == 0) { 1388a8e1175bSopenharmony_ci *sig_len = rsa_ctx->len; 1389a8e1175bSopenharmony_ci } 1390a8e1175bSopenharmony_ci return ret; 1391a8e1175bSopenharmony_ci 1392a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 1393a8e1175bSopenharmony_ci 1394a8e1175bSopenharmony_ci#else 1395a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 1396a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ 1397a8e1175bSopenharmony_ci} 1398a8e1175bSopenharmony_ci 1399a8e1175bSopenharmony_ci/* 1400a8e1175bSopenharmony_ci * Decrypt message 1401a8e1175bSopenharmony_ci */ 1402a8e1175bSopenharmony_ciint mbedtls_pk_decrypt(mbedtls_pk_context *ctx, 1403a8e1175bSopenharmony_ci const unsigned char *input, size_t ilen, 1404a8e1175bSopenharmony_ci unsigned char *output, size_t *olen, size_t osize, 1405a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 1406a8e1175bSopenharmony_ci{ 1407a8e1175bSopenharmony_ci if (ctx->pk_info == NULL) { 1408a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1409a8e1175bSopenharmony_ci } 1410a8e1175bSopenharmony_ci 1411a8e1175bSopenharmony_ci if (ctx->pk_info->decrypt_func == NULL) { 1412a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 1413a8e1175bSopenharmony_ci } 1414a8e1175bSopenharmony_ci 1415a8e1175bSopenharmony_ci return ctx->pk_info->decrypt_func(ctx, input, ilen, 1416a8e1175bSopenharmony_ci output, olen, osize, f_rng, p_rng); 1417a8e1175bSopenharmony_ci} 1418a8e1175bSopenharmony_ci 1419a8e1175bSopenharmony_ci/* 1420a8e1175bSopenharmony_ci * Encrypt message 1421a8e1175bSopenharmony_ci */ 1422a8e1175bSopenharmony_ciint mbedtls_pk_encrypt(mbedtls_pk_context *ctx, 1423a8e1175bSopenharmony_ci const unsigned char *input, size_t ilen, 1424a8e1175bSopenharmony_ci unsigned char *output, size_t *olen, size_t osize, 1425a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 1426a8e1175bSopenharmony_ci{ 1427a8e1175bSopenharmony_ci if (ctx->pk_info == NULL) { 1428a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1429a8e1175bSopenharmony_ci } 1430a8e1175bSopenharmony_ci 1431a8e1175bSopenharmony_ci if (ctx->pk_info->encrypt_func == NULL) { 1432a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 1433a8e1175bSopenharmony_ci } 1434a8e1175bSopenharmony_ci 1435a8e1175bSopenharmony_ci return ctx->pk_info->encrypt_func(ctx, input, ilen, 1436a8e1175bSopenharmony_ci output, olen, osize, f_rng, p_rng); 1437a8e1175bSopenharmony_ci} 1438a8e1175bSopenharmony_ci 1439a8e1175bSopenharmony_ci/* 1440a8e1175bSopenharmony_ci * Check public-private key pair 1441a8e1175bSopenharmony_ci */ 1442a8e1175bSopenharmony_ciint mbedtls_pk_check_pair(const mbedtls_pk_context *pub, 1443a8e1175bSopenharmony_ci const mbedtls_pk_context *prv, 1444a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 1445a8e1175bSopenharmony_ci void *p_rng) 1446a8e1175bSopenharmony_ci{ 1447a8e1175bSopenharmony_ci if (pub->pk_info == NULL || 1448a8e1175bSopenharmony_ci prv->pk_info == NULL) { 1449a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1450a8e1175bSopenharmony_ci } 1451a8e1175bSopenharmony_ci 1452a8e1175bSopenharmony_ci if (f_rng == NULL) { 1453a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1454a8e1175bSopenharmony_ci } 1455a8e1175bSopenharmony_ci 1456a8e1175bSopenharmony_ci if (prv->pk_info->check_pair_func == NULL) { 1457a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 1458a8e1175bSopenharmony_ci } 1459a8e1175bSopenharmony_ci 1460a8e1175bSopenharmony_ci if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) { 1461a8e1175bSopenharmony_ci if (pub->pk_info->type != MBEDTLS_PK_RSA) { 1462a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 1463a8e1175bSopenharmony_ci } 1464a8e1175bSopenharmony_ci } else { 1465a8e1175bSopenharmony_ci if ((prv->pk_info->type != MBEDTLS_PK_OPAQUE) && 1466a8e1175bSopenharmony_ci (pub->pk_info != prv->pk_info)) { 1467a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 1468a8e1175bSopenharmony_ci } 1469a8e1175bSopenharmony_ci } 1470a8e1175bSopenharmony_ci 1471a8e1175bSopenharmony_ci return prv->pk_info->check_pair_func((mbedtls_pk_context *) pub, 1472a8e1175bSopenharmony_ci (mbedtls_pk_context *) prv, 1473a8e1175bSopenharmony_ci f_rng, p_rng); 1474a8e1175bSopenharmony_ci} 1475a8e1175bSopenharmony_ci 1476a8e1175bSopenharmony_ci/* 1477a8e1175bSopenharmony_ci * Get key size in bits 1478a8e1175bSopenharmony_ci */ 1479a8e1175bSopenharmony_cisize_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx) 1480a8e1175bSopenharmony_ci{ 1481a8e1175bSopenharmony_ci /* For backward compatibility, accept NULL or a context that 1482a8e1175bSopenharmony_ci * isn't set up yet, and return a fake value that should be safe. */ 1483a8e1175bSopenharmony_ci if (ctx == NULL || ctx->pk_info == NULL) { 1484a8e1175bSopenharmony_ci return 0; 1485a8e1175bSopenharmony_ci } 1486a8e1175bSopenharmony_ci 1487a8e1175bSopenharmony_ci return ctx->pk_info->get_bitlen((mbedtls_pk_context *) ctx); 1488a8e1175bSopenharmony_ci} 1489a8e1175bSopenharmony_ci 1490a8e1175bSopenharmony_ci/* 1491a8e1175bSopenharmony_ci * Export debug information 1492a8e1175bSopenharmony_ci */ 1493a8e1175bSopenharmony_ciint mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items) 1494a8e1175bSopenharmony_ci{ 1495a8e1175bSopenharmony_ci if (ctx->pk_info == NULL) { 1496a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1497a8e1175bSopenharmony_ci } 1498a8e1175bSopenharmony_ci 1499a8e1175bSopenharmony_ci if (ctx->pk_info->debug_func == NULL) { 1500a8e1175bSopenharmony_ci return MBEDTLS_ERR_PK_TYPE_MISMATCH; 1501a8e1175bSopenharmony_ci } 1502a8e1175bSopenharmony_ci 1503a8e1175bSopenharmony_ci ctx->pk_info->debug_func((mbedtls_pk_context *) ctx, items); 1504a8e1175bSopenharmony_ci return 0; 1505a8e1175bSopenharmony_ci} 1506a8e1175bSopenharmony_ci 1507a8e1175bSopenharmony_ci/* 1508a8e1175bSopenharmony_ci * Access the PK type name 1509a8e1175bSopenharmony_ci */ 1510a8e1175bSopenharmony_ciconst char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx) 1511a8e1175bSopenharmony_ci{ 1512a8e1175bSopenharmony_ci if (ctx == NULL || ctx->pk_info == NULL) { 1513a8e1175bSopenharmony_ci return "invalid PK"; 1514a8e1175bSopenharmony_ci } 1515a8e1175bSopenharmony_ci 1516a8e1175bSopenharmony_ci return ctx->pk_info->name; 1517a8e1175bSopenharmony_ci} 1518a8e1175bSopenharmony_ci 1519a8e1175bSopenharmony_ci/* 1520a8e1175bSopenharmony_ci * Access the PK type 1521a8e1175bSopenharmony_ci */ 1522a8e1175bSopenharmony_cimbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) 1523a8e1175bSopenharmony_ci{ 1524a8e1175bSopenharmony_ci if (ctx == NULL || ctx->pk_info == NULL) { 1525a8e1175bSopenharmony_ci return MBEDTLS_PK_NONE; 1526a8e1175bSopenharmony_ci } 1527a8e1175bSopenharmony_ci 1528a8e1175bSopenharmony_ci return ctx->pk_info->type; 1529a8e1175bSopenharmony_ci} 1530a8e1175bSopenharmony_ci 1531a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_C */ 1532