xref: /optee_os/lib/libmbedtls/mbedtls/library/ecdh.c (revision 32b3180828fa15a49ccc86ecb4be9d274c140c89)
1817466cbSJens Wiklander /*
2817466cbSJens Wiklander  *  Elliptic curve Diffie-Hellman
3817466cbSJens Wiklander  *
47901324dSJerome Forissier  *  Copyright The Mbed TLS Contributors
57901324dSJerome Forissier  *  SPDX-License-Identifier: Apache-2.0
6817466cbSJens Wiklander  *
7817466cbSJens Wiklander  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8817466cbSJens Wiklander  *  not use this file except in compliance with the License.
9817466cbSJens Wiklander  *  You may obtain a copy of the License at
10817466cbSJens Wiklander  *
11817466cbSJens Wiklander  *  http://www.apache.org/licenses/LICENSE-2.0
12817466cbSJens Wiklander  *
13817466cbSJens Wiklander  *  Unless required by applicable law or agreed to in writing, software
14817466cbSJens Wiklander  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15817466cbSJens Wiklander  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16817466cbSJens Wiklander  *  See the License for the specific language governing permissions and
17817466cbSJens Wiklander  *  limitations under the License.
18817466cbSJens Wiklander  */
19817466cbSJens Wiklander 
20817466cbSJens Wiklander /*
21817466cbSJens Wiklander  * References:
22817466cbSJens Wiklander  *
23817466cbSJens Wiklander  * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
24817466cbSJens Wiklander  * RFC 4492
25817466cbSJens Wiklander  */
26817466cbSJens Wiklander 
277901324dSJerome Forissier #include "common.h"
28817466cbSJens Wiklander 
29817466cbSJens Wiklander #if defined(MBEDTLS_ECDH_C)
30817466cbSJens Wiklander 
31817466cbSJens Wiklander #include "mbedtls/ecdh.h"
323d3b0591SJens Wiklander #include "mbedtls/platform_util.h"
3311fa71b9SJerome Forissier #include "mbedtls/error.h"
34817466cbSJens Wiklander 
35817466cbSJens Wiklander #include <string.h>
36817466cbSJens Wiklander 
373d3b0591SJens Wiklander #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
383d3b0591SJens Wiklander typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed;
393d3b0591SJens Wiklander #endif
403d3b0591SJens Wiklander 
415b25c76aSJerome Forissier static mbedtls_ecp_group_id mbedtls_ecdh_grp_id(
425b25c76aSJerome Forissier     const mbedtls_ecdh_context *ctx)
435b25c76aSJerome Forissier {
445b25c76aSJerome Forissier #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
45*32b31808SJens Wiklander     return ctx->grp.id;
465b25c76aSJerome Forissier #else
47*32b31808SJens Wiklander     return ctx->grp_id;
485b25c76aSJerome Forissier #endif
495b25c76aSJerome Forissier }
505b25c76aSJerome Forissier 
5111fa71b9SJerome Forissier int mbedtls_ecdh_can_do(mbedtls_ecp_group_id gid)
5211fa71b9SJerome Forissier {
5311fa71b9SJerome Forissier     /* At this time, all groups support ECDH. */
5411fa71b9SJerome Forissier     (void) gid;
55*32b31808SJens Wiklander     return 1;
5611fa71b9SJerome Forissier }
5711fa71b9SJerome Forissier 
583d3b0591SJens Wiklander #if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
59817466cbSJens Wiklander /*
603d3b0591SJens Wiklander  * Generate public key (restartable version)
613d3b0591SJens Wiklander  *
623d3b0591SJens Wiklander  * Note: this internal function relies on its caller preserving the value of
633d3b0591SJens Wiklander  * the output parameter 'd' across continuation calls. This would not be
643d3b0591SJens Wiklander  * acceptable for a public function but is OK here as we control call sites.
653d3b0591SJens Wiklander  */
663d3b0591SJens Wiklander static int ecdh_gen_public_restartable(mbedtls_ecp_group *grp,
673d3b0591SJens Wiklander                                        mbedtls_mpi *d, mbedtls_ecp_point *Q,
683d3b0591SJens Wiklander                                        int (*f_rng)(void *, unsigned char *, size_t),
693d3b0591SJens Wiklander                                        void *p_rng,
703d3b0591SJens Wiklander                                        mbedtls_ecp_restart_ctx *rs_ctx)
713d3b0591SJens Wiklander {
7211fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
733d3b0591SJens Wiklander 
74*32b31808SJens Wiklander     int restarting = 0;
753d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
76*32b31808SJens Wiklander     restarting = (rs_ctx != NULL && rs_ctx->rsm != NULL);
773d3b0591SJens Wiklander #endif
78*32b31808SJens Wiklander     /* If multiplication is in progress, we already generated a privkey */
79*32b31808SJens Wiklander     if (!restarting) {
803d3b0591SJens Wiklander         MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, d, f_rng, p_rng));
81*32b31808SJens Wiklander     }
823d3b0591SJens Wiklander 
833d3b0591SJens Wiklander     MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, Q, d, &grp->G,
843d3b0591SJens Wiklander                                                 f_rng, p_rng, rs_ctx));
853d3b0591SJens Wiklander 
863d3b0591SJens Wiklander cleanup:
87*32b31808SJens Wiklander     return ret;
883d3b0591SJens Wiklander }
893d3b0591SJens Wiklander 
903d3b0591SJens Wiklander /*
913d3b0591SJens Wiklander  * Generate public key
92817466cbSJens Wiklander  */
93817466cbSJens Wiklander int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
94817466cbSJens Wiklander                             int (*f_rng)(void *, unsigned char *, size_t),
95817466cbSJens Wiklander                             void *p_rng)
96817466cbSJens Wiklander {
97*32b31808SJens Wiklander     return ecdh_gen_public_restartable(grp, d, Q, f_rng, p_rng, NULL);
98817466cbSJens Wiklander }
993d3b0591SJens Wiklander #endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */
100817466cbSJens Wiklander 
1013d3b0591SJens Wiklander #if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
102817466cbSJens Wiklander /*
103817466cbSJens Wiklander  * Compute shared secret (SEC1 3.3.1)
104817466cbSJens Wiklander  */
1053d3b0591SJens Wiklander static int ecdh_compute_shared_restartable(mbedtls_ecp_group *grp,
1063d3b0591SJens Wiklander                                            mbedtls_mpi *z,
107817466cbSJens Wiklander                                            const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
108817466cbSJens Wiklander                                            int (*f_rng)(void *, unsigned char *, size_t),
1093d3b0591SJens Wiklander                                            void *p_rng,
1103d3b0591SJens Wiklander                                            mbedtls_ecp_restart_ctx *rs_ctx)
111817466cbSJens Wiklander {
11211fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
113817466cbSJens Wiklander     mbedtls_ecp_point P;
114817466cbSJens Wiklander 
115817466cbSJens Wiklander     mbedtls_ecp_point_init(&P);
116817466cbSJens Wiklander 
1173d3b0591SJens Wiklander     MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, &P, d, Q,
1183d3b0591SJens Wiklander                                                 f_rng, p_rng, rs_ctx));
119817466cbSJens Wiklander 
120*32b31808SJens Wiklander     if (mbedtls_ecp_is_zero(&P)) {
121817466cbSJens Wiklander         ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
122817466cbSJens Wiklander         goto cleanup;
123817466cbSJens Wiklander     }
124817466cbSJens Wiklander 
125817466cbSJens Wiklander     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(z, &P.X));
126817466cbSJens Wiklander 
127817466cbSJens Wiklander cleanup:
128817466cbSJens Wiklander     mbedtls_ecp_point_free(&P);
129817466cbSJens Wiklander 
130*32b31808SJens Wiklander     return ret;
131817466cbSJens Wiklander }
132817466cbSJens Wiklander 
133817466cbSJens Wiklander /*
1343d3b0591SJens Wiklander  * Compute shared secret (SEC1 3.3.1)
1353d3b0591SJens Wiklander  */
1363d3b0591SJens Wiklander int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z,
1373d3b0591SJens Wiklander                                 const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
1383d3b0591SJens Wiklander                                 int (*f_rng)(void *, unsigned char *, size_t),
1393d3b0591SJens Wiklander                                 void *p_rng)
1403d3b0591SJens Wiklander {
141*32b31808SJens Wiklander     return ecdh_compute_shared_restartable(grp, z, Q, d,
142*32b31808SJens Wiklander                                            f_rng, p_rng, NULL);
1433d3b0591SJens Wiklander }
1443d3b0591SJens Wiklander #endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
1453d3b0591SJens Wiklander 
1463d3b0591SJens Wiklander static void ecdh_init_internal(mbedtls_ecdh_context_mbed *ctx)
1473d3b0591SJens Wiklander {
1483d3b0591SJens Wiklander     mbedtls_ecp_group_init(&ctx->grp);
1493d3b0591SJens Wiklander     mbedtls_mpi_init(&ctx->d);
1503d3b0591SJens Wiklander     mbedtls_ecp_point_init(&ctx->Q);
1513d3b0591SJens Wiklander     mbedtls_ecp_point_init(&ctx->Qp);
1523d3b0591SJens Wiklander     mbedtls_mpi_init(&ctx->z);
1533d3b0591SJens Wiklander 
1543d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
1553d3b0591SJens Wiklander     mbedtls_ecp_restart_init(&ctx->rs);
1563d3b0591SJens Wiklander #endif
1573d3b0591SJens Wiklander }
1583d3b0591SJens Wiklander 
1593d3b0591SJens Wiklander /*
160817466cbSJens Wiklander  * Initialize context
161817466cbSJens Wiklander  */
162817466cbSJens Wiklander void mbedtls_ecdh_init(mbedtls_ecdh_context *ctx)
163817466cbSJens Wiklander {
1643d3b0591SJens Wiklander #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
1653d3b0591SJens Wiklander     ecdh_init_internal(ctx);
1663d3b0591SJens Wiklander     mbedtls_ecp_point_init(&ctx->Vi);
1673d3b0591SJens Wiklander     mbedtls_ecp_point_init(&ctx->Vf);
1683d3b0591SJens Wiklander     mbedtls_mpi_init(&ctx->_d);
1693d3b0591SJens Wiklander #else
170817466cbSJens Wiklander     memset(ctx, 0, sizeof(mbedtls_ecdh_context));
1713d3b0591SJens Wiklander 
1723d3b0591SJens Wiklander     ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
1733d3b0591SJens Wiklander #endif
1743d3b0591SJens Wiklander     ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
1753d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
1763d3b0591SJens Wiklander     ctx->restart_enabled = 0;
1773d3b0591SJens Wiklander #endif
178817466cbSJens Wiklander }
179817466cbSJens Wiklander 
1803d3b0591SJens Wiklander static int ecdh_setup_internal(mbedtls_ecdh_context_mbed *ctx,
1813d3b0591SJens Wiklander                                mbedtls_ecp_group_id grp_id)
1823d3b0591SJens Wiklander {
18311fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1843d3b0591SJens Wiklander 
1853d3b0591SJens Wiklander     ret = mbedtls_ecp_group_load(&ctx->grp, grp_id);
186*32b31808SJens Wiklander     if (ret != 0) {
187*32b31808SJens Wiklander         return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
1883d3b0591SJens Wiklander     }
1893d3b0591SJens Wiklander 
190*32b31808SJens Wiklander     return 0;
1913d3b0591SJens Wiklander }
1923d3b0591SJens Wiklander 
1933d3b0591SJens Wiklander /*
1943d3b0591SJens Wiklander  * Setup context
1953d3b0591SJens Wiklander  */
1963d3b0591SJens Wiklander int mbedtls_ecdh_setup(mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id)
1973d3b0591SJens Wiklander {
1983d3b0591SJens Wiklander #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
199*32b31808SJens Wiklander     return ecdh_setup_internal(ctx, grp_id);
2003d3b0591SJens Wiklander #else
201*32b31808SJens Wiklander     switch (grp_id) {
20211fa71b9SJerome Forissier #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
20311fa71b9SJerome Forissier         case MBEDTLS_ECP_DP_CURVE25519:
20411fa71b9SJerome Forissier             ctx->point_format = MBEDTLS_ECP_PF_COMPRESSED;
20511fa71b9SJerome Forissier             ctx->var = MBEDTLS_ECDH_VARIANT_EVEREST;
20611fa71b9SJerome Forissier             ctx->grp_id = grp_id;
207*32b31808SJens Wiklander             return mbedtls_everest_setup(&ctx->ctx.everest_ecdh, grp_id);
20811fa71b9SJerome Forissier #endif
2093d3b0591SJens Wiklander         default:
2103d3b0591SJens Wiklander             ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
2113d3b0591SJens Wiklander             ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
2123d3b0591SJens Wiklander             ctx->grp_id = grp_id;
2133d3b0591SJens Wiklander             ecdh_init_internal(&ctx->ctx.mbed_ecdh);
214*32b31808SJens Wiklander             return ecdh_setup_internal(&ctx->ctx.mbed_ecdh, grp_id);
2153d3b0591SJens Wiklander     }
2163d3b0591SJens Wiklander #endif
2173d3b0591SJens Wiklander }
2183d3b0591SJens Wiklander 
2193d3b0591SJens Wiklander static void ecdh_free_internal(mbedtls_ecdh_context_mbed *ctx)
2203d3b0591SJens Wiklander {
2213d3b0591SJens Wiklander     mbedtls_ecp_group_free(&ctx->grp);
2223d3b0591SJens Wiklander     mbedtls_mpi_free(&ctx->d);
2233d3b0591SJens Wiklander     mbedtls_ecp_point_free(&ctx->Q);
2243d3b0591SJens Wiklander     mbedtls_ecp_point_free(&ctx->Qp);
2253d3b0591SJens Wiklander     mbedtls_mpi_free(&ctx->z);
2263d3b0591SJens Wiklander 
2273d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
2283d3b0591SJens Wiklander     mbedtls_ecp_restart_free(&ctx->rs);
2293d3b0591SJens Wiklander #endif
2303d3b0591SJens Wiklander }
2313d3b0591SJens Wiklander 
2323d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
2333d3b0591SJens Wiklander /*
2343d3b0591SJens Wiklander  * Enable restartable operations for context
2353d3b0591SJens Wiklander  */
2363d3b0591SJens Wiklander void mbedtls_ecdh_enable_restart(mbedtls_ecdh_context *ctx)
2373d3b0591SJens Wiklander {
2383d3b0591SJens Wiklander     ctx->restart_enabled = 1;
2393d3b0591SJens Wiklander }
2403d3b0591SJens Wiklander #endif
2413d3b0591SJens Wiklander 
242817466cbSJens Wiklander /*
243817466cbSJens Wiklander  * Free context
244817466cbSJens Wiklander  */
245817466cbSJens Wiklander void mbedtls_ecdh_free(mbedtls_ecdh_context *ctx)
246817466cbSJens Wiklander {
247*32b31808SJens Wiklander     if (ctx == NULL) {
248817466cbSJens Wiklander         return;
249*32b31808SJens Wiklander     }
250817466cbSJens Wiklander 
2513d3b0591SJens Wiklander #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
252817466cbSJens Wiklander     mbedtls_ecp_point_free(&ctx->Vi);
253817466cbSJens Wiklander     mbedtls_ecp_point_free(&ctx->Vf);
254817466cbSJens Wiklander     mbedtls_mpi_free(&ctx->_d);
2553d3b0591SJens Wiklander     ecdh_free_internal(ctx);
2563d3b0591SJens Wiklander #else
257*32b31808SJens Wiklander     switch (ctx->var) {
25811fa71b9SJerome Forissier #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
25911fa71b9SJerome Forissier         case MBEDTLS_ECDH_VARIANT_EVEREST:
26011fa71b9SJerome Forissier             mbedtls_everest_free(&ctx->ctx.everest_ecdh);
26111fa71b9SJerome Forissier             break;
26211fa71b9SJerome Forissier #endif
2633d3b0591SJens Wiklander         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
2643d3b0591SJens Wiklander             ecdh_free_internal(&ctx->ctx.mbed_ecdh);
2653d3b0591SJens Wiklander             break;
2663d3b0591SJens Wiklander         default:
2673d3b0591SJens Wiklander             break;
2683d3b0591SJens Wiklander     }
2693d3b0591SJens Wiklander 
2703d3b0591SJens Wiklander     ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
2713d3b0591SJens Wiklander     ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
2723d3b0591SJens Wiklander     ctx->grp_id = MBEDTLS_ECP_DP_NONE;
2733d3b0591SJens Wiklander #endif
2743d3b0591SJens Wiklander }
2753d3b0591SJens Wiklander 
2763d3b0591SJens Wiklander static int ecdh_make_params_internal(mbedtls_ecdh_context_mbed *ctx,
2773d3b0591SJens Wiklander                                      size_t *olen, int point_format,
2783d3b0591SJens Wiklander                                      unsigned char *buf, size_t blen,
2793d3b0591SJens Wiklander                                      int (*f_rng)(void *,
2803d3b0591SJens Wiklander                                                   unsigned char *,
2813d3b0591SJens Wiklander                                                   size_t),
2823d3b0591SJens Wiklander                                      void *p_rng,
2833d3b0591SJens Wiklander                                      int restart_enabled)
2843d3b0591SJens Wiklander {
28511fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2863d3b0591SJens Wiklander     size_t grp_len, pt_len;
2873d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
2883d3b0591SJens Wiklander     mbedtls_ecp_restart_ctx *rs_ctx = NULL;
2893d3b0591SJens Wiklander #endif
2903d3b0591SJens Wiklander 
291*32b31808SJens Wiklander     if (ctx->grp.pbits == 0) {
292*32b31808SJens Wiklander         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
293*32b31808SJens Wiklander     }
2943d3b0591SJens Wiklander 
2953d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
296*32b31808SJens Wiklander     if (restart_enabled) {
2973d3b0591SJens Wiklander         rs_ctx = &ctx->rs;
298*32b31808SJens Wiklander     }
2993d3b0591SJens Wiklander #else
3003d3b0591SJens Wiklander     (void) restart_enabled;
3013d3b0591SJens Wiklander #endif
3023d3b0591SJens Wiklander 
3033d3b0591SJens Wiklander 
3043d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
3053d3b0591SJens Wiklander     if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q,
306*32b31808SJens Wiklander                                            f_rng, p_rng, rs_ctx)) != 0) {
307*32b31808SJens Wiklander         return ret;
308*32b31808SJens Wiklander     }
3093d3b0591SJens Wiklander #else
3103d3b0591SJens Wiklander     if ((ret = mbedtls_ecdh_gen_public(&ctx->grp, &ctx->d, &ctx->Q,
311*32b31808SJens Wiklander                                        f_rng, p_rng)) != 0) {
312*32b31808SJens Wiklander         return ret;
313*32b31808SJens Wiklander     }
3143d3b0591SJens Wiklander #endif /* MBEDTLS_ECP_RESTARTABLE */
3153d3b0591SJens Wiklander 
3163d3b0591SJens Wiklander     if ((ret = mbedtls_ecp_tls_write_group(&ctx->grp, &grp_len, buf,
317*32b31808SJens Wiklander                                            blen)) != 0) {
318*32b31808SJens Wiklander         return ret;
319*32b31808SJens Wiklander     }
3203d3b0591SJens Wiklander 
3213d3b0591SJens Wiklander     buf += grp_len;
3223d3b0591SJens Wiklander     blen -= grp_len;
3233d3b0591SJens Wiklander 
3243d3b0591SJens Wiklander     if ((ret = mbedtls_ecp_tls_write_point(&ctx->grp, &ctx->Q, point_format,
325*32b31808SJens Wiklander                                            &pt_len, buf, blen)) != 0) {
326*32b31808SJens Wiklander         return ret;
327*32b31808SJens Wiklander     }
3283d3b0591SJens Wiklander 
3293d3b0591SJens Wiklander     *olen = grp_len + pt_len;
330*32b31808SJens Wiklander     return 0;
331817466cbSJens Wiklander }
332817466cbSJens Wiklander 
333817466cbSJens Wiklander /*
33411fa71b9SJerome Forissier  * Setup and write the ServerKeyExchange parameters (RFC 4492)
335817466cbSJens Wiklander  *      struct {
336817466cbSJens Wiklander  *          ECParameters    curve_params;
337817466cbSJens Wiklander  *          ECPoint         public;
338817466cbSJens Wiklander  *      } ServerECDHParams;
339817466cbSJens Wiklander  */
340817466cbSJens Wiklander int mbedtls_ecdh_make_params(mbedtls_ecdh_context *ctx, size_t *olen,
341817466cbSJens Wiklander                              unsigned char *buf, size_t blen,
342817466cbSJens Wiklander                              int (*f_rng)(void *, unsigned char *, size_t),
343817466cbSJens Wiklander                              void *p_rng)
344817466cbSJens Wiklander {
3453d3b0591SJens Wiklander     int restart_enabled = 0;
3463d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
3473d3b0591SJens Wiklander     restart_enabled = ctx->restart_enabled;
3483d3b0591SJens Wiklander #else
3493d3b0591SJens Wiklander     (void) restart_enabled;
3503d3b0591SJens Wiklander #endif
351817466cbSJens Wiklander 
3523d3b0591SJens Wiklander #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
353*32b31808SJens Wiklander     return ecdh_make_params_internal(ctx, olen, ctx->point_format, buf, blen,
354*32b31808SJens Wiklander                                      f_rng, p_rng, restart_enabled);
3553d3b0591SJens Wiklander #else
356*32b31808SJens Wiklander     switch (ctx->var) {
35711fa71b9SJerome Forissier #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
35811fa71b9SJerome Forissier         case MBEDTLS_ECDH_VARIANT_EVEREST:
359*32b31808SJens Wiklander             return mbedtls_everest_make_params(&ctx->ctx.everest_ecdh, olen,
360*32b31808SJens Wiklander                                                buf, blen, f_rng, p_rng);
36111fa71b9SJerome Forissier #endif
3623d3b0591SJens Wiklander         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
363*32b31808SJens Wiklander             return ecdh_make_params_internal(&ctx->ctx.mbed_ecdh, olen,
3643d3b0591SJens Wiklander                                              ctx->point_format, buf, blen,
3653d3b0591SJens Wiklander                                              f_rng, p_rng,
366*32b31808SJens Wiklander                                              restart_enabled);
3673d3b0591SJens Wiklander         default:
3683d3b0591SJens Wiklander             return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
3693d3b0591SJens Wiklander     }
3703d3b0591SJens Wiklander #endif
3713d3b0591SJens Wiklander }
372817466cbSJens Wiklander 
3733d3b0591SJens Wiklander static int ecdh_read_params_internal(mbedtls_ecdh_context_mbed *ctx,
3743d3b0591SJens Wiklander                                      const unsigned char **buf,
3753d3b0591SJens Wiklander                                      const unsigned char *end)
3763d3b0591SJens Wiklander {
377*32b31808SJens Wiklander     return mbedtls_ecp_tls_read_point(&ctx->grp, &ctx->Qp, buf,
378*32b31808SJens Wiklander                                       end - *buf);
379817466cbSJens Wiklander }
380817466cbSJens Wiklander 
381817466cbSJens Wiklander /*
382039e02dfSJerome Forissier  * Read the ServerKeyExchange parameters (RFC 4492)
383817466cbSJens Wiklander  *      struct {
384817466cbSJens Wiklander  *          ECParameters    curve_params;
385817466cbSJens Wiklander  *          ECPoint         public;
386817466cbSJens Wiklander  *      } ServerECDHParams;
387817466cbSJens Wiklander  */
388817466cbSJens Wiklander int mbedtls_ecdh_read_params(mbedtls_ecdh_context *ctx,
3893d3b0591SJens Wiklander                              const unsigned char **buf,
3903d3b0591SJens Wiklander                              const unsigned char *end)
391817466cbSJens Wiklander {
39211fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3933d3b0591SJens Wiklander     mbedtls_ecp_group_id grp_id;
3943d3b0591SJens Wiklander     if ((ret = mbedtls_ecp_tls_read_group_id(&grp_id, buf, end - *buf))
395*32b31808SJens Wiklander         != 0) {
396*32b31808SJens Wiklander         return ret;
397*32b31808SJens Wiklander     }
398817466cbSJens Wiklander 
399*32b31808SJens Wiklander     if ((ret = mbedtls_ecdh_setup(ctx, grp_id)) != 0) {
400*32b31808SJens Wiklander         return ret;
401*32b31808SJens Wiklander     }
4023d3b0591SJens Wiklander 
4033d3b0591SJens Wiklander #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
404*32b31808SJens Wiklander     return ecdh_read_params_internal(ctx, buf, end);
4053d3b0591SJens Wiklander #else
406*32b31808SJens Wiklander     switch (ctx->var) {
40711fa71b9SJerome Forissier #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
40811fa71b9SJerome Forissier         case MBEDTLS_ECDH_VARIANT_EVEREST:
409*32b31808SJens Wiklander             return mbedtls_everest_read_params(&ctx->ctx.everest_ecdh,
410*32b31808SJens Wiklander                                                buf, end);
41111fa71b9SJerome Forissier #endif
4123d3b0591SJens Wiklander         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
413*32b31808SJens Wiklander             return ecdh_read_params_internal(&ctx->ctx.mbed_ecdh,
414*32b31808SJens Wiklander                                              buf, end);
4153d3b0591SJens Wiklander         default:
4163d3b0591SJens Wiklander             return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
4173d3b0591SJens Wiklander     }
4183d3b0591SJens Wiklander #endif
419817466cbSJens Wiklander }
420817466cbSJens Wiklander 
4213d3b0591SJens Wiklander static int ecdh_get_params_internal(mbedtls_ecdh_context_mbed *ctx,
4223d3b0591SJens Wiklander                                     const mbedtls_ecp_keypair *key,
423817466cbSJens Wiklander                                     mbedtls_ecdh_side side)
424817466cbSJens Wiklander {
42511fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
426817466cbSJens Wiklander 
427817466cbSJens Wiklander     /* If it's not our key, just import the public part as Qp */
428*32b31808SJens Wiklander     if (side == MBEDTLS_ECDH_THEIRS) {
429*32b31808SJens Wiklander         return mbedtls_ecp_copy(&ctx->Qp, &key->Q);
430*32b31808SJens Wiklander     }
431817466cbSJens Wiklander 
432817466cbSJens Wiklander     /* Our key: import public (as Q) and private parts */
433*32b31808SJens Wiklander     if (side != MBEDTLS_ECDH_OURS) {
434*32b31808SJens Wiklander         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
435*32b31808SJens Wiklander     }
436817466cbSJens Wiklander 
437817466cbSJens Wiklander     if ((ret = mbedtls_ecp_copy(&ctx->Q, &key->Q)) != 0 ||
438*32b31808SJens Wiklander         (ret = mbedtls_mpi_copy(&ctx->d, &key->d)) != 0) {
439*32b31808SJens Wiklander         return ret;
440*32b31808SJens Wiklander     }
441817466cbSJens Wiklander 
442*32b31808SJens Wiklander     return 0;
443817466cbSJens Wiklander }
444817466cbSJens Wiklander 
445817466cbSJens Wiklander /*
4463d3b0591SJens Wiklander  * Get parameters from a keypair
4473d3b0591SJens Wiklander  */
4483d3b0591SJens Wiklander int mbedtls_ecdh_get_params(mbedtls_ecdh_context *ctx,
4493d3b0591SJens Wiklander                             const mbedtls_ecp_keypair *key,
4503d3b0591SJens Wiklander                             mbedtls_ecdh_side side)
4513d3b0591SJens Wiklander {
45211fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
453*32b31808SJens Wiklander     if (side != MBEDTLS_ECDH_OURS && side != MBEDTLS_ECDH_THEIRS) {
454*32b31808SJens Wiklander         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
455*32b31808SJens Wiklander     }
4563d3b0591SJens Wiklander 
457*32b31808SJens Wiklander     if (mbedtls_ecdh_grp_id(ctx) == MBEDTLS_ECP_DP_NONE) {
4585b25c76aSJerome Forissier         /* This is the first call to get_params(). Set up the context
4595b25c76aSJerome Forissier          * for use with the group. */
460*32b31808SJens Wiklander         if ((ret = mbedtls_ecdh_setup(ctx, key->grp.id)) != 0) {
461*32b31808SJens Wiklander             return ret;
4625b25c76aSJerome Forissier         }
463*32b31808SJens Wiklander     } else {
4645b25c76aSJerome Forissier         /* This is not the first call to get_params(). Check that the
4655b25c76aSJerome Forissier          * current key's group is the same as the context's, which was set
4665b25c76aSJerome Forissier          * from the first key's group. */
467*32b31808SJens Wiklander         if (mbedtls_ecdh_grp_id(ctx) != key->grp.id) {
468*32b31808SJens Wiklander             return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
469*32b31808SJens Wiklander         }
4705b25c76aSJerome Forissier     }
4713d3b0591SJens Wiklander 
4723d3b0591SJens Wiklander #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
473*32b31808SJens Wiklander     return ecdh_get_params_internal(ctx, key, side);
4743d3b0591SJens Wiklander #else
475*32b31808SJens Wiklander     switch (ctx->var) {
47611fa71b9SJerome Forissier #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
47711fa71b9SJerome Forissier         case MBEDTLS_ECDH_VARIANT_EVEREST:
47811fa71b9SJerome Forissier         {
47911fa71b9SJerome Forissier             mbedtls_everest_ecdh_side s = side == MBEDTLS_ECDH_OURS ?
48011fa71b9SJerome Forissier                                           MBEDTLS_EVEREST_ECDH_OURS :
48111fa71b9SJerome Forissier                                           MBEDTLS_EVEREST_ECDH_THEIRS;
482*32b31808SJens Wiklander             return mbedtls_everest_get_params(&ctx->ctx.everest_ecdh,
483*32b31808SJens Wiklander                                               key, s);
48411fa71b9SJerome Forissier         }
48511fa71b9SJerome Forissier #endif
4863d3b0591SJens Wiklander         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
487*32b31808SJens Wiklander             return ecdh_get_params_internal(&ctx->ctx.mbed_ecdh,
488*32b31808SJens Wiklander                                             key, side);
4893d3b0591SJens Wiklander         default:
4903d3b0591SJens Wiklander             return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
4913d3b0591SJens Wiklander     }
4923d3b0591SJens Wiklander #endif
4933d3b0591SJens Wiklander }
4943d3b0591SJens Wiklander 
4953d3b0591SJens Wiklander static int ecdh_make_public_internal(mbedtls_ecdh_context_mbed *ctx,
4963d3b0591SJens Wiklander                                      size_t *olen, int point_format,
4973d3b0591SJens Wiklander                                      unsigned char *buf, size_t blen,
4983d3b0591SJens Wiklander                                      int (*f_rng)(void *,
4993d3b0591SJens Wiklander                                                   unsigned char *,
5003d3b0591SJens Wiklander                                                   size_t),
5013d3b0591SJens Wiklander                                      void *p_rng,
5023d3b0591SJens Wiklander                                      int restart_enabled)
5033d3b0591SJens Wiklander {
50411fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
5053d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
5063d3b0591SJens Wiklander     mbedtls_ecp_restart_ctx *rs_ctx = NULL;
5073d3b0591SJens Wiklander #endif
5083d3b0591SJens Wiklander 
509*32b31808SJens Wiklander     if (ctx->grp.pbits == 0) {
510*32b31808SJens Wiklander         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
511*32b31808SJens Wiklander     }
5123d3b0591SJens Wiklander 
5133d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
514*32b31808SJens Wiklander     if (restart_enabled) {
5153d3b0591SJens Wiklander         rs_ctx = &ctx->rs;
516*32b31808SJens Wiklander     }
5173d3b0591SJens Wiklander #else
5183d3b0591SJens Wiklander     (void) restart_enabled;
5193d3b0591SJens Wiklander #endif
5203d3b0591SJens Wiklander 
5213d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
5223d3b0591SJens Wiklander     if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q,
523*32b31808SJens Wiklander                                            f_rng, p_rng, rs_ctx)) != 0) {
524*32b31808SJens Wiklander         return ret;
525*32b31808SJens Wiklander     }
5263d3b0591SJens Wiklander #else
5273d3b0591SJens Wiklander     if ((ret = mbedtls_ecdh_gen_public(&ctx->grp, &ctx->d, &ctx->Q,
528*32b31808SJens Wiklander                                        f_rng, p_rng)) != 0) {
529*32b31808SJens Wiklander         return ret;
530*32b31808SJens Wiklander     }
5313d3b0591SJens Wiklander #endif /* MBEDTLS_ECP_RESTARTABLE */
5323d3b0591SJens Wiklander 
5333d3b0591SJens Wiklander     return mbedtls_ecp_tls_write_point(&ctx->grp, &ctx->Q, point_format, olen,
5343d3b0591SJens Wiklander                                        buf, blen);
5353d3b0591SJens Wiklander }
5363d3b0591SJens Wiklander 
5373d3b0591SJens Wiklander /*
538817466cbSJens Wiklander  * Setup and export the client public value
539817466cbSJens Wiklander  */
540817466cbSJens Wiklander int mbedtls_ecdh_make_public(mbedtls_ecdh_context *ctx, size_t *olen,
541817466cbSJens Wiklander                              unsigned char *buf, size_t blen,
542817466cbSJens Wiklander                              int (*f_rng)(void *, unsigned char *, size_t),
543817466cbSJens Wiklander                              void *p_rng)
544817466cbSJens Wiklander {
5453d3b0591SJens Wiklander     int restart_enabled = 0;
5463d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
5473d3b0591SJens Wiklander     restart_enabled = ctx->restart_enabled;
5483d3b0591SJens Wiklander #endif
5493d3b0591SJens Wiklander 
5503d3b0591SJens Wiklander #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
551*32b31808SJens Wiklander     return ecdh_make_public_internal(ctx, olen, ctx->point_format, buf, blen,
552*32b31808SJens Wiklander                                      f_rng, p_rng, restart_enabled);
5533d3b0591SJens Wiklander #else
554*32b31808SJens Wiklander     switch (ctx->var) {
55511fa71b9SJerome Forissier #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
55611fa71b9SJerome Forissier         case MBEDTLS_ECDH_VARIANT_EVEREST:
557*32b31808SJens Wiklander             return mbedtls_everest_make_public(&ctx->ctx.everest_ecdh, olen,
558*32b31808SJens Wiklander                                                buf, blen, f_rng, p_rng);
55911fa71b9SJerome Forissier #endif
5603d3b0591SJens Wiklander         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
561*32b31808SJens Wiklander             return ecdh_make_public_internal(&ctx->ctx.mbed_ecdh, olen,
5623d3b0591SJens Wiklander                                              ctx->point_format, buf, blen,
5633d3b0591SJens Wiklander                                              f_rng, p_rng,
564*32b31808SJens Wiklander                                              restart_enabled);
5653d3b0591SJens Wiklander         default:
5663d3b0591SJens Wiklander             return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
5673d3b0591SJens Wiklander     }
5683d3b0591SJens Wiklander #endif
5693d3b0591SJens Wiklander }
5703d3b0591SJens Wiklander 
5713d3b0591SJens Wiklander static int ecdh_read_public_internal(mbedtls_ecdh_context_mbed *ctx,
5723d3b0591SJens Wiklander                                      const unsigned char *buf, size_t blen)
5733d3b0591SJens Wiklander {
57411fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
5753d3b0591SJens Wiklander     const unsigned char *p = buf;
576817466cbSJens Wiklander 
5773d3b0591SJens Wiklander     if ((ret = mbedtls_ecp_tls_read_point(&ctx->grp, &ctx->Qp, &p,
578*32b31808SJens Wiklander                                           blen)) != 0) {
579*32b31808SJens Wiklander         return ret;
580*32b31808SJens Wiklander     }
581817466cbSJens Wiklander 
582*32b31808SJens Wiklander     if ((size_t) (p - buf) != blen) {
583*32b31808SJens Wiklander         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
584*32b31808SJens Wiklander     }
5853d3b0591SJens Wiklander 
586*32b31808SJens Wiklander     return 0;
587817466cbSJens Wiklander }
588817466cbSJens Wiklander 
589817466cbSJens Wiklander /*
590817466cbSJens Wiklander  * Parse and import the client's public value
591817466cbSJens Wiklander  */
592817466cbSJens Wiklander int mbedtls_ecdh_read_public(mbedtls_ecdh_context *ctx,
593817466cbSJens Wiklander                              const unsigned char *buf, size_t blen)
594817466cbSJens Wiklander {
5953d3b0591SJens Wiklander #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
596*32b31808SJens Wiklander     return ecdh_read_public_internal(ctx, buf, blen);
5973d3b0591SJens Wiklander #else
598*32b31808SJens Wiklander     switch (ctx->var) {
59911fa71b9SJerome Forissier #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
60011fa71b9SJerome Forissier         case MBEDTLS_ECDH_VARIANT_EVEREST:
601*32b31808SJens Wiklander             return mbedtls_everest_read_public(&ctx->ctx.everest_ecdh,
602*32b31808SJens Wiklander                                                buf, blen);
60311fa71b9SJerome Forissier #endif
6043d3b0591SJens Wiklander         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
605*32b31808SJens Wiklander             return ecdh_read_public_internal(&ctx->ctx.mbed_ecdh,
606*32b31808SJens Wiklander                                              buf, blen);
6073d3b0591SJens Wiklander         default:
6083d3b0591SJens Wiklander             return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
6093d3b0591SJens Wiklander     }
6103d3b0591SJens Wiklander #endif
6113d3b0591SJens Wiklander }
6123d3b0591SJens Wiklander 
6133d3b0591SJens Wiklander static int ecdh_calc_secret_internal(mbedtls_ecdh_context_mbed *ctx,
6143d3b0591SJens Wiklander                                      size_t *olen, unsigned char *buf,
6153d3b0591SJens Wiklander                                      size_t blen,
6163d3b0591SJens Wiklander                                      int (*f_rng)(void *,
6173d3b0591SJens Wiklander                                                   unsigned char *,
6183d3b0591SJens Wiklander                                                   size_t),
6193d3b0591SJens Wiklander                                      void *p_rng,
6203d3b0591SJens Wiklander                                      int restart_enabled)
6213d3b0591SJens Wiklander {
62211fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
6233d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
6243d3b0591SJens Wiklander     mbedtls_ecp_restart_ctx *rs_ctx = NULL;
6253d3b0591SJens Wiklander #endif
626817466cbSJens Wiklander 
627*32b31808SJens Wiklander     if (ctx == NULL || ctx->grp.pbits == 0) {
628*32b31808SJens Wiklander         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
629*32b31808SJens Wiklander     }
630817466cbSJens Wiklander 
6313d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
632*32b31808SJens Wiklander     if (restart_enabled) {
6333d3b0591SJens Wiklander         rs_ctx = &ctx->rs;
634*32b31808SJens Wiklander     }
6353d3b0591SJens Wiklander #else
6363d3b0591SJens Wiklander     (void) restart_enabled;
6373d3b0591SJens Wiklander #endif
6383d3b0591SJens Wiklander 
6393d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
6403d3b0591SJens Wiklander     if ((ret = ecdh_compute_shared_restartable(&ctx->grp, &ctx->z, &ctx->Qp,
6413d3b0591SJens Wiklander                                                &ctx->d, f_rng, p_rng,
642*32b31808SJens Wiklander                                                rs_ctx)) != 0) {
643*32b31808SJens Wiklander         return ret;
6443d3b0591SJens Wiklander     }
6453d3b0591SJens Wiklander #else
6463d3b0591SJens Wiklander     if ((ret = mbedtls_ecdh_compute_shared(&ctx->grp, &ctx->z, &ctx->Qp,
647*32b31808SJens Wiklander                                            &ctx->d, f_rng, p_rng)) != 0) {
648*32b31808SJens Wiklander         return ret;
6493d3b0591SJens Wiklander     }
6503d3b0591SJens Wiklander #endif /* MBEDTLS_ECP_RESTARTABLE */
651817466cbSJens Wiklander 
652*32b31808SJens Wiklander     if (mbedtls_mpi_size(&ctx->z) > blen) {
653*32b31808SJens Wiklander         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
654*32b31808SJens Wiklander     }
655817466cbSJens Wiklander 
6563d3b0591SJens Wiklander     *olen = ctx->grp.pbits / 8 + ((ctx->grp.pbits % 8) != 0);
65711fa71b9SJerome Forissier 
658*32b31808SJens Wiklander     if (mbedtls_ecp_get_type(&ctx->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
65911fa71b9SJerome Forissier         return mbedtls_mpi_write_binary_le(&ctx->z, buf, *olen);
660*32b31808SJens Wiklander     }
66111fa71b9SJerome Forissier 
6623d3b0591SJens Wiklander     return mbedtls_mpi_write_binary(&ctx->z, buf, *olen);
663817466cbSJens Wiklander }
664817466cbSJens Wiklander 
665817466cbSJens Wiklander /*
666817466cbSJens Wiklander  * Derive and export the shared secret
667817466cbSJens Wiklander  */
668817466cbSJens Wiklander int mbedtls_ecdh_calc_secret(mbedtls_ecdh_context *ctx, size_t *olen,
669817466cbSJens Wiklander                              unsigned char *buf, size_t blen,
670817466cbSJens Wiklander                              int (*f_rng)(void *, unsigned char *, size_t),
671817466cbSJens Wiklander                              void *p_rng)
672817466cbSJens Wiklander {
6733d3b0591SJens Wiklander     int restart_enabled = 0;
6743d3b0591SJens Wiklander #if defined(MBEDTLS_ECP_RESTARTABLE)
6753d3b0591SJens Wiklander     restart_enabled = ctx->restart_enabled;
6763d3b0591SJens Wiklander #endif
677817466cbSJens Wiklander 
6783d3b0591SJens Wiklander #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
679*32b31808SJens Wiklander     return ecdh_calc_secret_internal(ctx, olen, buf, blen, f_rng, p_rng,
680*32b31808SJens Wiklander                                      restart_enabled);
6813d3b0591SJens Wiklander #else
682*32b31808SJens Wiklander     switch (ctx->var) {
68311fa71b9SJerome Forissier #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
68411fa71b9SJerome Forissier         case MBEDTLS_ECDH_VARIANT_EVEREST:
685*32b31808SJens Wiklander             return mbedtls_everest_calc_secret(&ctx->ctx.everest_ecdh, olen,
686*32b31808SJens Wiklander                                                buf, blen, f_rng, p_rng);
68711fa71b9SJerome Forissier #endif
6883d3b0591SJens Wiklander         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
689*32b31808SJens Wiklander             return ecdh_calc_secret_internal(&ctx->ctx.mbed_ecdh, olen, buf,
6903d3b0591SJens Wiklander                                              blen, f_rng, p_rng,
691*32b31808SJens Wiklander                                              restart_enabled);
6923d3b0591SJens Wiklander         default:
693*32b31808SJens Wiklander             return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
6943d3b0591SJens Wiklander     }
6953d3b0591SJens Wiklander #endif
696817466cbSJens Wiklander }
697817466cbSJens Wiklander #endif /* MBEDTLS_ECDH_C */
698