1*b0563631STom Van Eyck /* 2*b0563631STom Van Eyck * PSA ECP layer on top of Mbed TLS crypto 3*b0563631STom Van Eyck */ 4*b0563631STom Van Eyck /* 5*b0563631STom Van Eyck * Copyright The Mbed TLS Contributors 6*b0563631STom Van Eyck * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 7*b0563631STom Van Eyck */ 8*b0563631STom Van Eyck 9*b0563631STom Van Eyck #include "common.h" 10*b0563631STom Van Eyck 11*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_C) 12*b0563631STom Van Eyck 13*b0563631STom Van Eyck #include <psa/crypto.h> 14*b0563631STom Van Eyck #include "psa_crypto_core.h" 15*b0563631STom Van Eyck #include "psa_crypto_ecp.h" 16*b0563631STom Van Eyck #include "psa_crypto_random_impl.h" 17*b0563631STom Van Eyck #include "mbedtls/psa_util.h" 18*b0563631STom Van Eyck 19*b0563631STom Van Eyck #include <stdlib.h> 20*b0563631STom Van Eyck #include <string.h> 21*b0563631STom Van Eyck #include "mbedtls/platform.h" 22*b0563631STom Van Eyck 23*b0563631STom Van Eyck #include <mbedtls/ecdsa.h> 24*b0563631STom Van Eyck #include <mbedtls/ecdh.h> 25*b0563631STom Van Eyck #include <mbedtls/ecp.h> 26*b0563631STom Van Eyck #include <mbedtls/error.h> 27*b0563631STom Van Eyck 28*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ 29*b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ 30*b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \ 31*b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \ 32*b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 33*b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || \ 34*b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) 35*b0563631STom Van Eyck /* Helper function to verify if the provided EC's family and key bit size are valid. 36*b0563631STom Van Eyck * 37*b0563631STom Van Eyck * Note: "bits" parameter is used both as input and output and it might be updated 38*b0563631STom Van Eyck * in case provided input value is not multiple of 8 ("sloppy" bits). 39*b0563631STom Van Eyck */ 40*b0563631STom Van Eyck static int check_ecc_parameters(psa_ecc_family_t family, size_t *bits) 41*b0563631STom Van Eyck { 42*b0563631STom Van Eyck switch (family) { 43*b0563631STom Van Eyck case PSA_ECC_FAMILY_SECP_R1: 44*b0563631STom Van Eyck switch (*bits) { 45*b0563631STom Van Eyck case 192: 46*b0563631STom Van Eyck case 224: 47*b0563631STom Van Eyck case 256: 48*b0563631STom Van Eyck case 384: 49*b0563631STom Van Eyck case 521: 50*b0563631STom Van Eyck return PSA_SUCCESS; 51*b0563631STom Van Eyck case 528: 52*b0563631STom Van Eyck *bits = 521; 53*b0563631STom Van Eyck return PSA_SUCCESS; 54*b0563631STom Van Eyck } 55*b0563631STom Van Eyck break; 56*b0563631STom Van Eyck 57*b0563631STom Van Eyck case PSA_ECC_FAMILY_BRAINPOOL_P_R1: 58*b0563631STom Van Eyck switch (*bits) { 59*b0563631STom Van Eyck case 256: 60*b0563631STom Van Eyck case 384: 61*b0563631STom Van Eyck case 512: 62*b0563631STom Van Eyck return PSA_SUCCESS; 63*b0563631STom Van Eyck } 64*b0563631STom Van Eyck break; 65*b0563631STom Van Eyck 66*b0563631STom Van Eyck case PSA_ECC_FAMILY_MONTGOMERY: 67*b0563631STom Van Eyck switch (*bits) { 68*b0563631STom Van Eyck case 448: 69*b0563631STom Van Eyck case 255: 70*b0563631STom Van Eyck return PSA_SUCCESS; 71*b0563631STom Van Eyck case 256: 72*b0563631STom Van Eyck *bits = 255; 73*b0563631STom Van Eyck return PSA_SUCCESS; 74*b0563631STom Van Eyck } 75*b0563631STom Van Eyck break; 76*b0563631STom Van Eyck 77*b0563631STom Van Eyck case PSA_ECC_FAMILY_SECP_K1: 78*b0563631STom Van Eyck switch (*bits) { 79*b0563631STom Van Eyck case 192: 80*b0563631STom Van Eyck /* secp224k1 is not and will not be supported in PSA (#3541). */ 81*b0563631STom Van Eyck case 256: 82*b0563631STom Van Eyck return PSA_SUCCESS; 83*b0563631STom Van Eyck } 84*b0563631STom Van Eyck break; 85*b0563631STom Van Eyck } 86*b0563631STom Van Eyck 87*b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 88*b0563631STom Van Eyck } 89*b0563631STom Van Eyck 90*b0563631STom Van Eyck psa_status_t mbedtls_psa_ecp_load_representation( 91*b0563631STom Van Eyck psa_key_type_t type, size_t curve_bits, 92*b0563631STom Van Eyck const uint8_t *data, size_t data_length, 93*b0563631STom Van Eyck mbedtls_ecp_keypair **p_ecp) 94*b0563631STom Van Eyck { 95*b0563631STom Van Eyck mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE; 96*b0563631STom Van Eyck psa_status_t status; 97*b0563631STom Van Eyck mbedtls_ecp_keypair *ecp = NULL; 98*b0563631STom Van Eyck size_t curve_bytes = data_length; 99*b0563631STom Van Eyck int explicit_bits = (curve_bits != 0); 100*b0563631STom Van Eyck 101*b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) && 102*b0563631STom Van Eyck PSA_KEY_TYPE_ECC_GET_FAMILY(type) != PSA_ECC_FAMILY_MONTGOMERY) { 103*b0563631STom Van Eyck /* A Weierstrass public key is represented as: 104*b0563631STom Van Eyck * - The byte 0x04; 105*b0563631STom Van Eyck * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; 106*b0563631STom Van Eyck * - `y_P` as a `ceiling(m/8)`-byte string, big-endian. 107*b0563631STom Van Eyck * So its data length is 2m+1 where m is the curve size in bits. 108*b0563631STom Van Eyck */ 109*b0563631STom Van Eyck if ((data_length & 1) == 0) { 110*b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 111*b0563631STom Van Eyck } 112*b0563631STom Van Eyck curve_bytes = data_length / 2; 113*b0563631STom Van Eyck 114*b0563631STom Van Eyck /* Montgomery public keys are represented in compressed format, meaning 115*b0563631STom Van Eyck * their curve_bytes is equal to the amount of input. */ 116*b0563631STom Van Eyck 117*b0563631STom Van Eyck /* Private keys are represented in uncompressed private random integer 118*b0563631STom Van Eyck * format, meaning their curve_bytes is equal to the amount of input. */ 119*b0563631STom Van Eyck } 120*b0563631STom Van Eyck 121*b0563631STom Van Eyck if (explicit_bits) { 122*b0563631STom Van Eyck /* With an explicit bit-size, the data must have the matching length. */ 123*b0563631STom Van Eyck if (curve_bytes != PSA_BITS_TO_BYTES(curve_bits)) { 124*b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 125*b0563631STom Van Eyck } 126*b0563631STom Van Eyck } else { 127*b0563631STom Van Eyck /* We need to infer the bit-size from the data. Since the only 128*b0563631STom Van Eyck * information we have is the length in bytes, the value of curve_bits 129*b0563631STom Van Eyck * at this stage is rounded up to the nearest multiple of 8. */ 130*b0563631STom Van Eyck curve_bits = PSA_BYTES_TO_BITS(curve_bytes); 131*b0563631STom Van Eyck } 132*b0563631STom Van Eyck 133*b0563631STom Van Eyck /* Allocate and initialize a key representation. */ 134*b0563631STom Van Eyck ecp = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair)); 135*b0563631STom Van Eyck if (ecp == NULL) { 136*b0563631STom Van Eyck return PSA_ERROR_INSUFFICIENT_MEMORY; 137*b0563631STom Van Eyck } 138*b0563631STom Van Eyck mbedtls_ecp_keypair_init(ecp); 139*b0563631STom Van Eyck 140*b0563631STom Van Eyck status = check_ecc_parameters(PSA_KEY_TYPE_ECC_GET_FAMILY(type), &curve_bits); 141*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 142*b0563631STom Van Eyck goto exit; 143*b0563631STom Van Eyck } 144*b0563631STom Van Eyck 145*b0563631STom Van Eyck /* Load the group. */ 146*b0563631STom Van Eyck grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(type), 147*b0563631STom Van Eyck curve_bits); 148*b0563631STom Van Eyck if (grp_id == MBEDTLS_ECP_DP_NONE) { 149*b0563631STom Van Eyck status = PSA_ERROR_NOT_SUPPORTED; 150*b0563631STom Van Eyck goto exit; 151*b0563631STom Van Eyck } 152*b0563631STom Van Eyck 153*b0563631STom Van Eyck status = mbedtls_to_psa_error( 154*b0563631STom Van Eyck mbedtls_ecp_group_load(&ecp->grp, grp_id)); 155*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 156*b0563631STom Van Eyck goto exit; 157*b0563631STom Van Eyck } 158*b0563631STom Van Eyck 159*b0563631STom Van Eyck /* Load the key material. */ 160*b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) { 161*b0563631STom Van Eyck /* Load the public value. */ 162*b0563631STom Van Eyck status = mbedtls_to_psa_error( 163*b0563631STom Van Eyck mbedtls_ecp_point_read_binary(&ecp->grp, &ecp->Q, 164*b0563631STom Van Eyck data, 165*b0563631STom Van Eyck data_length)); 166*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 167*b0563631STom Van Eyck goto exit; 168*b0563631STom Van Eyck } 169*b0563631STom Van Eyck 170*b0563631STom Van Eyck /* Check that the point is on the curve. */ 171*b0563631STom Van Eyck status = mbedtls_to_psa_error( 172*b0563631STom Van Eyck mbedtls_ecp_check_pubkey(&ecp->grp, &ecp->Q)); 173*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 174*b0563631STom Van Eyck goto exit; 175*b0563631STom Van Eyck } 176*b0563631STom Van Eyck } else { 177*b0563631STom Van Eyck /* Load and validate the secret value. */ 178*b0563631STom Van Eyck status = mbedtls_to_psa_error( 179*b0563631STom Van Eyck mbedtls_ecp_read_key(ecp->grp.id, 180*b0563631STom Van Eyck ecp, 181*b0563631STom Van Eyck data, 182*b0563631STom Van Eyck data_length)); 183*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 184*b0563631STom Van Eyck goto exit; 185*b0563631STom Van Eyck } 186*b0563631STom Van Eyck } 187*b0563631STom Van Eyck 188*b0563631STom Van Eyck *p_ecp = ecp; 189*b0563631STom Van Eyck exit: 190*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 191*b0563631STom Van Eyck mbedtls_ecp_keypair_free(ecp); 192*b0563631STom Van Eyck mbedtls_free(ecp); 193*b0563631STom Van Eyck } 194*b0563631STom Van Eyck 195*b0563631STom Van Eyck return status; 196*b0563631STom Van Eyck } 197*b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) || 198*b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || 199*b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || 200*b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || 201*b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || 202*b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || 203*b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) */ 204*b0563631STom Van Eyck 205*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ 206*b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \ 207*b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) 208*b0563631STom Van Eyck 209*b0563631STom Van Eyck psa_status_t mbedtls_psa_ecp_import_key( 210*b0563631STom Van Eyck const psa_key_attributes_t *attributes, 211*b0563631STom Van Eyck const uint8_t *data, size_t data_length, 212*b0563631STom Van Eyck uint8_t *key_buffer, size_t key_buffer_size, 213*b0563631STom Van Eyck size_t *key_buffer_length, size_t *bits) 214*b0563631STom Van Eyck { 215*b0563631STom Van Eyck psa_status_t status; 216*b0563631STom Van Eyck mbedtls_ecp_keypair *ecp = NULL; 217*b0563631STom Van Eyck 218*b0563631STom Van Eyck /* Parse input */ 219*b0563631STom Van Eyck status = mbedtls_psa_ecp_load_representation(attributes->type, 220*b0563631STom Van Eyck attributes->bits, 221*b0563631STom Van Eyck data, 222*b0563631STom Van Eyck data_length, 223*b0563631STom Van Eyck &ecp); 224*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 225*b0563631STom Van Eyck goto exit; 226*b0563631STom Van Eyck } 227*b0563631STom Van Eyck 228*b0563631STom Van Eyck if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type) == 229*b0563631STom Van Eyck PSA_ECC_FAMILY_MONTGOMERY) { 230*b0563631STom Van Eyck *bits = ecp->grp.nbits + 1; 231*b0563631STom Van Eyck } else { 232*b0563631STom Van Eyck *bits = ecp->grp.nbits; 233*b0563631STom Van Eyck } 234*b0563631STom Van Eyck 235*b0563631STom Van Eyck /* Re-export the data to PSA export format. There is currently no support 236*b0563631STom Van Eyck * for other input formats then the export format, so this is a 1-1 237*b0563631STom Van Eyck * copy operation. */ 238*b0563631STom Van Eyck status = mbedtls_psa_ecp_export_key(attributes->type, 239*b0563631STom Van Eyck ecp, 240*b0563631STom Van Eyck key_buffer, 241*b0563631STom Van Eyck key_buffer_size, 242*b0563631STom Van Eyck key_buffer_length); 243*b0563631STom Van Eyck exit: 244*b0563631STom Van Eyck /* Always free the PK object (will also free contained ECP context) */ 245*b0563631STom Van Eyck mbedtls_ecp_keypair_free(ecp); 246*b0563631STom Van Eyck mbedtls_free(ecp); 247*b0563631STom Van Eyck 248*b0563631STom Van Eyck return status; 249*b0563631STom Van Eyck } 250*b0563631STom Van Eyck 251*b0563631STom Van Eyck psa_status_t mbedtls_psa_ecp_export_key(psa_key_type_t type, 252*b0563631STom Van Eyck mbedtls_ecp_keypair *ecp, 253*b0563631STom Van Eyck uint8_t *data, 254*b0563631STom Van Eyck size_t data_size, 255*b0563631STom Van Eyck size_t *data_length) 256*b0563631STom Van Eyck { 257*b0563631STom Van Eyck psa_status_t status; 258*b0563631STom Van Eyck 259*b0563631STom Van Eyck if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) { 260*b0563631STom Van Eyck /* Check whether the public part is loaded */ 261*b0563631STom Van Eyck if (mbedtls_ecp_is_zero(&ecp->Q)) { 262*b0563631STom Van Eyck /* Calculate the public key */ 263*b0563631STom Van Eyck status = mbedtls_to_psa_error( 264*b0563631STom Van Eyck mbedtls_ecp_mul(&ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G, 265*b0563631STom Van Eyck mbedtls_psa_get_random, 266*b0563631STom Van Eyck MBEDTLS_PSA_RANDOM_STATE)); 267*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 268*b0563631STom Van Eyck return status; 269*b0563631STom Van Eyck } 270*b0563631STom Van Eyck } 271*b0563631STom Van Eyck 272*b0563631STom Van Eyck status = mbedtls_to_psa_error( 273*b0563631STom Van Eyck mbedtls_ecp_point_write_binary(&ecp->grp, &ecp->Q, 274*b0563631STom Van Eyck MBEDTLS_ECP_PF_UNCOMPRESSED, 275*b0563631STom Van Eyck data_length, 276*b0563631STom Van Eyck data, 277*b0563631STom Van Eyck data_size)); 278*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 279*b0563631STom Van Eyck memset(data, 0, data_size); 280*b0563631STom Van Eyck } 281*b0563631STom Van Eyck 282*b0563631STom Van Eyck return status; 283*b0563631STom Van Eyck } else { 284*b0563631STom Van Eyck status = mbedtls_to_psa_error( 285*b0563631STom Van Eyck mbedtls_ecp_write_key_ext(ecp, data_length, data, data_size)); 286*b0563631STom Van Eyck return status; 287*b0563631STom Van Eyck } 288*b0563631STom Van Eyck } 289*b0563631STom Van Eyck 290*b0563631STom Van Eyck psa_status_t mbedtls_psa_ecp_export_public_key( 291*b0563631STom Van Eyck const psa_key_attributes_t *attributes, 292*b0563631STom Van Eyck const uint8_t *key_buffer, size_t key_buffer_size, 293*b0563631STom Van Eyck uint8_t *data, size_t data_size, size_t *data_length) 294*b0563631STom Van Eyck { 295*b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 296*b0563631STom Van Eyck mbedtls_ecp_keypair *ecp = NULL; 297*b0563631STom Van Eyck 298*b0563631STom Van Eyck status = mbedtls_psa_ecp_load_representation( 299*b0563631STom Van Eyck attributes->type, attributes->bits, 300*b0563631STom Van Eyck key_buffer, key_buffer_size, &ecp); 301*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 302*b0563631STom Van Eyck return status; 303*b0563631STom Van Eyck } 304*b0563631STom Van Eyck 305*b0563631STom Van Eyck status = mbedtls_psa_ecp_export_key( 306*b0563631STom Van Eyck PSA_KEY_TYPE_ECC_PUBLIC_KEY( 307*b0563631STom Van Eyck PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)), 308*b0563631STom Van Eyck ecp, data, data_size, data_length); 309*b0563631STom Van Eyck 310*b0563631STom Van Eyck mbedtls_ecp_keypair_free(ecp); 311*b0563631STom Van Eyck mbedtls_free(ecp); 312*b0563631STom Van Eyck 313*b0563631STom Van Eyck return status; 314*b0563631STom Van Eyck } 315*b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || 316*b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || 317*b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */ 318*b0563631STom Van Eyck 319*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE) 320*b0563631STom Van Eyck psa_status_t mbedtls_psa_ecp_generate_key( 321*b0563631STom Van Eyck const psa_key_attributes_t *attributes, 322*b0563631STom Van Eyck uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length) 323*b0563631STom Van Eyck { 324*b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 325*b0563631STom Van Eyck int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 326*b0563631STom Van Eyck 327*b0563631STom Van Eyck psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( 328*b0563631STom Van Eyck attributes->type); 329*b0563631STom Van Eyck mbedtls_ecp_group_id grp_id = 330*b0563631STom Van Eyck mbedtls_ecc_group_from_psa(curve, attributes->bits); 331*b0563631STom Van Eyck 332*b0563631STom Van Eyck const mbedtls_ecp_curve_info *curve_info = 333*b0563631STom Van Eyck mbedtls_ecp_curve_info_from_grp_id(grp_id); 334*b0563631STom Van Eyck mbedtls_ecp_keypair ecp; 335*b0563631STom Van Eyck 336*b0563631STom Van Eyck if (grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL) { 337*b0563631STom Van Eyck return PSA_ERROR_NOT_SUPPORTED; 338*b0563631STom Van Eyck } 339*b0563631STom Van Eyck 340*b0563631STom Van Eyck mbedtls_ecp_keypair_init(&ecp); 341*b0563631STom Van Eyck ret = mbedtls_ecp_gen_key(grp_id, &ecp, 342*b0563631STom Van Eyck mbedtls_psa_get_random, 343*b0563631STom Van Eyck MBEDTLS_PSA_RANDOM_STATE); 344*b0563631STom Van Eyck if (ret != 0) { 345*b0563631STom Van Eyck mbedtls_ecp_keypair_free(&ecp); 346*b0563631STom Van Eyck return mbedtls_to_psa_error(ret); 347*b0563631STom Van Eyck } 348*b0563631STom Van Eyck 349*b0563631STom Van Eyck status = mbedtls_to_psa_error( 350*b0563631STom Van Eyck mbedtls_ecp_write_key_ext(&ecp, key_buffer_length, 351*b0563631STom Van Eyck key_buffer, key_buffer_size)); 352*b0563631STom Van Eyck 353*b0563631STom Van Eyck mbedtls_ecp_keypair_free(&ecp); 354*b0563631STom Van Eyck 355*b0563631STom Van Eyck return status; 356*b0563631STom Van Eyck } 357*b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE */ 358*b0563631STom Van Eyck 359*b0563631STom Van Eyck /****************************************************************/ 360*b0563631STom Van Eyck /* ECDSA sign/verify */ 361*b0563631STom Van Eyck /****************************************************************/ 362*b0563631STom Van Eyck 363*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 364*b0563631STom Van Eyck defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) 365*b0563631STom Van Eyck psa_status_t mbedtls_psa_ecdsa_sign_hash( 366*b0563631STom Van Eyck const psa_key_attributes_t *attributes, 367*b0563631STom Van Eyck const uint8_t *key_buffer, size_t key_buffer_size, 368*b0563631STom Van Eyck psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, 369*b0563631STom Van Eyck uint8_t *signature, size_t signature_size, size_t *signature_length) 370*b0563631STom Van Eyck { 371*b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 372*b0563631STom Van Eyck mbedtls_ecp_keypair *ecp = NULL; 373*b0563631STom Van Eyck int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 374*b0563631STom Van Eyck size_t curve_bytes; 375*b0563631STom Van Eyck mbedtls_mpi r, s; 376*b0563631STom Van Eyck 377*b0563631STom Van Eyck status = mbedtls_psa_ecp_load_representation(attributes->type, 378*b0563631STom Van Eyck attributes->bits, 379*b0563631STom Van Eyck key_buffer, 380*b0563631STom Van Eyck key_buffer_size, 381*b0563631STom Van Eyck &ecp); 382*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 383*b0563631STom Van Eyck return status; 384*b0563631STom Van Eyck } 385*b0563631STom Van Eyck 386*b0563631STom Van Eyck curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits); 387*b0563631STom Van Eyck mbedtls_mpi_init(&r); 388*b0563631STom Van Eyck mbedtls_mpi_init(&s); 389*b0563631STom Van Eyck 390*b0563631STom Van Eyck if (signature_size < 2 * curve_bytes) { 391*b0563631STom Van Eyck ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 392*b0563631STom Van Eyck goto cleanup; 393*b0563631STom Van Eyck } 394*b0563631STom Van Eyck 395*b0563631STom Van Eyck if (PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) { 396*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) 397*b0563631STom Van Eyck psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg); 398*b0563631STom Van Eyck mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg); 399*b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_ext( 400*b0563631STom Van Eyck &ecp->grp, &r, &s, 401*b0563631STom Van Eyck &ecp->d, hash, 402*b0563631STom Van Eyck hash_length, md_alg, 403*b0563631STom Van Eyck mbedtls_psa_get_random, 404*b0563631STom Van Eyck MBEDTLS_PSA_RANDOM_STATE)); 405*b0563631STom Van Eyck #else 406*b0563631STom Van Eyck ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; 407*b0563631STom Van Eyck goto cleanup; 408*b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ 409*b0563631STom Van Eyck } else { 410*b0563631STom Van Eyck (void) alg; 411*b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign(&ecp->grp, &r, &s, &ecp->d, 412*b0563631STom Van Eyck hash, hash_length, 413*b0563631STom Van Eyck mbedtls_psa_get_random, 414*b0563631STom Van Eyck MBEDTLS_PSA_RANDOM_STATE)); 415*b0563631STom Van Eyck } 416*b0563631STom Van Eyck 417*b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&r, 418*b0563631STom Van Eyck signature, 419*b0563631STom Van Eyck curve_bytes)); 420*b0563631STom Van Eyck MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&s, 421*b0563631STom Van Eyck signature + curve_bytes, 422*b0563631STom Van Eyck curve_bytes)); 423*b0563631STom Van Eyck cleanup: 424*b0563631STom Van Eyck mbedtls_mpi_free(&r); 425*b0563631STom Van Eyck mbedtls_mpi_free(&s); 426*b0563631STom Van Eyck if (ret == 0) { 427*b0563631STom Van Eyck *signature_length = 2 * curve_bytes; 428*b0563631STom Van Eyck } 429*b0563631STom Van Eyck 430*b0563631STom Van Eyck mbedtls_ecp_keypair_free(ecp); 431*b0563631STom Van Eyck mbedtls_free(ecp); 432*b0563631STom Van Eyck 433*b0563631STom Van Eyck return mbedtls_to_psa_error(ret); 434*b0563631STom Van Eyck } 435*b0563631STom Van Eyck 436*b0563631STom Van Eyck psa_status_t mbedtls_psa_ecp_load_public_part(mbedtls_ecp_keypair *ecp) 437*b0563631STom Van Eyck { 438*b0563631STom Van Eyck int ret = 0; 439*b0563631STom Van Eyck 440*b0563631STom Van Eyck /* Check whether the public part is loaded. If not, load it. */ 441*b0563631STom Van Eyck if (mbedtls_ecp_is_zero(&ecp->Q)) { 442*b0563631STom Van Eyck ret = mbedtls_ecp_mul(&ecp->grp, &ecp->Q, 443*b0563631STom Van Eyck &ecp->d, &ecp->grp.G, 444*b0563631STom Van Eyck mbedtls_psa_get_random, 445*b0563631STom Van Eyck MBEDTLS_PSA_RANDOM_STATE); 446*b0563631STom Van Eyck } 447*b0563631STom Van Eyck 448*b0563631STom Van Eyck return mbedtls_to_psa_error(ret); 449*b0563631STom Van Eyck } 450*b0563631STom Van Eyck 451*b0563631STom Van Eyck psa_status_t mbedtls_psa_ecdsa_verify_hash( 452*b0563631STom Van Eyck const psa_key_attributes_t *attributes, 453*b0563631STom Van Eyck const uint8_t *key_buffer, size_t key_buffer_size, 454*b0563631STom Van Eyck psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, 455*b0563631STom Van Eyck const uint8_t *signature, size_t signature_length) 456*b0563631STom Van Eyck { 457*b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 458*b0563631STom Van Eyck mbedtls_ecp_keypair *ecp = NULL; 459*b0563631STom Van Eyck size_t curve_bytes; 460*b0563631STom Van Eyck mbedtls_mpi r, s; 461*b0563631STom Van Eyck 462*b0563631STom Van Eyck (void) alg; 463*b0563631STom Van Eyck 464*b0563631STom Van Eyck status = mbedtls_psa_ecp_load_representation(attributes->type, 465*b0563631STom Van Eyck attributes->bits, 466*b0563631STom Van Eyck key_buffer, 467*b0563631STom Van Eyck key_buffer_size, 468*b0563631STom Van Eyck &ecp); 469*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 470*b0563631STom Van Eyck return status; 471*b0563631STom Van Eyck } 472*b0563631STom Van Eyck 473*b0563631STom Van Eyck curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits); 474*b0563631STom Van Eyck mbedtls_mpi_init(&r); 475*b0563631STom Van Eyck mbedtls_mpi_init(&s); 476*b0563631STom Van Eyck 477*b0563631STom Van Eyck if (signature_length != 2 * curve_bytes) { 478*b0563631STom Van Eyck status = PSA_ERROR_INVALID_SIGNATURE; 479*b0563631STom Van Eyck goto cleanup; 480*b0563631STom Van Eyck } 481*b0563631STom Van Eyck 482*b0563631STom Van Eyck status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&r, 483*b0563631STom Van Eyck signature, 484*b0563631STom Van Eyck curve_bytes)); 485*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 486*b0563631STom Van Eyck goto cleanup; 487*b0563631STom Van Eyck } 488*b0563631STom Van Eyck 489*b0563631STom Van Eyck status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&s, 490*b0563631STom Van Eyck signature + curve_bytes, 491*b0563631STom Van Eyck curve_bytes)); 492*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 493*b0563631STom Van Eyck goto cleanup; 494*b0563631STom Van Eyck } 495*b0563631STom Van Eyck 496*b0563631STom Van Eyck status = mbedtls_psa_ecp_load_public_part(ecp); 497*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 498*b0563631STom Van Eyck goto cleanup; 499*b0563631STom Van Eyck } 500*b0563631STom Van Eyck 501*b0563631STom Van Eyck status = mbedtls_to_psa_error(mbedtls_ecdsa_verify(&ecp->grp, hash, 502*b0563631STom Van Eyck hash_length, &ecp->Q, 503*b0563631STom Van Eyck &r, &s)); 504*b0563631STom Van Eyck cleanup: 505*b0563631STom Van Eyck mbedtls_mpi_free(&r); 506*b0563631STom Van Eyck mbedtls_mpi_free(&s); 507*b0563631STom Van Eyck mbedtls_ecp_keypair_free(ecp); 508*b0563631STom Van Eyck mbedtls_free(ecp); 509*b0563631STom Van Eyck 510*b0563631STom Van Eyck return status; 511*b0563631STom Van Eyck } 512*b0563631STom Van Eyck 513*b0563631STom Van Eyck #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ 514*b0563631STom Van Eyck * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ 515*b0563631STom Van Eyck 516*b0563631STom Van Eyck /****************************************************************/ 517*b0563631STom Van Eyck /* ECDH Key Agreement */ 518*b0563631STom Van Eyck /****************************************************************/ 519*b0563631STom Van Eyck 520*b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) 521*b0563631STom Van Eyck psa_status_t mbedtls_psa_key_agreement_ecdh( 522*b0563631STom Van Eyck const psa_key_attributes_t *attributes, 523*b0563631STom Van Eyck const uint8_t *key_buffer, size_t key_buffer_size, 524*b0563631STom Van Eyck psa_algorithm_t alg, const uint8_t *peer_key, size_t peer_key_length, 525*b0563631STom Van Eyck uint8_t *shared_secret, size_t shared_secret_size, 526*b0563631STom Van Eyck size_t *shared_secret_length) 527*b0563631STom Van Eyck { 528*b0563631STom Van Eyck psa_status_t status; 529*b0563631STom Van Eyck if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type) || 530*b0563631STom Van Eyck !PSA_ALG_IS_ECDH(alg)) { 531*b0563631STom Van Eyck return PSA_ERROR_INVALID_ARGUMENT; 532*b0563631STom Van Eyck } 533*b0563631STom Van Eyck mbedtls_ecp_keypair *ecp = NULL; 534*b0563631STom Van Eyck status = mbedtls_psa_ecp_load_representation( 535*b0563631STom Van Eyck attributes->type, 536*b0563631STom Van Eyck attributes->bits, 537*b0563631STom Van Eyck key_buffer, 538*b0563631STom Van Eyck key_buffer_size, 539*b0563631STom Van Eyck &ecp); 540*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 541*b0563631STom Van Eyck return status; 542*b0563631STom Van Eyck } 543*b0563631STom Van Eyck mbedtls_ecp_keypair *their_key = NULL; 544*b0563631STom Van Eyck mbedtls_ecdh_context ecdh; 545*b0563631STom Van Eyck size_t bits = 0; 546*b0563631STom Van Eyck psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(ecp->grp.id, &bits); 547*b0563631STom Van Eyck mbedtls_ecdh_init(&ecdh); 548*b0563631STom Van Eyck 549*b0563631STom Van Eyck status = mbedtls_psa_ecp_load_representation( 550*b0563631STom Van Eyck PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve), 551*b0563631STom Van Eyck bits, 552*b0563631STom Van Eyck peer_key, 553*b0563631STom Van Eyck peer_key_length, 554*b0563631STom Van Eyck &their_key); 555*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 556*b0563631STom Van Eyck goto exit; 557*b0563631STom Van Eyck } 558*b0563631STom Van Eyck 559*b0563631STom Van Eyck status = mbedtls_to_psa_error( 560*b0563631STom Van Eyck mbedtls_ecdh_get_params(&ecdh, their_key, MBEDTLS_ECDH_THEIRS)); 561*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 562*b0563631STom Van Eyck goto exit; 563*b0563631STom Van Eyck } 564*b0563631STom Van Eyck status = mbedtls_to_psa_error( 565*b0563631STom Van Eyck mbedtls_ecdh_get_params(&ecdh, ecp, MBEDTLS_ECDH_OURS)); 566*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 567*b0563631STom Van Eyck goto exit; 568*b0563631STom Van Eyck } 569*b0563631STom Van Eyck 570*b0563631STom Van Eyck status = mbedtls_to_psa_error( 571*b0563631STom Van Eyck mbedtls_ecdh_calc_secret(&ecdh, 572*b0563631STom Van Eyck shared_secret_length, 573*b0563631STom Van Eyck shared_secret, shared_secret_size, 574*b0563631STom Van Eyck mbedtls_psa_get_random, 575*b0563631STom Van Eyck MBEDTLS_PSA_RANDOM_STATE)); 576*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 577*b0563631STom Van Eyck goto exit; 578*b0563631STom Van Eyck } 579*b0563631STom Van Eyck if (PSA_BITS_TO_BYTES(bits) != *shared_secret_length) { 580*b0563631STom Van Eyck status = PSA_ERROR_CORRUPTION_DETECTED; 581*b0563631STom Van Eyck } 582*b0563631STom Van Eyck exit: 583*b0563631STom Van Eyck if (status != PSA_SUCCESS) { 584*b0563631STom Van Eyck mbedtls_platform_zeroize(shared_secret, shared_secret_size); 585*b0563631STom Van Eyck } 586*b0563631STom Van Eyck mbedtls_ecdh_free(&ecdh); 587*b0563631STom Van Eyck mbedtls_ecp_keypair_free(their_key); 588*b0563631STom Van Eyck mbedtls_free(their_key); 589*b0563631STom Van Eyck mbedtls_ecp_keypair_free(ecp); 590*b0563631STom Van Eyck mbedtls_free(ecp); 591*b0563631STom Van Eyck return status; 592*b0563631STom Van Eyck } 593*b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */ 594*b0563631STom Van Eyck 595*b0563631STom Van Eyck 596*b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_C */ 597