1817466cbSJens Wiklander /* 2817466cbSJens Wiklander * Public Key abstraction layer 3817466cbSJens Wiklander * 47901324dSJerome Forissier * Copyright The Mbed TLS Contributors 57901324dSJerome Forissier * SPDX-License-Identifier: Apache-2.0 6817466cbSJens Wiklander * 7817466cbSJens Wiklander * Licensed under the Apache License, Version 2.0 (the "License"); you may 8817466cbSJens Wiklander * not use this file except in compliance with the License. 9817466cbSJens Wiklander * You may obtain a copy of the License at 10817466cbSJens Wiklander * 11817466cbSJens Wiklander * http://www.apache.org/licenses/LICENSE-2.0 12817466cbSJens Wiklander * 13817466cbSJens Wiklander * Unless required by applicable law or agreed to in writing, software 14817466cbSJens Wiklander * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15817466cbSJens Wiklander * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16817466cbSJens Wiklander * See the License for the specific language governing permissions and 17817466cbSJens Wiklander * limitations under the License. 18817466cbSJens Wiklander */ 19817466cbSJens Wiklander 207901324dSJerome Forissier #include "common.h" 21817466cbSJens Wiklander 22817466cbSJens Wiklander #if defined(MBEDTLS_PK_C) 23817466cbSJens Wiklander #include "mbedtls/pk.h" 24*32b31808SJens Wiklander #include "pk_wrap.h" 25*32b31808SJens Wiklander #include "pkwrite.h" 26*32b31808SJens Wiklander 27*32b31808SJens Wiklander #include "hash_info.h" 28817466cbSJens Wiklander 293d3b0591SJens Wiklander #include "mbedtls/platform_util.h" 3011fa71b9SJerome Forissier #include "mbedtls/error.h" 31817466cbSJens Wiklander 32817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 33817466cbSJens Wiklander #include "mbedtls/rsa.h" 34817466cbSJens Wiklander #endif 35817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C) 36817466cbSJens Wiklander #include "mbedtls/ecp.h" 37817466cbSJens Wiklander #endif 38817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 39817466cbSJens Wiklander #include "mbedtls/ecdsa.h" 40817466cbSJens Wiklander #endif 41817466cbSJens Wiklander 42*32b31808SJens Wiklander #if defined(MBEDTLS_PSA_CRYPTO_C) 4311fa71b9SJerome Forissier #include "mbedtls/psa_util.h" 44*32b31808SJens Wiklander #define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status) 45*32b31808SJens Wiklander #define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ 46*32b31808SJens Wiklander psa_to_pk_rsa_errors, \ 47*32b31808SJens Wiklander psa_pk_status_to_mbedtls) 48*32b31808SJens Wiklander #define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ 49*32b31808SJens Wiklander psa_to_pk_ecdsa_errors, \ 50*32b31808SJens Wiklander psa_pk_status_to_mbedtls) 5111fa71b9SJerome Forissier #endif 5211fa71b9SJerome Forissier 53817466cbSJens Wiklander #include <limits.h> 543d3b0591SJens Wiklander #include <stdint.h> 55817466cbSJens Wiklander 56817466cbSJens Wiklander /* 57817466cbSJens Wiklander * Initialise a mbedtls_pk_context 58817466cbSJens Wiklander */ 59817466cbSJens Wiklander void mbedtls_pk_init(mbedtls_pk_context *ctx) 60817466cbSJens Wiklander { 61817466cbSJens Wiklander ctx->pk_info = NULL; 62817466cbSJens Wiklander ctx->pk_ctx = NULL; 63817466cbSJens Wiklander } 64817466cbSJens Wiklander 65817466cbSJens Wiklander /* 66817466cbSJens Wiklander * Free (the components of) a mbedtls_pk_context 67817466cbSJens Wiklander */ 68817466cbSJens Wiklander void mbedtls_pk_free(mbedtls_pk_context *ctx) 69817466cbSJens Wiklander { 70*32b31808SJens Wiklander if (ctx == NULL) { 71817466cbSJens Wiklander return; 72*32b31808SJens Wiklander } 73817466cbSJens Wiklander 74*32b31808SJens Wiklander if (ctx->pk_info != NULL) { 75817466cbSJens Wiklander ctx->pk_info->ctx_free_func(ctx->pk_ctx); 76*32b31808SJens Wiklander } 77817466cbSJens Wiklander 783d3b0591SJens Wiklander mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context)); 79817466cbSJens Wiklander } 80817466cbSJens Wiklander 813d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 823d3b0591SJens Wiklander /* 833d3b0591SJens Wiklander * Initialize a restart context 843d3b0591SJens Wiklander */ 853d3b0591SJens Wiklander void mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx) 863d3b0591SJens Wiklander { 873d3b0591SJens Wiklander ctx->pk_info = NULL; 883d3b0591SJens Wiklander ctx->rs_ctx = NULL; 893d3b0591SJens Wiklander } 903d3b0591SJens Wiklander 913d3b0591SJens Wiklander /* 923d3b0591SJens Wiklander * Free the components of a restart context 933d3b0591SJens Wiklander */ 943d3b0591SJens Wiklander void mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx) 953d3b0591SJens Wiklander { 963d3b0591SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL || 97*32b31808SJens Wiklander ctx->pk_info->rs_free_func == NULL) { 983d3b0591SJens Wiklander return; 993d3b0591SJens Wiklander } 1003d3b0591SJens Wiklander 1013d3b0591SJens Wiklander ctx->pk_info->rs_free_func(ctx->rs_ctx); 1023d3b0591SJens Wiklander 1033d3b0591SJens Wiklander ctx->pk_info = NULL; 1043d3b0591SJens Wiklander ctx->rs_ctx = NULL; 1053d3b0591SJens Wiklander } 1063d3b0591SJens Wiklander #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 1073d3b0591SJens Wiklander 108817466cbSJens Wiklander /* 109817466cbSJens Wiklander * Get pk_info structure from type 110817466cbSJens Wiklander */ 111817466cbSJens Wiklander const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type) 112817466cbSJens Wiklander { 113817466cbSJens Wiklander switch (pk_type) { 114817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 115817466cbSJens Wiklander case MBEDTLS_PK_RSA: 116*32b31808SJens Wiklander return &mbedtls_rsa_info; 117817466cbSJens Wiklander #endif 118817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C) 119817466cbSJens Wiklander case MBEDTLS_PK_ECKEY: 120*32b31808SJens Wiklander return &mbedtls_eckey_info; 121817466cbSJens Wiklander case MBEDTLS_PK_ECKEY_DH: 122*32b31808SJens Wiklander return &mbedtls_eckeydh_info; 123817466cbSJens Wiklander #endif 124*32b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SOME) 125817466cbSJens Wiklander case MBEDTLS_PK_ECDSA: 126*32b31808SJens Wiklander return &mbedtls_ecdsa_info; 127817466cbSJens Wiklander #endif 128817466cbSJens Wiklander /* MBEDTLS_PK_RSA_ALT omitted on purpose */ 129817466cbSJens Wiklander default: 130*32b31808SJens Wiklander return NULL; 131817466cbSJens Wiklander } 132817466cbSJens Wiklander } 133817466cbSJens Wiklander 134817466cbSJens Wiklander /* 135817466cbSJens Wiklander * Initialise context 136817466cbSJens Wiklander */ 137817466cbSJens Wiklander int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info) 138817466cbSJens Wiklander { 139*32b31808SJens Wiklander if (info == NULL || ctx->pk_info != NULL) { 140*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 141*32b31808SJens Wiklander } 142817466cbSJens Wiklander 143*32b31808SJens Wiklander if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) { 144*32b31808SJens Wiklander return MBEDTLS_ERR_PK_ALLOC_FAILED; 145*32b31808SJens Wiklander } 146817466cbSJens Wiklander 147817466cbSJens Wiklander ctx->pk_info = info; 148817466cbSJens Wiklander 149*32b31808SJens Wiklander return 0; 150817466cbSJens Wiklander } 151817466cbSJens Wiklander 15211fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 15311fa71b9SJerome Forissier /* 15411fa71b9SJerome Forissier * Initialise a PSA-wrapping context 15511fa71b9SJerome Forissier */ 1567901324dSJerome Forissier int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, 157*32b31808SJens Wiklander const mbedtls_svc_key_id_t key) 15811fa71b9SJerome Forissier { 159*32b31808SJens Wiklander const mbedtls_pk_info_t *info = NULL; 16011fa71b9SJerome Forissier psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 161*32b31808SJens Wiklander mbedtls_svc_key_id_t *pk_ctx; 16211fa71b9SJerome Forissier psa_key_type_t type; 16311fa71b9SJerome Forissier 164*32b31808SJens Wiklander if (ctx == NULL || ctx->pk_info != NULL) { 165*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 166*32b31808SJens Wiklander } 16711fa71b9SJerome Forissier 168*32b31808SJens Wiklander if (PSA_SUCCESS != psa_get_key_attributes(key, &attributes)) { 169*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 170*32b31808SJens Wiklander } 17111fa71b9SJerome Forissier type = psa_get_key_type(&attributes); 17211fa71b9SJerome Forissier psa_reset_key_attributes(&attributes); 17311fa71b9SJerome Forissier 174*32b31808SJens Wiklander if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) { 175*32b31808SJens Wiklander info = &mbedtls_pk_ecdsa_opaque_info; 176*32b31808SJens Wiklander } else if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) { 177*32b31808SJens Wiklander info = &mbedtls_pk_rsa_opaque_info; 178*32b31808SJens Wiklander } else { 179*32b31808SJens Wiklander return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 180*32b31808SJens Wiklander } 18111fa71b9SJerome Forissier 182*32b31808SJens Wiklander if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) { 183*32b31808SJens Wiklander return MBEDTLS_ERR_PK_ALLOC_FAILED; 184*32b31808SJens Wiklander } 18511fa71b9SJerome Forissier 18611fa71b9SJerome Forissier ctx->pk_info = info; 18711fa71b9SJerome Forissier 188*32b31808SJens Wiklander pk_ctx = (mbedtls_svc_key_id_t *) ctx->pk_ctx; 18911fa71b9SJerome Forissier *pk_ctx = key; 19011fa71b9SJerome Forissier 191*32b31808SJens 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 207*32b31808SJens Wiklander if (ctx->pk_info != NULL) { 208*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 209*32b31808SJens Wiklander } 210817466cbSJens Wiklander 211*32b31808SJens Wiklander if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) { 212*32b31808SJens Wiklander return MBEDTLS_ERR_PK_ALLOC_FAILED; 213*32b31808SJens 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 224*32b31808SJens 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. */ 236*32b31808SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL) { 237*32b31808SJens Wiklander return 0; 238817466cbSJens Wiklander } 239817466cbSJens Wiklander 240*32b31808SJens Wiklander return ctx->pk_info->can_do(type); 241*32b31808SJens Wiklander } 242*32b31808SJens Wiklander 243*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 244*32b31808SJens Wiklander /* 245*32b31808SJens Wiklander * Tell if a PK can do the operations of the given PSA algorithm 246*32b31808SJens Wiklander */ 247*32b31808SJens Wiklander int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg, 248*32b31808SJens Wiklander psa_key_usage_t usage) 249*32b31808SJens Wiklander { 250*32b31808SJens Wiklander psa_key_usage_t key_usage; 251*32b31808SJens Wiklander 252*32b31808SJens Wiklander /* A context with null pk_info is not set up yet and can't do anything. 253*32b31808SJens Wiklander * For backward compatibility, also accept NULL instead of a context 254*32b31808SJens Wiklander * pointer. */ 255*32b31808SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL) { 256*32b31808SJens Wiklander return 0; 257*32b31808SJens Wiklander } 258*32b31808SJens Wiklander 259*32b31808SJens Wiklander /* Filter out non allowed algorithms */ 260*32b31808SJens Wiklander if (PSA_ALG_IS_ECDSA(alg) == 0 && 261*32b31808SJens Wiklander PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) == 0 && 262*32b31808SJens Wiklander PSA_ALG_IS_RSA_PSS(alg) == 0 && 263*32b31808SJens Wiklander alg != PSA_ALG_RSA_PKCS1V15_CRYPT && 264*32b31808SJens Wiklander PSA_ALG_IS_ECDH(alg) == 0) { 265*32b31808SJens Wiklander return 0; 266*32b31808SJens Wiklander } 267*32b31808SJens Wiklander 268*32b31808SJens Wiklander /* Filter out non allowed usage flags */ 269*32b31808SJens Wiklander if (usage == 0 || 270*32b31808SJens Wiklander (usage & ~(PSA_KEY_USAGE_SIGN_HASH | 271*32b31808SJens Wiklander PSA_KEY_USAGE_DECRYPT | 272*32b31808SJens Wiklander PSA_KEY_USAGE_DERIVE)) != 0) { 273*32b31808SJens Wiklander return 0; 274*32b31808SJens Wiklander } 275*32b31808SJens Wiklander 276*32b31808SJens Wiklander /* Wildcard hash is not allowed */ 277*32b31808SJens Wiklander if (PSA_ALG_IS_SIGN_HASH(alg) && 278*32b31808SJens Wiklander PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH) { 279*32b31808SJens Wiklander return 0; 280*32b31808SJens Wiklander } 281*32b31808SJens Wiklander 282*32b31808SJens Wiklander if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_OPAQUE) { 283*32b31808SJens Wiklander mbedtls_pk_type_t type; 284*32b31808SJens Wiklander 285*32b31808SJens Wiklander if (PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_ECDH(alg)) { 286*32b31808SJens Wiklander type = MBEDTLS_PK_ECKEY; 287*32b31808SJens Wiklander } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || 288*32b31808SJens Wiklander alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { 289*32b31808SJens Wiklander type = MBEDTLS_PK_RSA; 290*32b31808SJens Wiklander } else if (PSA_ALG_IS_RSA_PSS(alg)) { 291*32b31808SJens Wiklander type = MBEDTLS_PK_RSASSA_PSS; 292*32b31808SJens Wiklander } else { 293*32b31808SJens Wiklander return 0; 294*32b31808SJens Wiklander } 295*32b31808SJens Wiklander 296*32b31808SJens Wiklander if (ctx->pk_info->can_do(type) == 0) { 297*32b31808SJens Wiklander return 0; 298*32b31808SJens Wiklander } 299*32b31808SJens Wiklander 300*32b31808SJens Wiklander switch (type) { 301*32b31808SJens Wiklander case MBEDTLS_PK_ECKEY: 302*32b31808SJens Wiklander key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE; 303*32b31808SJens Wiklander break; 304*32b31808SJens Wiklander case MBEDTLS_PK_RSA: 305*32b31808SJens Wiklander case MBEDTLS_PK_RSASSA_PSS: 306*32b31808SJens Wiklander key_usage = PSA_KEY_USAGE_SIGN_HASH | 307*32b31808SJens Wiklander PSA_KEY_USAGE_SIGN_MESSAGE | 308*32b31808SJens Wiklander PSA_KEY_USAGE_DECRYPT; 309*32b31808SJens Wiklander break; 310*32b31808SJens Wiklander default: 311*32b31808SJens Wiklander /* Should never happen */ 312*32b31808SJens Wiklander return 0; 313*32b31808SJens Wiklander } 314*32b31808SJens Wiklander 315*32b31808SJens Wiklander return (key_usage & usage) == usage; 316*32b31808SJens Wiklander } 317*32b31808SJens Wiklander 318*32b31808SJens Wiklander const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx; 319*32b31808SJens Wiklander psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 320*32b31808SJens Wiklander psa_algorithm_t key_alg, key_alg2; 321*32b31808SJens Wiklander psa_status_t status; 322*32b31808SJens Wiklander 323*32b31808SJens Wiklander status = psa_get_key_attributes(*key, &attributes); 324*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 325*32b31808SJens Wiklander return 0; 326*32b31808SJens Wiklander } 327*32b31808SJens Wiklander 328*32b31808SJens Wiklander key_alg = psa_get_key_algorithm(&attributes); 329*32b31808SJens Wiklander key_alg2 = psa_get_key_enrollment_algorithm(&attributes); 330*32b31808SJens Wiklander key_usage = psa_get_key_usage_flags(&attributes); 331*32b31808SJens Wiklander psa_reset_key_attributes(&attributes); 332*32b31808SJens Wiklander 333*32b31808SJens Wiklander if ((key_usage & usage) != usage) { 334*32b31808SJens Wiklander return 0; 335*32b31808SJens Wiklander } 336*32b31808SJens Wiklander 337*32b31808SJens Wiklander /* 338*32b31808SJens Wiklander * Common case: the key alg or alg2 only allows alg. 339*32b31808SJens Wiklander * This will match PSA_ALG_RSA_PKCS1V15_CRYPT & PSA_ALG_IS_ECDH 340*32b31808SJens Wiklander * directly. 341*32b31808SJens Wiklander * This would also match ECDSA/RSA_PKCS1V15_SIGN/RSA_PSS with 342*32b31808SJens Wiklander * a fixed hash on key_alg/key_alg2. 343*32b31808SJens Wiklander */ 344*32b31808SJens Wiklander if (alg == key_alg || alg == key_alg2) { 345*32b31808SJens Wiklander return 1; 346*32b31808SJens Wiklander } 347*32b31808SJens Wiklander 348*32b31808SJens Wiklander /* 349*32b31808SJens Wiklander * If key_alg or key_alg2 is a hash-and-sign with a wildcard for the hash, 350*32b31808SJens Wiklander * and alg is the same hash-and-sign family with any hash, 351*32b31808SJens Wiklander * then alg is compliant with this key alg 352*32b31808SJens Wiklander */ 353*32b31808SJens Wiklander if (PSA_ALG_IS_SIGN_HASH(alg)) { 354*32b31808SJens Wiklander 355*32b31808SJens Wiklander if (PSA_ALG_IS_SIGN_HASH(key_alg) && 356*32b31808SJens Wiklander PSA_ALG_SIGN_GET_HASH(key_alg) == PSA_ALG_ANY_HASH && 357*32b31808SJens Wiklander (alg & ~PSA_ALG_HASH_MASK) == (key_alg & ~PSA_ALG_HASH_MASK)) { 358*32b31808SJens Wiklander return 1; 359*32b31808SJens Wiklander } 360*32b31808SJens Wiklander 361*32b31808SJens Wiklander if (PSA_ALG_IS_SIGN_HASH(key_alg2) && 362*32b31808SJens Wiklander PSA_ALG_SIGN_GET_HASH(key_alg2) == PSA_ALG_ANY_HASH && 363*32b31808SJens Wiklander (alg & ~PSA_ALG_HASH_MASK) == (key_alg2 & ~PSA_ALG_HASH_MASK)) { 364*32b31808SJens Wiklander return 1; 365*32b31808SJens Wiklander } 366*32b31808SJens Wiklander } 367*32b31808SJens Wiklander 368*32b31808SJens Wiklander return 0; 369*32b31808SJens Wiklander } 370*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 371*32b31808SJens Wiklander 372817466cbSJens Wiklander /* 373817466cbSJens Wiklander * Helper for mbedtls_pk_sign and mbedtls_pk_verify 374817466cbSJens Wiklander */ 375817466cbSJens Wiklander static inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len) 376817466cbSJens Wiklander { 377*32b31808SJens Wiklander if (*hash_len != 0) { 378*32b31808SJens Wiklander return 0; 379*32b31808SJens Wiklander } 380817466cbSJens Wiklander 381*32b31808SJens Wiklander *hash_len = mbedtls_hash_info_get_size(md_alg); 382817466cbSJens Wiklander 383*32b31808SJens Wiklander if (*hash_len == 0) { 384*32b31808SJens Wiklander return -1; 385*32b31808SJens Wiklander } 386817466cbSJens Wiklander 387*32b31808SJens Wiklander return 0; 388817466cbSJens Wiklander } 389817466cbSJens Wiklander 3903d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 3913d3b0591SJens Wiklander /* 3923d3b0591SJens Wiklander * Helper to set up a restart context if needed 3933d3b0591SJens Wiklander */ 3943d3b0591SJens Wiklander static int pk_restart_setup(mbedtls_pk_restart_ctx *ctx, 3953d3b0591SJens Wiklander const mbedtls_pk_info_t *info) 3963d3b0591SJens Wiklander { 3973d3b0591SJens Wiklander /* Don't do anything if already set up or invalid */ 398*32b31808SJens Wiklander if (ctx == NULL || ctx->pk_info != NULL) { 399*32b31808SJens Wiklander return 0; 400*32b31808SJens Wiklander } 4013d3b0591SJens Wiklander 4023d3b0591SJens Wiklander /* Should never happen when we're called */ 403*32b31808SJens Wiklander if (info->rs_alloc_func == NULL || info->rs_free_func == NULL) { 404*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 405*32b31808SJens Wiklander } 4063d3b0591SJens Wiklander 407*32b31808SJens Wiklander if ((ctx->rs_ctx = info->rs_alloc_func()) == NULL) { 408*32b31808SJens Wiklander return MBEDTLS_ERR_PK_ALLOC_FAILED; 409*32b31808SJens Wiklander } 4103d3b0591SJens Wiklander 4113d3b0591SJens Wiklander ctx->pk_info = info; 4123d3b0591SJens Wiklander 413*32b31808SJens Wiklander return 0; 4143d3b0591SJens Wiklander } 4153d3b0591SJens Wiklander #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 4163d3b0591SJens Wiklander 4173d3b0591SJens Wiklander /* 4183d3b0591SJens Wiklander * Verify a signature (restartable) 4193d3b0591SJens Wiklander */ 4203d3b0591SJens Wiklander int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx, 4213d3b0591SJens Wiklander mbedtls_md_type_t md_alg, 4223d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 4233d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 4243d3b0591SJens Wiklander mbedtls_pk_restart_ctx *rs_ctx) 4253d3b0591SJens Wiklander { 426*32b31808SJens Wiklander if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { 427*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 428*32b31808SJens Wiklander } 4293d3b0591SJens Wiklander 4303d3b0591SJens Wiklander if (ctx->pk_info == NULL || 431*32b31808SJens Wiklander pk_hashlen_helper(md_alg, &hash_len) != 0) { 432*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 433*32b31808SJens Wiklander } 4343d3b0591SJens Wiklander 4353d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 4363d3b0591SJens Wiklander /* optimization: use non-restartable version if restart disabled */ 4373d3b0591SJens Wiklander if (rs_ctx != NULL && 4383d3b0591SJens Wiklander mbedtls_ecp_restart_is_enabled() && 439*32b31808SJens Wiklander ctx->pk_info->verify_rs_func != NULL) { 44011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 4413d3b0591SJens Wiklander 442*32b31808SJens Wiklander if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) { 443*32b31808SJens Wiklander return ret; 444*32b31808SJens Wiklander } 4453d3b0591SJens Wiklander 4463d3b0591SJens Wiklander ret = ctx->pk_info->verify_rs_func(ctx->pk_ctx, 4473d3b0591SJens Wiklander md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx); 4483d3b0591SJens Wiklander 449*32b31808SJens Wiklander if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) { 4503d3b0591SJens Wiklander mbedtls_pk_restart_free(rs_ctx); 451*32b31808SJens Wiklander } 4523d3b0591SJens Wiklander 453*32b31808SJens Wiklander return ret; 4543d3b0591SJens Wiklander } 4553d3b0591SJens Wiklander #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 4563d3b0591SJens Wiklander (void) rs_ctx; 4573d3b0591SJens Wiklander #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 4583d3b0591SJens Wiklander 459*32b31808SJens Wiklander if (ctx->pk_info->verify_func == NULL) { 460*32b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 461*32b31808SJens Wiklander } 4623d3b0591SJens Wiklander 463*32b31808SJens Wiklander return ctx->pk_info->verify_func(ctx->pk_ctx, md_alg, hash, hash_len, 464*32b31808SJens Wiklander sig, sig_len); 4653d3b0591SJens Wiklander } 4663d3b0591SJens Wiklander 467817466cbSJens Wiklander /* 468817466cbSJens Wiklander * Verify a signature 469817466cbSJens Wiklander */ 470817466cbSJens Wiklander int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, 471817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 472817466cbSJens Wiklander const unsigned char *sig, size_t sig_len) 473817466cbSJens Wiklander { 474*32b31808SJens Wiklander return mbedtls_pk_verify_restartable(ctx, md_alg, hash, hash_len, 475*32b31808SJens Wiklander sig, sig_len, NULL); 476817466cbSJens Wiklander } 477817466cbSJens Wiklander 478817466cbSJens Wiklander /* 479817466cbSJens Wiklander * Verify a signature with options 480817466cbSJens Wiklander */ 481817466cbSJens Wiklander int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options, 482817466cbSJens Wiklander mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, 483817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 484817466cbSJens Wiklander const unsigned char *sig, size_t sig_len) 485817466cbSJens Wiklander { 486*32b31808SJens Wiklander if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { 487*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 488*32b31808SJens Wiklander } 4893d3b0591SJens Wiklander 490*32b31808SJens Wiklander if (ctx->pk_info == NULL) { 491*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 492*32b31808SJens Wiklander } 493817466cbSJens Wiklander 494*32b31808SJens Wiklander if (!mbedtls_pk_can_do(ctx, type)) { 495*32b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 496*32b31808SJens Wiklander } 497817466cbSJens Wiklander 498*32b31808SJens Wiklander if (type != MBEDTLS_PK_RSASSA_PSS) { 499*32b31808SJens Wiklander /* General case: no options */ 500*32b31808SJens Wiklander if (options != NULL) { 501*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 502*32b31808SJens Wiklander } 503*32b31808SJens Wiklander 504*32b31808SJens Wiklander return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len); 505*32b31808SJens Wiklander } 506*32b31808SJens Wiklander 507817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) 50811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 509817466cbSJens Wiklander const mbedtls_pk_rsassa_pss_options *pss_opts; 510817466cbSJens Wiklander 511*32b31808SJens Wiklander if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) { 512*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 513*32b31808SJens Wiklander } 514817466cbSJens Wiklander 515*32b31808SJens Wiklander if (options == NULL) { 516*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 517*32b31808SJens Wiklander } 518817466cbSJens Wiklander 519817466cbSJens Wiklander pss_opts = (const mbedtls_pk_rsassa_pss_options *) options; 520817466cbSJens Wiklander 521*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 522*32b31808SJens Wiklander if (pss_opts->mgf1_hash_id == md_alg) { 523*32b31808SJens Wiklander unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES]; 524*32b31808SJens Wiklander unsigned char *p; 525*32b31808SJens Wiklander int key_len; 526*32b31808SJens Wiklander size_t signature_length; 527*32b31808SJens Wiklander psa_status_t status = PSA_ERROR_DATA_CORRUPT; 528*32b31808SJens Wiklander psa_status_t destruction_status = PSA_ERROR_DATA_CORRUPT; 529*32b31808SJens Wiklander 530*32b31808SJens Wiklander psa_algorithm_t psa_md_alg = mbedtls_hash_info_psa_from_md(md_alg); 531*32b31808SJens Wiklander mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; 532*32b31808SJens Wiklander psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 533*32b31808SJens Wiklander psa_algorithm_t psa_sig_alg = PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg); 534*32b31808SJens Wiklander p = buf + sizeof(buf); 535*32b31808SJens Wiklander key_len = mbedtls_pk_write_pubkey(&p, buf, ctx); 536*32b31808SJens Wiklander 537*32b31808SJens Wiklander if (key_len < 0) { 538*32b31808SJens Wiklander return key_len; 539*32b31808SJens Wiklander } 540*32b31808SJens Wiklander 541*32b31808SJens Wiklander psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY); 542*32b31808SJens Wiklander psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); 543*32b31808SJens Wiklander psa_set_key_algorithm(&attributes, psa_sig_alg); 544*32b31808SJens Wiklander 545*32b31808SJens Wiklander status = psa_import_key(&attributes, 546*32b31808SJens Wiklander buf + sizeof(buf) - key_len, key_len, 547*32b31808SJens Wiklander &key_id); 548*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 549*32b31808SJens Wiklander psa_destroy_key(key_id); 550*32b31808SJens Wiklander return PSA_PK_TO_MBEDTLS_ERR(status); 551*32b31808SJens Wiklander } 552*32b31808SJens Wiklander 553*32b31808SJens Wiklander /* This function requires returning MBEDTLS_ERR_PK_SIG_LEN_MISMATCH 554*32b31808SJens Wiklander * on a valid signature with trailing data in a buffer, but 555*32b31808SJens Wiklander * mbedtls_psa_rsa_verify_hash requires the sig_len to be exact, 556*32b31808SJens Wiklander * so for this reason the passed sig_len is overwritten. Smaller 557*32b31808SJens Wiklander * signature lengths should not be accepted for verification. */ 558*32b31808SJens Wiklander signature_length = sig_len > mbedtls_pk_get_len(ctx) ? 559*32b31808SJens Wiklander mbedtls_pk_get_len(ctx) : sig_len; 560*32b31808SJens Wiklander status = psa_verify_hash(key_id, psa_sig_alg, hash, 561*32b31808SJens Wiklander hash_len, sig, signature_length); 562*32b31808SJens Wiklander destruction_status = psa_destroy_key(key_id); 563*32b31808SJens Wiklander 564*32b31808SJens Wiklander if (status == PSA_SUCCESS && sig_len > mbedtls_pk_get_len(ctx)) { 565*32b31808SJens Wiklander return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; 566*32b31808SJens Wiklander } 567*32b31808SJens Wiklander 568*32b31808SJens Wiklander if (status == PSA_SUCCESS) { 569*32b31808SJens Wiklander status = destruction_status; 570*32b31808SJens Wiklander } 571*32b31808SJens Wiklander 572*32b31808SJens Wiklander return PSA_PK_RSA_TO_MBEDTLS_ERR(status); 573*32b31808SJens Wiklander } else 574*32b31808SJens Wiklander #endif 575*32b31808SJens Wiklander { 576*32b31808SJens Wiklander if (sig_len < mbedtls_pk_get_len(ctx)) { 577*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_VERIFY_FAILED; 578*32b31808SJens Wiklander } 579817466cbSJens Wiklander 580817466cbSJens Wiklander ret = mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_pk_rsa(*ctx), 581817466cbSJens Wiklander md_alg, (unsigned int) hash_len, hash, 582817466cbSJens Wiklander pss_opts->mgf1_hash_id, 583817466cbSJens Wiklander pss_opts->expected_salt_len, 584817466cbSJens Wiklander sig); 585*32b31808SJens Wiklander if (ret != 0) { 586*32b31808SJens Wiklander return ret; 587817466cbSJens Wiklander } 588817466cbSJens Wiklander 589*32b31808SJens Wiklander if (sig_len > mbedtls_pk_get_len(ctx)) { 590*32b31808SJens Wiklander return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; 591*32b31808SJens Wiklander } 592817466cbSJens Wiklander 593*32b31808SJens Wiklander return 0; 594*32b31808SJens Wiklander } 595*32b31808SJens Wiklander #else 596*32b31808SJens Wiklander return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 597*32b31808SJens Wiklander #endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ 598817466cbSJens Wiklander } 599817466cbSJens Wiklander 600817466cbSJens Wiklander /* 6013d3b0591SJens Wiklander * Make a signature (restartable) 6023d3b0591SJens Wiklander */ 6033d3b0591SJens Wiklander int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx, 6043d3b0591SJens Wiklander mbedtls_md_type_t md_alg, 6053d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 606*32b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 6073d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 6083d3b0591SJens Wiklander mbedtls_pk_restart_ctx *rs_ctx) 6093d3b0591SJens Wiklander { 610*32b31808SJens Wiklander if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { 611*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 612*32b31808SJens Wiklander } 6133d3b0591SJens Wiklander 614*32b31808SJens Wiklander if (ctx->pk_info == NULL || pk_hashlen_helper(md_alg, &hash_len) != 0) { 615*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 616*32b31808SJens Wiklander } 6173d3b0591SJens Wiklander 6183d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 6193d3b0591SJens Wiklander /* optimization: use non-restartable version if restart disabled */ 6203d3b0591SJens Wiklander if (rs_ctx != NULL && 6213d3b0591SJens Wiklander mbedtls_ecp_restart_is_enabled() && 622*32b31808SJens Wiklander ctx->pk_info->sign_rs_func != NULL) { 62311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 6243d3b0591SJens Wiklander 625*32b31808SJens Wiklander if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) { 626*32b31808SJens Wiklander return ret; 627*32b31808SJens Wiklander } 6283d3b0591SJens Wiklander 6293d3b0591SJens Wiklander ret = ctx->pk_info->sign_rs_func(ctx->pk_ctx, md_alg, 630*32b31808SJens Wiklander hash, hash_len, 631*32b31808SJens Wiklander sig, sig_size, sig_len, 632*32b31808SJens Wiklander f_rng, p_rng, rs_ctx->rs_ctx); 6333d3b0591SJens Wiklander 634*32b31808SJens Wiklander if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) { 6353d3b0591SJens Wiklander mbedtls_pk_restart_free(rs_ctx); 636*32b31808SJens Wiklander } 6373d3b0591SJens Wiklander 638*32b31808SJens Wiklander return ret; 6393d3b0591SJens Wiklander } 6403d3b0591SJens Wiklander #else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 6413d3b0591SJens Wiklander (void) rs_ctx; 6423d3b0591SJens Wiklander #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 6433d3b0591SJens Wiklander 644*32b31808SJens Wiklander if (ctx->pk_info->sign_func == NULL) { 645*32b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 646*32b31808SJens Wiklander } 6473d3b0591SJens Wiklander 648*32b31808SJens Wiklander return ctx->pk_info->sign_func(ctx->pk_ctx, md_alg, 649*32b31808SJens Wiklander hash, hash_len, 650*32b31808SJens Wiklander sig, sig_size, sig_len, 651*32b31808SJens Wiklander f_rng, p_rng); 6523d3b0591SJens Wiklander } 6533d3b0591SJens Wiklander 6543d3b0591SJens Wiklander /* 655817466cbSJens Wiklander * Make a signature 656817466cbSJens Wiklander */ 657817466cbSJens Wiklander int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, 658817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 659*32b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 660817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 661817466cbSJens Wiklander { 662*32b31808SJens Wiklander return mbedtls_pk_sign_restartable(ctx, md_alg, hash, hash_len, 663*32b31808SJens Wiklander sig, sig_size, sig_len, 664*32b31808SJens Wiklander f_rng, p_rng, NULL); 665817466cbSJens Wiklander } 666817466cbSJens Wiklander 667*32b31808SJens Wiklander #if defined(MBEDTLS_PSA_CRYPTO_C) 668*32b31808SJens Wiklander /* 669*32b31808SJens Wiklander * Make a signature given a signature type. 670*32b31808SJens Wiklander */ 671*32b31808SJens Wiklander int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, 672*32b31808SJens Wiklander mbedtls_pk_context *ctx, 673*32b31808SJens Wiklander mbedtls_md_type_t md_alg, 674*32b31808SJens Wiklander const unsigned char *hash, size_t hash_len, 675*32b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 676*32b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 677*32b31808SJens Wiklander void *p_rng) 678*32b31808SJens Wiklander { 679*32b31808SJens Wiklander #if defined(MBEDTLS_RSA_C) 680*32b31808SJens Wiklander psa_algorithm_t psa_md_alg; 681*32b31808SJens Wiklander #endif /* MBEDTLS_RSA_C */ 682*32b31808SJens Wiklander *sig_len = 0; 683*32b31808SJens Wiklander 684*32b31808SJens Wiklander if (ctx->pk_info == NULL) { 685*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 686*32b31808SJens Wiklander } 687*32b31808SJens Wiklander 688*32b31808SJens Wiklander if (!mbedtls_pk_can_do(ctx, pk_type)) { 689*32b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 690*32b31808SJens Wiklander } 691*32b31808SJens Wiklander 692*32b31808SJens Wiklander if (pk_type != MBEDTLS_PK_RSASSA_PSS) { 693*32b31808SJens Wiklander return mbedtls_pk_sign(ctx, md_alg, hash, hash_len, 694*32b31808SJens Wiklander sig, sig_size, sig_len, f_rng, p_rng); 695*32b31808SJens Wiklander } 696*32b31808SJens Wiklander 697*32b31808SJens Wiklander #if defined(MBEDTLS_RSA_C) 698*32b31808SJens Wiklander psa_md_alg = mbedtls_hash_info_psa_from_md(md_alg); 699*32b31808SJens Wiklander if (psa_md_alg == 0) { 700*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 701*32b31808SJens Wiklander } 702*32b31808SJens Wiklander 703*32b31808SJens Wiklander if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) { 704*32b31808SJens Wiklander const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx; 705*32b31808SJens Wiklander psa_status_t status; 706*32b31808SJens Wiklander 707*32b31808SJens Wiklander status = psa_sign_hash(*key, PSA_ALG_RSA_PSS(psa_md_alg), 708*32b31808SJens Wiklander hash, hash_len, 709*32b31808SJens Wiklander sig, sig_size, sig_len); 710*32b31808SJens Wiklander return PSA_PK_RSA_TO_MBEDTLS_ERR(status); 711*32b31808SJens Wiklander } 712*32b31808SJens Wiklander 713*32b31808SJens Wiklander return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PSS(psa_md_alg), 714*32b31808SJens Wiklander ctx->pk_ctx, hash, hash_len, 715*32b31808SJens Wiklander sig, sig_size, sig_len); 716*32b31808SJens Wiklander #else /* MBEDTLS_RSA_C */ 717*32b31808SJens Wiklander return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 718*32b31808SJens Wiklander #endif /* !MBEDTLS_RSA_C */ 719*32b31808SJens Wiklander 720*32b31808SJens Wiklander } 721*32b31808SJens Wiklander #endif /* MBEDTLS_PSA_CRYPTO_C */ 722*32b31808SJens Wiklander 723817466cbSJens Wiklander /* 724817466cbSJens Wiklander * Decrypt message 725817466cbSJens Wiklander */ 726817466cbSJens Wiklander int mbedtls_pk_decrypt(mbedtls_pk_context *ctx, 727817466cbSJens Wiklander const unsigned char *input, size_t ilen, 728817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 729817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 730817466cbSJens Wiklander { 731*32b31808SJens Wiklander if (ctx->pk_info == NULL) { 732*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 733*32b31808SJens Wiklander } 7343d3b0591SJens Wiklander 735*32b31808SJens Wiklander if (ctx->pk_info->decrypt_func == NULL) { 736*32b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 737*32b31808SJens Wiklander } 738817466cbSJens Wiklander 739*32b31808SJens Wiklander return ctx->pk_info->decrypt_func(ctx->pk_ctx, input, ilen, 740*32b31808SJens Wiklander output, olen, osize, f_rng, p_rng); 741817466cbSJens Wiklander } 742817466cbSJens Wiklander 743817466cbSJens Wiklander /* 744817466cbSJens Wiklander * Encrypt message 745817466cbSJens Wiklander */ 746817466cbSJens Wiklander int mbedtls_pk_encrypt(mbedtls_pk_context *ctx, 747817466cbSJens Wiklander const unsigned char *input, size_t ilen, 748817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 749817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 750817466cbSJens Wiklander { 751*32b31808SJens Wiklander if (ctx->pk_info == NULL) { 752*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 753*32b31808SJens Wiklander } 7543d3b0591SJens Wiklander 755*32b31808SJens Wiklander if (ctx->pk_info->encrypt_func == NULL) { 756*32b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 757*32b31808SJens Wiklander } 758817466cbSJens Wiklander 759*32b31808SJens Wiklander return ctx->pk_info->encrypt_func(ctx->pk_ctx, input, ilen, 760*32b31808SJens Wiklander output, olen, osize, f_rng, p_rng); 761817466cbSJens Wiklander } 762817466cbSJens Wiklander 763817466cbSJens Wiklander /* 764817466cbSJens Wiklander * Check public-private key pair 765817466cbSJens Wiklander */ 766*32b31808SJens Wiklander int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, 767*32b31808SJens Wiklander const mbedtls_pk_context *prv, 768*32b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 769*32b31808SJens Wiklander void *p_rng) 770817466cbSJens Wiklander { 7713d3b0591SJens Wiklander if (pub->pk_info == NULL || 772*32b31808SJens Wiklander prv->pk_info == NULL) { 773*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 774817466cbSJens Wiklander } 775817466cbSJens Wiklander 776*32b31808SJens Wiklander if (f_rng == NULL) { 777*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 778817466cbSJens Wiklander } 779817466cbSJens Wiklander 780*32b31808SJens Wiklander if (prv->pk_info->check_pair_func == NULL) { 781*32b31808SJens Wiklander return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 782*32b31808SJens Wiklander } 783*32b31808SJens Wiklander 784*32b31808SJens Wiklander if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) { 785*32b31808SJens Wiklander if (pub->pk_info->type != MBEDTLS_PK_RSA) { 786*32b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 787*32b31808SJens Wiklander } 788*32b31808SJens Wiklander } else { 789*32b31808SJens Wiklander if (pub->pk_info != prv->pk_info) { 790*32b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 791*32b31808SJens Wiklander } 792*32b31808SJens Wiklander } 793*32b31808SJens Wiklander 794*32b31808SJens Wiklander return prv->pk_info->check_pair_func(pub->pk_ctx, prv->pk_ctx, f_rng, p_rng); 795817466cbSJens Wiklander } 796817466cbSJens Wiklander 797817466cbSJens Wiklander /* 798817466cbSJens Wiklander * Get key size in bits 799817466cbSJens Wiklander */ 800817466cbSJens Wiklander size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx) 801817466cbSJens Wiklander { 8023d3b0591SJens Wiklander /* For backward compatibility, accept NULL or a context that 8033d3b0591SJens Wiklander * isn't set up yet, and return a fake value that should be safe. */ 804*32b31808SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL) { 805*32b31808SJens Wiklander return 0; 806*32b31808SJens Wiklander } 807817466cbSJens Wiklander 808*32b31808SJens Wiklander return ctx->pk_info->get_bitlen(ctx->pk_ctx); 809817466cbSJens Wiklander } 810817466cbSJens Wiklander 811817466cbSJens Wiklander /* 812817466cbSJens Wiklander * Export debug information 813817466cbSJens Wiklander */ 814817466cbSJens Wiklander int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items) 815817466cbSJens Wiklander { 816*32b31808SJens Wiklander if (ctx->pk_info == NULL) { 817*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 818*32b31808SJens Wiklander } 819817466cbSJens Wiklander 820*32b31808SJens Wiklander if (ctx->pk_info->debug_func == NULL) { 821*32b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 822*32b31808SJens Wiklander } 823817466cbSJens Wiklander 824817466cbSJens Wiklander ctx->pk_info->debug_func(ctx->pk_ctx, items); 825*32b31808SJens Wiklander return 0; 826817466cbSJens Wiklander } 827817466cbSJens Wiklander 828817466cbSJens Wiklander /* 829817466cbSJens Wiklander * Access the PK type name 830817466cbSJens Wiklander */ 831817466cbSJens Wiklander const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx) 832817466cbSJens Wiklander { 833*32b31808SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL) { 834*32b31808SJens Wiklander return "invalid PK"; 835*32b31808SJens Wiklander } 836817466cbSJens Wiklander 837*32b31808SJens Wiklander return ctx->pk_info->name; 838817466cbSJens Wiklander } 839817466cbSJens Wiklander 840817466cbSJens Wiklander /* 841817466cbSJens Wiklander * Access the PK type 842817466cbSJens Wiklander */ 843817466cbSJens Wiklander mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) 844817466cbSJens Wiklander { 845*32b31808SJens Wiklander if (ctx == NULL || ctx->pk_info == NULL) { 846*32b31808SJens Wiklander return MBEDTLS_PK_NONE; 847*32b31808SJens Wiklander } 848817466cbSJens Wiklander 849*32b31808SJens Wiklander return ctx->pk_info->type; 850817466cbSJens Wiklander } 851817466cbSJens Wiklander 85211fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 85311fa71b9SJerome Forissier /* 85411fa71b9SJerome Forissier * Load the key to a PSA key slot, 85511fa71b9SJerome Forissier * then turn the PK context into a wrapper for that key slot. 85611fa71b9SJerome Forissier * 857*32b31808SJens Wiklander * Currently only works for EC & RSA private keys. 85811fa71b9SJerome Forissier */ 85911fa71b9SJerome Forissier int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk, 860*32b31808SJens Wiklander mbedtls_svc_key_id_t *key, 861*32b31808SJens Wiklander psa_algorithm_t alg, 862*32b31808SJens Wiklander psa_key_usage_t usage, 863*32b31808SJens Wiklander psa_algorithm_t alg2) 86411fa71b9SJerome Forissier { 865*32b31808SJens Wiklander #if !defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_RSA_C) 8667901324dSJerome Forissier ((void) pk); 8677901324dSJerome Forissier ((void) key); 868*32b31808SJens Wiklander ((void) alg); 869*32b31808SJens Wiklander ((void) usage); 870*32b31808SJens Wiklander ((void) alg2); 87111fa71b9SJerome Forissier #else 872*32b31808SJens Wiklander #if defined(MBEDTLS_ECP_C) 873*32b31808SJens Wiklander if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY) { 87411fa71b9SJerome Forissier const mbedtls_ecp_keypair *ec; 87511fa71b9SJerome Forissier unsigned char d[MBEDTLS_ECP_MAX_BYTES]; 87611fa71b9SJerome Forissier size_t d_len; 8777901324dSJerome Forissier psa_ecc_family_t curve_id; 87811fa71b9SJerome Forissier psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 87911fa71b9SJerome Forissier psa_key_type_t key_type; 88011fa71b9SJerome Forissier size_t bits; 88111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 882*32b31808SJens Wiklander psa_status_t status; 88311fa71b9SJerome Forissier 88411fa71b9SJerome Forissier /* export the private key material in the format PSA wants */ 88511fa71b9SJerome Forissier ec = mbedtls_pk_ec(*pk); 886*32b31808SJens Wiklander d_len = PSA_BITS_TO_BYTES(ec->grp.nbits); 887*32b31808SJens Wiklander if ((ret = mbedtls_mpi_write_binary(&ec->d, d, d_len)) != 0) { 888*32b31808SJens Wiklander return ret; 889*32b31808SJens Wiklander } 89011fa71b9SJerome Forissier 89111fa71b9SJerome Forissier curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits); 89211fa71b9SJerome Forissier key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id); 89311fa71b9SJerome Forissier 89411fa71b9SJerome Forissier /* prepare the key attributes */ 89511fa71b9SJerome Forissier psa_set_key_type(&attributes, key_type); 89611fa71b9SJerome Forissier psa_set_key_bits(&attributes, bits); 897*32b31808SJens Wiklander psa_set_key_usage_flags(&attributes, usage); 898*32b31808SJens Wiklander psa_set_key_algorithm(&attributes, alg); 899*32b31808SJens Wiklander if (alg2 != PSA_ALG_NONE) { 900*32b31808SJens Wiklander psa_set_key_enrollment_algorithm(&attributes, alg2); 901*32b31808SJens Wiklander } 90211fa71b9SJerome Forissier 90311fa71b9SJerome Forissier /* import private key into PSA */ 904*32b31808SJens Wiklander status = psa_import_key(&attributes, d, d_len, key); 905*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 906*32b31808SJens Wiklander return PSA_PK_TO_MBEDTLS_ERR(status); 907*32b31808SJens Wiklander } 90811fa71b9SJerome Forissier 90911fa71b9SJerome Forissier /* make PK context wrap the key slot */ 91011fa71b9SJerome Forissier mbedtls_pk_free(pk); 91111fa71b9SJerome Forissier mbedtls_pk_init(pk); 91211fa71b9SJerome Forissier 913*32b31808SJens Wiklander return mbedtls_pk_setup_opaque(pk, *key); 914*32b31808SJens Wiklander } else 91511fa71b9SJerome Forissier #endif /* MBEDTLS_ECP_C */ 916*32b31808SJens Wiklander #if defined(MBEDTLS_RSA_C) 917*32b31808SJens Wiklander if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA) { 918*32b31808SJens Wiklander unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES]; 919*32b31808SJens Wiklander psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 920*32b31808SJens Wiklander int key_len; 921*32b31808SJens Wiklander psa_status_t status; 922*32b31808SJens Wiklander 923*32b31808SJens Wiklander /* export the private key material in the format PSA wants */ 924*32b31808SJens Wiklander key_len = mbedtls_pk_write_key_der(pk, buf, sizeof(buf)); 925*32b31808SJens Wiklander if (key_len <= 0) { 926*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 927*32b31808SJens Wiklander } 928*32b31808SJens Wiklander 929*32b31808SJens Wiklander /* prepare the key attributes */ 930*32b31808SJens Wiklander psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); 931*32b31808SJens Wiklander psa_set_key_bits(&attributes, mbedtls_pk_get_bitlen(pk)); 932*32b31808SJens Wiklander psa_set_key_usage_flags(&attributes, usage); 933*32b31808SJens Wiklander psa_set_key_algorithm(&attributes, alg); 934*32b31808SJens Wiklander if (alg2 != PSA_ALG_NONE) { 935*32b31808SJens Wiklander psa_set_key_enrollment_algorithm(&attributes, alg2); 936*32b31808SJens Wiklander } 937*32b31808SJens Wiklander 938*32b31808SJens Wiklander /* import private key into PSA */ 939*32b31808SJens Wiklander status = psa_import_key(&attributes, 940*32b31808SJens Wiklander buf + sizeof(buf) - key_len, 941*32b31808SJens Wiklander key_len, key); 942*32b31808SJens Wiklander 943*32b31808SJens Wiklander mbedtls_platform_zeroize(buf, sizeof(buf)); 944*32b31808SJens Wiklander 945*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 946*32b31808SJens Wiklander return PSA_PK_TO_MBEDTLS_ERR(status); 947*32b31808SJens Wiklander } 948*32b31808SJens Wiklander 949*32b31808SJens Wiklander /* make PK context wrap the key slot */ 950*32b31808SJens Wiklander mbedtls_pk_free(pk); 951*32b31808SJens Wiklander mbedtls_pk_init(pk); 952*32b31808SJens Wiklander 953*32b31808SJens Wiklander return mbedtls_pk_setup_opaque(pk, *key); 954*32b31808SJens Wiklander } else 955*32b31808SJens Wiklander #endif /* MBEDTLS_RSA_C */ 956*32b31808SJens Wiklander #endif /* !MBEDTLS_ECP_C && !MBEDTLS_RSA_C */ 957*32b31808SJens Wiklander return MBEDTLS_ERR_PK_TYPE_MISMATCH; 95811fa71b9SJerome Forissier } 95911fa71b9SJerome Forissier #endif /* MBEDTLS_USE_PSA_CRYPTO */ 960817466cbSJens Wiklander #endif /* MBEDTLS_PK_C */ 961