1817466cbSJens Wiklander /* 2817466cbSJens Wiklander * Public Key abstraction layer: wrapper functions 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 22*32b31808SJens Wiklander #include "mbedtls/platform_util.h" 23*32b31808SJens Wiklander 24817466cbSJens Wiklander #if defined(MBEDTLS_PK_C) 25*32b31808SJens Wiklander #include "pk_wrap.h" 2611fa71b9SJerome Forissier #include "mbedtls/error.h" 27817466cbSJens Wiklander 28817466cbSJens Wiklander /* Even if RSA not activated, for the sake of RSA-alt */ 29817466cbSJens Wiklander #include "mbedtls/rsa.h" 30817466cbSJens Wiklander 31817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C) 32817466cbSJens Wiklander #include "mbedtls/ecp.h" 33817466cbSJens Wiklander #endif 34817466cbSJens Wiklander 35817466cbSJens Wiklander #if defined(MBEDTLS_ECDSA_C) 36817466cbSJens Wiklander #include "mbedtls/ecdsa.h" 37817466cbSJens Wiklander #endif 38817466cbSJens Wiklander 39*32b31808SJens Wiklander #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PSA_CRYPTO_C) 40*32b31808SJens Wiklander #include "pkwrite.h" 4111fa71b9SJerome Forissier #endif 4211fa71b9SJerome Forissier 43*32b31808SJens Wiklander #if defined(MBEDTLS_PSA_CRYPTO_C) 44*32b31808SJens Wiklander #include "mbedtls/psa_util.h" 45*32b31808SJens Wiklander #define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status) 46*32b31808SJens Wiklander #define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ 47*32b31808SJens Wiklander psa_to_pk_rsa_errors, \ 48*32b31808SJens Wiklander psa_pk_status_to_mbedtls) 49*32b31808SJens Wiklander #define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ 50*32b31808SJens Wiklander psa_to_pk_ecdsa_errors, \ 51*32b31808SJens Wiklander psa_pk_status_to_mbedtls) 523d3b0591SJens Wiklander #endif 533d3b0591SJens Wiklander 5411fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 5511fa71b9SJerome Forissier #include "psa/crypto.h" 56*32b31808SJens Wiklander #include "hash_info.h" 57*32b31808SJens Wiklander 58*32b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SOME) 59*32b31808SJens Wiklander #include "mbedtls/asn1write.h" 6011fa71b9SJerome Forissier #include "mbedtls/asn1.h" 6111fa71b9SJerome Forissier #endif 62*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 6311fa71b9SJerome Forissier 64817466cbSJens Wiklander #include "mbedtls/platform.h" 65817466cbSJens Wiklander 66817466cbSJens Wiklander #include <limits.h> 673d3b0591SJens Wiklander #include <stdint.h> 68*32b31808SJens Wiklander #include <string.h> 69*32b31808SJens Wiklander 70*32b31808SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 71*32b31808SJens Wiklander #if defined(MBEDTLS_PSA_CRYPTO_C) 72*32b31808SJens Wiklander int mbedtls_pk_error_from_psa(psa_status_t status) 73*32b31808SJens Wiklander { 74*32b31808SJens Wiklander switch (status) { 75*32b31808SJens Wiklander case PSA_SUCCESS: 76*32b31808SJens Wiklander return 0; 77*32b31808SJens Wiklander case PSA_ERROR_INVALID_HANDLE: 78*32b31808SJens Wiklander return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; 79*32b31808SJens Wiklander case PSA_ERROR_NOT_PERMITTED: 80*32b31808SJens Wiklander return MBEDTLS_ERR_ERROR_GENERIC_ERROR; 81*32b31808SJens Wiklander case PSA_ERROR_BUFFER_TOO_SMALL: 82*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; 83*32b31808SJens Wiklander case PSA_ERROR_NOT_SUPPORTED: 84*32b31808SJens Wiklander return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 85*32b31808SJens Wiklander case PSA_ERROR_INVALID_ARGUMENT: 86*32b31808SJens Wiklander return MBEDTLS_ERR_PK_INVALID_ALG; 87*32b31808SJens Wiklander case PSA_ERROR_INSUFFICIENT_MEMORY: 88*32b31808SJens Wiklander return MBEDTLS_ERR_PK_ALLOC_FAILED; 89*32b31808SJens Wiklander case PSA_ERROR_BAD_STATE: 90*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 91*32b31808SJens Wiklander case PSA_ERROR_COMMUNICATION_FAILURE: 92*32b31808SJens Wiklander case PSA_ERROR_HARDWARE_FAILURE: 93*32b31808SJens Wiklander return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; 94*32b31808SJens Wiklander case PSA_ERROR_DATA_CORRUPT: 95*32b31808SJens Wiklander case PSA_ERROR_DATA_INVALID: 96*32b31808SJens Wiklander case PSA_ERROR_STORAGE_FAILURE: 97*32b31808SJens Wiklander return MBEDTLS_ERR_PK_FILE_IO_ERROR; 98*32b31808SJens Wiklander case PSA_ERROR_CORRUPTION_DETECTED: 99*32b31808SJens Wiklander return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 100*32b31808SJens Wiklander default: 101*32b31808SJens Wiklander return MBEDTLS_ERR_ERROR_GENERIC_ERROR; 102*32b31808SJens Wiklander } 103*32b31808SJens Wiklander } 104*32b31808SJens Wiklander 105*32b31808SJens Wiklander #if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \ 106*32b31808SJens Wiklander defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) 107*32b31808SJens Wiklander int mbedtls_pk_error_from_psa_rsa(psa_status_t status) 108*32b31808SJens Wiklander { 109*32b31808SJens Wiklander switch (status) { 110*32b31808SJens Wiklander case PSA_ERROR_NOT_PERMITTED: 111*32b31808SJens Wiklander case PSA_ERROR_INVALID_ARGUMENT: 112*32b31808SJens Wiklander case PSA_ERROR_INVALID_HANDLE: 113*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 114*32b31808SJens Wiklander case PSA_ERROR_BUFFER_TOO_SMALL: 115*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; 116*32b31808SJens Wiklander case PSA_ERROR_INSUFFICIENT_ENTROPY: 117*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_RNG_FAILED; 118*32b31808SJens Wiklander case PSA_ERROR_INVALID_SIGNATURE: 119*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_VERIFY_FAILED; 120*32b31808SJens Wiklander case PSA_ERROR_INVALID_PADDING: 121*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_INVALID_PADDING; 122*32b31808SJens Wiklander case PSA_SUCCESS: 123*32b31808SJens Wiklander return 0; 124*32b31808SJens Wiklander case PSA_ERROR_NOT_SUPPORTED: 125*32b31808SJens Wiklander return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 126*32b31808SJens Wiklander case PSA_ERROR_INSUFFICIENT_MEMORY: 127*32b31808SJens Wiklander return MBEDTLS_ERR_PK_ALLOC_FAILED; 128*32b31808SJens Wiklander case PSA_ERROR_BAD_STATE: 129*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 130*32b31808SJens Wiklander case PSA_ERROR_COMMUNICATION_FAILURE: 131*32b31808SJens Wiklander case PSA_ERROR_HARDWARE_FAILURE: 132*32b31808SJens Wiklander return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; 133*32b31808SJens Wiklander case PSA_ERROR_DATA_CORRUPT: 134*32b31808SJens Wiklander case PSA_ERROR_DATA_INVALID: 135*32b31808SJens Wiklander case PSA_ERROR_STORAGE_FAILURE: 136*32b31808SJens Wiklander return MBEDTLS_ERR_PK_FILE_IO_ERROR; 137*32b31808SJens Wiklander case PSA_ERROR_CORRUPTION_DETECTED: 138*32b31808SJens Wiklander return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 139*32b31808SJens Wiklander default: 140*32b31808SJens Wiklander return MBEDTLS_ERR_ERROR_GENERIC_ERROR; 141*32b31808SJens Wiklander } 142*32b31808SJens Wiklander } 143*32b31808SJens Wiklander #endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR */ 144*32b31808SJens Wiklander #endif /* MBEDTLS_PSA_CRYPTO_C */ 145*32b31808SJens Wiklander 146*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 147*32b31808SJens Wiklander #if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) 148*32b31808SJens Wiklander int mbedtls_pk_error_from_psa_ecdsa(psa_status_t status) 149*32b31808SJens Wiklander { 150*32b31808SJens Wiklander switch (status) { 151*32b31808SJens Wiklander case PSA_ERROR_NOT_PERMITTED: 152*32b31808SJens Wiklander case PSA_ERROR_INVALID_ARGUMENT: 153*32b31808SJens Wiklander return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 154*32b31808SJens Wiklander case PSA_ERROR_INVALID_HANDLE: 155*32b31808SJens Wiklander return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; 156*32b31808SJens Wiklander case PSA_ERROR_BUFFER_TOO_SMALL: 157*32b31808SJens Wiklander return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 158*32b31808SJens Wiklander case PSA_ERROR_INSUFFICIENT_ENTROPY: 159*32b31808SJens Wiklander return MBEDTLS_ERR_ECP_RANDOM_FAILED; 160*32b31808SJens Wiklander case PSA_ERROR_INVALID_SIGNATURE: 161*32b31808SJens Wiklander return MBEDTLS_ERR_ECP_VERIFY_FAILED; 162*32b31808SJens Wiklander case PSA_SUCCESS: 163*32b31808SJens Wiklander return 0; 164*32b31808SJens Wiklander case PSA_ERROR_NOT_SUPPORTED: 165*32b31808SJens Wiklander return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 166*32b31808SJens Wiklander case PSA_ERROR_INSUFFICIENT_MEMORY: 167*32b31808SJens Wiklander return MBEDTLS_ERR_PK_ALLOC_FAILED; 168*32b31808SJens Wiklander case PSA_ERROR_BAD_STATE: 169*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 170*32b31808SJens Wiklander case PSA_ERROR_COMMUNICATION_FAILURE: 171*32b31808SJens Wiklander case PSA_ERROR_HARDWARE_FAILURE: 172*32b31808SJens Wiklander return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; 173*32b31808SJens Wiklander case PSA_ERROR_DATA_CORRUPT: 174*32b31808SJens Wiklander case PSA_ERROR_DATA_INVALID: 175*32b31808SJens Wiklander case PSA_ERROR_STORAGE_FAILURE: 176*32b31808SJens Wiklander return MBEDTLS_ERR_PK_FILE_IO_ERROR; 177*32b31808SJens Wiklander case PSA_ERROR_CORRUPTION_DETECTED: 178*32b31808SJens Wiklander return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 179*32b31808SJens Wiklander default: 180*32b31808SJens Wiklander return MBEDTLS_ERR_ERROR_GENERIC_ERROR; 181*32b31808SJens Wiklander } 182*32b31808SJens Wiklander } 183*32b31808SJens Wiklander #endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ 184*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 185*32b31808SJens Wiklander #endif /* !MBEDTLS_DEPRECATED_REMOVED */ 186817466cbSJens Wiklander 187817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 188817466cbSJens Wiklander static int rsa_can_do(mbedtls_pk_type_t type) 189817466cbSJens Wiklander { 190*32b31808SJens Wiklander return type == MBEDTLS_PK_RSA || 191*32b31808SJens Wiklander type == MBEDTLS_PK_RSASSA_PSS; 192817466cbSJens Wiklander } 193817466cbSJens Wiklander 194817466cbSJens Wiklander static size_t rsa_get_bitlen(const void *ctx) 195817466cbSJens Wiklander { 1963d3b0591SJens Wiklander const mbedtls_rsa_context *rsa = (const mbedtls_rsa_context *) ctx; 197*32b31808SJens Wiklander return 8 * mbedtls_rsa_get_len(rsa); 198817466cbSJens Wiklander } 199817466cbSJens Wiklander 200*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 201*32b31808SJens Wiklander static int rsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg, 202*32b31808SJens Wiklander const unsigned char *hash, size_t hash_len, 203*32b31808SJens Wiklander const unsigned char *sig, size_t sig_len) 204*32b31808SJens Wiklander { 205*32b31808SJens Wiklander mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx; 206*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 207*32b31808SJens Wiklander psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 208*32b31808SJens Wiklander mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; 209*32b31808SJens Wiklander psa_status_t status; 210*32b31808SJens Wiklander mbedtls_pk_context key; 211*32b31808SJens Wiklander int key_len; 212*32b31808SJens Wiklander unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES]; 213*32b31808SJens Wiklander psa_algorithm_t psa_alg_md = 214*32b31808SJens Wiklander PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_hash_info_psa_from_md(md_alg)); 215*32b31808SJens Wiklander size_t rsa_len = mbedtls_rsa_get_len(rsa); 216*32b31808SJens Wiklander 217*32b31808SJens Wiklander if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) { 218*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 219*32b31808SJens Wiklander } 220*32b31808SJens Wiklander 221*32b31808SJens Wiklander if (sig_len < rsa_len) { 222*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_VERIFY_FAILED; 223*32b31808SJens Wiklander } 224*32b31808SJens Wiklander 225*32b31808SJens Wiklander /* mbedtls_pk_write_pubkey_der() expects a full PK context; 226*32b31808SJens Wiklander * re-construct one to make it happy */ 227*32b31808SJens Wiklander key.pk_info = &mbedtls_rsa_info; 228*32b31808SJens Wiklander key.pk_ctx = ctx; 229*32b31808SJens Wiklander key_len = mbedtls_pk_write_pubkey_der(&key, buf, sizeof(buf)); 230*32b31808SJens Wiklander if (key_len <= 0) { 231*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 232*32b31808SJens Wiklander } 233*32b31808SJens Wiklander 234*32b31808SJens Wiklander psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); 235*32b31808SJens Wiklander psa_set_key_algorithm(&attributes, psa_alg_md); 236*32b31808SJens Wiklander psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY); 237*32b31808SJens Wiklander 238*32b31808SJens Wiklander status = psa_import_key(&attributes, 239*32b31808SJens Wiklander buf + sizeof(buf) - key_len, key_len, 240*32b31808SJens Wiklander &key_id); 241*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 242*32b31808SJens Wiklander ret = PSA_PK_TO_MBEDTLS_ERR(status); 243*32b31808SJens Wiklander goto cleanup; 244*32b31808SJens Wiklander } 245*32b31808SJens Wiklander 246*32b31808SJens Wiklander status = psa_verify_hash(key_id, psa_alg_md, hash, hash_len, 247*32b31808SJens Wiklander sig, sig_len); 248*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 249*32b31808SJens Wiklander ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status); 250*32b31808SJens Wiklander goto cleanup; 251*32b31808SJens Wiklander } 252*32b31808SJens Wiklander ret = 0; 253*32b31808SJens Wiklander 254*32b31808SJens Wiklander cleanup: 255*32b31808SJens Wiklander status = psa_destroy_key(key_id); 256*32b31808SJens Wiklander if (ret == 0 && status != PSA_SUCCESS) { 257*32b31808SJens Wiklander ret = PSA_PK_TO_MBEDTLS_ERR(status); 258*32b31808SJens Wiklander } 259*32b31808SJens Wiklander 260*32b31808SJens Wiklander return ret; 261*32b31808SJens Wiklander } 262*32b31808SJens Wiklander #else 263817466cbSJens Wiklander static int rsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg, 264817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 265817466cbSJens Wiklander const unsigned char *sig, size_t sig_len) 266817466cbSJens Wiklander { 26711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2683d3b0591SJens Wiklander mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx; 2693d3b0591SJens Wiklander size_t rsa_len = mbedtls_rsa_get_len(rsa); 270817466cbSJens Wiklander 271*32b31808SJens Wiklander if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) { 272*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 273*32b31808SJens Wiklander } 274817466cbSJens Wiklander 275*32b31808SJens Wiklander if (sig_len < rsa_len) { 276*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_VERIFY_FAILED; 277*32b31808SJens Wiklander } 278817466cbSJens Wiklander 279*32b31808SJens Wiklander if ((ret = mbedtls_rsa_pkcs1_verify(rsa, md_alg, 280*32b31808SJens Wiklander (unsigned int) hash_len, 281*32b31808SJens Wiklander hash, sig)) != 0) { 282*32b31808SJens Wiklander return ret; 283*32b31808SJens Wiklander } 284817466cbSJens Wiklander 2853d3b0591SJens Wiklander /* The buffer contains a valid signature followed by extra data. 2863d3b0591SJens Wiklander * We have a special error code for that so that so that callers can 2873d3b0591SJens Wiklander * use mbedtls_pk_verify() to check "Does the buffer start with a 2883d3b0591SJens Wiklander * valid signature?" and not just "Does the buffer contain a valid 2893d3b0591SJens Wiklander * signature?". */ 290*32b31808SJens Wiklander if (sig_len > rsa_len) { 291*32b31808SJens Wiklander return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; 292817466cbSJens Wiklander } 293817466cbSJens Wiklander 294*32b31808SJens Wiklander return 0; 295*32b31808SJens Wiklander } 296*32b31808SJens Wiklander #endif 297*32b31808SJens Wiklander 298*32b31808SJens Wiklander #if defined(MBEDTLS_PSA_CRYPTO_C) 299*32b31808SJens Wiklander int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg, 300*32b31808SJens Wiklander mbedtls_rsa_context *rsa_ctx, 301*32b31808SJens Wiklander const unsigned char *hash, size_t hash_len, 302*32b31808SJens Wiklander unsigned char *sig, size_t sig_size, 303*32b31808SJens Wiklander size_t *sig_len) 304*32b31808SJens Wiklander { 305*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 306*32b31808SJens Wiklander psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 307*32b31808SJens Wiklander mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; 308*32b31808SJens Wiklander psa_status_t status; 309*32b31808SJens Wiklander mbedtls_pk_context key; 310*32b31808SJens Wiklander int key_len; 311*32b31808SJens Wiklander unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES]; 312*32b31808SJens Wiklander mbedtls_pk_info_t pk_info = mbedtls_rsa_info; 313*32b31808SJens Wiklander 314*32b31808SJens Wiklander *sig_len = mbedtls_rsa_get_len(rsa_ctx); 315*32b31808SJens Wiklander if (sig_size < *sig_len) { 316*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; 317*32b31808SJens Wiklander } 318*32b31808SJens Wiklander 319*32b31808SJens Wiklander /* mbedtls_pk_write_key_der() expects a full PK context; 320*32b31808SJens Wiklander * re-construct one to make it happy */ 321*32b31808SJens Wiklander key.pk_info = &pk_info; 322*32b31808SJens Wiklander key.pk_ctx = rsa_ctx; 323*32b31808SJens Wiklander key_len = mbedtls_pk_write_key_der(&key, buf, sizeof(buf)); 324*32b31808SJens Wiklander if (key_len <= 0) { 325*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 326*32b31808SJens Wiklander } 327*32b31808SJens Wiklander psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); 328*32b31808SJens Wiklander psa_set_key_algorithm(&attributes, alg); 329*32b31808SJens Wiklander psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); 330*32b31808SJens Wiklander 331*32b31808SJens Wiklander status = psa_import_key(&attributes, 332*32b31808SJens Wiklander buf + sizeof(buf) - key_len, key_len, 333*32b31808SJens Wiklander &key_id); 334*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 335*32b31808SJens Wiklander ret = PSA_PK_TO_MBEDTLS_ERR(status); 336*32b31808SJens Wiklander goto cleanup; 337*32b31808SJens Wiklander } 338*32b31808SJens Wiklander status = psa_sign_hash(key_id, alg, hash, hash_len, 339*32b31808SJens Wiklander sig, sig_size, sig_len); 340*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 341*32b31808SJens Wiklander ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status); 342*32b31808SJens Wiklander goto cleanup; 343*32b31808SJens Wiklander } 344*32b31808SJens Wiklander 345*32b31808SJens Wiklander ret = 0; 346*32b31808SJens Wiklander 347*32b31808SJens Wiklander cleanup: 348*32b31808SJens Wiklander status = psa_destroy_key(key_id); 349*32b31808SJens Wiklander if (ret == 0 && status != PSA_SUCCESS) { 350*32b31808SJens Wiklander ret = PSA_PK_TO_MBEDTLS_ERR(status); 351*32b31808SJens Wiklander } 352*32b31808SJens Wiklander return ret; 353*32b31808SJens Wiklander } 354*32b31808SJens Wiklander #endif /* MBEDTLS_PSA_CRYPTO_C */ 355*32b31808SJens Wiklander 356*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 357817466cbSJens Wiklander static int rsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg, 358817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 359*32b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 360*32b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 361*32b31808SJens Wiklander { 362*32b31808SJens Wiklander ((void) f_rng); 363*32b31808SJens Wiklander ((void) p_rng); 364*32b31808SJens Wiklander 365*32b31808SJens Wiklander psa_algorithm_t psa_md_alg; 366*32b31808SJens Wiklander psa_md_alg = mbedtls_hash_info_psa_from_md(md_alg); 367*32b31808SJens Wiklander if (psa_md_alg == 0) { 368*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 369*32b31808SJens Wiklander } 370*32b31808SJens Wiklander 371*32b31808SJens Wiklander return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PKCS1V15_SIGN( 372*32b31808SJens Wiklander psa_md_alg), 373*32b31808SJens Wiklander ctx, hash, hash_len, 374*32b31808SJens Wiklander sig, sig_size, sig_len); 375*32b31808SJens Wiklander } 376*32b31808SJens Wiklander #else 377*32b31808SJens Wiklander static int rsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg, 378*32b31808SJens Wiklander const unsigned char *hash, size_t hash_len, 379*32b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 380817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 381817466cbSJens Wiklander { 3823d3b0591SJens Wiklander mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx; 3833d3b0591SJens Wiklander 384*32b31808SJens Wiklander if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) { 385*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 386817466cbSJens Wiklander } 387817466cbSJens Wiklander 388*32b31808SJens Wiklander *sig_len = mbedtls_rsa_get_len(rsa); 389*32b31808SJens Wiklander if (sig_size < *sig_len) { 390*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; 391*32b31808SJens Wiklander } 392*32b31808SJens Wiklander 393*32b31808SJens Wiklander return mbedtls_rsa_pkcs1_sign(rsa, f_rng, p_rng, 394*32b31808SJens Wiklander md_alg, (unsigned int) hash_len, 395*32b31808SJens Wiklander hash, sig); 396*32b31808SJens Wiklander } 397*32b31808SJens Wiklander #endif 398*32b31808SJens Wiklander 399*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 400*32b31808SJens Wiklander static int rsa_decrypt_wrap(void *ctx, 401*32b31808SJens Wiklander const unsigned char *input, size_t ilen, 402*32b31808SJens Wiklander unsigned char *output, size_t *olen, size_t osize, 403*32b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 404*32b31808SJens Wiklander { 405*32b31808SJens Wiklander mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx; 406*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 407*32b31808SJens Wiklander psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 408*32b31808SJens Wiklander mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; 409*32b31808SJens Wiklander psa_status_t status; 410*32b31808SJens Wiklander mbedtls_pk_context key; 411*32b31808SJens Wiklander int key_len; 412*32b31808SJens Wiklander unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES]; 413*32b31808SJens Wiklander 414*32b31808SJens Wiklander ((void) f_rng); 415*32b31808SJens Wiklander ((void) p_rng); 416*32b31808SJens Wiklander 417*32b31808SJens Wiklander #if !defined(MBEDTLS_RSA_ALT) 418*32b31808SJens Wiklander if (rsa->padding != MBEDTLS_RSA_PKCS_V15) { 419*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_INVALID_PADDING; 420*32b31808SJens Wiklander } 421*32b31808SJens Wiklander #endif /* !MBEDTLS_RSA_ALT */ 422*32b31808SJens Wiklander 423*32b31808SJens Wiklander if (ilen != mbedtls_rsa_get_len(rsa)) { 424*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 425*32b31808SJens Wiklander } 426*32b31808SJens Wiklander 427*32b31808SJens Wiklander /* mbedtls_pk_write_key_der() expects a full PK context; 428*32b31808SJens Wiklander * re-construct one to make it happy */ 429*32b31808SJens Wiklander key.pk_info = &mbedtls_rsa_info; 430*32b31808SJens Wiklander key.pk_ctx = ctx; 431*32b31808SJens Wiklander key_len = mbedtls_pk_write_key_der(&key, buf, sizeof(buf)); 432*32b31808SJens Wiklander if (key_len <= 0) { 433*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 434*32b31808SJens Wiklander } 435*32b31808SJens Wiklander 436*32b31808SJens Wiklander psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); 437*32b31808SJens Wiklander psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); 438*32b31808SJens Wiklander psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT); 439*32b31808SJens Wiklander 440*32b31808SJens Wiklander status = psa_import_key(&attributes, 441*32b31808SJens Wiklander buf + sizeof(buf) - key_len, key_len, 442*32b31808SJens Wiklander &key_id); 443*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 444*32b31808SJens Wiklander ret = PSA_PK_TO_MBEDTLS_ERR(status); 445*32b31808SJens Wiklander goto cleanup; 446*32b31808SJens Wiklander } 447*32b31808SJens Wiklander 448*32b31808SJens Wiklander status = psa_asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, 449*32b31808SJens Wiklander input, ilen, 450*32b31808SJens Wiklander NULL, 0, 451*32b31808SJens Wiklander output, osize, olen); 452*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 453*32b31808SJens Wiklander ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status); 454*32b31808SJens Wiklander goto cleanup; 455*32b31808SJens Wiklander } 456*32b31808SJens Wiklander 457*32b31808SJens Wiklander ret = 0; 458*32b31808SJens Wiklander 459*32b31808SJens Wiklander cleanup: 460*32b31808SJens Wiklander mbedtls_platform_zeroize(buf, sizeof(buf)); 461*32b31808SJens Wiklander status = psa_destroy_key(key_id); 462*32b31808SJens Wiklander if (ret == 0 && status != PSA_SUCCESS) { 463*32b31808SJens Wiklander ret = PSA_PK_TO_MBEDTLS_ERR(status); 464*32b31808SJens Wiklander } 465*32b31808SJens Wiklander 466*32b31808SJens Wiklander return ret; 467*32b31808SJens Wiklander } 468*32b31808SJens Wiklander #else 469817466cbSJens Wiklander static int rsa_decrypt_wrap(void *ctx, 470817466cbSJens Wiklander const unsigned char *input, size_t ilen, 471817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 472817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 473817466cbSJens Wiklander { 4743d3b0591SJens Wiklander mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx; 4753d3b0591SJens Wiklander 476*32b31808SJens Wiklander if (ilen != mbedtls_rsa_get_len(rsa)) { 477*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 478817466cbSJens Wiklander } 479817466cbSJens Wiklander 480*32b31808SJens Wiklander return mbedtls_rsa_pkcs1_decrypt(rsa, f_rng, p_rng, 481*32b31808SJens Wiklander olen, input, output, osize); 482*32b31808SJens Wiklander } 483*32b31808SJens Wiklander #endif 484*32b31808SJens Wiklander 485*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 486*32b31808SJens Wiklander static int rsa_encrypt_wrap(void *ctx, 487*32b31808SJens Wiklander const unsigned char *input, size_t ilen, 488*32b31808SJens Wiklander unsigned char *output, size_t *olen, size_t osize, 489*32b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 490*32b31808SJens Wiklander { 491*32b31808SJens Wiklander mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx; 492*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 493*32b31808SJens Wiklander psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 494*32b31808SJens Wiklander mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; 495*32b31808SJens Wiklander psa_status_t status; 496*32b31808SJens Wiklander mbedtls_pk_context key; 497*32b31808SJens Wiklander int key_len; 498*32b31808SJens Wiklander unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES]; 499*32b31808SJens Wiklander 500*32b31808SJens Wiklander ((void) f_rng); 501*32b31808SJens Wiklander ((void) p_rng); 502*32b31808SJens Wiklander 503*32b31808SJens Wiklander #if !defined(MBEDTLS_RSA_ALT) 504*32b31808SJens Wiklander if (rsa->padding != MBEDTLS_RSA_PKCS_V15) { 505*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_INVALID_PADDING; 506*32b31808SJens Wiklander } 507*32b31808SJens Wiklander #endif 508*32b31808SJens Wiklander 509*32b31808SJens Wiklander if (mbedtls_rsa_get_len(rsa) > osize) { 510*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; 511*32b31808SJens Wiklander } 512*32b31808SJens Wiklander 513*32b31808SJens Wiklander /* mbedtls_pk_write_pubkey_der() expects a full PK context; 514*32b31808SJens Wiklander * re-construct one to make it happy */ 515*32b31808SJens Wiklander key.pk_info = &mbedtls_rsa_info; 516*32b31808SJens Wiklander key.pk_ctx = ctx; 517*32b31808SJens Wiklander key_len = mbedtls_pk_write_pubkey_der(&key, buf, sizeof(buf)); 518*32b31808SJens Wiklander if (key_len <= 0) { 519*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 520*32b31808SJens Wiklander } 521*32b31808SJens Wiklander 522*32b31808SJens Wiklander psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); 523*32b31808SJens Wiklander psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT); 524*32b31808SJens Wiklander psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY); 525*32b31808SJens Wiklander 526*32b31808SJens Wiklander status = psa_import_key(&attributes, 527*32b31808SJens Wiklander buf + sizeof(buf) - key_len, key_len, 528*32b31808SJens Wiklander &key_id); 529*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 530*32b31808SJens Wiklander ret = PSA_PK_TO_MBEDTLS_ERR(status); 531*32b31808SJens Wiklander goto cleanup; 532*32b31808SJens Wiklander } 533*32b31808SJens Wiklander 534*32b31808SJens Wiklander status = psa_asymmetric_encrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, 535*32b31808SJens Wiklander input, ilen, 536*32b31808SJens Wiklander NULL, 0, 537*32b31808SJens Wiklander output, osize, olen); 538*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 539*32b31808SJens Wiklander ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status); 540*32b31808SJens Wiklander goto cleanup; 541*32b31808SJens Wiklander } 542*32b31808SJens Wiklander 543*32b31808SJens Wiklander ret = 0; 544*32b31808SJens Wiklander 545*32b31808SJens Wiklander cleanup: 546*32b31808SJens Wiklander status = psa_destroy_key(key_id); 547*32b31808SJens Wiklander if (ret == 0 && status != PSA_SUCCESS) { 548*32b31808SJens Wiklander ret = PSA_PK_TO_MBEDTLS_ERR(status); 549*32b31808SJens Wiklander } 550*32b31808SJens Wiklander 551*32b31808SJens Wiklander return ret; 552*32b31808SJens Wiklander } 553*32b31808SJens Wiklander #else 554817466cbSJens Wiklander static int rsa_encrypt_wrap(void *ctx, 555817466cbSJens Wiklander const unsigned char *input, size_t ilen, 556817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 557817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 558817466cbSJens Wiklander { 5593d3b0591SJens Wiklander mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) ctx; 5603d3b0591SJens Wiklander *olen = mbedtls_rsa_get_len(rsa); 561817466cbSJens Wiklander 562*32b31808SJens Wiklander if (*olen > osize) { 563*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; 564817466cbSJens Wiklander } 565817466cbSJens Wiklander 566*32b31808SJens Wiklander return mbedtls_rsa_pkcs1_encrypt(rsa, f_rng, p_rng, 567*32b31808SJens Wiklander ilen, input, output); 568*32b31808SJens Wiklander } 569*32b31808SJens Wiklander #endif 570*32b31808SJens Wiklander 571*32b31808SJens Wiklander static int rsa_check_pair_wrap(const void *pub, const void *prv, 572*32b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 573*32b31808SJens Wiklander void *p_rng) 574817466cbSJens Wiklander { 575*32b31808SJens Wiklander (void) f_rng; 576*32b31808SJens Wiklander (void) p_rng; 577*32b31808SJens Wiklander return mbedtls_rsa_check_pub_priv((const mbedtls_rsa_context *) pub, 578*32b31808SJens Wiklander (const mbedtls_rsa_context *) prv); 579817466cbSJens Wiklander } 580817466cbSJens Wiklander 581817466cbSJens Wiklander static void *rsa_alloc_wrap(void) 582817466cbSJens Wiklander { 583817466cbSJens Wiklander void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_context)); 584817466cbSJens Wiklander 585*32b31808SJens Wiklander if (ctx != NULL) { 586*32b31808SJens Wiklander mbedtls_rsa_init((mbedtls_rsa_context *) ctx); 587*32b31808SJens Wiklander } 588817466cbSJens Wiklander 589*32b31808SJens Wiklander return ctx; 590817466cbSJens Wiklander } 591817466cbSJens Wiklander 592817466cbSJens Wiklander static void rsa_free_wrap(void *ctx) 593817466cbSJens Wiklander { 594817466cbSJens Wiklander mbedtls_rsa_free((mbedtls_rsa_context *) ctx); 595817466cbSJens Wiklander mbedtls_free(ctx); 596817466cbSJens Wiklander } 597817466cbSJens Wiklander 598817466cbSJens Wiklander static void rsa_debug(const void *ctx, mbedtls_pk_debug_item *items) 599817466cbSJens Wiklander { 600*32b31808SJens Wiklander #if defined(MBEDTLS_RSA_ALT) 601*32b31808SJens Wiklander /* Not supported */ 602*32b31808SJens Wiklander (void) ctx; 603*32b31808SJens Wiklander (void) items; 604*32b31808SJens Wiklander #else 605817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_MPI; 606817466cbSJens Wiklander items->name = "rsa.N"; 607817466cbSJens Wiklander items->value = &(((mbedtls_rsa_context *) ctx)->N); 608817466cbSJens Wiklander 609817466cbSJens Wiklander items++; 610817466cbSJens Wiklander 611817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_MPI; 612817466cbSJens Wiklander items->name = "rsa.E"; 613817466cbSJens Wiklander items->value = &(((mbedtls_rsa_context *) ctx)->E); 614*32b31808SJens Wiklander #endif 615817466cbSJens Wiklander } 616817466cbSJens Wiklander 617817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_info = { 618817466cbSJens Wiklander MBEDTLS_PK_RSA, 619817466cbSJens Wiklander "RSA", 620817466cbSJens Wiklander rsa_get_bitlen, 621817466cbSJens Wiklander rsa_can_do, 622817466cbSJens Wiklander rsa_verify_wrap, 623817466cbSJens Wiklander rsa_sign_wrap, 6243d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 6253d3b0591SJens Wiklander NULL, 6263d3b0591SJens Wiklander NULL, 6273d3b0591SJens Wiklander #endif 628817466cbSJens Wiklander rsa_decrypt_wrap, 629817466cbSJens Wiklander rsa_encrypt_wrap, 630817466cbSJens Wiklander rsa_check_pair_wrap, 631817466cbSJens Wiklander rsa_alloc_wrap, 632817466cbSJens Wiklander rsa_free_wrap, 6333d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 6343d3b0591SJens Wiklander NULL, 6353d3b0591SJens Wiklander NULL, 6363d3b0591SJens Wiklander #endif 637817466cbSJens Wiklander rsa_debug, 638817466cbSJens Wiklander }; 639817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */ 640817466cbSJens Wiklander 641817466cbSJens Wiklander #if defined(MBEDTLS_ECP_C) 642817466cbSJens Wiklander /* 643817466cbSJens Wiklander * Generic EC key 644817466cbSJens Wiklander */ 645817466cbSJens Wiklander static int eckey_can_do(mbedtls_pk_type_t type) 646817466cbSJens Wiklander { 647*32b31808SJens Wiklander return type == MBEDTLS_PK_ECKEY || 648817466cbSJens Wiklander type == MBEDTLS_PK_ECKEY_DH || 649*32b31808SJens Wiklander type == MBEDTLS_PK_ECDSA; 650817466cbSJens Wiklander } 651817466cbSJens Wiklander 652817466cbSJens Wiklander static size_t eckey_get_bitlen(const void *ctx) 653817466cbSJens Wiklander { 654*32b31808SJens Wiklander return ((mbedtls_ecp_keypair *) ctx)->grp.pbits; 655817466cbSJens Wiklander } 656817466cbSJens Wiklander 657*32b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) 658*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 659*32b31808SJens Wiklander /* 660*32b31808SJens Wiklander * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of 661*32b31808SJens Wiklander * those integers and convert it to the fixed-length encoding expected by PSA. 662*32b31808SJens Wiklander */ 663*32b31808SJens Wiklander static int extract_ecdsa_sig_int(unsigned char **from, const unsigned char *end, 664*32b31808SJens Wiklander unsigned char *to, size_t to_len) 665*32b31808SJens Wiklander { 666*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 667*32b31808SJens Wiklander size_t unpadded_len, padding_len; 668*32b31808SJens Wiklander 669*32b31808SJens Wiklander if ((ret = mbedtls_asn1_get_tag(from, end, &unpadded_len, 670*32b31808SJens Wiklander MBEDTLS_ASN1_INTEGER)) != 0) { 671*32b31808SJens Wiklander return ret; 672*32b31808SJens Wiklander } 673*32b31808SJens Wiklander 674*32b31808SJens Wiklander while (unpadded_len > 0 && **from == 0x00) { 675*32b31808SJens Wiklander (*from)++; 676*32b31808SJens Wiklander unpadded_len--; 677*32b31808SJens Wiklander } 678*32b31808SJens Wiklander 679*32b31808SJens Wiklander if (unpadded_len > to_len || unpadded_len == 0) { 680*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; 681*32b31808SJens Wiklander } 682*32b31808SJens Wiklander 683*32b31808SJens Wiklander padding_len = to_len - unpadded_len; 684*32b31808SJens Wiklander memset(to, 0x00, padding_len); 685*32b31808SJens Wiklander memcpy(to + padding_len, *from, unpadded_len); 686*32b31808SJens Wiklander (*from) += unpadded_len; 687*32b31808SJens Wiklander 688*32b31808SJens Wiklander return 0; 689*32b31808SJens Wiklander } 690*32b31808SJens Wiklander 691*32b31808SJens Wiklander /* 692*32b31808SJens Wiklander * Convert a signature from an ASN.1 sequence of two integers 693*32b31808SJens Wiklander * to a raw {r,s} buffer. Note: the provided sig buffer must be at least 694*32b31808SJens Wiklander * twice as big as int_size. 695*32b31808SJens Wiklander */ 696*32b31808SJens Wiklander static int extract_ecdsa_sig(unsigned char **p, const unsigned char *end, 697*32b31808SJens Wiklander unsigned char *sig, size_t int_size) 698*32b31808SJens Wiklander { 699*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 700*32b31808SJens Wiklander size_t tmp_size; 701*32b31808SJens Wiklander 702*32b31808SJens Wiklander if ((ret = mbedtls_asn1_get_tag(p, end, &tmp_size, 703*32b31808SJens Wiklander MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { 704*32b31808SJens Wiklander return ret; 705*32b31808SJens Wiklander } 706*32b31808SJens Wiklander 707*32b31808SJens Wiklander /* Extract r */ 708*32b31808SJens Wiklander if ((ret = extract_ecdsa_sig_int(p, end, sig, int_size)) != 0) { 709*32b31808SJens Wiklander return ret; 710*32b31808SJens Wiklander } 711*32b31808SJens Wiklander /* Extract s */ 712*32b31808SJens Wiklander if ((ret = extract_ecdsa_sig_int(p, end, sig + int_size, int_size)) != 0) { 713*32b31808SJens Wiklander return ret; 714*32b31808SJens Wiklander } 715*32b31808SJens Wiklander 716*32b31808SJens Wiklander return 0; 717*32b31808SJens Wiklander } 718*32b31808SJens Wiklander 719*32b31808SJens Wiklander static int ecdsa_verify_wrap(void *ctx_arg, mbedtls_md_type_t md_alg, 720*32b31808SJens Wiklander const unsigned char *hash, size_t hash_len, 721*32b31808SJens Wiklander const unsigned char *sig, size_t sig_len) 722*32b31808SJens Wiklander { 723*32b31808SJens Wiklander mbedtls_ecp_keypair *ctx = ctx_arg; 724*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 725*32b31808SJens Wiklander psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 726*32b31808SJens Wiklander mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; 727*32b31808SJens Wiklander psa_status_t status; 728*32b31808SJens Wiklander size_t key_len; 729*32b31808SJens Wiklander /* This buffer will initially contain the public key and then the signature 730*32b31808SJens Wiklander * but at different points in time. For all curves except secp224k1, which 731*32b31808SJens Wiklander * is not currently supported in PSA, the public key is one byte longer 732*32b31808SJens Wiklander * (header byte + 2 numbers, while the signature is only 2 numbers), 733*32b31808SJens Wiklander * so use that as the buffer size. */ 734*32b31808SJens Wiklander unsigned char buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; 735*32b31808SJens Wiklander unsigned char *p; 736*32b31808SJens Wiklander psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY; 737*32b31808SJens Wiklander size_t curve_bits; 738*32b31808SJens Wiklander psa_ecc_family_t curve = 739*32b31808SJens Wiklander mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits); 740*32b31808SJens Wiklander const size_t signature_part_size = (ctx->grp.nbits + 7) / 8; 741*32b31808SJens Wiklander ((void) md_alg); 742*32b31808SJens Wiklander 743*32b31808SJens Wiklander if (curve == 0) { 744*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 745*32b31808SJens Wiklander } 746*32b31808SJens Wiklander 747*32b31808SJens Wiklander psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve)); 748*32b31808SJens Wiklander psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); 749*32b31808SJens Wiklander psa_set_key_algorithm(&attributes, psa_sig_md); 750*32b31808SJens Wiklander 751*32b31808SJens Wiklander ret = mbedtls_ecp_point_write_binary(&ctx->grp, &ctx->Q, 752*32b31808SJens Wiklander MBEDTLS_ECP_PF_UNCOMPRESSED, 753*32b31808SJens Wiklander &key_len, buf, sizeof(buf)); 754*32b31808SJens Wiklander if (ret != 0) { 755*32b31808SJens Wiklander goto cleanup; 756*32b31808SJens Wiklander } 757*32b31808SJens Wiklander 758*32b31808SJens Wiklander status = psa_import_key(&attributes, 759*32b31808SJens Wiklander buf, key_len, 760*32b31808SJens Wiklander &key_id); 761*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 762*32b31808SJens Wiklander ret = PSA_PK_TO_MBEDTLS_ERR(status); 763*32b31808SJens Wiklander goto cleanup; 764*32b31808SJens Wiklander } 765*32b31808SJens Wiklander 766*32b31808SJens Wiklander /* We don't need the exported key anymore and can 767*32b31808SJens Wiklander * reuse its buffer for signature extraction. */ 768*32b31808SJens Wiklander if (2 * signature_part_size > sizeof(buf)) { 769*32b31808SJens Wiklander ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; 770*32b31808SJens Wiklander goto cleanup; 771*32b31808SJens Wiklander } 772*32b31808SJens Wiklander 773*32b31808SJens Wiklander p = (unsigned char *) sig; 774*32b31808SJens Wiklander if ((ret = extract_ecdsa_sig(&p, sig + sig_len, buf, 775*32b31808SJens Wiklander signature_part_size)) != 0) { 776*32b31808SJens Wiklander goto cleanup; 777*32b31808SJens Wiklander } 778*32b31808SJens Wiklander 779*32b31808SJens Wiklander status = psa_verify_hash(key_id, psa_sig_md, 780*32b31808SJens Wiklander hash, hash_len, 781*32b31808SJens Wiklander buf, 2 * signature_part_size); 782*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 783*32b31808SJens Wiklander ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status); 784*32b31808SJens Wiklander goto cleanup; 785*32b31808SJens Wiklander } 786*32b31808SJens Wiklander 787*32b31808SJens Wiklander if (p != sig + sig_len) { 788*32b31808SJens Wiklander ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; 789*32b31808SJens Wiklander goto cleanup; 790*32b31808SJens Wiklander } 791*32b31808SJens Wiklander ret = 0; 792*32b31808SJens Wiklander 793*32b31808SJens Wiklander cleanup: 794*32b31808SJens Wiklander status = psa_destroy_key(key_id); 795*32b31808SJens Wiklander if (ret == 0 && status != PSA_SUCCESS) { 796*32b31808SJens Wiklander ret = PSA_PK_TO_MBEDTLS_ERR(status); 797*32b31808SJens Wiklander } 798*32b31808SJens Wiklander 799*32b31808SJens Wiklander return ret; 800*32b31808SJens Wiklander } 801*32b31808SJens Wiklander #else /* MBEDTLS_USE_PSA_CRYPTO */ 802817466cbSJens Wiklander static int ecdsa_verify_wrap(void *ctx, mbedtls_md_type_t md_alg, 803817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 804817466cbSJens Wiklander const unsigned char *sig, size_t sig_len) 805817466cbSJens Wiklander { 80611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 807*32b31808SJens Wiklander ((void) md_alg); 808817466cbSJens Wiklander 809*32b31808SJens Wiklander ret = mbedtls_ecdsa_read_signature((mbedtls_ecdsa_context *) ctx, 810*32b31808SJens Wiklander hash, hash_len, sig, sig_len); 811817466cbSJens Wiklander 812*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) { 813*32b31808SJens Wiklander return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; 814817466cbSJens Wiklander } 815817466cbSJens Wiklander 816*32b31808SJens Wiklander return ret; 817*32b31808SJens Wiklander } 818*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 819*32b31808SJens Wiklander #endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */ 820*32b31808SJens Wiklander 821*32b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) 822*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 823*32b31808SJens Wiklander /* 824*32b31808SJens Wiklander * Simultaneously convert and move raw MPI from the beginning of a buffer 825*32b31808SJens Wiklander * to an ASN.1 MPI at the end of the buffer. 826*32b31808SJens Wiklander * See also mbedtls_asn1_write_mpi(). 827*32b31808SJens Wiklander * 828*32b31808SJens Wiklander * p: pointer to the end of the output buffer 829*32b31808SJens Wiklander * start: start of the output buffer, and also of the mpi to write at the end 830*32b31808SJens Wiklander * n_len: length of the mpi to read from start 831*32b31808SJens Wiklander */ 832*32b31808SJens Wiklander static int asn1_write_mpibuf(unsigned char **p, unsigned char *start, 833*32b31808SJens Wiklander size_t n_len) 834817466cbSJens Wiklander { 83511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 836*32b31808SJens Wiklander size_t len = 0; 837817466cbSJens Wiklander 838*32b31808SJens Wiklander if ((size_t) (*p - start) < n_len) { 839*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 840817466cbSJens Wiklander } 841817466cbSJens Wiklander 842*32b31808SJens Wiklander len = n_len; 843*32b31808SJens Wiklander *p -= len; 844*32b31808SJens Wiklander memmove(*p, start, len); 845*32b31808SJens Wiklander 846*32b31808SJens Wiklander /* ASN.1 DER encoding requires minimal length, so skip leading 0s. 847*32b31808SJens Wiklander * Neither r nor s should be 0, but as a failsafe measure, still detect 848*32b31808SJens Wiklander * that rather than overflowing the buffer in case of a PSA error. */ 849*32b31808SJens Wiklander while (len > 0 && **p == 0x00) { 850*32b31808SJens Wiklander ++(*p); 851*32b31808SJens Wiklander --len; 852*32b31808SJens Wiklander } 853*32b31808SJens Wiklander 854*32b31808SJens Wiklander /* this is only reached if the signature was invalid */ 855*32b31808SJens Wiklander if (len == 0) { 856*32b31808SJens Wiklander return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; 857*32b31808SJens Wiklander } 858*32b31808SJens Wiklander 859*32b31808SJens Wiklander /* if the msb is 1, ASN.1 requires that we prepend a 0. 860*32b31808SJens Wiklander * Neither r nor s can be 0, so we can assume len > 0 at all times. */ 861*32b31808SJens Wiklander if (**p & 0x80) { 862*32b31808SJens Wiklander if (*p - start < 1) { 863*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 864*32b31808SJens Wiklander } 865*32b31808SJens Wiklander 866*32b31808SJens Wiklander *--(*p) = 0x00; 867*32b31808SJens Wiklander len += 1; 868*32b31808SJens Wiklander } 869*32b31808SJens Wiklander 870*32b31808SJens Wiklander MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); 871*32b31808SJens Wiklander MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, 872*32b31808SJens Wiklander MBEDTLS_ASN1_INTEGER)); 873*32b31808SJens Wiklander 874*32b31808SJens Wiklander return (int) len; 875*32b31808SJens Wiklander } 876*32b31808SJens Wiklander 877*32b31808SJens Wiklander /* Transcode signature from PSA format to ASN.1 sequence. 878*32b31808SJens Wiklander * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of 879*32b31808SJens Wiklander * MPIs, and in-place. 880*32b31808SJens Wiklander * 881*32b31808SJens Wiklander * [in/out] sig: the signature pre- and post-transcoding 882*32b31808SJens Wiklander * [in/out] sig_len: signature length pre- and post-transcoding 883*32b31808SJens Wiklander * [int] buf_len: the available size the in/out buffer 884*32b31808SJens Wiklander */ 885*32b31808SJens Wiklander static int pk_ecdsa_sig_asn1_from_psa(unsigned char *sig, size_t *sig_len, 886*32b31808SJens Wiklander size_t buf_len) 887*32b31808SJens Wiklander { 888*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 889*32b31808SJens Wiklander size_t len = 0; 890*32b31808SJens Wiklander const size_t rs_len = *sig_len / 2; 891*32b31808SJens Wiklander unsigned char *p = sig + buf_len; 892*32b31808SJens Wiklander 893*32b31808SJens Wiklander MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig + rs_len, rs_len)); 894*32b31808SJens Wiklander MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig, rs_len)); 895*32b31808SJens Wiklander 896*32b31808SJens Wiklander MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, sig, len)); 897*32b31808SJens Wiklander MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, sig, 898*32b31808SJens Wiklander MBEDTLS_ASN1_CONSTRUCTED | 899*32b31808SJens Wiklander MBEDTLS_ASN1_SEQUENCE)); 900*32b31808SJens Wiklander 901*32b31808SJens Wiklander memmove(sig, p, len); 902*32b31808SJens Wiklander *sig_len = len; 903*32b31808SJens Wiklander 904*32b31808SJens Wiklander return 0; 905*32b31808SJens Wiklander } 906*32b31808SJens Wiklander 907*32b31808SJens Wiklander static int ecdsa_sign_wrap(void *ctx_arg, mbedtls_md_type_t md_alg, 908*32b31808SJens Wiklander const unsigned char *hash, size_t hash_len, 909*32b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 910*32b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 911*32b31808SJens Wiklander { 912*32b31808SJens Wiklander mbedtls_ecp_keypair *ctx = ctx_arg; 913*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 914*32b31808SJens Wiklander psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 915*32b31808SJens Wiklander mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; 916*32b31808SJens Wiklander psa_status_t status; 917*32b31808SJens Wiklander unsigned char buf[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH]; 918*32b31808SJens Wiklander #if defined(MBEDTLS_ECDSA_DETERMINISTIC) 919*32b31808SJens Wiklander psa_algorithm_t psa_sig_md = 920*32b31808SJens Wiklander PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_hash_info_psa_from_md(md_alg)); 921*32b31808SJens Wiklander #else 922*32b31808SJens Wiklander psa_algorithm_t psa_sig_md = 923*32b31808SJens Wiklander PSA_ALG_ECDSA(mbedtls_hash_info_psa_from_md(md_alg)); 924*32b31808SJens Wiklander #endif 925*32b31808SJens Wiklander size_t curve_bits; 926*32b31808SJens Wiklander psa_ecc_family_t curve = 927*32b31808SJens Wiklander mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits); 928*32b31808SJens Wiklander size_t key_len = PSA_BITS_TO_BYTES(curve_bits); 929*32b31808SJens Wiklander 930*32b31808SJens Wiklander /* PSA has its own RNG */ 931*32b31808SJens Wiklander ((void) f_rng); 932*32b31808SJens Wiklander ((void) p_rng); 933*32b31808SJens Wiklander 934*32b31808SJens Wiklander if (curve == 0) { 935*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 936*32b31808SJens Wiklander } 937*32b31808SJens Wiklander 938*32b31808SJens Wiklander if (key_len > sizeof(buf)) { 939*32b31808SJens Wiklander return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 940*32b31808SJens Wiklander } 941*32b31808SJens Wiklander ret = mbedtls_mpi_write_binary(&ctx->d, buf, key_len); 942*32b31808SJens Wiklander if (ret != 0) { 943*32b31808SJens Wiklander goto cleanup; 944*32b31808SJens Wiklander } 945*32b31808SJens Wiklander 946*32b31808SJens Wiklander psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); 947*32b31808SJens Wiklander psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); 948*32b31808SJens Wiklander psa_set_key_algorithm(&attributes, psa_sig_md); 949*32b31808SJens Wiklander 950*32b31808SJens Wiklander status = psa_import_key(&attributes, 951*32b31808SJens Wiklander buf, key_len, 952*32b31808SJens Wiklander &key_id); 953*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 954*32b31808SJens Wiklander ret = PSA_PK_TO_MBEDTLS_ERR(status); 955*32b31808SJens Wiklander goto cleanup; 956*32b31808SJens Wiklander } 957*32b31808SJens Wiklander 958*32b31808SJens Wiklander status = psa_sign_hash(key_id, psa_sig_md, hash, hash_len, 959*32b31808SJens Wiklander sig, sig_size, sig_len); 960*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 961*32b31808SJens Wiklander ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status); 962*32b31808SJens Wiklander goto cleanup; 963*32b31808SJens Wiklander } 964*32b31808SJens Wiklander 965*32b31808SJens Wiklander ret = pk_ecdsa_sig_asn1_from_psa(sig, sig_len, sig_size); 966*32b31808SJens Wiklander 967*32b31808SJens Wiklander cleanup: 968*32b31808SJens Wiklander mbedtls_platform_zeroize(buf, sizeof(buf)); 969*32b31808SJens Wiklander status = psa_destroy_key(key_id); 970*32b31808SJens Wiklander if (ret == 0 && status != PSA_SUCCESS) { 971*32b31808SJens Wiklander ret = PSA_PK_TO_MBEDTLS_ERR(status); 972*32b31808SJens Wiklander } 973*32b31808SJens Wiklander 974*32b31808SJens Wiklander return ret; 975*32b31808SJens Wiklander } 976*32b31808SJens Wiklander #else /* MBEDTLS_USE_PSA_CRYPTO */ 977*32b31808SJens Wiklander static int ecdsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg, 978*32b31808SJens Wiklander const unsigned char *hash, size_t hash_len, 979*32b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 980*32b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 981*32b31808SJens Wiklander { 982*32b31808SJens Wiklander return mbedtls_ecdsa_write_signature((mbedtls_ecdsa_context *) ctx, 983*32b31808SJens Wiklander md_alg, hash, hash_len, 984*32b31808SJens Wiklander sig, sig_size, sig_len, 985*32b31808SJens Wiklander f_rng, p_rng); 986*32b31808SJens Wiklander } 987*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 988*32b31808SJens Wiklander #endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */ 989*32b31808SJens Wiklander 990*32b31808SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 9913d3b0591SJens Wiklander /* Forward declarations */ 9923d3b0591SJens Wiklander static int ecdsa_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg, 9933d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 9943d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 9953d3b0591SJens Wiklander void *rs_ctx); 9963d3b0591SJens Wiklander 9973d3b0591SJens Wiklander static int ecdsa_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg, 9983d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 999*32b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 10003d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 10013d3b0591SJens Wiklander void *rs_ctx); 10023d3b0591SJens Wiklander 10033d3b0591SJens Wiklander /* 10043d3b0591SJens Wiklander * Restart context for ECDSA operations with ECKEY context 10053d3b0591SJens Wiklander * 10063d3b0591SJens Wiklander * We need to store an actual ECDSA context, as we need to pass the same to 10073d3b0591SJens Wiklander * the underlying ecdsa function, so we can't create it on the fly every time. 10083d3b0591SJens Wiklander */ 1009*32b31808SJens Wiklander typedef struct { 10103d3b0591SJens Wiklander mbedtls_ecdsa_restart_ctx ecdsa_rs; 10113d3b0591SJens Wiklander mbedtls_ecdsa_context ecdsa_ctx; 10123d3b0591SJens Wiklander } eckey_restart_ctx; 10133d3b0591SJens Wiklander 10143d3b0591SJens Wiklander static void *eckey_rs_alloc(void) 10153d3b0591SJens Wiklander { 10163d3b0591SJens Wiklander eckey_restart_ctx *rs_ctx; 10173d3b0591SJens Wiklander 10183d3b0591SJens Wiklander void *ctx = mbedtls_calloc(1, sizeof(eckey_restart_ctx)); 10193d3b0591SJens Wiklander 1020*32b31808SJens Wiklander if (ctx != NULL) { 10213d3b0591SJens Wiklander rs_ctx = ctx; 10223d3b0591SJens Wiklander mbedtls_ecdsa_restart_init(&rs_ctx->ecdsa_rs); 10233d3b0591SJens Wiklander mbedtls_ecdsa_init(&rs_ctx->ecdsa_ctx); 10243d3b0591SJens Wiklander } 10253d3b0591SJens Wiklander 1026*32b31808SJens Wiklander return ctx; 10273d3b0591SJens Wiklander } 10283d3b0591SJens Wiklander 10293d3b0591SJens Wiklander static void eckey_rs_free(void *ctx) 10303d3b0591SJens Wiklander { 10313d3b0591SJens Wiklander eckey_restart_ctx *rs_ctx; 10323d3b0591SJens Wiklander 1033*32b31808SJens Wiklander if (ctx == NULL) { 10343d3b0591SJens Wiklander return; 1035*32b31808SJens Wiklander } 10363d3b0591SJens Wiklander 10373d3b0591SJens Wiklander rs_ctx = ctx; 10383d3b0591SJens Wiklander mbedtls_ecdsa_restart_free(&rs_ctx->ecdsa_rs); 10393d3b0591SJens Wiklander mbedtls_ecdsa_free(&rs_ctx->ecdsa_ctx); 10403d3b0591SJens Wiklander 10413d3b0591SJens Wiklander mbedtls_free(ctx); 10423d3b0591SJens Wiklander } 10433d3b0591SJens Wiklander 10443d3b0591SJens Wiklander static int eckey_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg, 10453d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 10463d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 10473d3b0591SJens Wiklander void *rs_ctx) 10483d3b0591SJens Wiklander { 104911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 10503d3b0591SJens Wiklander eckey_restart_ctx *rs = rs_ctx; 10513d3b0591SJens Wiklander 10523d3b0591SJens Wiklander /* Should never happen */ 1053*32b31808SJens Wiklander if (rs == NULL) { 1054*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1055*32b31808SJens Wiklander } 10563d3b0591SJens Wiklander 10573d3b0591SJens Wiklander /* set up our own sub-context if needed (that is, on first run) */ 1058*32b31808SJens Wiklander if (rs->ecdsa_ctx.grp.pbits == 0) { 10593d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, ctx)); 1060*32b31808SJens Wiklander } 10613d3b0591SJens Wiklander 10623d3b0591SJens Wiklander MBEDTLS_MPI_CHK(ecdsa_verify_rs_wrap(&rs->ecdsa_ctx, 10633d3b0591SJens Wiklander md_alg, hash, hash_len, 10643d3b0591SJens Wiklander sig, sig_len, &rs->ecdsa_rs)); 10653d3b0591SJens Wiklander 10663d3b0591SJens Wiklander cleanup: 1067*32b31808SJens Wiklander return ret; 10683d3b0591SJens Wiklander } 10693d3b0591SJens Wiklander 10703d3b0591SJens Wiklander static int eckey_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg, 10713d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 1072*32b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 10733d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 10743d3b0591SJens Wiklander void *rs_ctx) 10753d3b0591SJens Wiklander { 107611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 10773d3b0591SJens Wiklander eckey_restart_ctx *rs = rs_ctx; 10783d3b0591SJens Wiklander 10793d3b0591SJens Wiklander /* Should never happen */ 1080*32b31808SJens Wiklander if (rs == NULL) { 1081*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1082*32b31808SJens Wiklander } 10833d3b0591SJens Wiklander 10843d3b0591SJens Wiklander /* set up our own sub-context if needed (that is, on first run) */ 1085*32b31808SJens Wiklander if (rs->ecdsa_ctx.grp.pbits == 0) { 10863d3b0591SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, ctx)); 1087*32b31808SJens Wiklander } 10883d3b0591SJens Wiklander 10893d3b0591SJens Wiklander MBEDTLS_MPI_CHK(ecdsa_sign_rs_wrap(&rs->ecdsa_ctx, md_alg, 1090*32b31808SJens Wiklander hash, hash_len, sig, sig_size, sig_len, 10913d3b0591SJens Wiklander f_rng, p_rng, &rs->ecdsa_rs)); 10923d3b0591SJens Wiklander 10933d3b0591SJens Wiklander cleanup: 1094*32b31808SJens Wiklander return ret; 10953d3b0591SJens Wiklander } 1096*32b31808SJens Wiklander #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 1097817466cbSJens Wiklander 1098*32b31808SJens Wiklander static int eckey_check_pair(const void *pub, const void *prv, 1099*32b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 1100*32b31808SJens Wiklander void *p_rng) 1101817466cbSJens Wiklander { 1102*32b31808SJens Wiklander return mbedtls_ecp_check_pub_priv((const mbedtls_ecp_keypair *) pub, 1103*32b31808SJens Wiklander (const mbedtls_ecp_keypair *) prv, 1104*32b31808SJens Wiklander f_rng, p_rng); 1105817466cbSJens Wiklander } 1106817466cbSJens Wiklander 1107817466cbSJens Wiklander static void *eckey_alloc_wrap(void) 1108817466cbSJens Wiklander { 1109817466cbSJens Wiklander void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair)); 1110817466cbSJens Wiklander 1111*32b31808SJens Wiklander if (ctx != NULL) { 1112817466cbSJens Wiklander mbedtls_ecp_keypair_init(ctx); 1113*32b31808SJens Wiklander } 1114817466cbSJens Wiklander 1115*32b31808SJens Wiklander return ctx; 1116817466cbSJens Wiklander } 1117817466cbSJens Wiklander 1118817466cbSJens Wiklander static void eckey_free_wrap(void *ctx) 1119817466cbSJens Wiklander { 1120817466cbSJens Wiklander mbedtls_ecp_keypair_free((mbedtls_ecp_keypair *) ctx); 1121817466cbSJens Wiklander mbedtls_free(ctx); 1122817466cbSJens Wiklander } 1123817466cbSJens Wiklander 1124817466cbSJens Wiklander static void eckey_debug(const void *ctx, mbedtls_pk_debug_item *items) 1125817466cbSJens Wiklander { 1126817466cbSJens Wiklander items->type = MBEDTLS_PK_DEBUG_ECP; 1127817466cbSJens Wiklander items->name = "eckey.Q"; 1128817466cbSJens Wiklander items->value = &(((mbedtls_ecp_keypair *) ctx)->Q); 1129817466cbSJens Wiklander } 1130817466cbSJens Wiklander 1131817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckey_info = { 1132817466cbSJens Wiklander MBEDTLS_PK_ECKEY, 1133817466cbSJens Wiklander "EC", 1134817466cbSJens Wiklander eckey_get_bitlen, 1135817466cbSJens Wiklander eckey_can_do, 1136*32b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) 1137*32b31808SJens Wiklander ecdsa_verify_wrap, /* Compatible key structures */ 1138*32b31808SJens Wiklander #else 1139*32b31808SJens Wiklander NULL, 1140*32b31808SJens Wiklander #endif 1141*32b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) 1142*32b31808SJens Wiklander ecdsa_sign_wrap, /* Compatible key structures */ 1143*32b31808SJens Wiklander #else 1144*32b31808SJens Wiklander NULL, 1145*32b31808SJens Wiklander #endif 1146*32b31808SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 11473d3b0591SJens Wiklander eckey_verify_rs_wrap, 11483d3b0591SJens Wiklander eckey_sign_rs_wrap, 1149817466cbSJens Wiklander #endif 1150817466cbSJens Wiklander NULL, 1151817466cbSJens Wiklander NULL, 1152817466cbSJens Wiklander eckey_check_pair, 1153817466cbSJens Wiklander eckey_alloc_wrap, 1154817466cbSJens Wiklander eckey_free_wrap, 11553d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 11563d3b0591SJens Wiklander eckey_rs_alloc, 11573d3b0591SJens Wiklander eckey_rs_free, 11583d3b0591SJens Wiklander #endif 1159817466cbSJens Wiklander eckey_debug, 1160817466cbSJens Wiklander }; 1161817466cbSJens Wiklander 1162817466cbSJens Wiklander /* 1163817466cbSJens Wiklander * EC key restricted to ECDH 1164817466cbSJens Wiklander */ 1165817466cbSJens Wiklander static int eckeydh_can_do(mbedtls_pk_type_t type) 1166817466cbSJens Wiklander { 1167*32b31808SJens Wiklander return type == MBEDTLS_PK_ECKEY || 1168*32b31808SJens Wiklander type == MBEDTLS_PK_ECKEY_DH; 1169817466cbSJens Wiklander } 1170817466cbSJens Wiklander 1171817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_eckeydh_info = { 1172817466cbSJens Wiklander MBEDTLS_PK_ECKEY_DH, 1173817466cbSJens Wiklander "EC_DH", 1174817466cbSJens Wiklander eckey_get_bitlen, /* Same underlying key structure */ 1175817466cbSJens Wiklander eckeydh_can_do, 1176817466cbSJens Wiklander NULL, 1177817466cbSJens Wiklander NULL, 11783d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 11793d3b0591SJens Wiklander NULL, 11803d3b0591SJens Wiklander NULL, 11813d3b0591SJens Wiklander #endif 1182817466cbSJens Wiklander NULL, 1183817466cbSJens Wiklander NULL, 1184817466cbSJens Wiklander eckey_check_pair, 1185817466cbSJens Wiklander eckey_alloc_wrap, /* Same underlying key structure */ 1186817466cbSJens Wiklander eckey_free_wrap, /* Same underlying key structure */ 11873d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 11883d3b0591SJens Wiklander NULL, 11893d3b0591SJens Wiklander NULL, 11903d3b0591SJens Wiklander #endif 1191817466cbSJens Wiklander eckey_debug, /* Same underlying key structure */ 1192817466cbSJens Wiklander }; 1193817466cbSJens Wiklander #endif /* MBEDTLS_ECP_C */ 1194817466cbSJens Wiklander 1195*32b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SOME) 1196817466cbSJens Wiklander static int ecdsa_can_do(mbedtls_pk_type_t type) 1197817466cbSJens Wiklander { 1198*32b31808SJens Wiklander return type == MBEDTLS_PK_ECDSA; 1199817466cbSJens Wiklander } 1200817466cbSJens Wiklander 1201*32b31808SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 12023d3b0591SJens Wiklander static int ecdsa_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg, 12033d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 12043d3b0591SJens Wiklander const unsigned char *sig, size_t sig_len, 12053d3b0591SJens Wiklander void *rs_ctx) 12063d3b0591SJens Wiklander { 120711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 12083d3b0591SJens Wiklander ((void) md_alg); 12093d3b0591SJens Wiklander 12103d3b0591SJens Wiklander ret = mbedtls_ecdsa_read_signature_restartable( 12113d3b0591SJens Wiklander (mbedtls_ecdsa_context *) ctx, 12123d3b0591SJens Wiklander hash, hash_len, sig, sig_len, 12133d3b0591SJens Wiklander (mbedtls_ecdsa_restart_ctx *) rs_ctx); 12143d3b0591SJens Wiklander 1215*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) { 1216*32b31808SJens Wiklander return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; 1217*32b31808SJens Wiklander } 12183d3b0591SJens Wiklander 1219*32b31808SJens Wiklander return ret; 12203d3b0591SJens Wiklander } 12213d3b0591SJens Wiklander 12223d3b0591SJens Wiklander static int ecdsa_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg, 12233d3b0591SJens Wiklander const unsigned char *hash, size_t hash_len, 1224*32b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 12253d3b0591SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, 12263d3b0591SJens Wiklander void *rs_ctx) 12273d3b0591SJens Wiklander { 1228*32b31808SJens Wiklander return mbedtls_ecdsa_write_signature_restartable( 12293d3b0591SJens Wiklander (mbedtls_ecdsa_context *) ctx, 1230*32b31808SJens Wiklander md_alg, hash, hash_len, sig, sig_size, sig_len, f_rng, p_rng, 1231*32b31808SJens Wiklander (mbedtls_ecdsa_restart_ctx *) rs_ctx); 12323d3b0591SJens Wiklander 12333d3b0591SJens Wiklander } 12343d3b0591SJens Wiklander 12353d3b0591SJens Wiklander static void *ecdsa_rs_alloc(void) 12363d3b0591SJens Wiklander { 12373d3b0591SJens Wiklander void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecdsa_restart_ctx)); 12383d3b0591SJens Wiklander 1239*32b31808SJens Wiklander if (ctx != NULL) { 12403d3b0591SJens Wiklander mbedtls_ecdsa_restart_init(ctx); 1241*32b31808SJens Wiklander } 12423d3b0591SJens Wiklander 1243*32b31808SJens Wiklander return ctx; 12443d3b0591SJens Wiklander } 12453d3b0591SJens Wiklander 12463d3b0591SJens Wiklander static void ecdsa_rs_free(void *ctx) 12473d3b0591SJens Wiklander { 12483d3b0591SJens Wiklander mbedtls_ecdsa_restart_free(ctx); 12493d3b0591SJens Wiklander mbedtls_free(ctx); 12503d3b0591SJens Wiklander } 1251*32b31808SJens Wiklander #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ 12523d3b0591SJens Wiklander 1253817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_ecdsa_info = { 1254817466cbSJens Wiklander MBEDTLS_PK_ECDSA, 1255817466cbSJens Wiklander "ECDSA", 1256817466cbSJens Wiklander eckey_get_bitlen, /* Compatible key structures */ 1257817466cbSJens Wiklander ecdsa_can_do, 1258*32b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) 1259*32b31808SJens Wiklander ecdsa_verify_wrap, /* Compatible key structures */ 1260*32b31808SJens Wiklander #else 1261*32b31808SJens Wiklander NULL, 1262*32b31808SJens Wiklander #endif 1263*32b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) 1264*32b31808SJens Wiklander ecdsa_sign_wrap, /* Compatible key structures */ 1265*32b31808SJens Wiklander #else 1266*32b31808SJens Wiklander NULL, 1267*32b31808SJens Wiklander #endif 1268*32b31808SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 12693d3b0591SJens Wiklander ecdsa_verify_rs_wrap, 12703d3b0591SJens Wiklander ecdsa_sign_rs_wrap, 12713d3b0591SJens Wiklander #endif 1272817466cbSJens Wiklander NULL, 1273817466cbSJens Wiklander NULL, 1274817466cbSJens Wiklander eckey_check_pair, /* Compatible key structures */ 1275*32b31808SJens Wiklander eckey_alloc_wrap, /* Compatible key structures */ 1276*32b31808SJens Wiklander eckey_free_wrap, /* Compatible key structures */ 1277*32b31808SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 12783d3b0591SJens Wiklander ecdsa_rs_alloc, 12793d3b0591SJens Wiklander ecdsa_rs_free, 12803d3b0591SJens Wiklander #endif 1281817466cbSJens Wiklander eckey_debug, /* Compatible key structures */ 1282817466cbSJens Wiklander }; 1283*32b31808SJens Wiklander #endif /* MBEDTLS_PK_CAN_ECDSA_SOME */ 1284817466cbSJens Wiklander 1285817466cbSJens Wiklander #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) 1286817466cbSJens Wiklander /* 1287817466cbSJens Wiklander * Support for alternative RSA-private implementations 1288817466cbSJens Wiklander */ 1289817466cbSJens Wiklander 1290817466cbSJens Wiklander static int rsa_alt_can_do(mbedtls_pk_type_t type) 1291817466cbSJens Wiklander { 1292*32b31808SJens Wiklander return type == MBEDTLS_PK_RSA; 1293817466cbSJens Wiklander } 1294817466cbSJens Wiklander 1295817466cbSJens Wiklander static size_t rsa_alt_get_bitlen(const void *ctx) 1296817466cbSJens Wiklander { 1297817466cbSJens Wiklander const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx; 1298817466cbSJens Wiklander 1299*32b31808SJens Wiklander return 8 * rsa_alt->key_len_func(rsa_alt->key); 1300817466cbSJens Wiklander } 1301817466cbSJens Wiklander 1302817466cbSJens Wiklander static int rsa_alt_sign_wrap(void *ctx, mbedtls_md_type_t md_alg, 1303817466cbSJens Wiklander const unsigned char *hash, size_t hash_len, 1304*32b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 1305817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 1306817466cbSJens Wiklander { 1307817466cbSJens Wiklander mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; 1308817466cbSJens Wiklander 1309*32b31808SJens Wiklander if (UINT_MAX < hash_len) { 1310*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1311*32b31808SJens Wiklander } 1312817466cbSJens Wiklander 1313817466cbSJens Wiklander *sig_len = rsa_alt->key_len_func(rsa_alt->key); 1314*32b31808SJens Wiklander if (*sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE) { 1315*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BAD_INPUT_DATA; 1316*32b31808SJens Wiklander } 1317*32b31808SJens Wiklander if (*sig_len > sig_size) { 1318*32b31808SJens Wiklander return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; 1319*32b31808SJens Wiklander } 1320817466cbSJens Wiklander 1321*32b31808SJens Wiklander return rsa_alt->sign_func(rsa_alt->key, f_rng, p_rng, 1322*32b31808SJens Wiklander md_alg, (unsigned int) hash_len, hash, sig); 1323817466cbSJens Wiklander } 1324817466cbSJens Wiklander 1325817466cbSJens Wiklander static int rsa_alt_decrypt_wrap(void *ctx, 1326817466cbSJens Wiklander const unsigned char *input, size_t ilen, 1327817466cbSJens Wiklander unsigned char *output, size_t *olen, size_t osize, 1328817466cbSJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 1329817466cbSJens Wiklander { 1330817466cbSJens Wiklander mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; 1331817466cbSJens Wiklander 1332817466cbSJens Wiklander ((void) f_rng); 1333817466cbSJens Wiklander ((void) p_rng); 1334817466cbSJens Wiklander 1335*32b31808SJens Wiklander if (ilen != rsa_alt->key_len_func(rsa_alt->key)) { 1336*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; 1337*32b31808SJens Wiklander } 1338817466cbSJens Wiklander 1339*32b31808SJens Wiklander return rsa_alt->decrypt_func(rsa_alt->key, 1340*32b31808SJens Wiklander olen, input, output, osize); 1341817466cbSJens Wiklander } 1342817466cbSJens Wiklander 1343817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 1344*32b31808SJens Wiklander static int rsa_alt_check_pair(const void *pub, const void *prv, 1345*32b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 1346*32b31808SJens Wiklander void *p_rng) 1347817466cbSJens Wiklander { 1348817466cbSJens Wiklander unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; 1349817466cbSJens Wiklander unsigned char hash[32]; 1350817466cbSJens Wiklander size_t sig_len = 0; 135111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1352817466cbSJens Wiklander 1353*32b31808SJens Wiklander if (rsa_alt_get_bitlen(prv) != rsa_get_bitlen(pub)) { 1354*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; 1355*32b31808SJens Wiklander } 1356817466cbSJens Wiklander 1357817466cbSJens Wiklander memset(hash, 0x2a, sizeof(hash)); 1358817466cbSJens Wiklander 1359817466cbSJens Wiklander if ((ret = rsa_alt_sign_wrap((void *) prv, MBEDTLS_MD_NONE, 1360817466cbSJens Wiklander hash, sizeof(hash), 1361*32b31808SJens Wiklander sig, sizeof(sig), &sig_len, 1362*32b31808SJens Wiklander f_rng, p_rng)) != 0) { 1363*32b31808SJens Wiklander return ret; 1364817466cbSJens Wiklander } 1365817466cbSJens Wiklander 1366817466cbSJens Wiklander if (rsa_verify_wrap((void *) pub, MBEDTLS_MD_NONE, 1367*32b31808SJens Wiklander hash, sizeof(hash), sig, sig_len) != 0) { 1368*32b31808SJens Wiklander return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; 1369817466cbSJens Wiklander } 1370817466cbSJens Wiklander 1371*32b31808SJens Wiklander return 0; 1372817466cbSJens Wiklander } 1373817466cbSJens Wiklander #endif /* MBEDTLS_RSA_C */ 1374817466cbSJens Wiklander 1375817466cbSJens Wiklander static void *rsa_alt_alloc_wrap(void) 1376817466cbSJens Wiklander { 1377817466cbSJens Wiklander void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_alt_context)); 1378817466cbSJens Wiklander 1379*32b31808SJens Wiklander if (ctx != NULL) { 1380817466cbSJens Wiklander memset(ctx, 0, sizeof(mbedtls_rsa_alt_context)); 1381*32b31808SJens Wiklander } 1382817466cbSJens Wiklander 1383*32b31808SJens Wiklander return ctx; 1384817466cbSJens Wiklander } 1385817466cbSJens Wiklander 1386817466cbSJens Wiklander static void rsa_alt_free_wrap(void *ctx) 1387817466cbSJens Wiklander { 13883d3b0591SJens Wiklander mbedtls_platform_zeroize(ctx, sizeof(mbedtls_rsa_alt_context)); 1389817466cbSJens Wiklander mbedtls_free(ctx); 1390817466cbSJens Wiklander } 1391817466cbSJens Wiklander 1392817466cbSJens Wiklander const mbedtls_pk_info_t mbedtls_rsa_alt_info = { 1393817466cbSJens Wiklander MBEDTLS_PK_RSA_ALT, 1394817466cbSJens Wiklander "RSA-alt", 1395817466cbSJens Wiklander rsa_alt_get_bitlen, 1396817466cbSJens Wiklander rsa_alt_can_do, 1397817466cbSJens Wiklander NULL, 1398817466cbSJens Wiklander rsa_alt_sign_wrap, 13993d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 14003d3b0591SJens Wiklander NULL, 14013d3b0591SJens Wiklander NULL, 14023d3b0591SJens Wiklander #endif 1403817466cbSJens Wiklander rsa_alt_decrypt_wrap, 1404817466cbSJens Wiklander NULL, 1405817466cbSJens Wiklander #if defined(MBEDTLS_RSA_C) 1406817466cbSJens Wiklander rsa_alt_check_pair, 1407817466cbSJens Wiklander #else 1408817466cbSJens Wiklander NULL, 1409817466cbSJens Wiklander #endif 1410817466cbSJens Wiklander rsa_alt_alloc_wrap, 1411817466cbSJens Wiklander rsa_alt_free_wrap, 14123d3b0591SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 14133d3b0591SJens Wiklander NULL, 14143d3b0591SJens Wiklander NULL, 14153d3b0591SJens Wiklander #endif 1416817466cbSJens Wiklander NULL, 1417817466cbSJens Wiklander }; 1418817466cbSJens Wiklander 1419817466cbSJens Wiklander #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ 1420817466cbSJens Wiklander 142111fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 142211fa71b9SJerome Forissier 142311fa71b9SJerome Forissier static void *pk_opaque_alloc_wrap(void) 142411fa71b9SJerome Forissier { 1425*32b31808SJens Wiklander void *ctx = mbedtls_calloc(1, sizeof(mbedtls_svc_key_id_t)); 142611fa71b9SJerome Forissier 1427*32b31808SJens Wiklander /* no _init() function to call, as calloc() already zeroized */ 142811fa71b9SJerome Forissier 1429*32b31808SJens Wiklander return ctx; 143011fa71b9SJerome Forissier } 143111fa71b9SJerome Forissier 143211fa71b9SJerome Forissier static void pk_opaque_free_wrap(void *ctx) 143311fa71b9SJerome Forissier { 1434*32b31808SJens Wiklander mbedtls_platform_zeroize(ctx, sizeof(mbedtls_svc_key_id_t)); 143511fa71b9SJerome Forissier mbedtls_free(ctx); 143611fa71b9SJerome Forissier } 143711fa71b9SJerome Forissier 143811fa71b9SJerome Forissier static size_t pk_opaque_get_bitlen(const void *ctx) 143911fa71b9SJerome Forissier { 1440*32b31808SJens Wiklander const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx; 144111fa71b9SJerome Forissier size_t bits; 144211fa71b9SJerome Forissier psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 144311fa71b9SJerome Forissier 1444*32b31808SJens Wiklander if (PSA_SUCCESS != psa_get_key_attributes(*key, &attributes)) { 1445*32b31808SJens Wiklander return 0; 1446*32b31808SJens Wiklander } 144711fa71b9SJerome Forissier 144811fa71b9SJerome Forissier bits = psa_get_key_bits(&attributes); 144911fa71b9SJerome Forissier psa_reset_key_attributes(&attributes); 1450*32b31808SJens Wiklander return bits; 145111fa71b9SJerome Forissier } 145211fa71b9SJerome Forissier 1453*32b31808SJens Wiklander static int pk_opaque_ecdsa_can_do(mbedtls_pk_type_t type) 145411fa71b9SJerome Forissier { 1455*32b31808SJens Wiklander return type == MBEDTLS_PK_ECKEY || 1456*32b31808SJens Wiklander type == MBEDTLS_PK_ECDSA; 145711fa71b9SJerome Forissier } 145811fa71b9SJerome Forissier 1459*32b31808SJens Wiklander static int pk_opaque_rsa_can_do(mbedtls_pk_type_t type) 146011fa71b9SJerome Forissier { 1461*32b31808SJens Wiklander return type == MBEDTLS_PK_RSA || 1462*32b31808SJens Wiklander type == MBEDTLS_PK_RSASSA_PSS; 146311fa71b9SJerome Forissier } 146411fa71b9SJerome Forissier 146511fa71b9SJerome Forissier static int pk_opaque_sign_wrap(void *ctx, mbedtls_md_type_t md_alg, 146611fa71b9SJerome Forissier const unsigned char *hash, size_t hash_len, 1467*32b31808SJens Wiklander unsigned char *sig, size_t sig_size, size_t *sig_len, 146811fa71b9SJerome Forissier int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 146911fa71b9SJerome Forissier { 1470*32b31808SJens Wiklander #if !defined(MBEDTLS_PK_CAN_ECDSA_SIGN) && !defined(MBEDTLS_RSA_C) 14717901324dSJerome Forissier ((void) ctx); 14727901324dSJerome Forissier ((void) md_alg); 14737901324dSJerome Forissier ((void) hash); 14747901324dSJerome Forissier ((void) hash_len); 14757901324dSJerome Forissier ((void) sig); 1476*32b31808SJens Wiklander ((void) sig_size); 14777901324dSJerome Forissier ((void) sig_len); 14787901324dSJerome Forissier ((void) f_rng); 14797901324dSJerome Forissier ((void) p_rng); 1480*32b31808SJens Wiklander return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 1481*32b31808SJens Wiklander #else /* !MBEDTLS_PK_CAN_ECDSA_SIGN && !MBEDTLS_RSA_C */ 1482*32b31808SJens Wiklander const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx; 148311fa71b9SJerome Forissier psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 1484*32b31808SJens Wiklander psa_algorithm_t alg; 1485*32b31808SJens Wiklander psa_key_type_t type; 148611fa71b9SJerome Forissier psa_status_t status; 148711fa71b9SJerome Forissier 148811fa71b9SJerome Forissier /* PSA has its own RNG */ 148911fa71b9SJerome Forissier (void) f_rng; 149011fa71b9SJerome Forissier (void) p_rng; 149111fa71b9SJerome Forissier 149211fa71b9SJerome Forissier status = psa_get_key_attributes(*key, &attributes); 1493*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1494*32b31808SJens Wiklander return PSA_PK_TO_MBEDTLS_ERR(status); 1495*32b31808SJens Wiklander } 1496*32b31808SJens Wiklander 1497*32b31808SJens Wiklander type = psa_get_key_type(&attributes); 149811fa71b9SJerome Forissier psa_reset_key_attributes(&attributes); 1499*32b31808SJens Wiklander 1500*32b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) 1501*32b31808SJens Wiklander if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) { 1502*32b31808SJens Wiklander alg = PSA_ALG_ECDSA(mbedtls_hash_info_psa_from_md(md_alg)); 1503*32b31808SJens Wiklander } else 1504*32b31808SJens Wiklander #endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */ 1505*32b31808SJens Wiklander #if defined(MBEDTLS_RSA_C) 1506*32b31808SJens Wiklander if (PSA_KEY_TYPE_IS_RSA(type)) { 1507*32b31808SJens Wiklander alg = PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_hash_info_psa_from_md(md_alg)); 1508*32b31808SJens Wiklander } else 1509*32b31808SJens Wiklander #endif /* MBEDTLS_RSA_C */ 1510*32b31808SJens Wiklander return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; 151111fa71b9SJerome Forissier 151211fa71b9SJerome Forissier /* make the signature */ 151311fa71b9SJerome Forissier status = psa_sign_hash(*key, alg, hash, hash_len, 1514*32b31808SJens Wiklander sig, sig_size, sig_len); 1515*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1516*32b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) 1517*32b31808SJens Wiklander if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) { 1518*32b31808SJens Wiklander return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status); 1519*32b31808SJens Wiklander } else 1520*32b31808SJens Wiklander #endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */ 1521*32b31808SJens Wiklander #if defined(MBEDTLS_RSA_C) 1522*32b31808SJens Wiklander if (PSA_KEY_TYPE_IS_RSA(type)) { 1523*32b31808SJens Wiklander return PSA_PK_RSA_TO_MBEDTLS_ERR(status); 1524*32b31808SJens Wiklander } else 1525*32b31808SJens Wiklander #endif /* MBEDTLS_RSA_C */ 1526*32b31808SJens Wiklander return PSA_PK_TO_MBEDTLS_ERR(status); 152711fa71b9SJerome Forissier } 152811fa71b9SJerome Forissier 1529*32b31808SJens Wiklander #if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) 1530*32b31808SJens Wiklander if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) { 1531*32b31808SJens Wiklander /* transcode it to ASN.1 sequence */ 1532*32b31808SJens Wiklander return pk_ecdsa_sig_asn1_from_psa(sig, sig_len, sig_size); 1533*32b31808SJens Wiklander } 1534*32b31808SJens Wiklander #endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */ 1535*32b31808SJens Wiklander 1536*32b31808SJens Wiklander return 0; 1537*32b31808SJens Wiklander #endif /* !MBEDTLS_PK_CAN_ECDSA_SIGN && !MBEDTLS_RSA_C */ 1538*32b31808SJens Wiklander } 1539*32b31808SJens Wiklander 1540*32b31808SJens Wiklander const mbedtls_pk_info_t mbedtls_pk_ecdsa_opaque_info = { 154111fa71b9SJerome Forissier MBEDTLS_PK_OPAQUE, 154211fa71b9SJerome Forissier "Opaque", 154311fa71b9SJerome Forissier pk_opaque_get_bitlen, 1544*32b31808SJens Wiklander pk_opaque_ecdsa_can_do, 154511fa71b9SJerome Forissier NULL, /* verify - will be done later */ 154611fa71b9SJerome Forissier pk_opaque_sign_wrap, 154711fa71b9SJerome Forissier #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 154811fa71b9SJerome Forissier NULL, /* restartable verify - not relevant */ 154911fa71b9SJerome Forissier NULL, /* restartable sign - not relevant */ 155011fa71b9SJerome Forissier #endif 1551*32b31808SJens Wiklander NULL, /* decrypt - not relevant */ 1552*32b31808SJens Wiklander NULL, /* encrypt - not relevant */ 1553*32b31808SJens Wiklander NULL, /* check_pair - could be done later or left NULL */ 1554*32b31808SJens Wiklander pk_opaque_alloc_wrap, 1555*32b31808SJens Wiklander pk_opaque_free_wrap, 1556*32b31808SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 1557*32b31808SJens Wiklander NULL, /* restart alloc - not relevant */ 1558*32b31808SJens Wiklander NULL, /* restart free - not relevant */ 1559*32b31808SJens Wiklander #endif 1560*32b31808SJens Wiklander NULL, /* debug - could be done later, or even left NULL */ 1561*32b31808SJens Wiklander }; 1562*32b31808SJens Wiklander 1563*32b31808SJens Wiklander #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) 1564*32b31808SJens Wiklander static int pk_opaque_rsa_decrypt(void *ctx, 1565*32b31808SJens Wiklander const unsigned char *input, size_t ilen, 1566*32b31808SJens Wiklander unsigned char *output, size_t *olen, size_t osize, 1567*32b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) 1568*32b31808SJens Wiklander { 1569*32b31808SJens Wiklander const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx; 1570*32b31808SJens Wiklander psa_status_t status; 1571*32b31808SJens Wiklander 1572*32b31808SJens Wiklander /* PSA has its own RNG */ 1573*32b31808SJens Wiklander (void) f_rng; 1574*32b31808SJens Wiklander (void) p_rng; 1575*32b31808SJens Wiklander 1576*32b31808SJens Wiklander status = psa_asymmetric_decrypt(*key, PSA_ALG_RSA_PKCS1V15_CRYPT, 1577*32b31808SJens Wiklander input, ilen, 1578*32b31808SJens Wiklander NULL, 0, 1579*32b31808SJens Wiklander output, osize, olen); 1580*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1581*32b31808SJens Wiklander return PSA_PK_RSA_TO_MBEDTLS_ERR(status); 1582*32b31808SJens Wiklander } 1583*32b31808SJens Wiklander 1584*32b31808SJens Wiklander return 0; 1585*32b31808SJens Wiklander } 1586*32b31808SJens Wiklander #endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR */ 1587*32b31808SJens Wiklander 1588*32b31808SJens Wiklander const mbedtls_pk_info_t mbedtls_pk_rsa_opaque_info = { 1589*32b31808SJens Wiklander MBEDTLS_PK_OPAQUE, 1590*32b31808SJens Wiklander "Opaque", 1591*32b31808SJens Wiklander pk_opaque_get_bitlen, 1592*32b31808SJens Wiklander pk_opaque_rsa_can_do, 1593*32b31808SJens Wiklander NULL, /* verify - will be done later */ 1594*32b31808SJens Wiklander pk_opaque_sign_wrap, 1595*32b31808SJens Wiklander #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 1596*32b31808SJens Wiklander NULL, /* restartable verify - not relevant */ 1597*32b31808SJens Wiklander NULL, /* restartable sign - not relevant */ 1598*32b31808SJens Wiklander #endif 1599*32b31808SJens Wiklander #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) 1600*32b31808SJens Wiklander pk_opaque_rsa_decrypt, 1601*32b31808SJens Wiklander #else 1602*32b31808SJens Wiklander NULL, /* decrypt - not available */ 1603*32b31808SJens Wiklander #endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY */ 160411fa71b9SJerome Forissier NULL, /* encrypt - will be done later */ 160511fa71b9SJerome Forissier NULL, /* check_pair - could be done later or left NULL */ 160611fa71b9SJerome Forissier pk_opaque_alloc_wrap, 160711fa71b9SJerome Forissier pk_opaque_free_wrap, 160811fa71b9SJerome Forissier #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) 160911fa71b9SJerome Forissier NULL, /* restart alloc - not relevant */ 161011fa71b9SJerome Forissier NULL, /* restart free - not relevant */ 161111fa71b9SJerome Forissier #endif 161211fa71b9SJerome Forissier NULL, /* debug - could be done later, or even left NULL */ 161311fa71b9SJerome Forissier }; 161411fa71b9SJerome Forissier 161511fa71b9SJerome Forissier #endif /* MBEDTLS_USE_PSA_CRYPTO */ 161611fa71b9SJerome Forissier 1617817466cbSJens Wiklander #endif /* MBEDTLS_PK_C */ 1618