Coverage Report

Created: 2024-07-27 06:36

/src/openssl/providers/implementations/signature/ecdsa_sig.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
/*
11
 * ECDSA low level APIs are deprecated for public use, but still ok for
12
 * internal use.
13
 */
14
#include "internal/deprecated.h"
15
16
#include <string.h> /* memcpy */
17
#include <openssl/crypto.h>
18
#include <openssl/core_dispatch.h>
19
#include <openssl/core_names.h>
20
#include <openssl/dsa.h>
21
#include <openssl/params.h>
22
#include <openssl/evp.h>
23
#include <openssl/err.h>
24
#include <openssl/proverr.h>
25
#include "internal/nelem.h"
26
#include "internal/sizes.h"
27
#include "internal/cryptlib.h"
28
#include "internal/deterministic_nonce.h"
29
#include "prov/providercommon.h"
30
#include "prov/implementations.h"
31
#include "prov/provider_ctx.h"
32
#include "prov/securitycheck.h"
33
#include "prov/fipsindicator.h"
34
#include "crypto/ec.h"
35
#include "prov/der_ec.h"
36
37
static OSSL_FUNC_signature_newctx_fn ecdsa_newctx;
38
static OSSL_FUNC_signature_sign_init_fn ecdsa_sign_init;
39
static OSSL_FUNC_signature_verify_init_fn ecdsa_verify_init;
40
static OSSL_FUNC_signature_sign_fn ecdsa_sign;
41
static OSSL_FUNC_signature_verify_fn ecdsa_verify;
42
static OSSL_FUNC_signature_digest_sign_init_fn ecdsa_digest_sign_init;
43
static OSSL_FUNC_signature_digest_sign_update_fn ecdsa_digest_signverify_update;
44
static OSSL_FUNC_signature_digest_sign_final_fn ecdsa_digest_sign_final;
45
static OSSL_FUNC_signature_digest_verify_init_fn ecdsa_digest_verify_init;
46
static OSSL_FUNC_signature_digest_verify_update_fn ecdsa_digest_signverify_update;
47
static OSSL_FUNC_signature_digest_verify_final_fn ecdsa_digest_verify_final;
48
static OSSL_FUNC_signature_freectx_fn ecdsa_freectx;
49
static OSSL_FUNC_signature_dupctx_fn ecdsa_dupctx;
50
static OSSL_FUNC_signature_get_ctx_params_fn ecdsa_get_ctx_params;
51
static OSSL_FUNC_signature_gettable_ctx_params_fn ecdsa_gettable_ctx_params;
52
static OSSL_FUNC_signature_set_ctx_params_fn ecdsa_set_ctx_params;
53
static OSSL_FUNC_signature_settable_ctx_params_fn ecdsa_settable_ctx_params;
54
static OSSL_FUNC_signature_get_ctx_md_params_fn ecdsa_get_ctx_md_params;
55
static OSSL_FUNC_signature_gettable_ctx_md_params_fn ecdsa_gettable_ctx_md_params;
56
static OSSL_FUNC_signature_set_ctx_md_params_fn ecdsa_set_ctx_md_params;
57
static OSSL_FUNC_signature_settable_ctx_md_params_fn ecdsa_settable_ctx_md_params;
58
59
/*
60
 * What's passed as an actual key is defined by the KEYMGMT interface.
61
 * We happen to know that our KEYMGMT simply passes DSA structures, so
62
 * we use that here too.
63
 */
64
65
typedef struct {
66
    OSSL_LIB_CTX *libctx;
67
    char *propq;
68
    EC_KEY *ec;
69
    char mdname[OSSL_MAX_NAME_SIZE];
70
71
    /*
72
     * Flag to determine if the hash function can be changed (1) or not (0)
73
     * Because it's dangerous to change during a DigestSign or DigestVerify
74
     * operation, this flag is cleared by their Init function, and set again
75
     * by their Final function.
76
     */
77
    unsigned int flag_allow_md : 1;
78
79
    /* The Algorithm Identifier of the combined signature algorithm */
80
    unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE];
81
    unsigned char *aid;
82
    size_t  aid_len;
83
    size_t mdsize;
84
    int operation;
85
86
    EVP_MD *md;
87
    EVP_MD_CTX *mdctx;
88
    /*
89
     * Internally used to cache the results of calling the EC group
90
     * sign_setup() methods which are then passed to the sign operation.
91
     * This is used by CAVS failure tests to terminate a loop if the signature
92
     * is not valid.
93
     * This could of also been done with a simple flag.
94
     */
