quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

psa_crypto_ecp.c (19994B)


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