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