95
    BIGNUM *kinv;
96
    BIGNUM *r;
97
#if !defined(OPENSSL_NO_ACVP_TESTS)
98
    /*
99
     * This indicates that KAT (CAVS) test is running. Externally an app will
100
     * override the random callback such that the generated private key and k
101
     * are known.
102
     * Normal operation will loop to choose a new k if the signature is not
103
     * valid - but for this mode of operation it forces a failure instead.
104
     */
105
    unsigned int kattest;
106
#endif
107
    /* If this is set then the generated k is not random */
108
    unsigned int nonce_type;
109
    OSSL_FIPS_IND_DECLARE
110
} PROV_ECDSA_CTX;
111
112
static void *ecdsa_newctx(void *provctx, const char *propq)
113
0
{
114
0
    PROV_ECDSA_CTX *ctx;
115
116
0
    if (!ossl_prov_is_running())
117
0
        return NULL;
118
119
0
    ctx = OPENSSL_zalloc(sizeof(PROV_ECDSA_CTX));
120
0
    if (ctx == NULL)
121
0
        return NULL;
122
123
0
    OSSL_FIPS_IND_INIT(ctx)
124
0
    ctx->flag_allow_md = 1;
125
0
    ctx->libctx = PROV_LIBCTX_OF(provctx);
126
0
    if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) {
127
0
        OPENSSL_free(ctx);
128
0
        ctx = NULL;
129
0
    }
130
0
    return ctx;
131
0
}
132
133
static int ecdsa_signverify_init(void *vctx, void *ec,
134
                                 const OSSL_PARAM params[], int operation,
135
                                 const char *desc)
136
0
{
137
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
138
139
0
    if (!ossl_prov_is_running()
140
0
            || ctx == NULL)
141
0
        return 0;
142
143
0
    if (ec == NULL && ctx->ec == NULL) {
144
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
145
0
        return 0;
146
0
    }
147
148
0
    if (ec != NULL) {
149
0
        if (!EC_KEY_up_ref(ec))
150
0
            return 0;
151
0
        EC_KEY_free(ctx->ec);
152
0
        ctx->ec = ec;
153
0
    }
154
155
0
    ctx->operation = operation;
156
157
0
    OSSL_FIPS_IND_SET_APPROVED(ctx)
158
0
    if (!ecdsa_set_ctx_params(ctx, params))
159
0
        return 0;
160
#ifdef FIPS_MODULE
161
    if (!ossl_fips_ind_ec_key_check(OSSL_FIPS_IND_GET(ctx),
162
                                    OSSL_FIPS_IND_SETTABLE0, ctx->libctx,
163
                                    EC_KEY_get0_group(ctx->ec), desc,
164
                                    operation == EVP_PKEY_OP_SIGN))
165
        return 0;
166
#endif
167
0
    return 1;
168
0
}
169
170
static int ecdsa_sign_init(void *vctx, void *ec, const OSSL_PARAM params[])
171
0
{
172
0
    return ecdsa_signverify_init(vctx, ec, params, EVP_PKEY_OP_SIGN,
173
0
                                 "ECDSA Sign Init");
174
0
}
175
176
static int ecdsa_verify_init(void *vctx, void *ec, const OSSL_PARAM params[])
177
0
{
178
0
    return ecdsa_signverify_init(vctx, ec, params, EVP_PKEY_OP_VERIFY,
179
0
                                 "ECDSA Verify Init");
180
0
}
181
182
static int ecdsa_sign(void *vctx, unsigned char *sig, size_t *siglen,
183
                      size_t sigsize, const unsigned char *tbs, size_t tbslen)
