blob: 9c4ddce9c382e53577d53245859d74c0382de241 [file] [log] [blame]
Manuel Pégourié-Gonnard0bad5c22013-01-26 15:30:46 +01001/*
2 * Elliptic curve Diffie-Hellman
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Manuel Pégourié-Gonnard0bad5c22013-01-26 15:30:46 +010018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnard0bad5c22013-01-26 15:30:46 +010020 */
21
22/*
23 * References:
24 *
25 * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
Manuel Pégourié-Gonnard63533e42013-02-10 14:21:04 +010026 * RFC 4492
Manuel Pégourié-Gonnard0bad5c22013-01-26 15:30:46 +010027 */
28
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020029#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020031#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020033#endif
Manuel Pégourié-Gonnard0bad5c22013-01-26 15:30:46 +010034
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020035#if defined(MBEDTLS_ECDH_C)
Manuel Pégourié-Gonnard0bad5c22013-01-26 15:30:46 +010036
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/ecdh.h"
Hanno Becker91796d72018-12-17 18:10:51 +000038#include "mbedtls/platform_util.h"
Manuel Pégourié-Gonnard0bad5c22013-01-26 15:30:46 +010039
Rich Evans00ab4702015-02-06 13:43:58 +000040#include <string.h>
41
Hanno Becker91796d72018-12-17 18:10:51 +000042/* Parameter validation macros based on platform_util.h */
43#define ECDH_VALIDATE_RET( cond ) \
44 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
45#define ECDH_VALIDATE( cond ) \
46 MBEDTLS_INTERNAL_VALIDATE( cond )
47
Janos Follath5a3e1bf2018-08-13 15:54:22 +010048#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
49typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed;
50#endif
51
Gilles Peskine30816292019-02-22 12:31:25 +010052static mbedtls_ecp_group_id mbedtls_ecdh_grp_id(
53 const mbedtls_ecdh_context *ctx )
54{
55#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
56 return( ctx->grp.id );
57#else
58 return( ctx->grp_id );
59#endif
60}
61
Gilles Peskine20b3ef32019-02-11 18:41:27 +010062int mbedtls_ecdh_can_do( mbedtls_ecp_group_id gid )
63{
64 /* At this time, all groups support ECDH. */
65 (void) gid;
66 return 1;
67}
68
Ron Eldora84c1cb2017-10-10 19:04:27 +030069#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +010070/*
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +020071 * Generate public key (restartable version)
Manuel Pégourié-Gonnardc0edc962018-10-16 10:38:19 +020072 *
73 * Note: this internal function relies on its caller preserving the value of
Manuel Pégourié-Gonnardca29fdf2018-10-22 09:56:53 +020074 * the output parameter 'd' across continuation calls. This would not be
Manuel Pégourié-Gonnardc0edc962018-10-16 10:38:19 +020075 * acceptable for a public function but is OK here as we control call sites.
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +020076 */
77static int ecdh_gen_public_restartable( mbedtls_ecp_group *grp,
78 mbedtls_mpi *d, mbedtls_ecp_point *Q,
79 int (*f_rng)(void *, unsigned char *, size_t),
80 void *p_rng,
81 mbedtls_ecp_restart_ctx *rs_ctx )
82{
83 int ret;
84
85 /* If multiplication is in progress, we already generated a privkey */
86#if defined(MBEDTLS_ECP_RESTARTABLE)
87 if( rs_ctx == NULL || rs_ctx->rsm == NULL )
88#endif
89 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) );
90
91 MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, Q, d, &grp->G,
92 f_rng, p_rng, rs_ctx ) );
93
94cleanup:
95 return( ret );
96}
97
98/*
99 * Generate public key
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +0100100 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200101int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +0100102 int (*f_rng)(void *, unsigned char *, size_t),
103 void *p_rng )
104{
Hanno Becker91796d72018-12-17 18:10:51 +0000105 ECDH_VALIDATE_RET( grp != NULL );
106 ECDH_VALIDATE_RET( d != NULL );
107 ECDH_VALIDATE_RET( Q != NULL );
108 ECDH_VALIDATE_RET( f_rng != NULL );
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200109 return( ecdh_gen_public_restartable( grp, d, Q, f_rng, p_rng, NULL ) );
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +0100110}
Ron Eldor936d2842018-11-01 13:05:52 +0200111#endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +0100112
Ron Eldora84c1cb2017-10-10 19:04:27 +0300113#if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +0100114/*
115 * Compute shared secret (SEC1 3.3.1)
116 */
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200117static int ecdh_compute_shared_restartable( mbedtls_ecp_group *grp,
118 mbedtls_mpi *z,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200119 const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +0200120 int (*f_rng)(void *, unsigned char *, size_t),
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200121 void *p_rng,
122 mbedtls_ecp_restart_ctx *rs_ctx )
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +0100123{
124 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200125 mbedtls_ecp_point P;
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +0100126
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200127 mbedtls_ecp_point_init( &P );
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +0100128
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200129 MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &P, d, Q,
130 f_rng, p_rng, rs_ctx ) );
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +0100131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132 if( mbedtls_ecp_is_zero( &P ) )
Paul Bakkerb548d772013-07-26 14:21:34 +0200133 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200134 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
Paul Bakkerb548d772013-07-26 14:21:34 +0200135 goto cleanup;
136 }
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +0100137
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200138 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) );
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +0100139
140cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200141 mbedtls_ecp_point_free( &P );
Manuel Pégourié-Gonnard6545ca72013-01-26 16:05:22 +0100142
143 return( ret );
144}
145
Manuel Pégourié-Gonnard63533e42013-02-10 14:21:04 +0100146/*
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200147 * Compute shared secret (SEC1 3.3.1)
148 */
149int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
150 const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
151 int (*f_rng)(void *, unsigned char *, size_t),
152 void *p_rng )
153{
Hanno Becker91796d72018-12-17 18:10:51 +0000154 ECDH_VALIDATE_RET( grp != NULL );
155 ECDH_VALIDATE_RET( Q != NULL );
156 ECDH_VALIDATE_RET( d != NULL );
157 ECDH_VALIDATE_RET( z != NULL );
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200158 return( ecdh_compute_shared_restartable( grp, z, Q, d,
159 f_rng, p_rng, NULL ) );
160}
Ron Eldor936d2842018-11-01 13:05:52 +0200161#endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200162
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100163static void ecdh_init_internal( mbedtls_ecdh_context_mbed *ctx )
Manuel Pégourié-Gonnard63533e42013-02-10 14:21:04 +0100164{
Christoph M. Wintersteiger2f563e32019-02-18 13:06:02 +0000165 mbedtls_ecp_group_free( &ctx->grp );
166 mbedtls_mpi_free( &ctx->d );
167 mbedtls_ecp_point_free( &ctx->Q );
168 mbedtls_ecp_point_free( &ctx->Qp );
169 mbedtls_mpi_free( &ctx->z );
170
Manuel Pégourié-Gonnard5bd38b12017-08-23 16:55:59 +0200171 mbedtls_ecp_group_init( &ctx->grp );
172 mbedtls_mpi_init( &ctx->d );
173 mbedtls_ecp_point_init( &ctx->Q );
174 mbedtls_ecp_point_init( &ctx->Qp );
175 mbedtls_mpi_init( &ctx->z );
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200176
177#if defined(MBEDTLS_ECP_RESTARTABLE)
Christoph M. Wintersteiger2f563e32019-02-18 13:06:02 +0000178 mbedtls_ecp_restart_free( &ctx->rs );
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200179 mbedtls_ecp_restart_init( &ctx->rs );
180#endif
Manuel Pégourié-Gonnard63533e42013-02-10 14:21:04 +0100181}
182
Manuel Pégourié-Gonnard63533e42013-02-10 14:21:04 +0100183/*
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100184 * Initialize context
Janos Follathf61e4862018-10-30 11:53:25 +0000185 */
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100186void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
187{
Hanno Becker91796d72018-12-17 18:10:51 +0000188 ECDH_VALIDATE( ctx != NULL );
189
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100190#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
191 ecdh_init_internal( ctx );
192 mbedtls_ecp_point_init( &ctx->Vi );
193 mbedtls_ecp_point_init( &ctx->Vf );
194 mbedtls_mpi_init( &ctx->_d );
195#else
Christoph M. Wintersteigerd8c45d52019-02-20 17:16:53 +0000196 memset( ctx, 0, sizeof( mbedtls_ecdh_context ) );
197
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100198 ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
199#endif
200 ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
201#if defined(MBEDTLS_ECP_RESTARTABLE)
202 ctx->restart_enabled = 0;
203#endif
204}
205
206static int ecdh_setup_internal( mbedtls_ecdh_context_mbed *ctx,
207 mbedtls_ecp_group_id grp_id )
Janos Follathf61e4862018-10-30 11:53:25 +0000208{
209 int ret;
210
211 ret = mbedtls_ecp_group_load( &ctx->grp, grp_id );
212 if( ret != 0 )
213 {
Janos Follathf61e4862018-10-30 11:53:25 +0000214 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
215 }
216
217 return( 0 );
218}
219
220/*
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100221 * Setup context
Manuel Pégourié-Gonnard63533e42013-02-10 14:21:04 +0100222 */
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100223int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id )
Manuel Pégourié-Gonnard63533e42013-02-10 14:21:04 +0100224{
Hanno Becker91796d72018-12-17 18:10:51 +0000225 ECDH_VALIDATE_RET( ctx != NULL );
Manuel Pégourié-Gonnard63533e42013-02-10 14:21:04 +0100226
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100227#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
228 return( ecdh_setup_internal( ctx, grp_id ) );
229#else
230 switch( grp_id )
231 {
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100232#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
Christoph M. Wintersteiger3ff60bc2019-02-15 12:59:59 +0000233 case MBEDTLS_ECP_DP_CURVE25519:
234 ctx->point_format = MBEDTLS_ECP_PF_COMPRESSED;
235 ctx->var = MBEDTLS_ECDH_VARIANT_EVEREST;
236 ctx->grp_id = grp_id;
237 return( mbedtls_everest_setup( &ctx->ctx.everest_ecdh, grp_id ) );
Christoph M. Wintersteiger78c9c462018-12-06 17:16:32 +0000238#endif
Christoph M. Wintersteiger3ff60bc2019-02-15 12:59:59 +0000239 default:
240 ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
241 ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
242 ctx->grp_id = grp_id;
243 ecdh_init_internal( &ctx->ctx.mbed_ecdh );
244 return( ecdh_setup_internal( &ctx->ctx.mbed_ecdh, grp_id ) );
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100245 }
246#endif
247}
248
249static void ecdh_free_internal( mbedtls_ecdh_context_mbed *ctx )
250{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200251 mbedtls_ecp_group_free( &ctx->grp );
Manuel Pégourié-Gonnard5bd38b12017-08-23 16:55:59 +0200252 mbedtls_mpi_free( &ctx->d );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200253 mbedtls_ecp_point_free( &ctx->Q );
254 mbedtls_ecp_point_free( &ctx->Qp );
Manuel Pégourié-Gonnard5bd38b12017-08-23 16:55:59 +0200255 mbedtls_mpi_free( &ctx->z );
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200256
257#if defined(MBEDTLS_ECP_RESTARTABLE)
258 mbedtls_ecp_restart_free( &ctx->rs );
259#endif
Manuel Pégourié-Gonnard63533e42013-02-10 14:21:04 +0100260}
261
Manuel Pégourié-Gonnard23e41622017-05-18 12:35:37 +0200262#if defined(MBEDTLS_ECP_RESTARTABLE)
263/*
264 * Enable restartable operations for context
265 */
266void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx )
267{
Hanno Beckera7634e82018-12-18 18:45:00 +0000268 ECDH_VALIDATE( ctx != NULL );
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100269
Manuel Pégourié-Gonnard23e41622017-05-18 12:35:37 +0200270 ctx->restart_enabled = 1;
271}
272#endif
273
Manuel Pégourié-Gonnard13724762013-02-10 15:01:54 +0100274/*
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100275 * Free context
Manuel Pégourié-Gonnard13724762013-02-10 15:01:54 +0100276 */
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100277void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
278{
279 if( ctx == NULL )
280 return;
281
282#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
283 mbedtls_ecp_point_free( &ctx->Vi );
284 mbedtls_ecp_point_free( &ctx->Vf );
285 mbedtls_mpi_free( &ctx->_d );
286 ecdh_free_internal( ctx );
287#else
288 switch( ctx->var )
289 {
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100290#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
291 case MBEDTLS_ECDH_VARIANT_EVEREST:
Christoph M. Wintersteiger4936beb2018-12-12 17:26:41 +0000292 mbedtls_everest_free( &ctx->ctx.everest_ecdh );
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100293 break;
294#endif
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100295 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
296 ecdh_free_internal( &ctx->ctx.mbed_ecdh );
297 break;
298 default:
299 break;
300 }
301
302 ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
303 ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
304 ctx->grp_id = MBEDTLS_ECP_DP_NONE;
305#endif
306}
307
308static int ecdh_make_params_internal( mbedtls_ecdh_context_mbed *ctx,
309 size_t *olen, int point_format,
310 unsigned char *buf, size_t blen,
311 int (*f_rng)(void *,
312 unsigned char *,
313 size_t),
314 void *p_rng,
315 int restart_enabled )
Manuel Pégourié-Gonnard13724762013-02-10 15:01:54 +0100316{
317 int ret;
318 size_t grp_len, pt_len;
Ron Eldor2981d8f2018-11-05 18:07:10 +0200319#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200320 mbedtls_ecp_restart_ctx *rs_ctx = NULL;
Ron Eldor936d2842018-11-01 13:05:52 +0200321#endif
Manuel Pégourié-Gonnard13724762013-02-10 15:01:54 +0100322
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100323 if( ctx->grp.pbits == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200324 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardf35b7392013-02-11 22:12:39 +0100325
Ron Eldor19779c42018-11-05 16:58:13 +0200326#if defined(MBEDTLS_ECP_RESTARTABLE)
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100327 if( restart_enabled )
Manuel Pégourié-Gonnard23e41622017-05-18 12:35:37 +0200328 rs_ctx = &ctx->rs;
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100329#else
330 (void) restart_enabled;
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200331#endif
332
Ron Eldor8493f802018-11-01 11:32:15 +0200333
Ron Eldor2981d8f2018-11-05 18:07:10 +0200334#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200335 if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q,
Manuel Pégourié-Gonnardee68cff2018-10-15 15:27:49 +0200336 f_rng, p_rng, rs_ctx ) ) != 0 )
Manuel Pégourié-Gonnard13724762013-02-10 15:01:54 +0100337 return( ret );
Ron Eldor2981d8f2018-11-05 18:07:10 +0200338#else
339 if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
340 f_rng, p_rng ) ) != 0 )
341 return( ret );
342#endif /* MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard13724762013-02-10 15:01:54 +0100343
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100344 if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf,
345 blen ) ) != 0 )
Manuel Pégourié-Gonnard13724762013-02-10 15:01:54 +0100346 return( ret );
347
348 buf += grp_len;
349 blen -= grp_len;
350
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100351 if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format,
Manuel Pégourié-Gonnardee68cff2018-10-15 15:27:49 +0200352 &pt_len, buf, blen ) ) != 0 )
Manuel Pégourié-Gonnard13724762013-02-10 15:01:54 +0100353 return( ret );
354
355 *olen = grp_len + pt_len;
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200356 return( 0 );
Manuel Pégourié-Gonnard13724762013-02-10 15:01:54 +0100357}
358
Manuel Pégourié-Gonnard854fbd72013-02-11 20:28:55 +0100359/*
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100360 * Setup and write the ServerKeyExchange parameters (RFC 4492)
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100361 * struct {
362 * ECParameters curve_params;
363 * ECPoint public;
364 * } ServerECDHParams;
365 */
366int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
367 unsigned char *buf, size_t blen,
368 int (*f_rng)(void *, unsigned char *, size_t),
369 void *p_rng )
370{
371 int restart_enabled = 0;
Hanno Becker91796d72018-12-17 18:10:51 +0000372 ECDH_VALIDATE_RET( ctx != NULL );
373 ECDH_VALIDATE_RET( olen != NULL );
374 ECDH_VALIDATE_RET( buf != NULL );
375 ECDH_VALIDATE_RET( f_rng != NULL );
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100376
377#if defined(MBEDTLS_ECP_RESTARTABLE)
378 restart_enabled = ctx->restart_enabled;
379#else
380 (void) restart_enabled;
381#endif
382
383#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
384 return( ecdh_make_params_internal( ctx, olen, ctx->point_format, buf, blen,
385 f_rng, p_rng, restart_enabled ) );
386#else
387 switch( ctx->var )
388 {
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100389#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
390 case MBEDTLS_ECDH_VARIANT_EVEREST:
Christoph M. Wintersteiger4936beb2018-12-12 17:26:41 +0000391 return( mbedtls_everest_make_params( &ctx->ctx.everest_ecdh, olen,
392 buf, blen, f_rng, p_rng ) );
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100393#endif
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100394 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
395 return( ecdh_make_params_internal( &ctx->ctx.mbed_ecdh, olen,
396 ctx->point_format, buf, blen,
397 f_rng, p_rng,
398 restart_enabled ) );
399 default:
400 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
401 }
402#endif
403}
404
405static int ecdh_read_params_internal( mbedtls_ecdh_context_mbed *ctx,
406 const unsigned char **buf,
407 const unsigned char *end )
408{
409 return( mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf,
410 end - *buf ) );
411}
412
413/*
Manuel Pégourié-Gonnard854fbd72013-02-11 20:28:55 +0100414 * Read the ServerKeyExhange parameters (RFC 4492)
415 * struct {
416 * ECParameters curve_params;
417 * ECPoint public;
418 * } ServerECDHParams;
419 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100421 const unsigned char **buf,
422 const unsigned char *end )
Manuel Pégourié-Gonnard854fbd72013-02-11 20:28:55 +0100423{
424 int ret;
Janos Follathf61e4862018-10-30 11:53:25 +0000425 mbedtls_ecp_group_id grp_id;
Hanno Becker91796d72018-12-17 18:10:51 +0000426 ECDH_VALIDATE_RET( ctx != NULL );
427 ECDH_VALIDATE_RET( buf != NULL );
428 ECDH_VALIDATE_RET( *buf != NULL );
429 ECDH_VALIDATE_RET( end != NULL );
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100430
Janos Follathf61e4862018-10-30 11:53:25 +0000431 if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, end - *buf ) )
432 != 0 )
Manuel Pégourié-Gonnard854fbd72013-02-11 20:28:55 +0100433 return( ret );
434
Janos Follathf61e4862018-10-30 11:53:25 +0000435 if( ( ret = mbedtls_ecdh_setup( ctx, grp_id ) ) != 0 )
436 return( ret );
437
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100438#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
439 return( ecdh_read_params_internal( ctx, buf, end ) );
440#else
441 switch( ctx->var )
442 {
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100443#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
444 case MBEDTLS_ECDH_VARIANT_EVEREST:
Christoph M. Wintersteiger4936beb2018-12-12 17:26:41 +0000445 return( mbedtls_everest_read_params( &ctx->ctx.everest_ecdh,
446 buf, end) );
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100447#endif
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100448 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
449 return( ecdh_read_params_internal( &ctx->ctx.mbed_ecdh,
450 buf, end ) );
451 default:
452 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
453 }
454#endif
Manuel Pégourié-Gonnard854fbd72013-02-11 20:28:55 +0100455}
Manuel Pégourié-Gonnard0bad5c22013-01-26 15:30:46 +0100456
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100457static int ecdh_get_params_internal( mbedtls_ecdh_context_mbed *ctx,
458 const mbedtls_ecp_keypair *key,
459 mbedtls_ecdh_side side )
Manuel Pégourié-Gonnardcdff3cf2013-12-12 09:55:52 +0100460{
461 int ret;
462
Manuel Pégourié-Gonnardcdff3cf2013-12-12 09:55:52 +0100463 /* If it's not our key, just import the public part as Qp */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464 if( side == MBEDTLS_ECDH_THEIRS )
465 return( mbedtls_ecp_copy( &ctx->Qp, &key->Q ) );
Manuel Pégourié-Gonnardcdff3cf2013-12-12 09:55:52 +0100466
467 /* Our key: import public (as Q) and private parts */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 if( side != MBEDTLS_ECDH_OURS )
469 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardcdff3cf2013-12-12 09:55:52 +0100470
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 if( ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 ||
472 ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 )
Manuel Pégourié-Gonnardcdff3cf2013-12-12 09:55:52 +0100473 return( ret );
474
475 return( 0 );
476}
477
478/*
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100479 * Get parameters from a keypair
Manuel Pégourié-Gonnard5cceb412013-02-11 21:51:45 +0100480 */
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100481int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
482 const mbedtls_ecp_keypair *key,
483 mbedtls_ecdh_side side )
484{
485 int ret;
Hanno Becker91796d72018-12-17 18:10:51 +0000486 ECDH_VALIDATE_RET( ctx != NULL );
487 ECDH_VALIDATE_RET( key != NULL );
488 ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS ||
489 side == MBEDTLS_ECDH_THEIRS );
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100490
Gilles Peskine30816292019-02-22 12:31:25 +0100491 if( mbedtls_ecdh_grp_id( ctx ) == MBEDTLS_ECP_DP_NONE )
Gilles Peskine0b1b71d2018-11-07 22:10:59 +0100492 {
493 /* This is the first call to get_params(). Set up the context
494 * for use with the group. */
495 if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 )
496 return( ret );
497 }
498 else
499 {
500 /* This is not the first call to get_params(). Check that the
501 * current key's group is the same as the context's, which was set
502 * from the first key's group. */
Gilles Peskine30816292019-02-22 12:31:25 +0100503 if( mbedtls_ecdh_grp_id( ctx ) != key->grp.id )
Gilles Peskine0b1b71d2018-11-07 22:10:59 +0100504 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
505 }
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100506
507#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
508 return( ecdh_get_params_internal( ctx, key, side ) );
509#else
510 switch( ctx->var )
511 {
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100512#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
513 case MBEDTLS_ECDH_VARIANT_EVEREST:
Christoph M. Wintersteiger4936beb2018-12-12 17:26:41 +0000514 {
Christoph M. Wintersteiger2e724a12019-01-07 14:19:41 +0000515 mbedtls_everest_ecdh_side s = side == MBEDTLS_ECDH_OURS ?
Christoph M. Wintersteiger4936beb2018-12-12 17:26:41 +0000516 MBEDTLS_EVEREST_ECDH_OURS :
517 MBEDTLS_EVEREST_ECDH_THEIRS;
518 return( mbedtls_everest_get_params( &ctx->ctx.everest_ecdh,
519 key, s) );
520 }
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100521#endif
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100522 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
523 return( ecdh_get_params_internal( &ctx->ctx.mbed_ecdh,
524 key, side ) );
525 default:
526 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
527 }
528#endif
529}
530
531static int ecdh_make_public_internal( mbedtls_ecdh_context_mbed *ctx,
532 size_t *olen, int point_format,
533 unsigned char *buf, size_t blen,
534 int (*f_rng)(void *,
535 unsigned char *,
536 size_t),
537 void *p_rng,
538 int restart_enabled )
Manuel Pégourié-Gonnard5cceb412013-02-11 21:51:45 +0100539{
540 int ret;
Ron Eldor2981d8f2018-11-05 18:07:10 +0200541#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200542 mbedtls_ecp_restart_ctx *rs_ctx = NULL;
Ron Eldor936d2842018-11-01 13:05:52 +0200543#endif
Manuel Pégourié-Gonnard5cceb412013-02-11 21:51:45 +0100544
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100545 if( ctx->grp.pbits == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200546 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardf35b7392013-02-11 22:12:39 +0100547
Ron Eldorb430d9f2018-11-05 17:18:29 +0200548#if defined(MBEDTLS_ECP_RESTARTABLE)
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100549 if( restart_enabled )
Manuel Pégourié-Gonnard23e41622017-05-18 12:35:37 +0200550 rs_ctx = &ctx->rs;
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100551#else
552 (void) restart_enabled;
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200553#endif
554
Ron Eldor2981d8f2018-11-05 18:07:10 +0200555#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200556 if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q,
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100557 f_rng, p_rng, rs_ctx ) ) != 0 )
Manuel Pégourié-Gonnard5cceb412013-02-11 21:51:45 +0100558 return( ret );
Ron Eldor2981d8f2018-11-05 18:07:10 +0200559#else
560 if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
561 f_rng, p_rng ) ) != 0 )
562 return( ret );
563#endif /* MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard5cceb412013-02-11 21:51:45 +0100564
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100565 return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format, olen,
566 buf, blen );
Manuel Pégourié-Gonnard5cceb412013-02-11 21:51:45 +0100567}
568
569/*
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100570 * Setup and export the client public value
Manuel Pégourié-Gonnard5cceb412013-02-11 21:51:45 +0100571 */
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100572int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
573 unsigned char *buf, size_t blen,
574 int (*f_rng)(void *, unsigned char *, size_t),
575 void *p_rng )
Manuel Pégourié-Gonnard5cceb412013-02-11 21:51:45 +0100576{
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100577 int restart_enabled = 0;
Hanno Becker91796d72018-12-17 18:10:51 +0000578 ECDH_VALIDATE_RET( ctx != NULL );
579 ECDH_VALIDATE_RET( olen != NULL );
580 ECDH_VALIDATE_RET( buf != NULL );
Hanno Beckerc81cfec2018-12-18 23:32:42 +0000581 ECDH_VALIDATE_RET( f_rng != NULL );
Manuel Pégourié-Gonnardf35b7392013-02-11 22:12:39 +0100582
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100583#if defined(MBEDTLS_ECP_RESTARTABLE)
584 restart_enabled = ctx->restart_enabled;
585#endif
586
587#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
588 return( ecdh_make_public_internal( ctx, olen, ctx->point_format, buf, blen,
589 f_rng, p_rng, restart_enabled ) );
590#else
591 switch( ctx->var )
592 {
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100593#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
594 case MBEDTLS_ECDH_VARIANT_EVEREST:
Christoph M. Wintersteiger4936beb2018-12-12 17:26:41 +0000595 return( mbedtls_everest_make_public( &ctx->ctx.everest_ecdh, olen,
596 buf, blen, f_rng, p_rng ) );
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100597#endif
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100598 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
599 return( ecdh_make_public_internal( &ctx->ctx.mbed_ecdh, olen,
600 ctx->point_format, buf, blen,
601 f_rng, p_rng,
602 restart_enabled ) );
603 default:
604 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
605 }
606#endif
607}
608
609static int ecdh_read_public_internal( mbedtls_ecdh_context_mbed *ctx,
610 const unsigned char *buf, size_t blen )
611{
612 int ret;
613 const unsigned char *p = buf;
614
615 if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p,
616 blen ) ) != 0 )
Manuel Pégourié-Gonnard969ccc62014-03-26 19:53:25 +0100617 return( ret );
618
619 if( (size_t)( p - buf ) != blen )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard969ccc62014-03-26 19:53:25 +0100621
622 return( 0 );
Manuel Pégourié-Gonnard5cceb412013-02-11 21:51:45 +0100623}
624
Manuel Pégourié-Gonnard424fda52013-02-11 22:05:42 +0100625/*
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100626 * Parse and import the client's public value
Manuel Pégourié-Gonnard424fda52013-02-11 22:05:42 +0100627 */
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100628int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
629 const unsigned char *buf, size_t blen )
630{
Hanno Becker91796d72018-12-17 18:10:51 +0000631 ECDH_VALIDATE_RET( ctx != NULL );
632 ECDH_VALIDATE_RET( buf != NULL );
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100633
634#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
635 return( ecdh_read_public_internal( ctx, buf, blen ) );
636#else
637 switch( ctx->var )
638 {
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100639#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
640 case MBEDTLS_ECDH_VARIANT_EVEREST:
Christoph M. Wintersteiger4936beb2018-12-12 17:26:41 +0000641 return( mbedtls_everest_read_public( &ctx->ctx.everest_ecdh,
642 buf, blen ) );
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100643#endif
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100644 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
645 return( ecdh_read_public_internal( &ctx->ctx.mbed_ecdh,
646 buf, blen ) );
647 default:
648 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
649 }
650#endif
651}
652
653static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx,
654 size_t *olen, unsigned char *buf,
655 size_t blen,
656 int (*f_rng)(void *,
657 unsigned char *,
658 size_t),
659 void *p_rng,
660 int restart_enabled )
Manuel Pégourié-Gonnard424fda52013-02-11 22:05:42 +0100661{
662 int ret;
Ron Eldor2981d8f2018-11-05 18:07:10 +0200663#if defined(MBEDTLS_ECP_RESTARTABLE)
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200664 mbedtls_ecp_restart_ctx *rs_ctx = NULL;
Ron Eldor936d2842018-11-01 13:05:52 +0200665#endif
Manuel Pégourié-Gonnard424fda52013-02-11 22:05:42 +0100666
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200667 if( ctx == NULL || ctx->grp.pbits == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200668 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardf35b7392013-02-11 22:12:39 +0100669
Ron Eldorb430d9f2018-11-05 17:18:29 +0200670#if defined(MBEDTLS_ECP_RESTARTABLE)
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100671 if( restart_enabled )
Manuel Pégourié-Gonnard23e41622017-05-18 12:35:37 +0200672 rs_ctx = &ctx->rs;
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100673#else
674 (void) restart_enabled;
Manuel Pégourié-Gonnard66ba48a2017-04-27 11:38:26 +0200675#endif
676
Ron Eldor2981d8f2018-11-05 18:07:10 +0200677#if defined(MBEDTLS_ECP_RESTARTABLE)
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100678 if( ( ret = ecdh_compute_shared_restartable( &ctx->grp, &ctx->z, &ctx->Qp,
679 &ctx->d, f_rng, p_rng,
680 rs_ctx ) ) != 0 )
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +0200681 {
Manuel Pégourié-Gonnard424fda52013-02-11 22:05:42 +0100682 return( ret );
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +0200683 }
Ron Eldor2981d8f2018-11-05 18:07:10 +0200684#else
685 if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp,
686 &ctx->d, f_rng, p_rng ) ) != 0 )
687 {
688 return( ret );
689 }
690#endif /* MBEDTLS_ECP_RESTARTABLE */
Manuel Pégourié-Gonnard424fda52013-02-11 22:05:42 +0100691
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200692 if( mbedtls_mpi_size( &ctx->z ) > blen )
693 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Paul Bakker41c83d32013-03-20 14:39:14 +0100694
Manuel Pégourié-Gonnard0a56c2c2014-01-17 21:24:04 +0100695 *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
Janos Follathab0f71a2019-02-20 10:48:49 +0000696
Janos Follath52ff8e92019-02-26 13:56:04 +0000697 if( mbedtls_ecp_get_type( &ctx->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
Janos Follathab0f71a2019-02-20 10:48:49 +0000698 return mbedtls_mpi_write_binary_le( &ctx->z, buf, *olen );
699
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200700 return mbedtls_mpi_write_binary( &ctx->z, buf, *olen );
Manuel Pégourié-Gonnard424fda52013-02-11 22:05:42 +0100701}
702
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100703/*
704 * Derive and export the shared secret
705 */
706int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
707 unsigned char *buf, size_t blen,
708 int (*f_rng)(void *, unsigned char *, size_t),
709 void *p_rng )
710{
711 int restart_enabled = 0;
Hanno Becker91796d72018-12-17 18:10:51 +0000712 ECDH_VALIDATE_RET( ctx != NULL );
713 ECDH_VALIDATE_RET( olen != NULL );
714 ECDH_VALIDATE_RET( buf != NULL );
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100715
716#if defined(MBEDTLS_ECP_RESTARTABLE)
717 restart_enabled = ctx->restart_enabled;
718#endif
719
720#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
721 return( ecdh_calc_secret_internal( ctx, olen, buf, blen, f_rng, p_rng,
722 restart_enabled ) );
723#else
724 switch( ctx->var )
725 {
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100726#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
727 case MBEDTLS_ECDH_VARIANT_EVEREST:
Christoph M. Wintersteiger4936beb2018-12-12 17:26:41 +0000728 return( mbedtls_everest_calc_secret( &ctx->ctx.everest_ecdh, olen,
729 buf, blen, f_rng, p_rng ) );
Christoph M. Wintersteigerc9f737b2018-10-25 13:03:05 +0100730#endif
Janos Follath5a3e1bf2018-08-13 15:54:22 +0100731 case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
732 return( ecdh_calc_secret_internal( &ctx->ctx.mbed_ecdh, olen, buf,
733 blen, f_rng, p_rng,
734 restart_enabled ) );
735 default:
736 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
737 }
738#endif
739}
740
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200741#endif /* MBEDTLS_ECDH_C */