Coverage Report

Created: 2025-07-01 06:54

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