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