184
0
{
185
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
186
0
    int ret;
187
0
    unsigned int sltmp;
188
0
    size_t ecsize = ECDSA_size(ctx->ec);
189
190
0
    if (!ossl_prov_is_running())
191
0
        return 0;
192
193
0
    if (sig == NULL) {
194
0
        *siglen = ecsize;
195
0
        return 1;
196
0
    }
197
198
#if !defined(OPENSSL_NO_ACVP_TESTS)
199
    if (ctx->kattest && !ECDSA_sign_setup(ctx->ec, NULL, &ctx->kinv, &ctx->r))
200
        return 0;
201
#endif
202
203
0
    if (sigsize < (size_t)ecsize)
204
0
        return 0;
205
206
0
    if (ctx->mdsize != 0 && tbslen != ctx->mdsize)
207
0
        return 0;
208
209
0
    if (ctx->nonce_type != 0) {
210
0
        ret = ossl_ecdsa_deterministic_sign(tbs, tbslen, sig, &sltmp,
211
0
                                            ctx->ec, ctx->nonce_type,
212
0
                                            ctx->mdname,
213
0
                                            ctx->libctx, ctx->propq);
214
0
    } else {
215
0
        ret = ECDSA_sign_ex(0, tbs, tbslen, sig, &sltmp, ctx->kinv, ctx->r,
216
0
                            ctx->ec);
217
0
    }
218
0
    if (ret <= 0)
219
0
        return 0;
220
221
0
    *siglen = sltmp;
222
0
    return 1;
223
0
}
224
225
static int ecdsa_verify(void *vctx, const unsigned char *sig, size_t siglen,
226
                        const unsigned char *tbs, size_t tbslen)
227
0
{
228
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
229
230
0
    if (!ossl_prov_is_running() || (ctx->mdsize != 0 && tbslen != ctx->mdsize))
231
0
        return 0;
232
233
0
    return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->ec);
234
0
}
235
236
static int ecdsa_setup_md(PROV_ECDSA_CTX *ctx, const char *mdname,
237
                          const char *mdprops, const char *desc)
238
0
{
239
0
    EVP_MD *md = NULL;
240
0
    size_t mdname_len;
241
0
    int md_nid, md_size;
242
0
    WPACKET pkt;
243
244
0
    if (mdname == NULL)
245
0
        return 1;
246
247
0
    mdname_len = strlen(mdname);
248
0
    if (mdname_len >= sizeof(ctx->mdname)) {
249
0
        ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
250
0
                       "%s exceeds name buffer length", mdname);
251
0
        return 0;
252
0
    }
253
0
    if (mdprops == NULL)
254
0
        mdprops = ctx->propq;
255
0
    md = EVP_MD_fetch(ctx->libctx, mdname, mdprops);
256
0
    if (md == NULL) {
257
0
        ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
258
0
                       "%s could not be fetched", mdname);
259
0
        return 0;
260
0
    }
261
0
    md_size = EVP_MD_get_size(md);
262
0
    if (md_size <= 0) {
263
0
        ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
264
0
                       "%s has invalid md size %d", mdname, md_size);
265
0
        goto err;
266
0
    }
267
0
    md_nid = ossl_digest_get_approved_nid(md);
268
0
    if (md_nid < 0) {
269
0
        ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,
270
0
                       "digest=%s", mdname);
271
0
        goto err;
272
0
    }
273
274
#ifdef FIPS_MODULE
275
    {
276
        int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN);
277
278
        if (!ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND_GET(ctx),
279
                                             OSSL_FIPS_IND_SETTABLE1, ctx->libctx,
280
                                             md_nid, sha1_allowed, desc))
281
            goto err;
282
    }
283
#endif
284
285
0
    if (!ctx->flag_allow_md) {
286
0
        if (ctx->mdname[0] != '\0' && !EVP_MD_is_a(md, ctx->mdname)) {
287
0
            ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,
288
0
                           "digest %s != %s", mdname, ctx->mdname);
289
0
            goto err;
290
0
        }
291
0
        EVP_MD_free(md);
292
0
        return 1;
293
0
    }
294
295
0
    EVP_MD_CTX_free(ctx->mdctx);
296
0
    EVP_MD_free(ctx->md);
297
298
0
    ctx->aid_len = 0;
299
0
    if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf))
300
0
        && ossl_DER_w_algorithmIdentifier_ECDSA_with_MD(&pkt, -1, ctx->ec,
301
0
                                                        md_nid)
302
0
        && WPACKET_finish(&pkt)) {
303
0
        WPACKET_get_total_written(&pkt, &ctx->aid_len);
304
0
        ctx->aid = WPACKET_get_curr(&pkt);
305
0
    }
306
0
    WPACKET_cleanup(&pkt);
307
0
    ctx->mdctx = NULL;
308
0
    ctx->md = md;
309
0
    ctx->mdsize = (size_t)md_size;
310
0
    OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname));
311
312
0
    return 1;
313
0
err:
314
0
    EVP_MD_free(md);
315
0
    return 0;
