LCOV - code coverage report
Current view: top level - externals/mbedtls/library - ecdh.c (source / functions) Coverage Total Hit
Test: lcov.info Lines: 53.8 % 156 84
Test Date: 2026-03-12 12:01:18 Functions: 52.0 % 25 13
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 31.4 % 70 22

             Branch data     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                 :           8 : static mbedtls_ecp_group_id mbedtls_ecdh_grp_id(
      30                 :             :     const mbedtls_ecdh_context *ctx)
      31                 :             : {
      32                 :             : #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
      33                 :             :     return ctx->grp.id;
      34                 :             : #else
      35                 :           8 :     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                 :           0 :     (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                 :           0 : 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                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
      61                 :             : 
      62                 :           0 :     int restarting = 0;
      63                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
      64                 :             :     restarting = (rs_ctx != NULL && rs_ctx->rsm != NULL);
      65                 :             : #endif
      66                 :             :     /* If multiplication is in progress, we already generated a privkey */
      67                 :           0 :     if (!restarting) {
      68         [ #  # ]:           0 :         MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, d, f_rng, p_rng));
      69                 :             :     }
      70                 :             : 
      71                 :           0 :     MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, Q, d, &grp->G,
      72                 :             :                                                 f_rng, p_rng, rs_ctx));
      73                 :             : 
      74                 :           0 : cleanup:
      75                 :           0 :     return ret;
      76                 :             : }
      77                 :             : 
      78                 :             : /*
      79                 :             :  * Generate public key
      80                 :             :  */
      81                 :           0 : 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                 :           0 :     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                 :           4 : 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                 :           4 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     101                 :           4 :     mbedtls_ecp_point P;
     102                 :             : 
     103                 :           4 :     mbedtls_ecp_point_init(&P);
     104                 :             : 
     105         [ -  + ]:           4 :     MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, &P, d, Q,
     106                 :             :                                                 f_rng, p_rng, rs_ctx));
     107                 :             : 
     108         [ -  + ]:           4 :     if (mbedtls_ecp_is_zero(&P)) {
     109                 :           0 :         ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     110                 :           0 :         goto cleanup;
     111                 :             :     }
     112                 :             : 
     113                 :           4 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(z, &P.X));
     114                 :             : 
     115                 :           4 : cleanup:
     116                 :           4 :     mbedtls_ecp_point_free(&P);
     117                 :             : 
     118                 :           4 :     return ret;
     119                 :             : }
     120                 :             : 
     121                 :             : /*
     122                 :             :  * Compute shared secret (SEC1 3.3.1)
     123                 :             :  */
     124                 :           4 : 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                 :           4 :     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                 :           4 : static void ecdh_init_internal(mbedtls_ecdh_context_mbed *ctx)
     135                 :             : {
     136                 :           4 :     mbedtls_ecp_group_init(&ctx->grp);
     137                 :           4 :     mbedtls_mpi_init(&ctx->d);
     138                 :           4 :     mbedtls_ecp_point_init(&ctx->Q);
     139                 :           4 :     mbedtls_ecp_point_init(&ctx->Qp);
     140                 :           4 :     mbedtls_mpi_init(&ctx->z);
     141                 :             : 
     142                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
     143                 :             :     mbedtls_ecp_restart_init(&ctx->rs);
     144                 :             : #endif
     145                 :           4 : }
     146                 :             : 
     147                 :           0 : mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx)
     148                 :             : {
     149                 :             : #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
     150                 :             :     return ctx->MBEDTLS_PRIVATE(grp).id;
     151                 :             : #else
     152                 :           0 :     return ctx->MBEDTLS_PRIVATE(grp_id);
     153                 :             : #endif
     154                 :             : }
     155                 :             : 
     156                 :             : /*
     157                 :             :  * Initialize context
     158                 :             :  */
     159                 :           4 : void mbedtls_ecdh_init(mbedtls_ecdh_context *ctx)
     160                 :             : {
     161                 :             : #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
     162                 :             :     ecdh_init_internal(ctx);
     163                 :             :     mbedtls_ecp_point_init(&ctx->Vi);
     164                 :             :     mbedtls_ecp_point_init(&ctx->Vf);
     165                 :             :     mbedtls_mpi_init(&ctx->_d);
     166                 :             : #else
     167                 :           4 :     memset(ctx, 0, sizeof(mbedtls_ecdh_context));
     168                 :             : 
     169                 :           4 :     ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
     170                 :             : #endif
     171                 :           4 :     ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
     172                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
     173                 :             :     ctx->restart_enabled = 0;
     174                 :             : #endif
     175                 :           4 : }
     176                 :             : 
     177                 :           4 : static int ecdh_setup_internal(mbedtls_ecdh_context_mbed *ctx,
     178                 :             :                                mbedtls_ecp_group_id grp_id)
     179                 :             : {
     180                 :           4 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     181                 :             : 
     182                 :           4 :     ret = mbedtls_ecp_group_load(&ctx->grp, grp_id);
     183         [ -  + ]:           4 :     if (ret != 0) {
     184                 :           0 :         return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
     185                 :             :     }
     186                 :             : 
     187                 :             :     return 0;
     188                 :             : }
     189                 :             : 
     190                 :             : /*
     191                 :             :  * Setup context
     192                 :             :  */
     193                 :           4 : int mbedtls_ecdh_setup(mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id)
     194                 :             : {
     195                 :             : #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
     196                 :             :     return ecdh_setup_internal(ctx, grp_id);
     197                 :             : #else
     198                 :           4 :     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                 :           4 :             ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
     208                 :           4 :             ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
     209                 :           4 :             ctx->grp_id = grp_id;
     210                 :           4 :             ecdh_init_internal(&ctx->ctx.mbed_ecdh);
     211                 :           4 :             return ecdh_setup_internal(&ctx->ctx.mbed_ecdh, grp_id);
     212                 :             :     }
     213                 :             : #endif
     214                 :             : }
     215                 :             : 
     216                 :           4 : static void ecdh_free_internal(mbedtls_ecdh_context_mbed *ctx)
     217                 :             : {
     218                 :           4 :     mbedtls_ecp_group_free(&ctx->grp);
     219                 :           4 :     mbedtls_mpi_free(&ctx->d);
     220                 :           4 :     mbedtls_ecp_point_free(&ctx->Q);
     221                 :           4 :     mbedtls_ecp_point_free(&ctx->Qp);
     222                 :           4 :     mbedtls_mpi_free(&ctx->z);
     223                 :             : 
     224                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
     225                 :             :     mbedtls_ecp_restart_free(&ctx->rs);
     226                 :             : #endif
     227                 :           4 : }
     228                 :             : 
     229                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
     230                 :             : /*
     231                 :             :  * Enable restartable operations for context
     232                 :             :  */
     233                 :             : void mbedtls_ecdh_enable_restart(mbedtls_ecdh_context *ctx)
     234                 :             : {
     235                 :             :     ctx->restart_enabled = 1;
     236                 :             : }
     237                 :             : #endif
     238                 :             : 
     239                 :             : /*
     240                 :             :  * Free context
     241                 :             :  */
     242                 :           4 : void mbedtls_ecdh_free(mbedtls_ecdh_context *ctx)
     243                 :             : {
     244         [ +  - ]:           4 :     if (ctx == NULL) {
     245                 :             :         return;
     246                 :             :     }
     247                 :             : 
     248                 :             : #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
     249                 :             :     mbedtls_ecp_point_free(&ctx->Vi);
     250                 :             :     mbedtls_ecp_point_free(&ctx->Vf);
     251                 :             :     mbedtls_mpi_free(&ctx->_d);
     252                 :             :     ecdh_free_internal(ctx);
     253                 :             : #else
     254         [ +  - ]:           4 :     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                 :           4 :         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
     261                 :           4 :             ecdh_free_internal(&ctx->ctx.mbed_ecdh);
     262                 :           4 :             break;
     263                 :             :         default:
     264                 :             :             break;
     265                 :             :     }
     266                 :             : 
     267                 :           4 :     ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
     268                 :           4 :     ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
     269                 :           4 :     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                 :           0 :     size_t grp_len, pt_len;
     284                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
     285                 :             :     mbedtls_ecp_restart_ctx *rs_ctx = NULL;
     286                 :             : #endif
     287                 :             : 
     288         [ #  # ]:           0 :     if (ctx->grp.pbits == 0) {
     289                 :             :         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     290                 :             :     }
     291                 :             : 
     292                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
     293                 :             :     if (restart_enabled) {
     294                 :             :         rs_ctx = &ctx->rs;
     295                 :             :     }
     296                 :             : #else
     297                 :           0 :     (void) restart_enabled;
     298                 :             : #endif
     299                 :             : 
     300                 :             : 
     301                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
     302                 :             :     if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q,
     303                 :             :                                            f_rng, p_rng, rs_ctx)) != 0) {
     304                 :             :         return ret;
     305                 :             :     }
     306                 :             : #else
     307         [ #  # ]:           0 :     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                 :             :         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                 :             :         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                 :             :     restart_enabled = ctx->restart_enabled;
     345                 :             : #else
     346                 :           0 :     (void) restart_enabled;
     347                 :             : #endif
     348                 :             : 
     349                 :             : #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
     350                 :             :     return ecdh_make_params_internal(ctx, olen, ctx->point_format, buf, blen,
     351                 :             :                                      f_rng, p_rng, restart_enabled);
     352                 :             : #else
     353         [ #  # ]:           0 :     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                 :           0 :         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
     360                 :           0 :             return ecdh_make_params_internal(&ctx->ctx.mbed_ecdh, olen,
     361                 :           0 :                                              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                 :           0 :     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                 :             :         return ret;
     394                 :             :     }
     395                 :             : 
     396         [ #  # ]:           0 :     if ((ret = mbedtls_ecdh_setup(ctx, grp_id)) != 0) {
     397                 :             :         return ret;
     398                 :             :     }
     399                 :             : 
     400                 :             : #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
     401                 :             :     return ecdh_read_params_internal(ctx, buf, end);
     402                 :             : #else
     403         [ #  # ]:           0 :     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                 :           0 :         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
     410                 :           0 :             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                 :           8 : static int ecdh_get_params_internal(mbedtls_ecdh_context_mbed *ctx,
     419                 :             :                                     const mbedtls_ecp_keypair *key,
     420                 :             :                                     mbedtls_ecdh_side side)
     421                 :             : {
     422                 :           8 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     423                 :             : 
     424                 :             :     /* If it's not our key, just import the public part as Qp */
     425         [ +  + ]:           8 :     if (side == MBEDTLS_ECDH_THEIRS) {
     426                 :           4 :         return mbedtls_ecp_copy(&ctx->Qp, &key->Q);
     427                 :             :     }
     428                 :             : 
     429                 :             :     /* Our key: import public (as Q) and private parts */
     430         [ +  - ]:           4 :     if (side != MBEDTLS_ECDH_OURS) {
     431                 :             :         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     432                 :             :     }
     433                 :             : 
     434         [ +  - ]:           4 :     if ((ret = mbedtls_ecp_copy(&ctx->Q, &key->Q)) != 0 ||
     435         [ -  + ]:           4 :         (ret = mbedtls_mpi_copy(&ctx->d, &key->d)) != 0) {
     436                 :           0 :         return ret;
     437                 :             :     }
     438                 :             : 
     439                 :             :     return 0;
     440                 :             : }
     441                 :             : 
     442                 :             : /*
     443                 :             :  * Get parameters from a keypair
     444                 :             :  */
     445                 :           8 : int mbedtls_ecdh_get_params(mbedtls_ecdh_context *ctx,
     446                 :             :                             const mbedtls_ecp_keypair *key,
     447                 :             :                             mbedtls_ecdh_side side)
     448                 :             : {
     449                 :           8 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     450         [ -  + ]:           8 :     if (side != MBEDTLS_ECDH_OURS && side != MBEDTLS_ECDH_THEIRS) {
     451                 :             :         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     452                 :             :     }
     453                 :             : 
     454         [ +  + ]:           8 :     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         [ +  - ]:           4 :         if ((ret = mbedtls_ecdh_setup(ctx, key->grp.id)) != 0) {
     458                 :             :             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         [ -  + ]:           4 :         if (mbedtls_ecdh_grp_id(ctx) != key->grp.id) {
     465                 :             :             return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     466                 :             :         }
     467                 :             :     }
     468                 :             : 
     469                 :             : #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
     470                 :             :     return ecdh_get_params_internal(ctx, key, side);
     471                 :             : #else
     472         [ -  + ]:           8 :     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                 :           8 :         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
     484                 :           8 :             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                 :             :     mbedtls_ecp_restart_ctx *rs_ctx = NULL;
     504                 :             : #endif
     505                 :             : 
     506         [ #  # ]:           0 :     if (ctx->grp.pbits == 0) {
     507                 :             :         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     508                 :             :     }
     509                 :             : 
     510                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
     511                 :             :     if (restart_enabled) {
     512                 :             :         rs_ctx = &ctx->rs;
     513                 :             :     }
     514                 :             : #else
     515                 :           0 :     (void) restart_enabled;
     516                 :             : #endif
     517                 :             : 
     518                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
     519                 :             :     if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q,
     520                 :             :                                            f_rng, p_rng, rs_ctx)) != 0) {
     521                 :             :         return ret;
     522                 :             :     }
     523                 :             : #else
     524         [ #  # ]:           0 :     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                 :             :     restart_enabled = ctx->restart_enabled;
     545                 :             : #endif
     546                 :             : 
     547                 :             : #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
     548                 :             :     return ecdh_make_public_internal(ctx, olen, ctx->point_format, buf, blen,
     549                 :             :                                      f_rng, p_rng, restart_enabled);
     550                 :             : #else
     551         [ #  # ]:           0 :     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                 :           0 :         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
     558                 :           0 :             return ecdh_make_public_internal(&ctx->ctx.mbed_ecdh, olen,
     559                 :           0 :                                              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                 :             :         return ret;
     577                 :             :     }
     578                 :             : 
     579         [ #  # ]:           0 :     if ((size_t) (p - buf) != blen) {
     580                 :           0 :         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     581                 :             :     }
     582                 :             : 
     583                 :             :     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                 :             :     return ecdh_read_public_internal(ctx, buf, blen);
     594                 :             : #else
     595         [ #  # ]:           0 :     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                 :           0 :         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
     602                 :           0 :             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                 :           4 : 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                 :           4 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     620                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
     621                 :             :     mbedtls_ecp_restart_ctx *rs_ctx = NULL;
     622                 :             : #endif
     623                 :             : 
     624   [ +  -  -  + ]:           4 :     if (ctx == NULL || ctx->grp.pbits == 0) {
     625                 :             :         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     626                 :             :     }
     627                 :             : 
     628                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
     629                 :             :     if (restart_enabled) {
     630                 :             :         rs_ctx = &ctx->rs;
     631                 :             :     }
     632                 :             : #else
     633                 :           4 :     (void) restart_enabled;
     634                 :             : #endif
     635                 :             : 
     636                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
     637                 :             :     if ((ret = ecdh_compute_shared_restartable(&ctx->grp, &ctx->z, &ctx->Qp,
     638                 :             :                                                &ctx->d, f_rng, p_rng,
     639                 :             :                                                rs_ctx)) != 0) {
     640                 :             :         return ret;
     641                 :             :     }
     642                 :             : #else
     643         [ +  - ]:           4 :     if ((ret = mbedtls_ecdh_compute_shared(&ctx->grp, &ctx->z, &ctx->Qp,
     644                 :           4 :                                            &ctx->d, f_rng, p_rng)) != 0) {
     645                 :             :         return ret;
     646                 :             :     }
     647                 :             : #endif /* MBEDTLS_ECP_RESTARTABLE */
     648                 :             : 
     649         [ -  + ]:           4 :     if (mbedtls_mpi_size(&ctx->z) > blen) {
     650                 :             :         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     651                 :             :     }
     652                 :             : 
     653                 :           4 :     *olen = ctx->grp.pbits / 8 + ((ctx->grp.pbits % 8) != 0);
     654                 :             : 
     655         [ -  + ]:           4 :     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                 :           4 :     return mbedtls_mpi_write_binary(&ctx->z, buf, *olen);
     660                 :             : }
     661                 :             : 
     662                 :             : /*
     663                 :             :  * Derive and export the shared secret
     664                 :             :  */
     665                 :           4 : 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                 :           4 :     int restart_enabled = 0;
     671                 :             : #if defined(MBEDTLS_ECP_RESTARTABLE)
     672                 :             :     restart_enabled = ctx->restart_enabled;
     673                 :             : #endif
     674                 :             : 
     675                 :             : #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
     676                 :             :     return ecdh_calc_secret_internal(ctx, olen, buf, blen, f_rng, p_rng,
     677                 :             :                                      restart_enabled);
     678                 :             : #else
     679         [ +  - ]:           4 :     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                 :           4 :         case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
     686                 :           4 :             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