1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * Elliptic curve Diffie-Hellman 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 5a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6a8e1175bSopenharmony_ci */ 7a8e1175bSopenharmony_ci 8a8e1175bSopenharmony_ci/* 9a8e1175bSopenharmony_ci * References: 10a8e1175bSopenharmony_ci * 11a8e1175bSopenharmony_ci * SEC1 https://www.secg.org/sec1-v2.pdf 12a8e1175bSopenharmony_ci * RFC 4492 13a8e1175bSopenharmony_ci */ 14a8e1175bSopenharmony_ci 15a8e1175bSopenharmony_ci#include "common.h" 16a8e1175bSopenharmony_ci 17a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_C) 18a8e1175bSopenharmony_ci 19a8e1175bSopenharmony_ci#include "mbedtls/ecdh.h" 20a8e1175bSopenharmony_ci#include "mbedtls/platform_util.h" 21a8e1175bSopenharmony_ci#include "mbedtls/error.h" 22a8e1175bSopenharmony_ci 23a8e1175bSopenharmony_ci#include <string.h> 24a8e1175bSopenharmony_ci 25a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 26a8e1175bSopenharmony_citypedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed; 27a8e1175bSopenharmony_ci#endif 28a8e1175bSopenharmony_ci 29a8e1175bSopenharmony_cistatic mbedtls_ecp_group_id mbedtls_ecdh_grp_id( 30a8e1175bSopenharmony_ci const mbedtls_ecdh_context *ctx) 31a8e1175bSopenharmony_ci{ 32a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 33a8e1175bSopenharmony_ci return ctx->grp.id; 34a8e1175bSopenharmony_ci#else 35a8e1175bSopenharmony_ci return ctx->grp_id; 36a8e1175bSopenharmony_ci#endif 37a8e1175bSopenharmony_ci} 38a8e1175bSopenharmony_ci 39a8e1175bSopenharmony_ciint mbedtls_ecdh_can_do(mbedtls_ecp_group_id gid) 40a8e1175bSopenharmony_ci{ 41a8e1175bSopenharmony_ci /* At this time, all groups support ECDH. */ 42a8e1175bSopenharmony_ci (void) gid; 43a8e1175bSopenharmony_ci return 1; 44a8e1175bSopenharmony_ci} 45a8e1175bSopenharmony_ci 46a8e1175bSopenharmony_ci#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) 47a8e1175bSopenharmony_ci/* 48a8e1175bSopenharmony_ci * Generate public key (restartable version) 49a8e1175bSopenharmony_ci * 50a8e1175bSopenharmony_ci * Note: this internal function relies on its caller preserving the value of 51a8e1175bSopenharmony_ci * the output parameter 'd' across continuation calls. This would not be 52a8e1175bSopenharmony_ci * acceptable for a public function but is OK here as we control call sites. 53a8e1175bSopenharmony_ci */ 54a8e1175bSopenharmony_cistatic int ecdh_gen_public_restartable(mbedtls_ecp_group *grp, 55a8e1175bSopenharmony_ci mbedtls_mpi *d, mbedtls_ecp_point *Q, 56a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 57a8e1175bSopenharmony_ci void *p_rng, 58a8e1175bSopenharmony_ci mbedtls_ecp_restart_ctx *rs_ctx) 59a8e1175bSopenharmony_ci{ 60a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 61a8e1175bSopenharmony_ci 62a8e1175bSopenharmony_ci int restarting = 0; 63a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 64a8e1175bSopenharmony_ci restarting = (rs_ctx != NULL && rs_ctx->rsm != NULL); 65a8e1175bSopenharmony_ci#endif 66a8e1175bSopenharmony_ci /* If multiplication is in progress, we already generated a privkey */ 67a8e1175bSopenharmony_ci if (!restarting) { 68a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, d, f_rng, p_rng)); 69a8e1175bSopenharmony_ci } 70a8e1175bSopenharmony_ci 71a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, Q, d, &grp->G, 72a8e1175bSopenharmony_ci f_rng, p_rng, rs_ctx)); 73a8e1175bSopenharmony_ci 74a8e1175bSopenharmony_cicleanup: 75a8e1175bSopenharmony_ci return ret; 76a8e1175bSopenharmony_ci} 77a8e1175bSopenharmony_ci 78a8e1175bSopenharmony_ci/* 79a8e1175bSopenharmony_ci * Generate public key 80a8e1175bSopenharmony_ci */ 81a8e1175bSopenharmony_ciint mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, 82a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 83a8e1175bSopenharmony_ci void *p_rng) 84a8e1175bSopenharmony_ci{ 85a8e1175bSopenharmony_ci return ecdh_gen_public_restartable(grp, d, Q, f_rng, p_rng, NULL); 86a8e1175bSopenharmony_ci} 87a8e1175bSopenharmony_ci#endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */ 88a8e1175bSopenharmony_ci 89a8e1175bSopenharmony_ci#if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) 90a8e1175bSopenharmony_ci/* 91a8e1175bSopenharmony_ci * Compute shared secret (SEC1 3.3.1) 92a8e1175bSopenharmony_ci */ 93a8e1175bSopenharmony_cistatic int ecdh_compute_shared_restartable(mbedtls_ecp_group *grp, 94a8e1175bSopenharmony_ci mbedtls_mpi *z, 95a8e1175bSopenharmony_ci const mbedtls_ecp_point *Q, const mbedtls_mpi *d, 96a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 97a8e1175bSopenharmony_ci void *p_rng, 98a8e1175bSopenharmony_ci mbedtls_ecp_restart_ctx *rs_ctx) 99a8e1175bSopenharmony_ci{ 100a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 101a8e1175bSopenharmony_ci mbedtls_ecp_point P; 102a8e1175bSopenharmony_ci 103a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&P); 104a8e1175bSopenharmony_ci 105a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, &P, d, Q, 106a8e1175bSopenharmony_ci f_rng, p_rng, rs_ctx)); 107a8e1175bSopenharmony_ci 108a8e1175bSopenharmony_ci if (mbedtls_ecp_is_zero(&P)) { 109a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 110a8e1175bSopenharmony_ci goto cleanup; 111a8e1175bSopenharmony_ci } 112a8e1175bSopenharmony_ci 113a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_copy(z, &P.X)); 114a8e1175bSopenharmony_ci 115a8e1175bSopenharmony_cicleanup: 116a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&P); 117a8e1175bSopenharmony_ci 118a8e1175bSopenharmony_ci return ret; 119a8e1175bSopenharmony_ci} 120a8e1175bSopenharmony_ci 121a8e1175bSopenharmony_ci/* 122a8e1175bSopenharmony_ci * Compute shared secret (SEC1 3.3.1) 123a8e1175bSopenharmony_ci */ 124a8e1175bSopenharmony_ciint mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z, 125a8e1175bSopenharmony_ci const mbedtls_ecp_point *Q, const mbedtls_mpi *d, 126a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 127a8e1175bSopenharmony_ci void *p_rng) 128a8e1175bSopenharmony_ci{ 129a8e1175bSopenharmony_ci return ecdh_compute_shared_restartable(grp, z, Q, d, 130a8e1175bSopenharmony_ci f_rng, p_rng, NULL); 131a8e1175bSopenharmony_ci} 132a8e1175bSopenharmony_ci#endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */ 133a8e1175bSopenharmony_ci 134a8e1175bSopenharmony_cistatic void ecdh_init_internal(mbedtls_ecdh_context_mbed *ctx) 135a8e1175bSopenharmony_ci{ 136a8e1175bSopenharmony_ci mbedtls_ecp_group_init(&ctx->grp); 137a8e1175bSopenharmony_ci mbedtls_mpi_init(&ctx->d); 138a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&ctx->Q); 139a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&ctx->Qp); 140a8e1175bSopenharmony_ci mbedtls_mpi_init(&ctx->z); 141a8e1175bSopenharmony_ci 142a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 143a8e1175bSopenharmony_ci mbedtls_ecp_restart_init(&ctx->rs); 144a8e1175bSopenharmony_ci#endif 145a8e1175bSopenharmony_ci} 146a8e1175bSopenharmony_ci 147a8e1175bSopenharmony_cimbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx) 148a8e1175bSopenharmony_ci{ 149a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 150a8e1175bSopenharmony_ci return ctx->MBEDTLS_PRIVATE(grp).id; 151a8e1175bSopenharmony_ci#else 152a8e1175bSopenharmony_ci return ctx->MBEDTLS_PRIVATE(grp_id); 153a8e1175bSopenharmony_ci#endif 154a8e1175bSopenharmony_ci} 155a8e1175bSopenharmony_ci 156a8e1175bSopenharmony_ci/* 157a8e1175bSopenharmony_ci * Initialize context 158a8e1175bSopenharmony_ci */ 159a8e1175bSopenharmony_civoid mbedtls_ecdh_init(mbedtls_ecdh_context *ctx) 160a8e1175bSopenharmony_ci{ 161a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 162a8e1175bSopenharmony_ci ecdh_init_internal(ctx); 163a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&ctx->Vi); 164a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&ctx->Vf); 165a8e1175bSopenharmony_ci mbedtls_mpi_init(&ctx->_d); 166a8e1175bSopenharmony_ci#else 167a8e1175bSopenharmony_ci memset(ctx, 0, sizeof(mbedtls_ecdh_context)); 168a8e1175bSopenharmony_ci 169a8e1175bSopenharmony_ci ctx->var = MBEDTLS_ECDH_VARIANT_NONE; 170a8e1175bSopenharmony_ci#endif 171a8e1175bSopenharmony_ci ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; 172a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 173a8e1175bSopenharmony_ci ctx->restart_enabled = 0; 174a8e1175bSopenharmony_ci#endif 175a8e1175bSopenharmony_ci} 176a8e1175bSopenharmony_ci 177a8e1175bSopenharmony_cistatic int ecdh_setup_internal(mbedtls_ecdh_context_mbed *ctx, 178a8e1175bSopenharmony_ci mbedtls_ecp_group_id grp_id) 179a8e1175bSopenharmony_ci{ 180a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 181a8e1175bSopenharmony_ci 182a8e1175bSopenharmony_ci ret = mbedtls_ecp_group_load(&ctx->grp, grp_id); 183a8e1175bSopenharmony_ci if (ret != 0) { 184a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; 185a8e1175bSopenharmony_ci } 186a8e1175bSopenharmony_ci 187a8e1175bSopenharmony_ci return 0; 188a8e1175bSopenharmony_ci} 189a8e1175bSopenharmony_ci 190a8e1175bSopenharmony_ci/* 191a8e1175bSopenharmony_ci * Setup context 192a8e1175bSopenharmony_ci */ 193a8e1175bSopenharmony_ciint mbedtls_ecdh_setup(mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id) 194a8e1175bSopenharmony_ci{ 195a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 196a8e1175bSopenharmony_ci return ecdh_setup_internal(ctx, grp_id); 197a8e1175bSopenharmony_ci#else 198a8e1175bSopenharmony_ci switch (grp_id) { 199a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) 200a8e1175bSopenharmony_ci case MBEDTLS_ECP_DP_CURVE25519: 201a8e1175bSopenharmony_ci ctx->point_format = MBEDTLS_ECP_PF_COMPRESSED; 202a8e1175bSopenharmony_ci ctx->var = MBEDTLS_ECDH_VARIANT_EVEREST; 203a8e1175bSopenharmony_ci ctx->grp_id = grp_id; 204a8e1175bSopenharmony_ci return mbedtls_everest_setup(&ctx->ctx.everest_ecdh, grp_id); 205a8e1175bSopenharmony_ci#endif 206a8e1175bSopenharmony_ci default: 207a8e1175bSopenharmony_ci ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; 208a8e1175bSopenharmony_ci ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0; 209a8e1175bSopenharmony_ci ctx->grp_id = grp_id; 210a8e1175bSopenharmony_ci ecdh_init_internal(&ctx->ctx.mbed_ecdh); 211a8e1175bSopenharmony_ci return ecdh_setup_internal(&ctx->ctx.mbed_ecdh, grp_id); 212a8e1175bSopenharmony_ci } 213a8e1175bSopenharmony_ci#endif 214a8e1175bSopenharmony_ci} 215a8e1175bSopenharmony_ci 216a8e1175bSopenharmony_cistatic void ecdh_free_internal(mbedtls_ecdh_context_mbed *ctx) 217a8e1175bSopenharmony_ci{ 218a8e1175bSopenharmony_ci mbedtls_ecp_group_free(&ctx->grp); 219a8e1175bSopenharmony_ci mbedtls_mpi_free(&ctx->d); 220a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&ctx->Q); 221a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&ctx->Qp); 222a8e1175bSopenharmony_ci mbedtls_mpi_free(&ctx->z); 223a8e1175bSopenharmony_ci 224a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 225a8e1175bSopenharmony_ci mbedtls_ecp_restart_free(&ctx->rs); 226a8e1175bSopenharmony_ci#endif 227a8e1175bSopenharmony_ci} 228a8e1175bSopenharmony_ci 229a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 230a8e1175bSopenharmony_ci/* 231a8e1175bSopenharmony_ci * Enable restartable operations for context 232a8e1175bSopenharmony_ci */ 233a8e1175bSopenharmony_civoid mbedtls_ecdh_enable_restart(mbedtls_ecdh_context *ctx) 234a8e1175bSopenharmony_ci{ 235a8e1175bSopenharmony_ci ctx->restart_enabled = 1; 236a8e1175bSopenharmony_ci} 237a8e1175bSopenharmony_ci#endif 238a8e1175bSopenharmony_ci 239a8e1175bSopenharmony_ci/* 240a8e1175bSopenharmony_ci * Free context 241a8e1175bSopenharmony_ci */ 242a8e1175bSopenharmony_civoid mbedtls_ecdh_free(mbedtls_ecdh_context *ctx) 243a8e1175bSopenharmony_ci{ 244a8e1175bSopenharmony_ci if (ctx == NULL) { 245a8e1175bSopenharmony_ci return; 246a8e1175bSopenharmony_ci } 247a8e1175bSopenharmony_ci 248a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 249a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&ctx->Vi); 250a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&ctx->Vf); 251a8e1175bSopenharmony_ci mbedtls_mpi_free(&ctx->_d); 252a8e1175bSopenharmony_ci ecdh_free_internal(ctx); 253a8e1175bSopenharmony_ci#else 254a8e1175bSopenharmony_ci switch (ctx->var) { 255a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) 256a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_EVEREST: 257a8e1175bSopenharmony_ci mbedtls_everest_free(&ctx->ctx.everest_ecdh); 258a8e1175bSopenharmony_ci break; 259a8e1175bSopenharmony_ci#endif 260a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: 261a8e1175bSopenharmony_ci ecdh_free_internal(&ctx->ctx.mbed_ecdh); 262a8e1175bSopenharmony_ci break; 263a8e1175bSopenharmony_ci default: 264a8e1175bSopenharmony_ci break; 265a8e1175bSopenharmony_ci } 266a8e1175bSopenharmony_ci 267a8e1175bSopenharmony_ci ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; 268a8e1175bSopenharmony_ci ctx->var = MBEDTLS_ECDH_VARIANT_NONE; 269a8e1175bSopenharmony_ci ctx->grp_id = MBEDTLS_ECP_DP_NONE; 270a8e1175bSopenharmony_ci#endif 271a8e1175bSopenharmony_ci} 272a8e1175bSopenharmony_ci 273a8e1175bSopenharmony_cistatic int ecdh_make_params_internal(mbedtls_ecdh_context_mbed *ctx, 274a8e1175bSopenharmony_ci size_t *olen, int point_format, 275a8e1175bSopenharmony_ci unsigned char *buf, size_t blen, 276a8e1175bSopenharmony_ci int (*f_rng)(void *, 277a8e1175bSopenharmony_ci unsigned char *, 278a8e1175bSopenharmony_ci size_t), 279a8e1175bSopenharmony_ci void *p_rng, 280a8e1175bSopenharmony_ci int restart_enabled) 281a8e1175bSopenharmony_ci{ 282a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 283a8e1175bSopenharmony_ci size_t grp_len, pt_len; 284a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 285a8e1175bSopenharmony_ci mbedtls_ecp_restart_ctx *rs_ctx = NULL; 286a8e1175bSopenharmony_ci#endif 287a8e1175bSopenharmony_ci 288a8e1175bSopenharmony_ci if (ctx->grp.pbits == 0) { 289a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 290a8e1175bSopenharmony_ci } 291a8e1175bSopenharmony_ci 292a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 293a8e1175bSopenharmony_ci if (restart_enabled) { 294a8e1175bSopenharmony_ci rs_ctx = &ctx->rs; 295a8e1175bSopenharmony_ci } 296a8e1175bSopenharmony_ci#else 297a8e1175bSopenharmony_ci (void) restart_enabled; 298a8e1175bSopenharmony_ci#endif 299a8e1175bSopenharmony_ci 300a8e1175bSopenharmony_ci 301a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 302a8e1175bSopenharmony_ci if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q, 303a8e1175bSopenharmony_ci f_rng, p_rng, rs_ctx)) != 0) { 304a8e1175bSopenharmony_ci return ret; 305a8e1175bSopenharmony_ci } 306a8e1175bSopenharmony_ci#else 307a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_gen_public(&ctx->grp, &ctx->d, &ctx->Q, 308a8e1175bSopenharmony_ci f_rng, p_rng)) != 0) { 309a8e1175bSopenharmony_ci return ret; 310a8e1175bSopenharmony_ci } 311a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECP_RESTARTABLE */ 312a8e1175bSopenharmony_ci 313a8e1175bSopenharmony_ci if ((ret = mbedtls_ecp_tls_write_group(&ctx->grp, &grp_len, buf, 314a8e1175bSopenharmony_ci blen)) != 0) { 315a8e1175bSopenharmony_ci return ret; 316a8e1175bSopenharmony_ci } 317a8e1175bSopenharmony_ci 318a8e1175bSopenharmony_ci buf += grp_len; 319a8e1175bSopenharmony_ci blen -= grp_len; 320a8e1175bSopenharmony_ci 321a8e1175bSopenharmony_ci if ((ret = mbedtls_ecp_tls_write_point(&ctx->grp, &ctx->Q, point_format, 322a8e1175bSopenharmony_ci &pt_len, buf, blen)) != 0) { 323a8e1175bSopenharmony_ci return ret; 324a8e1175bSopenharmony_ci } 325a8e1175bSopenharmony_ci 326a8e1175bSopenharmony_ci *olen = grp_len + pt_len; 327a8e1175bSopenharmony_ci return 0; 328a8e1175bSopenharmony_ci} 329a8e1175bSopenharmony_ci 330a8e1175bSopenharmony_ci/* 331a8e1175bSopenharmony_ci * Setup and write the ServerKeyExchange parameters (RFC 4492) 332a8e1175bSopenharmony_ci * struct { 333a8e1175bSopenharmony_ci * ECParameters curve_params; 334a8e1175bSopenharmony_ci * ECPoint public; 335a8e1175bSopenharmony_ci * } ServerECDHParams; 336a8e1175bSopenharmony_ci */ 337a8e1175bSopenharmony_ciint mbedtls_ecdh_make_params(mbedtls_ecdh_context *ctx, size_t *olen, 338a8e1175bSopenharmony_ci unsigned char *buf, size_t blen, 339a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 340a8e1175bSopenharmony_ci void *p_rng) 341a8e1175bSopenharmony_ci{ 342a8e1175bSopenharmony_ci int restart_enabled = 0; 343a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 344a8e1175bSopenharmony_ci restart_enabled = ctx->restart_enabled; 345a8e1175bSopenharmony_ci#else 346a8e1175bSopenharmony_ci (void) restart_enabled; 347a8e1175bSopenharmony_ci#endif 348a8e1175bSopenharmony_ci 349a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 350a8e1175bSopenharmony_ci return ecdh_make_params_internal(ctx, olen, ctx->point_format, buf, blen, 351a8e1175bSopenharmony_ci f_rng, p_rng, restart_enabled); 352a8e1175bSopenharmony_ci#else 353a8e1175bSopenharmony_ci switch (ctx->var) { 354a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) 355a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_EVEREST: 356a8e1175bSopenharmony_ci return mbedtls_everest_make_params(&ctx->ctx.everest_ecdh, olen, 357a8e1175bSopenharmony_ci buf, blen, f_rng, p_rng); 358a8e1175bSopenharmony_ci#endif 359a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: 360a8e1175bSopenharmony_ci return ecdh_make_params_internal(&ctx->ctx.mbed_ecdh, olen, 361a8e1175bSopenharmony_ci ctx->point_format, buf, blen, 362a8e1175bSopenharmony_ci f_rng, p_rng, 363a8e1175bSopenharmony_ci restart_enabled); 364a8e1175bSopenharmony_ci default: 365a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 366a8e1175bSopenharmony_ci } 367a8e1175bSopenharmony_ci#endif 368a8e1175bSopenharmony_ci} 369a8e1175bSopenharmony_ci 370a8e1175bSopenharmony_cistatic int ecdh_read_params_internal(mbedtls_ecdh_context_mbed *ctx, 371a8e1175bSopenharmony_ci const unsigned char **buf, 372a8e1175bSopenharmony_ci const unsigned char *end) 373a8e1175bSopenharmony_ci{ 374a8e1175bSopenharmony_ci return mbedtls_ecp_tls_read_point(&ctx->grp, &ctx->Qp, buf, 375a8e1175bSopenharmony_ci (size_t) (end - *buf)); 376a8e1175bSopenharmony_ci} 377a8e1175bSopenharmony_ci 378a8e1175bSopenharmony_ci/* 379a8e1175bSopenharmony_ci * Read the ServerKeyExchange parameters (RFC 4492) 380a8e1175bSopenharmony_ci * struct { 381a8e1175bSopenharmony_ci * ECParameters curve_params; 382a8e1175bSopenharmony_ci * ECPoint public; 383a8e1175bSopenharmony_ci * } ServerECDHParams; 384a8e1175bSopenharmony_ci */ 385a8e1175bSopenharmony_ciint mbedtls_ecdh_read_params(mbedtls_ecdh_context *ctx, 386a8e1175bSopenharmony_ci const unsigned char **buf, 387a8e1175bSopenharmony_ci const unsigned char *end) 388a8e1175bSopenharmony_ci{ 389a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 390a8e1175bSopenharmony_ci mbedtls_ecp_group_id grp_id; 391a8e1175bSopenharmony_ci if ((ret = mbedtls_ecp_tls_read_group_id(&grp_id, buf, (size_t) (end - *buf))) 392a8e1175bSopenharmony_ci != 0) { 393a8e1175bSopenharmony_ci return ret; 394a8e1175bSopenharmony_ci } 395a8e1175bSopenharmony_ci 396a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_setup(ctx, grp_id)) != 0) { 397a8e1175bSopenharmony_ci return ret; 398a8e1175bSopenharmony_ci } 399a8e1175bSopenharmony_ci 400a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 401a8e1175bSopenharmony_ci return ecdh_read_params_internal(ctx, buf, end); 402a8e1175bSopenharmony_ci#else 403a8e1175bSopenharmony_ci switch (ctx->var) { 404a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) 405a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_EVEREST: 406a8e1175bSopenharmony_ci return mbedtls_everest_read_params(&ctx->ctx.everest_ecdh, 407a8e1175bSopenharmony_ci buf, end); 408a8e1175bSopenharmony_ci#endif 409a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: 410a8e1175bSopenharmony_ci return ecdh_read_params_internal(&ctx->ctx.mbed_ecdh, 411a8e1175bSopenharmony_ci buf, end); 412a8e1175bSopenharmony_ci default: 413a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 414a8e1175bSopenharmony_ci } 415a8e1175bSopenharmony_ci#endif 416a8e1175bSopenharmony_ci} 417a8e1175bSopenharmony_ci 418a8e1175bSopenharmony_cistatic int ecdh_get_params_internal(mbedtls_ecdh_context_mbed *ctx, 419a8e1175bSopenharmony_ci const mbedtls_ecp_keypair *key, 420a8e1175bSopenharmony_ci mbedtls_ecdh_side side) 421a8e1175bSopenharmony_ci{ 422a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 423a8e1175bSopenharmony_ci 424a8e1175bSopenharmony_ci /* If it's not our key, just import the public part as Qp */ 425a8e1175bSopenharmony_ci if (side == MBEDTLS_ECDH_THEIRS) { 426a8e1175bSopenharmony_ci return mbedtls_ecp_copy(&ctx->Qp, &key->Q); 427a8e1175bSopenharmony_ci } 428a8e1175bSopenharmony_ci 429a8e1175bSopenharmony_ci /* Our key: import public (as Q) and private parts */ 430a8e1175bSopenharmony_ci if (side != MBEDTLS_ECDH_OURS) { 431a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 432a8e1175bSopenharmony_ci } 433a8e1175bSopenharmony_ci 434a8e1175bSopenharmony_ci if ((ret = mbedtls_ecp_copy(&ctx->Q, &key->Q)) != 0 || 435a8e1175bSopenharmony_ci (ret = mbedtls_mpi_copy(&ctx->d, &key->d)) != 0) { 436a8e1175bSopenharmony_ci return ret; 437a8e1175bSopenharmony_ci } 438a8e1175bSopenharmony_ci 439a8e1175bSopenharmony_ci return 0; 440a8e1175bSopenharmony_ci} 441a8e1175bSopenharmony_ci 442a8e1175bSopenharmony_ci/* 443a8e1175bSopenharmony_ci * Get parameters from a keypair 444a8e1175bSopenharmony_ci */ 445a8e1175bSopenharmony_ciint mbedtls_ecdh_get_params(mbedtls_ecdh_context *ctx, 446a8e1175bSopenharmony_ci const mbedtls_ecp_keypair *key, 447a8e1175bSopenharmony_ci mbedtls_ecdh_side side) 448a8e1175bSopenharmony_ci{ 449a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 450a8e1175bSopenharmony_ci if (side != MBEDTLS_ECDH_OURS && side != MBEDTLS_ECDH_THEIRS) { 451a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 452a8e1175bSopenharmony_ci } 453a8e1175bSopenharmony_ci 454a8e1175bSopenharmony_ci if (mbedtls_ecdh_grp_id(ctx) == MBEDTLS_ECP_DP_NONE) { 455a8e1175bSopenharmony_ci /* This is the first call to get_params(). Set up the context 456a8e1175bSopenharmony_ci * for use with the group. */ 457a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_setup(ctx, key->grp.id)) != 0) { 458a8e1175bSopenharmony_ci return ret; 459a8e1175bSopenharmony_ci } 460a8e1175bSopenharmony_ci } else { 461a8e1175bSopenharmony_ci /* This is not the first call to get_params(). Check that the 462a8e1175bSopenharmony_ci * current key's group is the same as the context's, which was set 463a8e1175bSopenharmony_ci * from the first key's group. */ 464a8e1175bSopenharmony_ci if (mbedtls_ecdh_grp_id(ctx) != key->grp.id) { 465a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 466a8e1175bSopenharmony_ci } 467a8e1175bSopenharmony_ci } 468a8e1175bSopenharmony_ci 469a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 470a8e1175bSopenharmony_ci return ecdh_get_params_internal(ctx, key, side); 471a8e1175bSopenharmony_ci#else 472a8e1175bSopenharmony_ci switch (ctx->var) { 473a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) 474a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_EVEREST: 475a8e1175bSopenharmony_ci { 476a8e1175bSopenharmony_ci mbedtls_everest_ecdh_side s = side == MBEDTLS_ECDH_OURS ? 477a8e1175bSopenharmony_ci MBEDTLS_EVEREST_ECDH_OURS : 478a8e1175bSopenharmony_ci MBEDTLS_EVEREST_ECDH_THEIRS; 479a8e1175bSopenharmony_ci return mbedtls_everest_get_params(&ctx->ctx.everest_ecdh, 480a8e1175bSopenharmony_ci key, s); 481a8e1175bSopenharmony_ci } 482a8e1175bSopenharmony_ci#endif 483a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: 484a8e1175bSopenharmony_ci return ecdh_get_params_internal(&ctx->ctx.mbed_ecdh, 485a8e1175bSopenharmony_ci key, side); 486a8e1175bSopenharmony_ci default: 487a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 488a8e1175bSopenharmony_ci } 489a8e1175bSopenharmony_ci#endif 490a8e1175bSopenharmony_ci} 491a8e1175bSopenharmony_ci 492a8e1175bSopenharmony_cistatic int ecdh_make_public_internal(mbedtls_ecdh_context_mbed *ctx, 493a8e1175bSopenharmony_ci size_t *olen, int point_format, 494a8e1175bSopenharmony_ci unsigned char *buf, size_t blen, 495a8e1175bSopenharmony_ci int (*f_rng)(void *, 496a8e1175bSopenharmony_ci unsigned char *, 497a8e1175bSopenharmony_ci size_t), 498a8e1175bSopenharmony_ci void *p_rng, 499a8e1175bSopenharmony_ci int restart_enabled) 500a8e1175bSopenharmony_ci{ 501a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 502a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 503a8e1175bSopenharmony_ci mbedtls_ecp_restart_ctx *rs_ctx = NULL; 504a8e1175bSopenharmony_ci#endif 505a8e1175bSopenharmony_ci 506a8e1175bSopenharmony_ci if (ctx->grp.pbits == 0) { 507a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 508a8e1175bSopenharmony_ci } 509a8e1175bSopenharmony_ci 510a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 511a8e1175bSopenharmony_ci if (restart_enabled) { 512a8e1175bSopenharmony_ci rs_ctx = &ctx->rs; 513a8e1175bSopenharmony_ci } 514a8e1175bSopenharmony_ci#else 515a8e1175bSopenharmony_ci (void) restart_enabled; 516a8e1175bSopenharmony_ci#endif 517a8e1175bSopenharmony_ci 518a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 519a8e1175bSopenharmony_ci if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q, 520a8e1175bSopenharmony_ci f_rng, p_rng, rs_ctx)) != 0) { 521a8e1175bSopenharmony_ci return ret; 522a8e1175bSopenharmony_ci } 523a8e1175bSopenharmony_ci#else 524a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_gen_public(&ctx->grp, &ctx->d, &ctx->Q, 525a8e1175bSopenharmony_ci f_rng, p_rng)) != 0) { 526a8e1175bSopenharmony_ci return ret; 527a8e1175bSopenharmony_ci } 528a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECP_RESTARTABLE */ 529a8e1175bSopenharmony_ci 530a8e1175bSopenharmony_ci return mbedtls_ecp_tls_write_point(&ctx->grp, &ctx->Q, point_format, olen, 531a8e1175bSopenharmony_ci buf, blen); 532a8e1175bSopenharmony_ci} 533a8e1175bSopenharmony_ci 534a8e1175bSopenharmony_ci/* 535a8e1175bSopenharmony_ci * Setup and export the client public value 536a8e1175bSopenharmony_ci */ 537a8e1175bSopenharmony_ciint mbedtls_ecdh_make_public(mbedtls_ecdh_context *ctx, size_t *olen, 538a8e1175bSopenharmony_ci unsigned char *buf, size_t blen, 539a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 540a8e1175bSopenharmony_ci void *p_rng) 541a8e1175bSopenharmony_ci{ 542a8e1175bSopenharmony_ci int restart_enabled = 0; 543a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 544a8e1175bSopenharmony_ci restart_enabled = ctx->restart_enabled; 545a8e1175bSopenharmony_ci#endif 546a8e1175bSopenharmony_ci 547a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 548a8e1175bSopenharmony_ci return ecdh_make_public_internal(ctx, olen, ctx->point_format, buf, blen, 549a8e1175bSopenharmony_ci f_rng, p_rng, restart_enabled); 550a8e1175bSopenharmony_ci#else 551a8e1175bSopenharmony_ci switch (ctx->var) { 552a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) 553a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_EVEREST: 554a8e1175bSopenharmony_ci return mbedtls_everest_make_public(&ctx->ctx.everest_ecdh, olen, 555a8e1175bSopenharmony_ci buf, blen, f_rng, p_rng); 556a8e1175bSopenharmony_ci#endif 557a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: 558a8e1175bSopenharmony_ci return ecdh_make_public_internal(&ctx->ctx.mbed_ecdh, olen, 559a8e1175bSopenharmony_ci ctx->point_format, buf, blen, 560a8e1175bSopenharmony_ci f_rng, p_rng, 561a8e1175bSopenharmony_ci restart_enabled); 562a8e1175bSopenharmony_ci default: 563a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 564a8e1175bSopenharmony_ci } 565a8e1175bSopenharmony_ci#endif 566a8e1175bSopenharmony_ci} 567a8e1175bSopenharmony_ci 568a8e1175bSopenharmony_cistatic int ecdh_read_public_internal(mbedtls_ecdh_context_mbed *ctx, 569a8e1175bSopenharmony_ci const unsigned char *buf, size_t blen) 570a8e1175bSopenharmony_ci{ 571a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 572a8e1175bSopenharmony_ci const unsigned char *p = buf; 573a8e1175bSopenharmony_ci 574a8e1175bSopenharmony_ci if ((ret = mbedtls_ecp_tls_read_point(&ctx->grp, &ctx->Qp, &p, 575a8e1175bSopenharmony_ci blen)) != 0) { 576a8e1175bSopenharmony_ci return ret; 577a8e1175bSopenharmony_ci } 578a8e1175bSopenharmony_ci 579a8e1175bSopenharmony_ci if ((size_t) (p - buf) != blen) { 580a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 581a8e1175bSopenharmony_ci } 582a8e1175bSopenharmony_ci 583a8e1175bSopenharmony_ci return 0; 584a8e1175bSopenharmony_ci} 585a8e1175bSopenharmony_ci 586a8e1175bSopenharmony_ci/* 587a8e1175bSopenharmony_ci * Parse and import the client's public value 588a8e1175bSopenharmony_ci */ 589a8e1175bSopenharmony_ciint mbedtls_ecdh_read_public(mbedtls_ecdh_context *ctx, 590a8e1175bSopenharmony_ci const unsigned char *buf, size_t blen) 591a8e1175bSopenharmony_ci{ 592a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 593a8e1175bSopenharmony_ci return ecdh_read_public_internal(ctx, buf, blen); 594a8e1175bSopenharmony_ci#else 595a8e1175bSopenharmony_ci switch (ctx->var) { 596a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) 597a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_EVEREST: 598a8e1175bSopenharmony_ci return mbedtls_everest_read_public(&ctx->ctx.everest_ecdh, 599a8e1175bSopenharmony_ci buf, blen); 600a8e1175bSopenharmony_ci#endif 601a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: 602a8e1175bSopenharmony_ci return ecdh_read_public_internal(&ctx->ctx.mbed_ecdh, 603a8e1175bSopenharmony_ci buf, blen); 604a8e1175bSopenharmony_ci default: 605a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 606a8e1175bSopenharmony_ci } 607a8e1175bSopenharmony_ci#endif 608a8e1175bSopenharmony_ci} 609a8e1175bSopenharmony_ci 610a8e1175bSopenharmony_cistatic int ecdh_calc_secret_internal(mbedtls_ecdh_context_mbed *ctx, 611a8e1175bSopenharmony_ci size_t *olen, unsigned char *buf, 612a8e1175bSopenharmony_ci size_t blen, 613a8e1175bSopenharmony_ci int (*f_rng)(void *, 614a8e1175bSopenharmony_ci unsigned char *, 615a8e1175bSopenharmony_ci size_t), 616a8e1175bSopenharmony_ci void *p_rng, 617a8e1175bSopenharmony_ci int restart_enabled) 618a8e1175bSopenharmony_ci{ 619a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 620a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 621a8e1175bSopenharmony_ci mbedtls_ecp_restart_ctx *rs_ctx = NULL; 622a8e1175bSopenharmony_ci#endif 623a8e1175bSopenharmony_ci 624a8e1175bSopenharmony_ci if (ctx == NULL || ctx->grp.pbits == 0) { 625a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 626a8e1175bSopenharmony_ci } 627a8e1175bSopenharmony_ci 628a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 629a8e1175bSopenharmony_ci if (restart_enabled) { 630a8e1175bSopenharmony_ci rs_ctx = &ctx->rs; 631a8e1175bSopenharmony_ci } 632a8e1175bSopenharmony_ci#else 633a8e1175bSopenharmony_ci (void) restart_enabled; 634a8e1175bSopenharmony_ci#endif 635a8e1175bSopenharmony_ci 636a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 637a8e1175bSopenharmony_ci if ((ret = ecdh_compute_shared_restartable(&ctx->grp, &ctx->z, &ctx->Qp, 638a8e1175bSopenharmony_ci &ctx->d, f_rng, p_rng, 639a8e1175bSopenharmony_ci rs_ctx)) != 0) { 640a8e1175bSopenharmony_ci return ret; 641a8e1175bSopenharmony_ci } 642a8e1175bSopenharmony_ci#else 643a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_compute_shared(&ctx->grp, &ctx->z, &ctx->Qp, 644a8e1175bSopenharmony_ci &ctx->d, f_rng, p_rng)) != 0) { 645a8e1175bSopenharmony_ci return ret; 646a8e1175bSopenharmony_ci } 647a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECP_RESTARTABLE */ 648a8e1175bSopenharmony_ci 649a8e1175bSopenharmony_ci if (mbedtls_mpi_size(&ctx->z) > blen) { 650a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 651a8e1175bSopenharmony_ci } 652a8e1175bSopenharmony_ci 653a8e1175bSopenharmony_ci *olen = ctx->grp.pbits / 8 + ((ctx->grp.pbits % 8) != 0); 654a8e1175bSopenharmony_ci 655a8e1175bSopenharmony_ci if (mbedtls_ecp_get_type(&ctx->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { 656a8e1175bSopenharmony_ci return mbedtls_mpi_write_binary_le(&ctx->z, buf, *olen); 657a8e1175bSopenharmony_ci } 658a8e1175bSopenharmony_ci 659a8e1175bSopenharmony_ci return mbedtls_mpi_write_binary(&ctx->z, buf, *olen); 660a8e1175bSopenharmony_ci} 661a8e1175bSopenharmony_ci 662a8e1175bSopenharmony_ci/* 663a8e1175bSopenharmony_ci * Derive and export the shared secret 664a8e1175bSopenharmony_ci */ 665a8e1175bSopenharmony_ciint mbedtls_ecdh_calc_secret(mbedtls_ecdh_context *ctx, size_t *olen, 666a8e1175bSopenharmony_ci unsigned char *buf, size_t blen, 667a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 668a8e1175bSopenharmony_ci void *p_rng) 669a8e1175bSopenharmony_ci{ 670a8e1175bSopenharmony_ci int restart_enabled = 0; 671a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_RESTARTABLE) 672a8e1175bSopenharmony_ci restart_enabled = ctx->restart_enabled; 673a8e1175bSopenharmony_ci#endif 674a8e1175bSopenharmony_ci 675a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 676a8e1175bSopenharmony_ci return ecdh_calc_secret_internal(ctx, olen, buf, blen, f_rng, p_rng, 677a8e1175bSopenharmony_ci restart_enabled); 678a8e1175bSopenharmony_ci#else 679a8e1175bSopenharmony_ci switch (ctx->var) { 680a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) 681a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_EVEREST: 682a8e1175bSopenharmony_ci return mbedtls_everest_calc_secret(&ctx->ctx.everest_ecdh, olen, 683a8e1175bSopenharmony_ci buf, blen, f_rng, p_rng); 684a8e1175bSopenharmony_ci#endif 685a8e1175bSopenharmony_ci case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: 686a8e1175bSopenharmony_ci return ecdh_calc_secret_internal(&ctx->ctx.mbed_ecdh, olen, buf, 687a8e1175bSopenharmony_ci blen, f_rng, p_rng, 688a8e1175bSopenharmony_ci restart_enabled); 689a8e1175bSopenharmony_ci default: 690a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 691a8e1175bSopenharmony_ci } 692a8e1175bSopenharmony_ci#endif 693a8e1175bSopenharmony_ci} 694a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECDH_C */ 695