316
0
}
317
318
static int ecdsa_digest_signverify_init(void *vctx, const char *mdname,
319
                                        void *ec, const OSSL_PARAM params[],
320
                                        int operation, const char *desc)
321
0
{
322
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
323
324
0
    if (!ossl_prov_is_running())
325
0
        return 0;
326
327
0
    if (!ecdsa_signverify_init(vctx, ec, params, operation, desc)
328
0
        || !ecdsa_setup_md(ctx, mdname, NULL, desc))
329
0
        return 0;
330
331
0
    ctx->flag_allow_md = 0;
332
333
0
    if (ctx->mdctx == NULL) {
334
0
        ctx->mdctx = EVP_MD_CTX_new();
335
0
        if (ctx->mdctx == NULL)
336
0
            goto error;
337
0
    }
338
339
0
    if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params))
340
0
        goto error;
341
0
    return 1;
342
0
error:
343
0
    EVP_MD_CTX_free(ctx->mdctx);
344
0
    ctx->mdctx = NULL;
345
0
    return 0;
346
0
}
347
348
static int ecdsa_digest_sign_init(void *vctx, const char *mdname, void *ec,
349
                                  const OSSL_PARAM params[])
350
0
{
351
0
    return ecdsa_digest_signverify_init(vctx, mdname, ec, params,
352
0
                                        EVP_PKEY_OP_SIGN,
353
0
                                        "ECDSA Digest Sign Init");
354
0
}
355
356
static int ecdsa_digest_verify_init(void *vctx, const char *mdname, void *ec,
357
                                    const OSSL_PARAM params[])
358
0
{
359
0
    return ecdsa_digest_signverify_init(vctx, mdname, ec, params,
360
0
                                        EVP_PKEY_OP_VERIFY,
361
0
                                        "ECDSA Digest Verify Init");
362
0
}
363
364
int ecdsa_digest_signverify_update(void *vctx, const unsigned char *data,
365
                                   size_t datalen)
366
0
{
367
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
368
369
0
    if (ctx == NULL || ctx->mdctx == NULL)
370
0
        return 0;
371
372
0
    return EVP_DigestUpdate(ctx->mdctx, data, datalen);
373
0
}
374
375
int ecdsa_digest_sign_final(void *vctx, unsigned char *sig, size_t *siglen,
376
                            size_t sigsize)
377
0
{
378
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
379
0
    unsigned char digest[EVP_MAX_MD_SIZE];
380
0
    unsigned int dlen = 0;
381
382
0
    if (!ossl_prov_is_running() || ctx == NULL || ctx->mdctx == NULL)
383
0
        return 0;
384
385
    /*
386
     * If sig is NULL then we're just finding out the sig size. Other fields
387
     * are ignored. Defer to ecdsa_sign.
388
     */
389
0
    if (sig != NULL
390
0
        && !EVP_DigestFinal_ex(ctx->mdctx, digest, &dlen))
391
0
        return 0;
392
0
    ctx->flag_allow_md = 1;
393
0
    return ecdsa_sign(vctx, sig, siglen, sigsize, digest, (size_t)dlen);
394
0
}
395
396
int ecdsa_digest_verify_final(void *vctx, const unsigned char *sig,
397
                              size_t siglen)
398
0
{
399
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
400
0
    unsigned char digest[EVP_MAX_MD_SIZE];
401
0
    unsigned int dlen = 0;
402
403
0
    if (!ossl_prov_is_running() || ctx == NULL || ctx->mdctx == NULL)
404
0
        return 0;
405
406
0
    if (!EVP_DigestFinal_ex(ctx->mdctx, digest, &dlen))
407
0
        return 0;
408
0
    ctx->flag_allow_md = 1;
409
0
    return ecdsa_verify(ctx, sig, siglen, digest, (size_t)dlen);
410
0
}
411
412
static void ecdsa_freectx(void *vctx)
413
0
{
414
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
415
416
0
    OPENSSL_free(ctx->propq);
417
0
    EVP_MD_CTX_free(ctx->mdctx);
418
0
    EVP_MD_free(ctx->md);
419
0
    ctx->propq = NULL;
420
0
    ctx->mdctx = NULL;
421
0
    ctx->md = NULL;
422
0
    ctx->mdsize = 0;
423
0
    EC_KEY_free(ctx->ec);
424
0
    BN_clear_free(ctx->kinv);
425
0
    BN_clear_free(ctx->r);
426
0
    OPENSSL_free(ctx);
427
0
}
428
429
static void *ecdsa_dupctx(void *vctx)
430
0
{
431
0
    PROV_ECDSA_CTX *srcctx = (PROV_ECDSA_CTX *)vctx;
432
0
    PROV_ECDSA_CTX *dstctx;
433
434
0
    if (!ossl_prov_is_running())
435
0
        return NULL;
436
437
0
    dstctx = OPENSSL_zalloc(sizeof(*srcctx));
438
0
    if (dstctx == NULL)
439
0
        return NULL;
440
441
0
    *dstctx = *srcctx;
442
0
    dstctx->ec = NULL;
443
0
    dstctx->md = NULL;
444
0
    dstctx->mdctx = NULL;
445
0
    dstctx->propq = NULL;
446
447
0
    if (srcctx->ec != NULL && !EC_KEY_up_ref(srcctx->ec))
448
0
        goto err;
449
    /* Test KATS should not need to be supported */
450
0
    if (srcctx->kinv != NULL || srcctx->r != NULL)
451
0
        goto err;
452
0
    dstctx->ec = srcctx->ec;
453
454
0
    if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md))
