xref: /third_party/mbedtls/library/ecdsa.c (revision a8e1175b)
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 */
37struct 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 */
48static void ecdsa_restart_ver_init(mbedtls_ecdsa_restart_ver_ctx *ctx)
49{
50    mbedtls_mpi_init(&ctx->u1);
51    mbedtls_mpi_init(&ctx->u2);
52    ctx->state = ecdsa_ver_init;
53}
54
55/*
56 * Free the components of a verify restart sub-context
57 */
58static void ecdsa_restart_ver_free(mbedtls_ecdsa_restart_ver_ctx *ctx)
59{
60    if (ctx == NULL) {
61        return;
62    }
63
64    mbedtls_mpi_free(&ctx->u1);
65    mbedtls_mpi_free(&ctx->u2);
66
67    ecdsa_restart_ver_init(ctx);
68}
69
70/*
71 * Sub-context for ecdsa_sign()
72 */
73struct 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 */
88static void ecdsa_restart_sig_init(mbedtls_ecdsa_restart_sig_ctx *ctx)
89{
90    ctx->sign_tries = 0;
91    ctx->key_tries = 0;
92    mbedtls_mpi_init(&ctx->k);
93    mbedtls_mpi_init(&ctx->r);
94    ctx->state = ecdsa_sig_init;
95}
96
97/*
98 * Free the components of a sign restart sub-context
99 */
100static void ecdsa_restart_sig_free(mbedtls_ecdsa_restart_sig_ctx *ctx)
101{
102    if (ctx == NULL) {
103        return;
104    }
105
106    mbedtls_mpi_free(&ctx->k);
107    mbedtls_mpi_free(&ctx->r);
108}
109
110#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
111/*
112 * Sub-context for ecdsa_sign_det()
113 */
114struct 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 */
125static 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 */
134static 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 */
203static int derive_mpi(const mbedtls_ecp_group *grp, mbedtls_mpi *x,
204                      const unsigned char *buf, size_t blen)
205{
206    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
207    size_t n_size = (grp->nbits + 7) / 8;
208    size_t use_size = blen > n_size ? n_size : blen;
209
210    MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(x, buf, use_size));
211    if (use_size * 8 > grp->nbits) {
212        MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(x, use_size * 8 - grp->nbits));
213    }
214
215    /* While at it, reduce modulo N */
216    if (mbedtls_mpi_cmp_mpi(x, &grp->N) >= 0) {
217        MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(x, x, &grp->N));
218    }
219
220cleanup:
221    return ret;
222}
223#endif /* ECDSA_DETERMINISTIC || !ECDSA_SIGN_ALT || !ECDSA_VERIFY_ALT */
224
225int mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid)
226{
227    switch (gid) {
228#ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
229        case MBEDTLS_ECP_DP_CURVE25519: return 0;
230#endif
231#ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
232        case MBEDTLS_ECP_DP_CURVE448: return 0;
233#endif
234        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 */
243int 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    int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries;
253    mbedtls_ecp_point R;
254    mbedtls_mpi k, e, t;
255    mbedtls_mpi *pk = &k, *pr = r;
256
257    /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
258    if (!mbedtls_ecdsa_can_do(grp->id) || grp->N.p == NULL) {
259        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
260    }
261
262    /* Make sure d is in range 1..n-1 */
263    if (mbedtls_mpi_cmp_int(d, 1) < 0 || mbedtls_mpi_cmp_mpi(d, &grp->N) >= 0) {
264        return MBEDTLS_ERR_ECP_INVALID_KEY;
265    }
266
267    mbedtls_ecp_point_init(&R);
268    mbedtls_mpi_init(&k); mbedtls_mpi_init(&e); mbedtls_mpi_init(&t);
269
270    ECDSA_RS_ENTER(sig);
271
272#if defined(MBEDTLS_ECP_RESTARTABLE)
273    if (rs_ctx != NULL && rs_ctx->sig != NULL) {
274        /* redirect to our context */
275        p_sign_tries = &rs_ctx->sig->sign_tries;
276        p_key_tries = &rs_ctx->sig->key_tries;
277        pk = &rs_ctx->sig->k;
278        pr = &rs_ctx->sig->r;
279
280        /* jump to current step */
281        if (rs_ctx->sig->state == ecdsa_sig_mul) {
282            goto mul;
283        }
284        if (rs_ctx->sig->state == ecdsa_sig_modn) {
285            goto modn;
286        }
287    }
288#endif /* MBEDTLS_ECP_RESTARTABLE */
289
290    *p_sign_tries = 0;
291    do {
292        if ((*p_sign_tries)++ > 10) {
293            ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
294            goto cleanup;
295        }
296
297        /*
298         * Steps 1-3: generate a suitable ephemeral keypair
299         * and set r = xR mod n
300         */
301        *p_key_tries = 0;
302        do {
303            if ((*p_key_tries)++ > 10) {
304                ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
305                goto cleanup;
306            }
307
308            MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, pk, f_rng, p_rng));
309
310#if defined(MBEDTLS_ECP_RESTARTABLE)
311            if (rs_ctx != NULL && rs_ctx->sig != NULL) {
312                rs_ctx->sig->state = ecdsa_sig_mul;
313            }
314
315mul:
316#endif
317            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            MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pr, &R.X, &grp->N));
322        } while (mbedtls_mpi_cmp_int(pr, 0) == 0);
323
324#if defined(MBEDTLS_ECP_RESTARTABLE)
325        if (rs_ctx != NULL && rs_ctx->sig != NULL) {
326            rs_ctx->sig->state = ecdsa_sig_modn;
327        }
328
329modn:
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        ECDSA_BUDGET(MBEDTLS_ECP_OPS_INV + 4);
336
337        /*
338         * Step 5: derive MPI from hashed message
339         */
340        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        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        MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(s, pr, d));
353        MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&e, &e, s));
354        MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&e, &e, &t));
355        MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pk, pk, &t));
356        MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pk, pk, &grp->N));
357        MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(s, pk, &grp->N));
358        MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(s, s, &e));
359        MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(s, s, &grp->N));
360    } while (mbedtls_mpi_cmp_int(s, 0) == 0);
361
362#if defined(MBEDTLS_ECP_RESTARTABLE)
363    if (rs_ctx != NULL && rs_ctx->sig != NULL) {
364        MBEDTLS_MPI_CHK(mbedtls_mpi_copy(r, pr));
365    }
366#endif
367
368cleanup:
369    mbedtls_ecp_point_free(&R);
370    mbedtls_mpi_free(&k); mbedtls_mpi_free(&e); mbedtls_mpi_free(&t);
371
372    ECDSA_RS_LEAVE(sig);
373
374    return ret;
375}
376
377/*
378 * Compute ECDSA signature of a hashed message
379 */
380int 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    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 */
397int 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
445sign:
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
458cleanup:
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 */
470int 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 */
488int 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    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
496    mbedtls_mpi e, s_inv, u1, u2;
497    mbedtls_ecp_point R;
498    mbedtls_mpi *pu1 = &u1, *pu2 = &u2;
499
500    mbedtls_ecp_point_init(&R);
501    mbedtls_mpi_init(&e); mbedtls_mpi_init(&s_inv);
502    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    if (!mbedtls_ecdsa_can_do(grp->id) || grp->N.p == NULL) {
506        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
507    }
508
509    ECDSA_RS_ENTER(ver);
510
511#if defined(MBEDTLS_ECP_RESTARTABLE)
512    if (rs_ctx != NULL && rs_ctx->ver != NULL) {
513        /* redirect to our context */
514        pu1 = &rs_ctx->ver->u1;
515        pu2 = &rs_ctx->ver->u2;
516
517        /* jump to current step */
518        if (rs_ctx->ver->state == ecdsa_ver_muladd) {
519            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    if (mbedtls_mpi_cmp_int(r, 1) < 0 || mbedtls_mpi_cmp_mpi(r, &grp->N) >= 0 ||
528        mbedtls_mpi_cmp_int(s, 1) < 0 || mbedtls_mpi_cmp_mpi(s, &grp->N) >= 0) {
529        ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
530        goto cleanup;
531    }
532
533    /*
534     * Step 3: derive MPI from hashed message
535     */
536    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    ECDSA_BUDGET(MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2);
542
543    MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&s_inv, s, &grp->N));
544
545    MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pu1, &e, &s_inv));
546    MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pu1, pu1, &grp->N));
547
548    MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pu2, r, &s_inv));
549    MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pu2, pu2, &grp->N));
550
551#if defined(MBEDTLS_ECP_RESTARTABLE)
552    if (rs_ctx != NULL && rs_ctx->ver != NULL) {
553        rs_ctx->ver->state = ecdsa_ver_muladd;
554    }
555
556muladd:
557#endif
558    /*
559     * Step 5: R = u1 G + u2 Q
560     */
561    MBEDTLS_MPI_CHK(mbedtls_ecp_muladd_restartable(grp,
562                                                   &R, pu1, &grp->G, pu2, Q, ECDSA_RS_ECP));
563
564    if (mbedtls_ecp_is_zero(&R)) {
565        ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
566        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    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    if (mbedtls_mpi_cmp_mpi(&R.X, r) != 0) {
579        ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
580        goto cleanup;
581    }
582
583cleanup:
584    mbedtls_ecp_point_free(&R);
585    mbedtls_mpi_free(&e); mbedtls_mpi_free(&s_inv);
586    mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2);
587
588    ECDSA_RS_LEAVE(ver);
589
590    return ret;
591}
592
593/*
594 * Verify ECDSA signature of hashed message
595 */
596int 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    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 */
609static 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    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
614    unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = { 0 };
615    unsigned char *p = buf + sizeof(buf);
616    size_t len = 0;
617
618    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, s));
619    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, r));
620
621    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, buf, len));
622    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, buf,
623                                                     MBEDTLS_ASN1_CONSTRUCTED |
624                                                     MBEDTLS_ASN1_SEQUENCE));
625
626    if (len > sig_size) {
627        return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
628    }
629
630    memcpy(sig, p, len);
631    *slen = len;
632
633    return 0;
634}
635
636/*
637 * Compute and write signature
638 */
639int 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    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
648    mbedtls_mpi r, s;
649    if (f_rng == NULL) {
650        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
651    }
652
653    mbedtls_mpi_init(&r);
654    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    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    MBEDTLS_MPI_CHK(ecdsa_signature_to_asn1(&r, &s, sig, sig_size, slen));
677
678cleanup:
679    mbedtls_mpi_free(&r);
680    mbedtls_mpi_free(&s);
681
682    return ret;
683}
684
685/*
686 * Compute and write signature
687 */
688int 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    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 */
703int 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    return mbedtls_ecdsa_read_signature_restartable(
708        ctx, hash, hlen, sig, slen, NULL);
709}
710
711/*
712 * Restartable read and check signature
713 */
714int 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    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
720    unsigned char *p = (unsigned char *) sig;
721    const unsigned char *end = sig + slen;
722    size_t len;
723    mbedtls_mpi r, s;
724    mbedtls_mpi_init(&r);
725    mbedtls_mpi_init(&s);
726
727    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
728                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
729        ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
730        goto cleanup;
731    }
732
733    if (p + len != end) {
734        ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
735                                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
736        goto cleanup;
737    }
738
739    if ((ret = mbedtls_asn1_get_mpi(&p, end, &r)) != 0 ||
740        (ret = mbedtls_asn1_get_mpi(&p, end, &s)) != 0) {
741        ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
742        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    if ((ret = mbedtls_ecdsa_verify_restartable(&ctx->grp, hash, hlen,
753                                                &ctx->Q, &r, &s, rs_ctx)) != 0) {
754        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    if (p != end) {
762        ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH;
763    }
764
765cleanup:
766    mbedtls_mpi_free(&r);
767    mbedtls_mpi_free(&s);
768
769    return ret;
770}
771
772#if !defined(MBEDTLS_ECDSA_GENKEY_ALT)
773/*
774 * Generate key pair
775 */
776int 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    int ret = 0;
780    ret = mbedtls_ecp_group_load(&ctx->grp, gid);
781    if (ret != 0) {
782        return ret;
783    }
784
785    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 */
793int mbedtls_ecdsa_from_keypair(mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key)
794{
795    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
796    if ((ret = mbedtls_ecp_group_copy(&ctx->grp, &key->grp)) != 0 ||
797        (ret = mbedtls_mpi_copy(&ctx->d, &key->d)) != 0 ||
798        (ret = mbedtls_ecp_copy(&ctx->Q, &key->Q)) != 0) {
799        mbedtls_ecdsa_free(ctx);
800    }
801
802    return ret;
803}
804
805/*
806 * Initialize context
807 */
808void mbedtls_ecdsa_init(mbedtls_ecdsa_context *ctx)
809{
810    mbedtls_ecp_keypair_init(ctx);
811}
812
813/*
814 * Free context
815 */
816void mbedtls_ecdsa_free(mbedtls_ecdsa_context *ctx)
817{
818    if (ctx == NULL) {
819        return;
820    }
821
822    mbedtls_ecp_keypair_free(ctx);
823}
824
825#if defined(MBEDTLS_ECP_RESTARTABLE)
826/*
827 * Initialize a restart context
828 */
829void mbedtls_ecdsa_restart_init(mbedtls_ecdsa_restart_ctx *ctx)
830{
831    mbedtls_ecp_restart_init(&ctx->ecp);
832
833    ctx->ver = NULL;
834    ctx->sig = NULL;
835#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
836    ctx->det = NULL;
837#endif
838}
839
840/*
841 * Free the components of a restart context
842 */
843void mbedtls_ecdsa_restart_free(mbedtls_ecdsa_restart_ctx *ctx)
844{
845    if (ctx == NULL) {
846        return;
847    }
848
849    mbedtls_ecp_restart_free(&ctx->ecp);
850
851    ecdsa_restart_ver_free(ctx->ver);
852    mbedtls_free(ctx->ver);
853    ctx->ver = NULL;
854
855    ecdsa_restart_sig_free(ctx->sig);
856    mbedtls_free(ctx->sig);
857    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 */
868