LCOV - code coverage report
Current view: top level - os_stub/mbedtlslib/mbedtls/library - ecdh.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 45.5 % 167 76
Test Date: 2025-06-29 08:09:00 Functions: 53.8 % 26 14

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

Generated by: LCOV version 2.0-1