455
0
        goto err;
456
0
    dstctx->md = srcctx->md;
457
458
0
    if (srcctx->mdctx != NULL) {
459
0
        dstctx->mdctx = EVP_MD_CTX_new();
460
0
        if (dstctx->mdctx == NULL
461
0
                || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx))
462
0
            goto err;
463
0
    }
464
465
0
    if (srcctx->propq != NULL) {
466
0
        dstctx->propq = OPENSSL_strdup(srcctx->propq);
467
0
        if (dstctx->propq == NULL)
468
0
            goto err;
469
0
    }
470
471
0
    return dstctx;
472
0
 err:
473
0
    ecdsa_freectx(dstctx);
474
0
    return NULL;
475
0
}
476
477
static int ecdsa_get_ctx_params(void *vctx, OSSL_PARAM *params)
478
0
{
479
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
480
0
    OSSL_PARAM *p;
481
482
0
    if (ctx == NULL)
483
0
        return 0;
484
485
0
    p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
486
0
    if (p != NULL && !OSSL_PARAM_set_octet_string(p, ctx->aid, ctx->aid_len))
487
0
        return 0;
488
489
0
    p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
490
0
    if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->mdsize))
491
0
        return 0;
492
493
0
    p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST);
494
0
    if (p != NULL && !OSSL_PARAM_set_utf8_string(p, ctx->md == NULL
495
0
                                                    ? ctx->mdname
496
0
                                                    : EVP_MD_get0_name(ctx->md)))
497
0
        return 0;
498
499
0
    p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE);
500
0
    if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->nonce_type))
501
0
        return 0;
502
0
    if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
503
0
        return 0;
504
0
    return 1;
505
0
}
506
507
static const OSSL_PARAM known_gettable_ctx_params[] = {
508
    OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
509
    OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
510
    OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
511
    OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL),
512
    OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
513
    OSSL_PARAM_END
514
};
515
516
static const OSSL_PARAM *ecdsa_gettable_ctx_params(ossl_unused void *vctx,
517
                                                   ossl_unused void *provctx)
518
0
{
519
0
    return known_gettable_ctx_params;
520
0
}
521
522
static int ecdsa_set_ctx_params(void *vctx, const OSSL_PARAM params[])
523
0
{
524
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
525
0
    const OSSL_PARAM *p;
526
0
    size_t mdsize = 0;
527
528
0
    if (ctx == NULL)
529
0
        return 0;
530
0
    if (params == NULL)
531
0
        return 1;
532
533
0
    if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
534
0
                                     OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK))
535
0
        return  0;
536
0
    if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, params,
537
0
                                     OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK))
538
0
        return  0;
539
540
#if !defined(OPENSSL_NO_ACVP_TESTS)
541
    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_KAT);
542
    if (p != NULL && !OSSL_PARAM_get_uint(p, &ctx->kattest))
543
        return 0;
544
#endif
545
546
0
    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);
547
0
    if (p != NULL) {
548
0
        char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname;
549
0
        char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops;
550
0
        const OSSL_PARAM *propsp =
551
0
            OSSL_PARAM_locate_const(params,
552
0
                                    OSSL_SIGNATURE_PARAM_PROPERTIES);
553
554
0
        if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname)))
555
0
            return 0;
