Coverage Report

Created: 2024-05-15 07:13

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