LCOV - code coverage report
Current view: top level - os_stub/mbedtlslib/mbedtls/library - ecdsa.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 61.0 % 231 141
Test Date: 2025-06-29 08:09:00 Functions: 57.1 % 21 12

            Line data    Source code
       1              : /*
       2              :  *  Elliptic curve DSA
       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              :  */
      13              : 
      14              : #include "common.h"
      15              : 
      16              : #if defined(MBEDTLS_ECDSA_C)
      17              : 
      18              : #include "mbedtls/ecdsa.h"
      19              : #include "mbedtls/asn1write.h"
      20              : 
      21              : #include <string.h>
      22              : 
      23              : #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
      24              : #include "mbedtls/hmac_drbg.h"
      25              : #endif
      26              : 
      27              : #include "mbedtls/platform.h"
      28              : 
      29              : #include "mbedtls/platform_util.h"
      30              : #include "mbedtls/error.h"
      31              : 
      32              : #if defined(MBEDTLS_ECP_RESTARTABLE)
      33              : 
      34              : /*
      35              :  * Sub-context for ecdsa_verify()
      36              :  */
      37              : struct mbedtls_ecdsa_restart_ver {
      38              :     mbedtls_mpi u1, u2;     /* intermediate values  */
      39              :     enum {                  /* what to do next?     */
      40              :         ecdsa_ver_init = 0, /* getting started      */
      41              :         ecdsa_ver_muladd,   /* muladd step          */
      42              :     } state;
      43              : };
      44              : 
      45              : /*
      46              :  * Init verify restart sub-context
      47              :  */
      48            0 : static void ecdsa_restart_ver_init(mbedtls_ecdsa_restart_ver_ctx *ctx)
      49              : {
      50            0 :     mbedtls_mpi_init(&ctx->u1);
      51            0 :     mbedtls_mpi_init(&ctx->u2);
      52            0 :     ctx->state = ecdsa_ver_init;
      53            0 : }
      54              : 
      55              : /*
      56              :  * Free the components of a verify restart sub-context
      57              :  */
      58            0 : static void ecdsa_restart_ver_free(mbedtls_ecdsa_restart_ver_ctx *ctx)
      59              : {
      60            0 :     if (ctx == NULL) {
      61            0 :         return;
      62              :     }
      63              : 
      64            0 :     mbedtls_mpi_free(&ctx->u1);
      65            0 :     mbedtls_mpi_free(&ctx->u2);
      66              : 
      67            0 :     ecdsa_restart_ver_init(ctx);
      68              : }
      69              : 
      70              : /*
      71              :  * Sub-context for ecdsa_sign()
      72              :  */
      73              : struct mbedtls_ecdsa_restart_sig {
      74              :     int sign_tries;
      75              :     int key_tries;
      76              :     mbedtls_mpi k;          /* per-signature random */
      77              :     mbedtls_mpi r;          /* r value              */
      78              :     enum {                  /* what to do next?     */
      79              :         ecdsa_sig_init = 0, /* getting started      */
      80              :         ecdsa_sig_mul,      /* doing ecp_mul()      */
      81              :         ecdsa_sig_modn,     /* mod N computations   */
      82              :     } state;
      83              : };
      84              : 
      85              : /*
      86              :  * Init verify sign sub-context
      87              :  */
      88            0 : static void ecdsa_restart_sig_init(mbedtls_ecdsa_restart_sig_ctx *ctx)
      89              : {
      90            0 :     ctx->sign_tries = 0;
      91            0 :     ctx->key_tries = 0;
      92            0 :     mbedtls_mpi_init(&ctx->k);
      93            0 :     mbedtls_mpi_init(&ctx->r);
      94            0 :     ctx->state = ecdsa_sig_init;
      95            0 : }
      96              : 
      97              : /*
      98              :  * Free the components of a sign restart sub-context
      99              :  */
     100            0 : static void ecdsa_restart_sig_free(mbedtls_ecdsa_restart_sig_ctx *ctx)
     101              : {
     102            0 :     if (ctx == NULL) {
     103            0 :         return;
     104              :     }
     105              : 
     106            0 :     mbedtls_mpi_free(&ctx->k);
     107            0 :     mbedtls_mpi_free(&ctx->r);
     108              : }
     109              : 
     110              : #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
     111              : /*
     112              :  * Sub-context for ecdsa_sign_det()
     113              :  */
     114              : struct mbedtls_ecdsa_restart_det {
     115              :     mbedtls_hmac_drbg_context rng_ctx;  /* DRBG state   */
     116              :     enum {                      /* what to do next?     */
     117              :         ecdsa_det_init = 0,     /* getting started      */
     118              :         ecdsa_det_sign,         /* make signature       */
     119              :     } state;
     120              : };
     121              : 
     122              : /*
     123              :  * Init verify sign_det sub-context
     124              :  */
     125              : static void ecdsa_restart_det_init(mbedtls_ecdsa_restart_det_ctx *ctx)
     126              : {
     127              :     mbedtls_hmac_drbg_init(&ctx->rng_ctx);
     128              :     ctx->state = ecdsa_det_init;
     129              : }
     130              : 
     131              : /*
     132              :  * Free the components of a sign_det restart sub-context
     133              :  */
     134              : static void ecdsa_restart_det_free(mbedtls_ecdsa_restart_det_ctx *ctx)
     135              : {
     136              :     if (ctx == NULL) {
     137              :         return;
     138              :     }
     139              : 
     140              :     mbedtls_hmac_drbg_free(&ctx->rng_ctx);
     141              : 
     142              :     ecdsa_restart_det_init(ctx);
     143              : }
     144              : #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
     145              : 
     146              : #define ECDSA_RS_ECP    (rs_ctx == NULL ? NULL : &rs_ctx->ecp)
     147              : 
     148              : /* Utility macro for checking and updating ops budget */
     149              : #define ECDSA_BUDGET(ops)   \
     150              :     MBEDTLS_MPI_CHK(mbedtls_ecp_check_budget(grp, ECDSA_RS_ECP, ops));
     151              : 
     152              : /* Call this when entering a function that needs its own sub-context */
     153              : #define ECDSA_RS_ENTER(SUB)   do {                                 \
     154              :         /* reset ops count for this call if top-level */                 \
     155              :         if (rs_ctx != NULL && rs_ctx->ecp.depth++ == 0)                 \
     156              :         rs_ctx->ecp.ops_done = 0;                                    \
     157              :                                                                      \
     158              :         /* set up our own sub-context if needed */                       \
     159              :         if (mbedtls_ecp_restart_is_enabled() &&                          \
     160              :             rs_ctx != NULL && rs_ctx->SUB == NULL)                      \
     161              :         {                                                                \
     162              :             rs_ctx->SUB = mbedtls_calloc(1, sizeof(*rs_ctx->SUB));   \
     163              :             if (rs_ctx->SUB == NULL)                                    \
     164              :             return MBEDTLS_ERR_ECP_ALLOC_FAILED;                  \
     165              :                                                                    \
     166              :             ecdsa_restart_## SUB ##_init(rs_ctx->SUB);                 \
     167              :         }                                                                \
     168              : } while (0)
     169              : 
     170              : /* Call this when leaving a function that needs its own sub-context */
     171              : #define ECDSA_RS_LEAVE(SUB)   do {                                 \
     172              :         /* clear our sub-context when not in progress (done or error) */ \
     173              :         if (rs_ctx != NULL && rs_ctx->SUB != NULL &&                     \
     174              :             ret != MBEDTLS_ERR_ECP_IN_PROGRESS)                         \
     175              :         {                                                                \
     176              :             ecdsa_restart_## SUB ##_free(rs_ctx->SUB);                 \
     177              :             mbedtls_free(rs_ctx->SUB);                                 \
     178              :             rs_ctx->SUB = NULL;                                          \
     179              :         }                                                                \
     180              :                                                                      \
     181              :         if (rs_ctx != NULL)                                             \
     182              :         rs_ctx->ecp.depth--;                                         \
     183              : } while (0)
     184              : 
     185              : #else /* MBEDTLS_ECP_RESTARTABLE */
     186              : 
     187              : #define ECDSA_RS_ECP    NULL
     188              : 
     189              : #define ECDSA_BUDGET(ops)     /* no-op; for compatibility */
     190              : 
     191              : #define ECDSA_RS_ENTER(SUB)   (void) rs_ctx
     192              : #define ECDSA_RS_LEAVE(SUB)   (void) rs_ctx
     193              : 
     194              : #endif /* MBEDTLS_ECP_RESTARTABLE */
     195              : 
     196              : #if defined(MBEDTLS_ECDSA_DETERMINISTIC) || \
     197              :     !defined(MBEDTLS_ECDSA_SIGN_ALT)     || \
     198              :     !defined(MBEDTLS_ECDSA_VERIFY_ALT)
     199              : /*
     200              :  * Derive a suitable integer for group grp from a buffer of length len
     201              :  * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
     202              :  */
     203         1618 : static int derive_mpi(const mbedtls_ecp_group *grp, mbedtls_mpi *x,
     204              :                       const unsigned char *buf, size_t blen)
     205              : {
     206         1618 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     207         1618 :     size_t n_size = (grp->nbits + 7) / 8;
     208         1618 :     size_t use_size = blen > n_size ? n_size : blen;
     209              : 
     210         1618 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(x, buf, use_size));
     211         1618 :     if (use_size * 8 > grp->nbits) {
     212            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(x, use_size * 8 - grp->nbits));
     213              :     }
     214              : 
     215              :     /* While at it, reduce modulo N */
     216         1618 :     if (mbedtls_mpi_cmp_mpi(x, &grp->N) >= 0) {
     217            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(x, x, &grp->N));
     218              :     }
     219              : 
     220         1618 : cleanup:
     221         1618 :     return ret;
     222              : }
     223              : #endif /* ECDSA_DETERMINISTIC || !ECDSA_SIGN_ALT || !ECDSA_VERIFY_ALT */
     224              : 
     225         1621 : int mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid)
     226              : {
     227         1621 :     switch (gid) {
     228              : #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
     229            0 :         case MBEDTLS_ECP_DP_CURVE25519: return 0;
     230              : #endif
     231              : #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
     232            0 :         case MBEDTLS_ECP_DP_CURVE448: return 0;
     233              : #endif
     234         1621 :         default: return 1;
     235              :     }
     236              : }
     237              : 
     238              : #if !defined(MBEDTLS_ECDSA_SIGN_ALT)
     239              : /*
     240              :  * Compute ECDSA signature of a hashed message (SEC1 4.1.3)
     241              :  * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
     242              :  */
     243          147 : int mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp,
     244              :                                    mbedtls_mpi *r, mbedtls_mpi *s,
     245              :                                    const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
     246              :                                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
     247              :                                    int (*f_rng_blind)(void *, unsigned char *, size_t),
     248              :                                    void *p_rng_blind,
     249              :                                    mbedtls_ecdsa_restart_ctx *rs_ctx)
     250              : {
     251              :     int ret, key_tries, sign_tries;
     252          147 :     int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries;
     253              :     mbedtls_ecp_point R;
     254              :     mbedtls_mpi k, e, t;
     255          147 :     mbedtls_mpi *pk = &k, *pr = r;
     256              : 
     257              :     /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
     258          147 :     if (!mbedtls_ecdsa_can_do(grp->id) || grp->N.p == NULL) {
     259            0 :         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     260              :     }
     261              : 
     262              :     /* Make sure d is in range 1..n-1 */
     263          147 :     if (mbedtls_mpi_cmp_int(d, 1) < 0 || mbedtls_mpi_cmp_mpi(d, &grp->N) >= 0) {
     264            0 :         return MBEDTLS_ERR_ECP_INVALID_KEY;
     265              :     }
     266              : 
     267          147 :     mbedtls_ecp_point_init(&R);
     268          147 :     mbedtls_mpi_init(&k); mbedtls_mpi_init(&e); mbedtls_mpi_init(&t);
     269              : 
     270          147 :     ECDSA_RS_ENTER(sig);
     271              : 
     272              : #if defined(MBEDTLS_ECP_RESTARTABLE)
     273          147 :     if (rs_ctx != NULL && rs_ctx->sig != NULL) {
     274              :         /* redirect to our context */
     275            0 :         p_sign_tries = &rs_ctx->sig->sign_tries;
     276            0 :         p_key_tries = &rs_ctx->sig->key_tries;
     277            0 :         pk = &rs_ctx->sig->k;
     278            0 :         pr = &rs_ctx->sig->r;
     279              : 
     280              :         /* jump to current step */
     281            0 :         if (rs_ctx->sig->state == ecdsa_sig_mul) {
     282            0 :             goto mul;
     283              :         }
     284            0 :         if (rs_ctx->sig->state == ecdsa_sig_modn) {
     285            0 :             goto modn;
     286              :         }
     287              :     }
     288              : #endif /* MBEDTLS_ECP_RESTARTABLE */
     289              : 
     290          147 :     *p_sign_tries = 0;
     291              :     do {
     292          147 :         if ((*p_sign_tries)++ > 10) {
     293            0 :             ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
     294            0 :             goto cleanup;
     295              :         }
     296              : 
     297              :         /*
     298              :          * Steps 1-3: generate a suitable ephemeral keypair
     299              :          * and set r = xR mod n
     300              :          */
     301          147 :         *p_key_tries = 0;
     302              :         do {
     303          147 :             if ((*p_key_tries)++ > 10) {
     304            0 :                 ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
     305            0 :                 goto cleanup;
     306              :             }
     307              : 
     308          147 :             MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, pk, f_rng, p_rng));
     309              : 
     310              : #if defined(MBEDTLS_ECP_RESTARTABLE)
     311          147 :             if (rs_ctx != NULL && rs_ctx->sig != NULL) {
     312            0 :                 rs_ctx->sig->state = ecdsa_sig_mul;
     313              :             }
     314              : 
     315          147 : mul:
     316              : #endif
     317          147 :             MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, &R, pk, &grp->G,
     318              :                                                         f_rng_blind,
     319              :                                                         p_rng_blind,
     320              :                                                         ECDSA_RS_ECP));
     321          147 :             MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pr, &R.X, &grp->N));
     322          147 :         } while (mbedtls_mpi_cmp_int(pr, 0) == 0);
     323              : 
     324              : #if defined(MBEDTLS_ECP_RESTARTABLE)
     325          147 :         if (rs_ctx != NULL && rs_ctx->sig != NULL) {
     326            0 :             rs_ctx->sig->state = ecdsa_sig_modn;
     327              :         }
     328              : 
     329          147 : modn:
     330              : #endif
     331              :         /*
     332              :          * Accounting for everything up to the end of the loop
     333              :          * (step 6, but checking now avoids saving e and t)
     334              :          */
     335          147 :         ECDSA_BUDGET(MBEDTLS_ECP_OPS_INV + 4);
     336              : 
     337              :         /*
     338              :          * Step 5: derive MPI from hashed message
     339              :          */
     340          147 :         MBEDTLS_MPI_CHK(derive_mpi(grp, &e, buf, blen));
     341              : 
     342              :         /*
     343              :          * Generate a random value to blind inv_mod in next step,
     344              :          * avoiding a potential timing leak.
     345              :          */
     346          147 :         MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, &t, f_rng_blind,
     347              :                                                 p_rng_blind));
     348              : 
     349              :         /*
     350              :          * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
     351              :          */
     352          147 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(s, pr, d));
     353          147 :         MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&e, &e, s));
     354          147 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&e, &e, &t));
     355          147 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pk, pk, &t));
     356          147 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pk, pk, &grp->N));
     357          147 :         MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(s, pk, &grp->N));
     358          147 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(s, s, &e));
     359          147 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(s, s, &grp->N));
     360          147 :     } while (mbedtls_mpi_cmp_int(s, 0) == 0);
     361              : 
     362              : #if defined(MBEDTLS_ECP_RESTARTABLE)
     363          147 :     if (rs_ctx != NULL && rs_ctx->sig != NULL) {
     364            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(r, pr));
     365              :     }
     366              : #endif
     367              : 
     368          147 : cleanup:
     369          147 :     mbedtls_ecp_point_free(&R);
     370          147 :     mbedtls_mpi_free(&k); mbedtls_mpi_free(&e); mbedtls_mpi_free(&t);
     371              : 
     372          147 :     ECDSA_RS_LEAVE(sig);
     373              : 
     374          147 :     return ret;
     375              : }
     376              : 
     377              : /*
     378              :  * Compute ECDSA signature of a hashed message
     379              :  */
     380          141 : int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
     381              :                        const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
     382              :                        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
     383              : {
     384              :     /* Use the same RNG for both blinding and ephemeral key generation */
     385          141 :     return mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen,
     386              :                                           f_rng, p_rng, f_rng, p_rng, NULL);
     387              : }
     388              : #endif /* !MBEDTLS_ECDSA_SIGN_ALT */
     389              : 
     390              : #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
     391              : /*
     392              :  * Deterministic signature wrapper
     393              :  *
     394              :  * note:    The f_rng_blind parameter must not be NULL.
     395              :  *
     396              :  */
     397              : int mbedtls_ecdsa_sign_det_restartable(mbedtls_ecp_group *grp,
     398              :                                        mbedtls_mpi *r, mbedtls_mpi *s,
     399              :                                        const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
     400              :                                        mbedtls_md_type_t md_alg,
     401              :                                        int (*f_rng_blind)(void *, unsigned char *, size_t),
     402              :                                        void *p_rng_blind,
     403              :                                        mbedtls_ecdsa_restart_ctx *rs_ctx)
     404              : {
     405              :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     406              :     mbedtls_hmac_drbg_context rng_ctx;
     407              :     mbedtls_hmac_drbg_context *p_rng = &rng_ctx;
     408              :     unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
     409              :     size_t grp_len = (grp->nbits + 7) / 8;
     410              :     const mbedtls_md_info_t *md_info;
     411              :     mbedtls_mpi h;
     412              : 
     413              :     if ((md_info = mbedtls_md_info_from_type(md_alg)) == NULL) {
     414              :         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     415              :     }
     416              : 
     417              :     mbedtls_mpi_init(&h);
     418              :     mbedtls_hmac_drbg_init(&rng_ctx);
     419              : 
     420              :     ECDSA_RS_ENTER(det);
     421              : 
     422              : #if defined(MBEDTLS_ECP_RESTARTABLE)
     423              :     if (rs_ctx != NULL && rs_ctx->det != NULL) {
     424              :         /* redirect to our context */
     425              :         p_rng = &rs_ctx->det->rng_ctx;
     426              : 
     427              :         /* jump to current step */
     428              :         if (rs_ctx->det->state == ecdsa_det_sign) {
     429              :             goto sign;
     430              :         }
     431              :     }
     432              : #endif /* MBEDTLS_ECP_RESTARTABLE */
     433              : 
     434              :     /* Use private key and message hash (reduced) to initialize HMAC_DRBG */
     435              :     MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(d, data, grp_len));
     436              :     MBEDTLS_MPI_CHK(derive_mpi(grp, &h, buf, blen));
     437              :     MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&h, data + grp_len, grp_len));
     438              :     MBEDTLS_MPI_CHK(mbedtls_hmac_drbg_seed_buf(p_rng, md_info, data, 2 * grp_len));
     439              : 
     440              : #if defined(MBEDTLS_ECP_RESTARTABLE)
     441              :     if (rs_ctx != NULL && rs_ctx->det != NULL) {
     442              :         rs_ctx->det->state = ecdsa_det_sign;
     443              :     }
     444              : 
     445              : sign:
     446              : #endif
     447              : #if defined(MBEDTLS_ECDSA_SIGN_ALT)
     448              :     (void) f_rng_blind;
     449              :     (void) p_rng_blind;
     450              :     ret = mbedtls_ecdsa_sign(grp, r, s, d, buf, blen,
     451              :                              mbedtls_hmac_drbg_random, p_rng);
     452              : #else
     453              :     ret = mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen,
     454              :                                          mbedtls_hmac_drbg_random, p_rng,
     455              :                                          f_rng_blind, p_rng_blind, rs_ctx);
     456              : #endif /* MBEDTLS_ECDSA_SIGN_ALT */
     457              : 
     458              : cleanup:
     459              :     mbedtls_hmac_drbg_free(&rng_ctx);
     460              :     mbedtls_mpi_free(&h);
     461              : 
     462              :     ECDSA_RS_LEAVE(det);
     463              : 
     464              :     return ret;
     465              : }
     466              : 
     467              : /*
     468              :  * Deterministic signature wrapper
     469              :  */
     470              : int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r,
     471              :                                mbedtls_mpi *s, const mbedtls_mpi *d,
     472              :                                const unsigned char *buf, size_t blen,
     473              :                                mbedtls_md_type_t md_alg,
     474              :                                int (*f_rng_blind)(void *, unsigned char *,
     475              :                                                   size_t),
     476              :                                void *p_rng_blind)
     477              : {
     478              :     return mbedtls_ecdsa_sign_det_restartable(grp, r, s, d, buf, blen, md_alg,
     479              :                                               f_rng_blind, p_rng_blind, NULL);
     480              : }
     481              : #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
     482              : 
     483              : #if !defined(MBEDTLS_ECDSA_VERIFY_ALT)
     484              : /*
     485              :  * Verify ECDSA signature of hashed message (SEC1 4.1.4)
     486              :  * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
     487              :  */
     488         1474 : int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp,
     489              :                                      const unsigned char *buf, size_t blen,
     490              :                                      const mbedtls_ecp_point *Q,
     491              :                                      const mbedtls_mpi *r,
     492              :                                      const mbedtls_mpi *s,
     493              :                                      mbedtls_ecdsa_restart_ctx *rs_ctx)
     494              : {
     495         1474 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     496              :     mbedtls_mpi e, s_inv, u1, u2;
     497              :     mbedtls_ecp_point R;
     498         1474 :     mbedtls_mpi *pu1 = &u1, *pu2 = &u2;
     499              : 
     500         1474 :     mbedtls_ecp_point_init(&R);
     501         1474 :     mbedtls_mpi_init(&e); mbedtls_mpi_init(&s_inv);
     502         1474 :     mbedtls_mpi_init(&u1); mbedtls_mpi_init(&u2);
     503              : 
     504              :     /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
     505         1474 :     if (!mbedtls_ecdsa_can_do(grp->id) || grp->N.p == NULL) {
     506            0 :         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     507              :     }
     508              : 
     509         1474 :     ECDSA_RS_ENTER(ver);
     510              : 
     511              : #if defined(MBEDTLS_ECP_RESTARTABLE)
     512         1474 :     if (rs_ctx != NULL && rs_ctx->ver != NULL) {
     513              :         /* redirect to our context */
     514            0 :         pu1 = &rs_ctx->ver->u1;
     515            0 :         pu2 = &rs_ctx->ver->u2;
     516              : 
     517              :         /* jump to current step */
     518            0 :         if (rs_ctx->ver->state == ecdsa_ver_muladd) {
     519            0 :             goto muladd;
     520              :         }
     521              :     }
     522              : #endif /* MBEDTLS_ECP_RESTARTABLE */
     523              : 
     524              :     /*
     525              :      * Step 1: make sure r and s are in range 1..n-1
     526              :      */
     527         2945 :     if (mbedtls_mpi_cmp_int(r, 1) < 0 || mbedtls_mpi_cmp_mpi(r, &grp->N) >= 0 ||
     528         2942 :         mbedtls_mpi_cmp_int(s, 1) < 0 || mbedtls_mpi_cmp_mpi(s, &grp->N) >= 0) {
     529            3 :         ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
     530            3 :         goto cleanup;
     531              :     }
     532              : 
     533              :     /*
     534              :      * Step 3: derive MPI from hashed message
     535              :      */
     536         1471 :     MBEDTLS_MPI_CHK(derive_mpi(grp, &e, buf, blen));
     537              : 
     538              :     /*
     539              :      * Step 4: u1 = e / s mod n, u2 = r / s mod n
     540              :      */
     541         1471 :     ECDSA_BUDGET(MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2);
     542              : 
     543         1471 :     MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&s_inv, s, &grp->N));
     544              : 
     545         1471 :     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pu1, &e, &s_inv));
     546         1471 :     MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pu1, pu1, &grp->N));
     547              : 
     548         1471 :     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pu2, r, &s_inv));
     549         1471 :     MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pu2, pu2, &grp->N));
     550              : 
     551              : #if defined(MBEDTLS_ECP_RESTARTABLE)
     552         1471 :     if (rs_ctx != NULL && rs_ctx->ver != NULL) {
     553            0 :         rs_ctx->ver->state = ecdsa_ver_muladd;
     554              :     }
     555              : 
     556         1471 : muladd:
     557              : #endif
     558              :     /*
     559              :      * Step 5: R = u1 G + u2 Q
     560              :      */
     561         1471 :     MBEDTLS_MPI_CHK(mbedtls_ecp_muladd_restartable(grp,
     562              :                                                    &R, pu1, &grp->G, pu2, Q, ECDSA_RS_ECP));
     563              : 
     564         1471 :     if (mbedtls_ecp_is_zero(&R)) {
     565            0 :         ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
     566            0 :         goto cleanup;
     567              :     }
     568              : 
     569              :     /*
     570              :      * Step 6: convert xR to an integer (no-op)
     571              :      * Step 7: reduce xR mod n (gives v)
     572              :      */
     573         1471 :     MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&R.X, &R.X, &grp->N));
     574              : 
     575              :     /*
     576              :      * Step 8: check if v (that is, R.X) is equal to r
     577              :      */
     578         1471 :     if (mbedtls_mpi_cmp_mpi(&R.X, r) != 0) {
     579           16 :         ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
     580           16 :         goto cleanup;
     581              :     }
     582              : 
     583         1455 : cleanup:
     584         1474 :     mbedtls_ecp_point_free(&R);
     585         1474 :     mbedtls_mpi_free(&e); mbedtls_mpi_free(&s_inv);
     586         1474 :     mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2);
     587              : 
     588         1474 :     ECDSA_RS_LEAVE(ver);
     589              : 
     590         1474 :     return ret;
     591              : }
     592              : 
     593              : /*
     594              :  * Verify ECDSA signature of hashed message
     595              :  */
     596           83 : int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
     597              :                          const unsigned char *buf, size_t blen,
     598              :                          const mbedtls_ecp_point *Q,
     599              :                          const mbedtls_mpi *r,
     600              :                          const mbedtls_mpi *s)
     601              : {
     602           83 :     return mbedtls_ecdsa_verify_restartable(grp, buf, blen, Q, r, s, NULL);
     603              : }
     604              : #endif /* !MBEDTLS_ECDSA_VERIFY_ALT */
     605              : 
     606              : /*
     607              :  * Convert a signature (given by context) to ASN.1
     608              :  */
     609            6 : static int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s,
     610              :                                    unsigned char *sig, size_t sig_size,
     611              :                                    size_t *slen)
     612              : {
     613            6 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     614            6 :     unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = { 0 };
     615            6 :     unsigned char *p = buf + sizeof(buf);
     616            6 :     size_t len = 0;
     617              : 
     618            6 :     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, s));
     619            6 :     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, r));
     620              : 
     621            6 :     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, buf, len));
     622            6 :     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, buf,
     623              :                                                      MBEDTLS_ASN1_CONSTRUCTED |
     624              :                                                      MBEDTLS_ASN1_SEQUENCE));
     625              : 
     626            6 :     if (len > sig_size) {
     627            0 :         return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
     628              :     }
     629              : 
     630            6 :     memcpy(sig, p, len);
     631            6 :     *slen = len;
     632              : 
     633            6 :     return 0;
     634              : }
     635              : 
     636              : /*
     637              :  * Compute and write signature
     638              :  */
     639            6 : int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
     640              :                                               mbedtls_md_type_t md_alg,
     641              :                                               const unsigned char *hash, size_t hlen,
     642              :                                               unsigned char *sig, size_t sig_size, size_t *slen,
     643              :                                               int (*f_rng)(void *, unsigned char *, size_t),
     644              :                                               void *p_rng,
     645              :                                               mbedtls_ecdsa_restart_ctx *rs_ctx)
     646              : {
     647            6 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     648              :     mbedtls_mpi r, s;
     649            6 :     if (f_rng == NULL) {
     650            0 :         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     651              :     }
     652              : 
     653            6 :     mbedtls_mpi_init(&r);
     654            6 :     mbedtls_mpi_init(&s);
     655              : 
     656              : #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
     657              :     MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_restartable(&ctx->grp, &r, &s, &ctx->d,
     658              :                                                        hash, hlen, md_alg, f_rng,
     659              :                                                        p_rng, rs_ctx));
     660              : #else
     661              :     (void) md_alg;
     662              : 
     663              : #if defined(MBEDTLS_ECDSA_SIGN_ALT)
     664              :     (void) rs_ctx;
     665              : 
     666              :     MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign(&ctx->grp, &r, &s, &ctx->d,
     667              :                                        hash, hlen, f_rng, p_rng));
     668              : #else
     669              :     /* Use the same RNG for both blinding and ephemeral key generation */
     670            6 :     MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_restartable(&ctx->grp, &r, &s, &ctx->d,
     671              :                                                    hash, hlen, f_rng, p_rng, f_rng,
     672              :                                                    p_rng, rs_ctx));
     673              : #endif /* MBEDTLS_ECDSA_SIGN_ALT */
     674              : #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
     675              : 
     676            6 :     MBEDTLS_MPI_CHK(ecdsa_signature_to_asn1(&r, &s, sig, sig_size, slen));
     677              : 
     678            6 : cleanup:
     679            6 :     mbedtls_mpi_free(&r);
     680            6 :     mbedtls_mpi_free(&s);
     681              : 
     682            6 :     return ret;
     683              : }
     684              : 
     685              : /*
     686              :  * Compute and write signature
     687              :  */
     688            6 : int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx,
     689              :                                   mbedtls_md_type_t md_alg,
     690              :                                   const unsigned char *hash, size_t hlen,
     691              :                                   unsigned char *sig, size_t sig_size, size_t *slen,
     692              :                                   int (*f_rng)(void *, unsigned char *, size_t),
     693              :                                   void *p_rng)
     694              : {
     695            6 :     return mbedtls_ecdsa_write_signature_restartable(
     696              :         ctx, md_alg, hash, hlen, sig, sig_size, slen,
     697              :         f_rng, p_rng, NULL);
     698              : }
     699              : 
     700              : /*
     701              :  * Read and check signature
     702              :  */
     703         1391 : int mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx,
     704              :                                  const unsigned char *hash, size_t hlen,
     705              :                                  const unsigned char *sig, size_t slen)
     706              : {
     707         1391 :     return mbedtls_ecdsa_read_signature_restartable(
     708              :         ctx, hash, hlen, sig, slen, NULL);
     709              : }
     710              : 
     711              : /*
     712              :  * Restartable read and check signature
     713              :  */
     714         1391 : int mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx,
     715              :                                              const unsigned char *hash, size_t hlen,
     716              :                                              const unsigned char *sig, size_t slen,
     717              :                                              mbedtls_ecdsa_restart_ctx *rs_ctx)
     718              : {
     719         1391 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     720         1391 :     unsigned char *p = (unsigned char *) sig;
     721         1391 :     const unsigned char *end = sig + slen;
     722              :     size_t len;
     723              :     mbedtls_mpi r, s;
     724         1391 :     mbedtls_mpi_init(&r);
     725         1391 :     mbedtls_mpi_init(&s);
     726              : 
     727         1391 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
     728              :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
     729            0 :         ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     730            0 :         goto cleanup;
     731              :     }
     732              : 
     733         1391 :     if (p + len != end) {
     734            0 :         ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
     735              :                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     736            0 :         goto cleanup;
     737              :     }
     738              : 
     739         2782 :     if ((ret = mbedtls_asn1_get_mpi(&p, end, &r)) != 0 ||
     740         1391 :         (ret = mbedtls_asn1_get_mpi(&p, end, &s)) != 0) {
     741            0 :         ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     742            0 :         goto cleanup;
     743              :     }
     744              : #if defined(MBEDTLS_ECDSA_VERIFY_ALT)
     745              :     (void) rs_ctx;
     746              : 
     747              :     if ((ret = mbedtls_ecdsa_verify(&ctx->grp, hash, hlen,
     748              :                                     &ctx->Q, &r, &s)) != 0) {
     749              :         goto cleanup;
     750              :     }
     751              : #else
     752         1391 :     if ((ret = mbedtls_ecdsa_verify_restartable(&ctx->grp, hash, hlen,
     753         1391 :                                                 &ctx->Q, &r, &s, rs_ctx)) != 0) {
     754            2 :         goto cleanup;
     755              :     }
     756              : #endif /* MBEDTLS_ECDSA_VERIFY_ALT */
     757              : 
     758              :     /* At this point we know that the buffer starts with a valid signature.
     759              :      * Return 0 if the buffer just contains the signature, and a specific
     760              :      * error code if the valid signature is followed by more data. */
     761         1389 :     if (p != end) {
     762            0 :         ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH;
     763              :     }
     764              : 
     765         1389 : cleanup:
     766         1391 :     mbedtls_mpi_free(&r);
     767         1391 :     mbedtls_mpi_free(&s);
     768              : 
     769         1391 :     return ret;
     770              : }
     771              : 
     772              : #if !defined(MBEDTLS_ECDSA_GENKEY_ALT)
     773              : /*
     774              :  * Generate key pair
     775              :  */
     776            0 : int mbedtls_ecdsa_genkey(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
     777              :                          int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
     778              : {
     779            0 :     int ret = 0;
     780            0 :     ret = mbedtls_ecp_group_load(&ctx->grp, gid);
     781            0 :     if (ret != 0) {
     782            0 :         return ret;
     783              :     }
     784              : 
     785            0 :     return mbedtls_ecp_gen_keypair(&ctx->grp, &ctx->d,
     786              :                                    &ctx->Q, f_rng, p_rng);
     787              : }
     788              : #endif /* !MBEDTLS_ECDSA_GENKEY_ALT */
     789              : 
     790              : /*
     791              :  * Set context from an mbedtls_ecp_keypair
     792              :  */
     793            6 : int mbedtls_ecdsa_from_keypair(mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key)
     794              : {
     795            6 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     796           12 :     if ((ret = mbedtls_ecp_group_copy(&ctx->grp, &key->grp)) != 0 ||
     797           12 :         (ret = mbedtls_mpi_copy(&ctx->d, &key->d)) != 0 ||
     798            6 :         (ret = mbedtls_ecp_copy(&ctx->Q, &key->Q)) != 0) {
     799            0 :         mbedtls_ecdsa_free(ctx);
     800              :     }
     801              : 
     802            6 :     return ret;
     803              : }
     804              : 
     805              : /*
     806              :  * Initialize context
     807              :  */
     808            0 : void mbedtls_ecdsa_init(mbedtls_ecdsa_context *ctx)
     809              : {
     810            0 :     mbedtls_ecp_keypair_init(ctx);
     811            0 : }
     812              : 
     813              : /*
     814              :  * Free context
     815              :  */
     816            0 : void mbedtls_ecdsa_free(mbedtls_ecdsa_context *ctx)
     817              : {
     818            0 :     if (ctx == NULL) {
     819            0 :         return;
     820              :     }
     821              : 
     822            0 :     mbedtls_ecp_keypair_free(ctx);
     823              : }
     824              : 
     825              : #if defined(MBEDTLS_ECP_RESTARTABLE)
     826              : /*
     827              :  * Initialize a restart context
     828              :  */
     829            0 : void mbedtls_ecdsa_restart_init(mbedtls_ecdsa_restart_ctx *ctx)
     830              : {
     831            0 :     mbedtls_ecp_restart_init(&ctx->ecp);
     832              : 
     833            0 :     ctx->ver = NULL;
     834            0 :     ctx->sig = NULL;
     835              : #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
     836              :     ctx->det = NULL;
     837              : #endif
     838            0 : }
     839              : 
     840              : /*
     841              :  * Free the components of a restart context
     842              :  */
     843            0 : void mbedtls_ecdsa_restart_free(mbedtls_ecdsa_restart_ctx *ctx)
     844              : {
     845            0 :     if (ctx == NULL) {
     846            0 :         return;
     847              :     }
     848              : 
     849            0 :     mbedtls_ecp_restart_free(&ctx->ecp);
     850              : 
     851            0 :     ecdsa_restart_ver_free(ctx->ver);
     852            0 :     mbedtls_free(ctx->ver);
     853            0 :     ctx->ver = NULL;
     854              : 
     855            0 :     ecdsa_restart_sig_free(ctx->sig);
     856            0 :     mbedtls_free(ctx->sig);
     857            0 :     ctx->sig = NULL;
     858              : 
     859              : #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
     860              :     ecdsa_restart_det_free(ctx->det);
     861              :     mbedtls_free(ctx->det);
     862              :     ctx->det = NULL;
     863              : #endif
     864              : }
     865              : #endif /* MBEDTLS_ECP_RESTARTABLE */
     866              : 
     867              : #endif /* MBEDTLS_ECDSA_C */
        

Generated by: LCOV version 2.0-1