556
0
        if (propsp != NULL
557
0
            && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops)))
558
0
            return 0;
559
0
        if (!ecdsa_setup_md(ctx, mdname, mdprops, "ECDSA Set Ctx"))
560
0
            return 0;
561
0
    }
562
563
0
    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
564
0
    if (p != NULL) {
565
0
        if (!OSSL_PARAM_get_size_t(p, &mdsize)
566
0
            || (!ctx->flag_allow_md && mdsize != ctx->mdsize))
567
0
            return 0;
568
0
        ctx->mdsize = mdsize;
569
0
    }
570
0
    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE);
571
0
    if (p != NULL
572
0
        && !OSSL_PARAM_get_uint(p, &ctx->nonce_type))
573
0
        return 0;
574
0
    return 1;
575
0
}
576
577
static const OSSL_PARAM settable_ctx_params[] = {
578
    OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
579
    OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
580
    OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0),
581
    OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_KAT, NULL),
582
    OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL),
583
    OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK)
584
    OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK)
585
    OSSL_PARAM_END
586
};
587
588
static const OSSL_PARAM settable_ctx_params_no_digest[] = {
589
    OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_KAT, NULL),
590
    OSSL_PARAM_END
591
};
592
593
static const OSSL_PARAM *ecdsa_settable_ctx_params(void *vctx,
594
                                                   ossl_unused void *provctx)
595
0
{
596
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
597
598
0
    if (ctx != NULL && !ctx->flag_allow_md)
599
0
        return settable_ctx_params_no_digest;
600
0
    return settable_ctx_params;
601
0
}
602
603
static int ecdsa_get_ctx_md_params(void *vctx, OSSL_PARAM *params)
604
0
{
605
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
606
607
0
    if (ctx->mdctx == NULL)
608
0
        return 0;
609
610
0
    return EVP_MD_CTX_get_params(ctx->mdctx, params);
611
0
}
612
613
static const OSSL_PARAM *ecdsa_gettable_ctx_md_params(void *vctx)
614
0
{
615
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
616
617
0
    if (ctx->md == NULL)
618
0
        return 0;
619
620
0
    return EVP_MD_gettable_ctx_params(ctx->md);
621
0
}
622
623
static int ecdsa_set_ctx_md_params(void *vctx, const OSSL_PARAM params[])
624
0
{
625
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
626
627
0
    if (ctx->mdctx == NULL)
628
0
        return 0;
629
630
0
    return EVP_MD_CTX_set_params(ctx->mdctx, params);
631
0
}
632
633
static const OSSL_PARAM *ecdsa_settable_ctx_md_params(void *vctx)
634
0
{
635
0
    PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
636
637
0
    if (ctx->md == NULL)
638
0
        return 0;
639
640
0
    return EVP_MD_settable_ctx_params(ctx->md);
641
0
}
642
643
const OSSL_DISPATCH ossl_ecdsa_signature_functions[] = {
644
    { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))ecdsa_newctx },
645
    { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))ecdsa_sign_init },
646
    { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))ecdsa_sign },
647
    { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))ecdsa_verify_init },
648
    { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))ecdsa_verify },
649
    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
650
      (void (*)(void))ecdsa_digest_sign_init },
651
    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE,
652
      (void (*)(void))ecdsa_digest_signverify_update },
653
    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL,
654
      (void (*)(void))ecdsa_digest_sign_final },
655
    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
656
      (void (*)(void))ecdsa_digest_verify_init },
657
    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE,
658
      (void (*)(void))ecdsa_digest_signverify_update },
659
    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL,
660
      (void (*)(void))ecdsa_digest_verify_final },
661
    { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))ecdsa_freectx },
662
    { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))ecdsa_dupctx },
663
    { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))ecdsa_get_ctx_params },
664
    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
665
      (void (*)(void))ecdsa_gettable_ctx_params },
666
    { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))ecdsa_set_ctx_params },
667
    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
668
      (void (*)(void))ecdsa_settable_ctx_params },
669
    { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS,
670
      (void (*)(void))ecdsa_get_ctx_md_params },
671
    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS,
672
      (void (*)(void))ecdsa_gettable_ctx_md_params },
673
    { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS,
674
      (void (*)(void))ecdsa_set_ctx_md_params },
675
    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS,
676
      (void (*)(void))ecdsa_settable_ctx_md_params },
677
    OSSL_DISPATCH_END
678
};