1b077aed3SPierre Pronchery /*
2e7be843bSPierre Pronchery * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.
3b077aed3SPierre Pronchery *
4b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
5b077aed3SPierre Pronchery * this file except in compliance with the License. You can obtain a copy
6b077aed3SPierre Pronchery * in the file LICENSE in the source distribution or at
7b077aed3SPierre Pronchery * https://www.openssl.org/source/license.html
8b077aed3SPierre Pronchery */
9b077aed3SPierre Pronchery
10b077aed3SPierre Pronchery /*
11b077aed3SPierre Pronchery * ECDSA low level APIs are deprecated for public use, but still ok for
12b077aed3SPierre Pronchery * internal use.
13b077aed3SPierre Pronchery */
14b077aed3SPierre Pronchery #include "internal/deprecated.h"
15b077aed3SPierre Pronchery
16b077aed3SPierre Pronchery #include <string.h> /* memcpy */
17b077aed3SPierre Pronchery #include <openssl/crypto.h>
18b077aed3SPierre Pronchery #include <openssl/core_dispatch.h>
19b077aed3SPierre Pronchery #include <openssl/core_names.h>
20b077aed3SPierre Pronchery #include <openssl/dsa.h>
21b077aed3SPierre Pronchery #include <openssl/params.h>
22b077aed3SPierre Pronchery #include <openssl/evp.h>
23b077aed3SPierre Pronchery #include <openssl/err.h>
24b077aed3SPierre Pronchery #include <openssl/proverr.h>
25b077aed3SPierre Pronchery #include "internal/nelem.h"
26b077aed3SPierre Pronchery #include "internal/sizes.h"
27b077aed3SPierre Pronchery #include "internal/cryptlib.h"
28e7be843bSPierre Pronchery #include "internal/deterministic_nonce.h"
29b077aed3SPierre Pronchery #include "prov/providercommon.h"
30b077aed3SPierre Pronchery #include "prov/implementations.h"
31b077aed3SPierre Pronchery #include "prov/provider_ctx.h"
32b077aed3SPierre Pronchery #include "prov/securitycheck.h"
33b077aed3SPierre Pronchery #include "prov/der_ec.h"
34e7be843bSPierre Pronchery #include "crypto/ec.h"
35b077aed3SPierre Pronchery
36b077aed3SPierre Pronchery static OSSL_FUNC_signature_newctx_fn ecdsa_newctx;
37b077aed3SPierre Pronchery static OSSL_FUNC_signature_sign_init_fn ecdsa_sign_init;
38b077aed3SPierre Pronchery static OSSL_FUNC_signature_verify_init_fn ecdsa_verify_init;
39b077aed3SPierre Pronchery static OSSL_FUNC_signature_sign_fn ecdsa_sign;
40e7be843bSPierre Pronchery static OSSL_FUNC_signature_sign_message_update_fn ecdsa_signverify_message_update;
41e7be843bSPierre Pronchery static OSSL_FUNC_signature_sign_message_final_fn ecdsa_sign_message_final;
42b077aed3SPierre Pronchery static OSSL_FUNC_signature_verify_fn ecdsa_verify;
43e7be843bSPierre Pronchery static OSSL_FUNC_signature_verify_message_update_fn ecdsa_signverify_message_update;
44e7be843bSPierre Pronchery static OSSL_FUNC_signature_verify_message_final_fn ecdsa_verify_message_final;
45b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_sign_init_fn ecdsa_digest_sign_init;
46b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_sign_update_fn ecdsa_digest_signverify_update;
47b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_sign_final_fn ecdsa_digest_sign_final;
48b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_verify_init_fn ecdsa_digest_verify_init;
49b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_verify_update_fn ecdsa_digest_signverify_update;
50b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_verify_final_fn ecdsa_digest_verify_final;
51b077aed3SPierre Pronchery static OSSL_FUNC_signature_freectx_fn ecdsa_freectx;
52b077aed3SPierre Pronchery static OSSL_FUNC_signature_dupctx_fn ecdsa_dupctx;
53e7be843bSPierre Pronchery static OSSL_FUNC_signature_query_key_types_fn ecdsa_sigalg_query_key_types;
54b077aed3SPierre Pronchery static OSSL_FUNC_signature_get_ctx_params_fn ecdsa_get_ctx_params;
55b077aed3SPierre Pronchery static OSSL_FUNC_signature_gettable_ctx_params_fn ecdsa_gettable_ctx_params;
56b077aed3SPierre Pronchery static OSSL_FUNC_signature_set_ctx_params_fn ecdsa_set_ctx_params;
57b077aed3SPierre Pronchery static OSSL_FUNC_signature_settable_ctx_params_fn ecdsa_settable_ctx_params;
58b077aed3SPierre Pronchery static OSSL_FUNC_signature_get_ctx_md_params_fn ecdsa_get_ctx_md_params;
59b077aed3SPierre Pronchery static OSSL_FUNC_signature_gettable_ctx_md_params_fn ecdsa_gettable_ctx_md_params;
60b077aed3SPierre Pronchery static OSSL_FUNC_signature_set_ctx_md_params_fn ecdsa_set_ctx_md_params;
61b077aed3SPierre Pronchery static OSSL_FUNC_signature_settable_ctx_md_params_fn ecdsa_settable_ctx_md_params;
62e7be843bSPierre Pronchery static OSSL_FUNC_signature_set_ctx_params_fn ecdsa_sigalg_set_ctx_params;
63e7be843bSPierre Pronchery static OSSL_FUNC_signature_settable_ctx_params_fn ecdsa_sigalg_settable_ctx_params;
64b077aed3SPierre Pronchery
65b077aed3SPierre Pronchery /*
66b077aed3SPierre Pronchery * What's passed as an actual key is defined by the KEYMGMT interface.
67b077aed3SPierre Pronchery * We happen to know that our KEYMGMT simply passes DSA structures, so
68b077aed3SPierre Pronchery * we use that here too.
69b077aed3SPierre Pronchery */
70b077aed3SPierre Pronchery
71b077aed3SPierre Pronchery typedef struct {
72b077aed3SPierre Pronchery OSSL_LIB_CTX *libctx;
73b077aed3SPierre Pronchery char *propq;
74b077aed3SPierre Pronchery EC_KEY *ec;
75e7be843bSPierre Pronchery /* |operation| reuses EVP's operation bitfield */
76e7be843bSPierre Pronchery int operation;
77b077aed3SPierre Pronchery
78b077aed3SPierre Pronchery /*
79e7be843bSPierre Pronchery * Flag to determine if a full sigalg is run (1) or if a composable
80e7be843bSPierre Pronchery * signature algorithm is run (0).
81e7be843bSPierre Pronchery *
82e7be843bSPierre Pronchery * When a full sigalg is run (1), this currently affects the following
83e7be843bSPierre Pronchery * other flags, which are to remain untouched after their initialization:
84e7be843bSPierre Pronchery *
85e7be843bSPierre Pronchery * - flag_allow_md (initialized to 0)
86e7be843bSPierre Pronchery */
87e7be843bSPierre Pronchery unsigned int flag_sigalg : 1;
88e7be843bSPierre Pronchery /*
89b077aed3SPierre Pronchery * Flag to determine if the hash function can be changed (1) or not (0)
90b077aed3SPierre Pronchery * Because it's dangerous to change during a DigestSign or DigestVerify
91b077aed3SPierre Pronchery * operation, this flag is cleared by their Init function, and set again
92b077aed3SPierre Pronchery * by their Final function.
93b077aed3SPierre Pronchery */
94b077aed3SPierre Pronchery unsigned int flag_allow_md : 1;
95b077aed3SPierre Pronchery
96b077aed3SPierre Pronchery /* The Algorithm Identifier of the combined signature algorithm */
97b077aed3SPierre Pronchery unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE];
98b077aed3SPierre Pronchery size_t aid_len;
99b077aed3SPierre Pronchery
100e7be843bSPierre Pronchery /* main digest */
101e7be843bSPierre Pronchery char mdname[OSSL_MAX_NAME_SIZE];
102b077aed3SPierre Pronchery EVP_MD *md;
103b077aed3SPierre Pronchery EVP_MD_CTX *mdctx;
104e7be843bSPierre Pronchery size_t mdsize;
105e7be843bSPierre Pronchery
106e7be843bSPierre Pronchery /* Signature, for verification */
107e7be843bSPierre Pronchery unsigned char *sig;
108e7be843bSPierre Pronchery size_t siglen;
109e7be843bSPierre Pronchery
110b077aed3SPierre Pronchery /*
111b077aed3SPierre Pronchery * Internally used to cache the results of calling the EC group
112b077aed3SPierre Pronchery * sign_setup() methods which are then passed to the sign operation.
113b077aed3SPierre Pronchery * This is used by CAVS failure tests to terminate a loop if the signature
114b077aed3SPierre Pronchery * is not valid.
115b077aed3SPierre Pronchery * This could of also been done with a simple flag.
116b077aed3SPierre Pronchery */
117b077aed3SPierre Pronchery BIGNUM *kinv;
118b077aed3SPierre Pronchery BIGNUM *r;
119b077aed3SPierre Pronchery #if !defined(OPENSSL_NO_ACVP_TESTS)
120b077aed3SPierre Pronchery /*
121b077aed3SPierre Pronchery * This indicates that KAT (CAVS) test is running. Externally an app will
122b077aed3SPierre Pronchery * override the random callback such that the generated private key and k
123b077aed3SPierre Pronchery * are known.
124b077aed3SPierre Pronchery * Normal operation will loop to choose a new k if the signature is not
125b077aed3SPierre Pronchery * valid - but for this mode of operation it forces a failure instead.
126b077aed3SPierre Pronchery */
127b077aed3SPierre Pronchery unsigned int kattest;
128b077aed3SPierre Pronchery #endif
129e7be843bSPierre Pronchery #ifdef FIPS_MODULE
130e7be843bSPierre Pronchery /*
131e7be843bSPierre Pronchery * FIPS 140-3 IG 2.4.B mandates that verification based on a digest of a
132e7be843bSPierre Pronchery * message is not permitted. However, signing based on a digest is still
133e7be843bSPierre Pronchery * permitted.
134e7be843bSPierre Pronchery */
135e7be843bSPierre Pronchery int verify_message;
136e7be843bSPierre Pronchery #endif
137e7be843bSPierre Pronchery /* If this is set then the generated k is not random */
138e7be843bSPierre Pronchery unsigned int nonce_type;
139e7be843bSPierre Pronchery OSSL_FIPS_IND_DECLARE
140b077aed3SPierre Pronchery } PROV_ECDSA_CTX;
141b077aed3SPierre Pronchery
ecdsa_newctx(void * provctx,const char * propq)142b077aed3SPierre Pronchery static void *ecdsa_newctx(void *provctx, const char *propq)
143b077aed3SPierre Pronchery {
144b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx;
145b077aed3SPierre Pronchery
146b077aed3SPierre Pronchery if (!ossl_prov_is_running())
147b077aed3SPierre Pronchery return NULL;
148b077aed3SPierre Pronchery
149b077aed3SPierre Pronchery ctx = OPENSSL_zalloc(sizeof(PROV_ECDSA_CTX));
150b077aed3SPierre Pronchery if (ctx == NULL)
151b077aed3SPierre Pronchery return NULL;
152b077aed3SPierre Pronchery
153e7be843bSPierre Pronchery OSSL_FIPS_IND_INIT(ctx)
154b077aed3SPierre Pronchery ctx->flag_allow_md = 1;
155e7be843bSPierre Pronchery #ifdef FIPS_MODULE
156e7be843bSPierre Pronchery ctx->verify_message = 1;
157e7be843bSPierre Pronchery #endif
158b077aed3SPierre Pronchery ctx->libctx = PROV_LIBCTX_OF(provctx);
159b077aed3SPierre Pronchery if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) {
160b077aed3SPierre Pronchery OPENSSL_free(ctx);
161b077aed3SPierre Pronchery ctx = NULL;
162b077aed3SPierre Pronchery }
163b077aed3SPierre Pronchery return ctx;
164b077aed3SPierre Pronchery }
165b077aed3SPierre Pronchery
ecdsa_setup_md(PROV_ECDSA_CTX * ctx,const char * mdname,const char * mdprops,const char * desc)166e7be843bSPierre Pronchery static int ecdsa_setup_md(PROV_ECDSA_CTX *ctx,
167e7be843bSPierre Pronchery const char *mdname, const char *mdprops,
168e7be843bSPierre Pronchery const char *desc)
169b077aed3SPierre Pronchery {
170e7be843bSPierre Pronchery EVP_MD *md = NULL;
171e7be843bSPierre Pronchery size_t mdname_len;
172e7be843bSPierre Pronchery int md_nid, md_size;
173e7be843bSPierre Pronchery WPACKET pkt;
174e7be843bSPierre Pronchery unsigned char *aid = NULL;
175b077aed3SPierre Pronchery
176e7be843bSPierre Pronchery if (mdname == NULL)
177e7be843bSPierre Pronchery return 1;
178e7be843bSPierre Pronchery
179e7be843bSPierre Pronchery mdname_len = strlen(mdname);
180e7be843bSPierre Pronchery if (mdname_len >= sizeof(ctx->mdname)) {
181e7be843bSPierre Pronchery ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
182e7be843bSPierre Pronchery "%s exceeds name buffer length", mdname);
183e7be843bSPierre Pronchery return 0;
184e7be843bSPierre Pronchery }
185e7be843bSPierre Pronchery if (mdprops == NULL)
186e7be843bSPierre Pronchery mdprops = ctx->propq;
187e7be843bSPierre Pronchery md = EVP_MD_fetch(ctx->libctx, mdname, mdprops);
188e7be843bSPierre Pronchery if (md == NULL) {
189e7be843bSPierre Pronchery ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
190e7be843bSPierre Pronchery "%s could not be fetched", mdname);
191e7be843bSPierre Pronchery return 0;
192e7be843bSPierre Pronchery }
193e7be843bSPierre Pronchery md_size = EVP_MD_get_size(md);
194e7be843bSPierre Pronchery if (md_size <= 0) {
195e7be843bSPierre Pronchery ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
196e7be843bSPierre Pronchery "%s has invalid md size %d", mdname, md_size);
197e7be843bSPierre Pronchery goto err;
198e7be843bSPierre Pronchery }
199e7be843bSPierre Pronchery md_nid = ossl_digest_get_approved_nid(md);
200e7be843bSPierre Pronchery #ifdef FIPS_MODULE
201e7be843bSPierre Pronchery if (md_nid == NID_undef) {
202e7be843bSPierre Pronchery ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,
203e7be843bSPierre Pronchery "digest=%s", mdname);
204e7be843bSPierre Pronchery goto err;
205e7be843bSPierre Pronchery }
206e7be843bSPierre Pronchery #endif
207e7be843bSPierre Pronchery /* XOF digests don't work */
208e7be843bSPierre Pronchery if (EVP_MD_xof(md)) {
209e7be843bSPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);
210e7be843bSPierre Pronchery goto err;
211e7be843bSPierre Pronchery }
212e7be843bSPierre Pronchery
213e7be843bSPierre Pronchery #ifdef FIPS_MODULE
214e7be843bSPierre Pronchery {
215e7be843bSPierre Pronchery int sha1_allowed
216e7be843bSPierre Pronchery = ((ctx->operation
217e7be843bSPierre Pronchery & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_SIGNMSG)) == 0);
218e7be843bSPierre Pronchery
219e7be843bSPierre Pronchery if (!ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND_GET(ctx),
220e7be843bSPierre Pronchery OSSL_FIPS_IND_SETTABLE1,
221e7be843bSPierre Pronchery ctx->libctx,
222*88b8b7f0SEnji Cooper md_nid, sha1_allowed, 0, desc,
223e7be843bSPierre Pronchery ossl_fips_config_signature_digest_check))
224e7be843bSPierre Pronchery goto err;
225e7be843bSPierre Pronchery }
226e7be843bSPierre Pronchery #endif
227e7be843bSPierre Pronchery
228e7be843bSPierre Pronchery if (!ctx->flag_allow_md) {
229e7be843bSPierre Pronchery if (ctx->mdname[0] != '\0' && !EVP_MD_is_a(md, ctx->mdname)) {
230e7be843bSPierre Pronchery ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,
231e7be843bSPierre Pronchery "digest %s != %s", mdname, ctx->mdname);
232e7be843bSPierre Pronchery goto err;
233e7be843bSPierre Pronchery }
234e7be843bSPierre Pronchery EVP_MD_free(md);
235e7be843bSPierre Pronchery return 1;
236e7be843bSPierre Pronchery }
237e7be843bSPierre Pronchery
238e7be843bSPierre Pronchery EVP_MD_CTX_free(ctx->mdctx);
239e7be843bSPierre Pronchery EVP_MD_free(ctx->md);
240e7be843bSPierre Pronchery
241e7be843bSPierre Pronchery ctx->aid_len = 0;
242e7be843bSPierre Pronchery #ifndef FIPS_MODULE
243e7be843bSPierre Pronchery if (md_nid != NID_undef) {
244e7be843bSPierre Pronchery #else
245e7be843bSPierre Pronchery {
246e7be843bSPierre Pronchery #endif
247e7be843bSPierre Pronchery if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf))
248e7be843bSPierre Pronchery && ossl_DER_w_algorithmIdentifier_ECDSA_with_MD(&pkt, -1, ctx->ec,
249e7be843bSPierre Pronchery md_nid)
250e7be843bSPierre Pronchery && WPACKET_finish(&pkt)) {
251e7be843bSPierre Pronchery WPACKET_get_total_written(&pkt, &ctx->aid_len);
252e7be843bSPierre Pronchery aid = WPACKET_get_curr(&pkt);
253e7be843bSPierre Pronchery }
254e7be843bSPierre Pronchery WPACKET_cleanup(&pkt);
255e7be843bSPierre Pronchery if (aid != NULL && ctx->aid_len != 0)
256e7be843bSPierre Pronchery memmove(ctx->aid_buf, aid, ctx->aid_len);
257e7be843bSPierre Pronchery }
258e7be843bSPierre Pronchery
259e7be843bSPierre Pronchery ctx->mdctx = NULL;
260e7be843bSPierre Pronchery ctx->md = md;
261e7be843bSPierre Pronchery ctx->mdsize = (size_t)md_size;
262e7be843bSPierre Pronchery OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname));
263e7be843bSPierre Pronchery
264e7be843bSPierre Pronchery return 1;
265e7be843bSPierre Pronchery err:
266e7be843bSPierre Pronchery EVP_MD_free(md);
267e7be843bSPierre Pronchery return 0;
268e7be843bSPierre Pronchery }
269e7be843bSPierre Pronchery
270e7be843bSPierre Pronchery static int
271e7be843bSPierre Pronchery ecdsa_signverify_init(PROV_ECDSA_CTX *ctx, void *ec,
272e7be843bSPierre Pronchery OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params,
273e7be843bSPierre Pronchery const OSSL_PARAM params[], int operation,
274e7be843bSPierre Pronchery const char *desc)
275e7be843bSPierre Pronchery {
276b077aed3SPierre Pronchery if (!ossl_prov_is_running()
277b077aed3SPierre Pronchery || ctx == NULL)
278b077aed3SPierre Pronchery return 0;
279b077aed3SPierre Pronchery
280b077aed3SPierre Pronchery if (ec == NULL && ctx->ec == NULL) {
281b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
282b077aed3SPierre Pronchery return 0;
283b077aed3SPierre Pronchery }
284b077aed3SPierre Pronchery
285b077aed3SPierre Pronchery if (ec != NULL) {
286b077aed3SPierre Pronchery if (!EC_KEY_up_ref(ec))
287b077aed3SPierre Pronchery return 0;
288b077aed3SPierre Pronchery EC_KEY_free(ctx->ec);
289b077aed3SPierre Pronchery ctx->ec = ec;
290b077aed3SPierre Pronchery }
291b077aed3SPierre Pronchery
292b077aed3SPierre Pronchery ctx->operation = operation;
293b077aed3SPierre Pronchery
294e7be843bSPierre Pronchery OSSL_FIPS_IND_SET_APPROVED(ctx)
295e7be843bSPierre Pronchery if (!set_ctx_params(ctx, params))
296b077aed3SPierre Pronchery return 0;
297e7be843bSPierre Pronchery #ifdef FIPS_MODULE
298e7be843bSPierre Pronchery if (!ossl_fips_ind_ec_key_check(OSSL_FIPS_IND_GET(ctx),
299e7be843bSPierre Pronchery OSSL_FIPS_IND_SETTABLE0, ctx->libctx,
300e7be843bSPierre Pronchery EC_KEY_get0_group(ctx->ec), desc,
301e7be843bSPierre Pronchery (operation & (EVP_PKEY_OP_SIGN
302e7be843bSPierre Pronchery | EVP_PKEY_OP_SIGNMSG)) != 0))
303e7be843bSPierre Pronchery return 0;
304e7be843bSPierre Pronchery #endif
305b077aed3SPierre Pronchery return 1;
306b077aed3SPierre Pronchery }
307b077aed3SPierre Pronchery
308b077aed3SPierre Pronchery static int ecdsa_sign_init(void *vctx, void *ec, const OSSL_PARAM params[])
309b077aed3SPierre Pronchery {
310e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
311e7be843bSPierre Pronchery
312e7be843bSPierre Pronchery #ifdef FIPS_MODULE
313e7be843bSPierre Pronchery ctx->verify_message = 1;
314e7be843bSPierre Pronchery #endif
315e7be843bSPierre Pronchery return ecdsa_signverify_init(ctx, ec, ecdsa_set_ctx_params, params,
316e7be843bSPierre Pronchery EVP_PKEY_OP_SIGN, "ECDSA Sign Init");
317b077aed3SPierre Pronchery }
318b077aed3SPierre Pronchery
319e7be843bSPierre Pronchery /*
320e7be843bSPierre Pronchery * Sign tbs without digesting it first. This is suitable for "primitive"
321e7be843bSPierre Pronchery * signing and signing the digest of a message.
322e7be843bSPierre Pronchery */
323e7be843bSPierre Pronchery static int ecdsa_sign_directly(void *vctx,
324e7be843bSPierre Pronchery unsigned char *sig, size_t *siglen, size_t sigsize,
325e7be843bSPierre Pronchery const unsigned char *tbs, size_t tbslen)
326b077aed3SPierre Pronchery {
327b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
328b077aed3SPierre Pronchery int ret;
329b077aed3SPierre Pronchery unsigned int sltmp;
330b077aed3SPierre Pronchery size_t ecsize = ECDSA_size(ctx->ec);
331b077aed3SPierre Pronchery
332b077aed3SPierre Pronchery if (!ossl_prov_is_running())
333b077aed3SPierre Pronchery return 0;
334b077aed3SPierre Pronchery
335b077aed3SPierre Pronchery if (sig == NULL) {
336b077aed3SPierre Pronchery *siglen = ecsize;
337b077aed3SPierre Pronchery return 1;
338b077aed3SPierre Pronchery }
339b077aed3SPierre Pronchery
340b077aed3SPierre Pronchery #if !defined(OPENSSL_NO_ACVP_TESTS)
341b077aed3SPierre Pronchery if (ctx->kattest && !ECDSA_sign_setup(ctx->ec, NULL, &ctx->kinv, &ctx->r))
342b077aed3SPierre Pronchery return 0;
343b077aed3SPierre Pronchery #endif
344b077aed3SPierre Pronchery
345b077aed3SPierre Pronchery if (sigsize < (size_t)ecsize)
346b077aed3SPierre Pronchery return 0;
347b077aed3SPierre Pronchery
348b077aed3SPierre Pronchery if (ctx->mdsize != 0 && tbslen != ctx->mdsize)
349b077aed3SPierre Pronchery return 0;
350b077aed3SPierre Pronchery
351e7be843bSPierre Pronchery if (ctx->nonce_type != 0) {
352e7be843bSPierre Pronchery const char *mdname = NULL;
353e7be843bSPierre Pronchery
354e7be843bSPierre Pronchery if (ctx->mdname[0] != '\0')
355e7be843bSPierre Pronchery mdname = ctx->mdname;
356e7be843bSPierre Pronchery ret = ossl_ecdsa_deterministic_sign(tbs, tbslen, sig, &sltmp,
357e7be843bSPierre Pronchery ctx->ec, ctx->nonce_type,
358e7be843bSPierre Pronchery mdname,
359e7be843bSPierre Pronchery ctx->libctx, ctx->propq);
360e7be843bSPierre Pronchery } else {
361e7be843bSPierre Pronchery ret = ECDSA_sign_ex(0, tbs, tbslen, sig, &sltmp, ctx->kinv, ctx->r,
362e7be843bSPierre Pronchery ctx->ec);
363e7be843bSPierre Pronchery }
364b077aed3SPierre Pronchery if (ret <= 0)
365b077aed3SPierre Pronchery return 0;
366b077aed3SPierre Pronchery
367b077aed3SPierre Pronchery *siglen = sltmp;
368b077aed3SPierre Pronchery return 1;
369b077aed3SPierre Pronchery }
370b077aed3SPierre Pronchery
371e7be843bSPierre Pronchery static int ecdsa_signverify_message_update(void *vctx,
372e7be843bSPierre Pronchery const unsigned char *data,
373e7be843bSPierre Pronchery size_t datalen)
374e7be843bSPierre Pronchery {
375e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
376e7be843bSPierre Pronchery
377e7be843bSPierre Pronchery if (ctx == NULL)
378e7be843bSPierre Pronchery return 0;
379e7be843bSPierre Pronchery
380e7be843bSPierre Pronchery return EVP_DigestUpdate(ctx->mdctx, data, datalen);
381e7be843bSPierre Pronchery }
382e7be843bSPierre Pronchery
383e7be843bSPierre Pronchery static int ecdsa_sign_message_final(void *vctx, unsigned char *sig,
384e7be843bSPierre Pronchery size_t *siglen, size_t sigsize)
385e7be843bSPierre Pronchery {
386e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
387e7be843bSPierre Pronchery unsigned char digest[EVP_MAX_MD_SIZE];
388e7be843bSPierre Pronchery unsigned int dlen = 0;
389e7be843bSPierre Pronchery
390e7be843bSPierre Pronchery if (!ossl_prov_is_running() || ctx == NULL)
391e7be843bSPierre Pronchery return 0;
392e7be843bSPierre Pronchery if (ctx->mdctx == NULL)
393e7be843bSPierre Pronchery return 0;
394e7be843bSPierre Pronchery /*
395e7be843bSPierre Pronchery * If sig is NULL then we're just finding out the sig size. Other fields
396e7be843bSPierre Pronchery * are ignored. Defer to ecdsa_sign.
397e7be843bSPierre Pronchery */
398e7be843bSPierre Pronchery if (sig != NULL
399e7be843bSPierre Pronchery && !EVP_DigestFinal_ex(ctx->mdctx, digest, &dlen))
400e7be843bSPierre Pronchery return 0;
401e7be843bSPierre Pronchery return ecdsa_sign_directly(vctx, sig, siglen, sigsize, digest, dlen);
402e7be843bSPierre Pronchery }
403e7be843bSPierre Pronchery
404e7be843bSPierre Pronchery /*
405e7be843bSPierre Pronchery * If signing a message, digest tbs and sign the result.
406e7be843bSPierre Pronchery * Otherwise, sign tbs directly.
407e7be843bSPierre Pronchery */
408e7be843bSPierre Pronchery static int ecdsa_sign(void *vctx, unsigned char *sig, size_t *siglen,
409e7be843bSPierre Pronchery size_t sigsize, const unsigned char *tbs, size_t tbslen)
410e7be843bSPierre Pronchery {
411e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
412e7be843bSPierre Pronchery
413e7be843bSPierre Pronchery if (ctx->operation == EVP_PKEY_OP_SIGNMSG) {
414e7be843bSPierre Pronchery /*
415e7be843bSPierre Pronchery * If |sig| is NULL, the caller is only looking for the sig length.
416e7be843bSPierre Pronchery * DO NOT update the input in this case.
417e7be843bSPierre Pronchery */
418e7be843bSPierre Pronchery if (sig == NULL)
419e7be843bSPierre Pronchery return ecdsa_sign_message_final(ctx, sig, siglen, sigsize);
420e7be843bSPierre Pronchery
421e7be843bSPierre Pronchery if (ecdsa_signverify_message_update(ctx, tbs, tbslen) <= 0)
422e7be843bSPierre Pronchery return 0;
423e7be843bSPierre Pronchery return ecdsa_sign_message_final(ctx, sig, siglen, sigsize);
424e7be843bSPierre Pronchery }
425e7be843bSPierre Pronchery return ecdsa_sign_directly(ctx, sig, siglen, sigsize, tbs, tbslen);
426e7be843bSPierre Pronchery }
427e7be843bSPierre Pronchery
428e7be843bSPierre Pronchery static int ecdsa_verify_init(void *vctx, void *ec, const OSSL_PARAM params[])
429e7be843bSPierre Pronchery {
430e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
431e7be843bSPierre Pronchery
432e7be843bSPierre Pronchery #ifdef FIPS_MODULE
433e7be843bSPierre Pronchery ctx->verify_message = 0;
434e7be843bSPierre Pronchery #endif
435e7be843bSPierre Pronchery return ecdsa_signverify_init(ctx, ec, ecdsa_set_ctx_params, params,
436e7be843bSPierre Pronchery EVP_PKEY_OP_VERIFY, "ECDSA Verify Init");
437e7be843bSPierre Pronchery }
438e7be843bSPierre Pronchery
439e7be843bSPierre Pronchery static int ecdsa_verify_directly(void *vctx,
440e7be843bSPierre Pronchery const unsigned char *sig, size_t siglen,
441b077aed3SPierre Pronchery const unsigned char *tbs, size_t tbslen)
442b077aed3SPierre Pronchery {
443b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
444b077aed3SPierre Pronchery
445b077aed3SPierre Pronchery if (!ossl_prov_is_running() || (ctx->mdsize != 0 && tbslen != ctx->mdsize))
446b077aed3SPierre Pronchery return 0;
447b077aed3SPierre Pronchery
448b077aed3SPierre Pronchery return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->ec);
449b077aed3SPierre Pronchery }
450b077aed3SPierre Pronchery
451e7be843bSPierre Pronchery static int ecdsa_verify_set_sig(void *vctx,
452e7be843bSPierre Pronchery const unsigned char *sig, size_t siglen)
453b077aed3SPierre Pronchery {
454e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
455e7be843bSPierre Pronchery OSSL_PARAM params[2];
456b077aed3SPierre Pronchery
457e7be843bSPierre Pronchery params[0] =
458e7be843bSPierre Pronchery OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE,
459e7be843bSPierre Pronchery (unsigned char *)sig, siglen);
460e7be843bSPierre Pronchery params[1] = OSSL_PARAM_construct_end();
461e7be843bSPierre Pronchery return ecdsa_sigalg_set_ctx_params(ctx, params);
462e7be843bSPierre Pronchery }
463b077aed3SPierre Pronchery
464e7be843bSPierre Pronchery static int ecdsa_verify_message_final(void *vctx)
465e7be843bSPierre Pronchery {
466e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
467e7be843bSPierre Pronchery unsigned char digest[EVP_MAX_MD_SIZE];
468e7be843bSPierre Pronchery unsigned int dlen = 0;
469e7be843bSPierre Pronchery
470e7be843bSPierre Pronchery if (!ossl_prov_is_running() || ctx == NULL || ctx->mdctx == NULL)
471b077aed3SPierre Pronchery return 0;
472e7be843bSPierre Pronchery
473e7be843bSPierre Pronchery /*
474e7be843bSPierre Pronchery * The digests used here are all known (see ecdsa_get_md_nid()), so they
475e7be843bSPierre Pronchery * should not exceed the internal buffer size of EVP_MAX_MD_SIZE.
476e7be843bSPierre Pronchery */
477e7be843bSPierre Pronchery if (!EVP_DigestFinal_ex(ctx->mdctx, digest, &dlen))
478b077aed3SPierre Pronchery return 0;
479e7be843bSPierre Pronchery
480e7be843bSPierre Pronchery return ecdsa_verify_directly(vctx, ctx->sig, ctx->siglen,
481e7be843bSPierre Pronchery digest, dlen);
482b077aed3SPierre Pronchery }
483e7be843bSPierre Pronchery
484e7be843bSPierre Pronchery /*
485e7be843bSPierre Pronchery * If verifying a message, digest tbs and verify the result.
486e7be843bSPierre Pronchery * Otherwise, verify tbs directly.
487e7be843bSPierre Pronchery */
488e7be843bSPierre Pronchery static int ecdsa_verify(void *vctx,
489e7be843bSPierre Pronchery const unsigned char *sig, size_t siglen,
490e7be843bSPierre Pronchery const unsigned char *tbs, size_t tbslen)
491e7be843bSPierre Pronchery {
492e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
493e7be843bSPierre Pronchery
494e7be843bSPierre Pronchery if (ctx->operation == EVP_PKEY_OP_VERIFYMSG) {
495e7be843bSPierre Pronchery if (ecdsa_verify_set_sig(ctx, sig, siglen) <= 0)
496b077aed3SPierre Pronchery return 0;
497e7be843bSPierre Pronchery if (ecdsa_signverify_message_update(ctx, tbs, tbslen) <= 0)
498b077aed3SPierre Pronchery return 0;
499e7be843bSPierre Pronchery return ecdsa_verify_message_final(ctx);
500b077aed3SPierre Pronchery }
501e7be843bSPierre Pronchery return ecdsa_verify_directly(ctx, sig, siglen, tbs, tbslen);
502b077aed3SPierre Pronchery }
503b077aed3SPierre Pronchery
504e7be843bSPierre Pronchery /* DigestSign/DigestVerify wrappers */
505b077aed3SPierre Pronchery
506b077aed3SPierre Pronchery static int ecdsa_digest_signverify_init(void *vctx, const char *mdname,
507b077aed3SPierre Pronchery void *ec, const OSSL_PARAM params[],
508e7be843bSPierre Pronchery int operation, const char *desc)
509b077aed3SPierre Pronchery {
510b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
511b077aed3SPierre Pronchery
512b077aed3SPierre Pronchery if (!ossl_prov_is_running())
513b077aed3SPierre Pronchery return 0;
514b077aed3SPierre Pronchery
515e7be843bSPierre Pronchery #ifdef FIPS_MODULE
516e7be843bSPierre Pronchery ctx->verify_message = 1;
517e7be843bSPierre Pronchery #endif
518e7be843bSPierre Pronchery if (!ecdsa_signverify_init(vctx, ec, ecdsa_set_ctx_params, params,
519e7be843bSPierre Pronchery operation, desc))
520e7be843bSPierre Pronchery return 0;
521e7be843bSPierre Pronchery
522e7be843bSPierre Pronchery if (mdname != NULL
523e7be843bSPierre Pronchery /* was ecdsa_setup_md already called in ecdsa_signverify_init()? */
524e7be843bSPierre Pronchery && (mdname[0] == '\0' || OPENSSL_strcasecmp(ctx->mdname, mdname) != 0)
525e7be843bSPierre Pronchery && !ecdsa_setup_md(ctx, mdname, NULL, desc))
526b077aed3SPierre Pronchery return 0;
527b077aed3SPierre Pronchery
528b077aed3SPierre Pronchery ctx->flag_allow_md = 0;
529b077aed3SPierre Pronchery
530b077aed3SPierre Pronchery if (ctx->mdctx == NULL) {
531b077aed3SPierre Pronchery ctx->mdctx = EVP_MD_CTX_new();
532b077aed3SPierre Pronchery if (ctx->mdctx == NULL)
533b077aed3SPierre Pronchery goto error;
534b077aed3SPierre Pronchery }
535b077aed3SPierre Pronchery
536b077aed3SPierre Pronchery if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params))
537b077aed3SPierre Pronchery goto error;
538b077aed3SPierre Pronchery return 1;
539b077aed3SPierre Pronchery error:
540b077aed3SPierre Pronchery EVP_MD_CTX_free(ctx->mdctx);
541b077aed3SPierre Pronchery ctx->mdctx = NULL;
542b077aed3SPierre Pronchery return 0;
543b077aed3SPierre Pronchery }
544b077aed3SPierre Pronchery
545b077aed3SPierre Pronchery static int ecdsa_digest_sign_init(void *vctx, const char *mdname, void *ec,
546b077aed3SPierre Pronchery const OSSL_PARAM params[])
547b077aed3SPierre Pronchery {
548b077aed3SPierre Pronchery return ecdsa_digest_signverify_init(vctx, mdname, ec, params,
549e7be843bSPierre Pronchery EVP_PKEY_OP_SIGNMSG,
550e7be843bSPierre Pronchery "ECDSA Digest Sign Init");
551b077aed3SPierre Pronchery }
552b077aed3SPierre Pronchery
553e7be843bSPierre Pronchery static int ecdsa_digest_signverify_update(void *vctx, const unsigned char *data,
554b077aed3SPierre Pronchery size_t datalen)
555b077aed3SPierre Pronchery {
556b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
557b077aed3SPierre Pronchery
558b077aed3SPierre Pronchery if (ctx == NULL || ctx->mdctx == NULL)
559b077aed3SPierre Pronchery return 0;
560e7be843bSPierre Pronchery /* Sigalg implementations shouldn't do digest_sign */
561e7be843bSPierre Pronchery if (ctx->flag_sigalg)
562e7be843bSPierre Pronchery return 0;
563b077aed3SPierre Pronchery
564e7be843bSPierre Pronchery return ecdsa_signverify_message_update(vctx, data, datalen);
565b077aed3SPierre Pronchery }
566b077aed3SPierre Pronchery
567b077aed3SPierre Pronchery int ecdsa_digest_sign_final(void *vctx, unsigned char *sig, size_t *siglen,
568b077aed3SPierre Pronchery size_t sigsize)
569b077aed3SPierre Pronchery {
570b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
571e7be843bSPierre Pronchery int ok = 0;
572b077aed3SPierre Pronchery
573e7be843bSPierre Pronchery if (ctx == NULL)
574e7be843bSPierre Pronchery return 0;
575e7be843bSPierre Pronchery /* Sigalg implementations shouldn't do digest_sign */
576e7be843bSPierre Pronchery if (ctx->flag_sigalg)
577b077aed3SPierre Pronchery return 0;
578b077aed3SPierre Pronchery
579e7be843bSPierre Pronchery ok = ecdsa_sign_message_final(ctx, sig, siglen, sigsize);
580e7be843bSPierre Pronchery
581b077aed3SPierre Pronchery ctx->flag_allow_md = 1;
582e7be843bSPierre Pronchery
583e7be843bSPierre Pronchery return ok;
584e7be843bSPierre Pronchery }
585e7be843bSPierre Pronchery
586e7be843bSPierre Pronchery static int ecdsa_digest_verify_init(void *vctx, const char *mdname, void *ec,
587e7be843bSPierre Pronchery const OSSL_PARAM params[])
588e7be843bSPierre Pronchery {
589e7be843bSPierre Pronchery return ecdsa_digest_signverify_init(vctx, mdname, ec, params,
590e7be843bSPierre Pronchery EVP_PKEY_OP_VERIFYMSG,
591e7be843bSPierre Pronchery "ECDSA Digest Verify Init");
592b077aed3SPierre Pronchery }
593b077aed3SPierre Pronchery
594b077aed3SPierre Pronchery int ecdsa_digest_verify_final(void *vctx, const unsigned char *sig,
595b077aed3SPierre Pronchery size_t siglen)
596b077aed3SPierre Pronchery {
597b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
598e7be843bSPierre Pronchery int ok = 0;
599b077aed3SPierre Pronchery
600b077aed3SPierre Pronchery if (!ossl_prov_is_running() || ctx == NULL || ctx->mdctx == NULL)
601b077aed3SPierre Pronchery return 0;
602b077aed3SPierre Pronchery
603e7be843bSPierre Pronchery /* Sigalg implementations shouldn't do digest_verify */
604e7be843bSPierre Pronchery if (ctx->flag_sigalg)
605b077aed3SPierre Pronchery return 0;
606e7be843bSPierre Pronchery
607e7be843bSPierre Pronchery if (ecdsa_verify_set_sig(ctx, sig, siglen))
608e7be843bSPierre Pronchery ok = ecdsa_verify_message_final(ctx);
609e7be843bSPierre Pronchery
610b077aed3SPierre Pronchery ctx->flag_allow_md = 1;
611e7be843bSPierre Pronchery
612e7be843bSPierre Pronchery return ok;
613b077aed3SPierre Pronchery }
614b077aed3SPierre Pronchery
615b077aed3SPierre Pronchery static void ecdsa_freectx(void *vctx)
616b077aed3SPierre Pronchery {
617b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
618b077aed3SPierre Pronchery
619b077aed3SPierre Pronchery EVP_MD_CTX_free(ctx->mdctx);
620b077aed3SPierre Pronchery EVP_MD_free(ctx->md);
621e7be843bSPierre Pronchery OPENSSL_free(ctx->propq);
622e7be843bSPierre Pronchery OPENSSL_free(ctx->sig);
623b077aed3SPierre Pronchery EC_KEY_free(ctx->ec);
624b077aed3SPierre Pronchery BN_clear_free(ctx->kinv);
625b077aed3SPierre Pronchery BN_clear_free(ctx->r);
626b077aed3SPierre Pronchery OPENSSL_free(ctx);
627b077aed3SPierre Pronchery }
628b077aed3SPierre Pronchery
629b077aed3SPierre Pronchery static void *ecdsa_dupctx(void *vctx)
630b077aed3SPierre Pronchery {
631b077aed3SPierre Pronchery PROV_ECDSA_CTX *srcctx = (PROV_ECDSA_CTX *)vctx;
632b077aed3SPierre Pronchery PROV_ECDSA_CTX *dstctx;
633b077aed3SPierre Pronchery
634b077aed3SPierre Pronchery if (!ossl_prov_is_running())
635b077aed3SPierre Pronchery return NULL;
636b077aed3SPierre Pronchery
637b077aed3SPierre Pronchery dstctx = OPENSSL_zalloc(sizeof(*srcctx));
638b077aed3SPierre Pronchery if (dstctx == NULL)
639b077aed3SPierre Pronchery return NULL;
640b077aed3SPierre Pronchery
641b077aed3SPierre Pronchery *dstctx = *srcctx;
642b077aed3SPierre Pronchery dstctx->ec = NULL;
643b077aed3SPierre Pronchery dstctx->propq = NULL;
644b077aed3SPierre Pronchery
645b077aed3SPierre Pronchery if (srcctx->ec != NULL && !EC_KEY_up_ref(srcctx->ec))
646b077aed3SPierre Pronchery goto err;
647b077aed3SPierre Pronchery /* Test KATS should not need to be supported */
648b077aed3SPierre Pronchery if (srcctx->kinv != NULL || srcctx->r != NULL)
649b077aed3SPierre Pronchery goto err;
650b077aed3SPierre Pronchery dstctx->ec = srcctx->ec;
651b077aed3SPierre Pronchery
652b077aed3SPierre Pronchery if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md))
653b077aed3SPierre Pronchery goto err;
654b077aed3SPierre Pronchery dstctx->md = srcctx->md;
655b077aed3SPierre Pronchery
656b077aed3SPierre Pronchery if (srcctx->mdctx != NULL) {
657b077aed3SPierre Pronchery dstctx->mdctx = EVP_MD_CTX_new();
658b077aed3SPierre Pronchery if (dstctx->mdctx == NULL
659b077aed3SPierre Pronchery || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx))
660b077aed3SPierre Pronchery goto err;
661b077aed3SPierre Pronchery }
662b077aed3SPierre Pronchery
663b077aed3SPierre Pronchery if (srcctx->propq != NULL) {
664b077aed3SPierre Pronchery dstctx->propq = OPENSSL_strdup(srcctx->propq);
665b077aed3SPierre Pronchery if (dstctx->propq == NULL)
666b077aed3SPierre Pronchery goto err;
667b077aed3SPierre Pronchery }
668b077aed3SPierre Pronchery
669b077aed3SPierre Pronchery return dstctx;
670b077aed3SPierre Pronchery err:
671b077aed3SPierre Pronchery ecdsa_freectx(dstctx);
672b077aed3SPierre Pronchery return NULL;
673b077aed3SPierre Pronchery }
674b077aed3SPierre Pronchery
675b077aed3SPierre Pronchery static int ecdsa_get_ctx_params(void *vctx, OSSL_PARAM *params)
676b077aed3SPierre Pronchery {
677b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
678b077aed3SPierre Pronchery OSSL_PARAM *p;
679b077aed3SPierre Pronchery
680b077aed3SPierre Pronchery if (ctx == NULL)
681b077aed3SPierre Pronchery return 0;
682b077aed3SPierre Pronchery
683b077aed3SPierre Pronchery p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
684e7be843bSPierre Pronchery if (p != NULL && !OSSL_PARAM_set_octet_string(p,
685e7be843bSPierre Pronchery ctx->aid_len == 0 ? NULL : ctx->aid_buf,
686e7be843bSPierre Pronchery ctx->aid_len))
687b077aed3SPierre Pronchery return 0;
688b077aed3SPierre Pronchery
689b077aed3SPierre Pronchery p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
690b077aed3SPierre Pronchery if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->mdsize))
691b077aed3SPierre Pronchery return 0;
692b077aed3SPierre Pronchery
693b077aed3SPierre Pronchery p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST);
694b077aed3SPierre Pronchery if (p != NULL && !OSSL_PARAM_set_utf8_string(p, ctx->md == NULL
695b077aed3SPierre Pronchery ? ctx->mdname
696b077aed3SPierre Pronchery : EVP_MD_get0_name(ctx->md)))
697b077aed3SPierre Pronchery return 0;
698b077aed3SPierre Pronchery
699e7be843bSPierre Pronchery p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE);
700e7be843bSPierre Pronchery if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->nonce_type))
701e7be843bSPierre Pronchery return 0;
702e7be843bSPierre Pronchery
703e7be843bSPierre Pronchery #ifdef FIPS_MODULE
704e7be843bSPierre Pronchery p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_FIPS_VERIFY_MESSAGE);
705e7be843bSPierre Pronchery if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->verify_message))
706e7be843bSPierre Pronchery return 0;
707e7be843bSPierre Pronchery #endif
708e7be843bSPierre Pronchery
709e7be843bSPierre Pronchery if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
710e7be843bSPierre Pronchery return 0;
711b077aed3SPierre Pronchery return 1;
712b077aed3SPierre Pronchery }
713b077aed3SPierre Pronchery
714b077aed3SPierre Pronchery static const OSSL_PARAM known_gettable_ctx_params[] = {
715b077aed3SPierre Pronchery OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
716b077aed3SPierre Pronchery OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
717b077aed3SPierre Pronchery OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
718e7be843bSPierre Pronchery OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL),
719e7be843bSPierre Pronchery #ifdef FIPS_MODULE
720e7be843bSPierre Pronchery OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_FIPS_VERIFY_MESSAGE, NULL),
721e7be843bSPierre Pronchery #endif
722e7be843bSPierre Pronchery OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
723b077aed3SPierre Pronchery OSSL_PARAM_END
724b077aed3SPierre Pronchery };
725b077aed3SPierre Pronchery
726b077aed3SPierre Pronchery static const OSSL_PARAM *ecdsa_gettable_ctx_params(ossl_unused void *vctx,
727b077aed3SPierre Pronchery ossl_unused void *provctx)
728b077aed3SPierre Pronchery {
729b077aed3SPierre Pronchery return known_gettable_ctx_params;
730b077aed3SPierre Pronchery }
731b077aed3SPierre Pronchery
732e7be843bSPierre Pronchery /**
733e7be843bSPierre Pronchery * @brief Set up common params for ecdsa_set_ctx_params and
734e7be843bSPierre Pronchery * ecdsa_sigalg_set_ctx_params. The caller is responsible for checking |vctx| is
735e7be843bSPierre Pronchery * not NULL and |params| is not empty.
736e7be843bSPierre Pronchery */
737e7be843bSPierre Pronchery static int ecdsa_common_set_ctx_params(void *vctx, const OSSL_PARAM params[])
738b077aed3SPierre Pronchery {
739b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
740b077aed3SPierre Pronchery const OSSL_PARAM *p;
741b077aed3SPierre Pronchery
742e7be843bSPierre Pronchery if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
743e7be843bSPierre Pronchery OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK))
744b077aed3SPierre Pronchery return 0;
745e7be843bSPierre Pronchery if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, params,
746e7be843bSPierre Pronchery OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK))
747e7be843bSPierre Pronchery return 0;
748b077aed3SPierre Pronchery
749b077aed3SPierre Pronchery #if !defined(OPENSSL_NO_ACVP_TESTS)
750b077aed3SPierre Pronchery p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_KAT);
751b077aed3SPierre Pronchery if (p != NULL && !OSSL_PARAM_get_uint(p, &ctx->kattest))
752b077aed3SPierre Pronchery return 0;
753b077aed3SPierre Pronchery #endif
754b077aed3SPierre Pronchery
755e7be843bSPierre Pronchery p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE);
756e7be843bSPierre Pronchery if (p != NULL
757e7be843bSPierre Pronchery && !OSSL_PARAM_get_uint(p, &ctx->nonce_type))
758e7be843bSPierre Pronchery return 0;
759e7be843bSPierre Pronchery return 1;
760e7be843bSPierre Pronchery }
761e7be843bSPierre Pronchery
762e7be843bSPierre Pronchery #define ECDSA_COMMON_SETTABLE_CTX_PARAMS \
763e7be843bSPierre Pronchery OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_KAT, NULL), \
764e7be843bSPierre Pronchery OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL), \
765e7be843bSPierre Pronchery OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK) \
766e7be843bSPierre Pronchery OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK) \
767e7be843bSPierre Pronchery OSSL_PARAM_END
768e7be843bSPierre Pronchery
769e7be843bSPierre Pronchery static int ecdsa_set_ctx_params(void *vctx, const OSSL_PARAM params[])
770e7be843bSPierre Pronchery {
771e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
772e7be843bSPierre Pronchery const OSSL_PARAM *p;
773e7be843bSPierre Pronchery size_t mdsize = 0;
774e7be843bSPierre Pronchery int ret;
775e7be843bSPierre Pronchery
776e7be843bSPierre Pronchery if (ctx == NULL)
777e7be843bSPierre Pronchery return 0;
778e7be843bSPierre Pronchery if (ossl_param_is_empty(params))
779e7be843bSPierre Pronchery return 1;
780e7be843bSPierre Pronchery
781e7be843bSPierre Pronchery if ((ret = ecdsa_common_set_ctx_params(ctx, params)) <= 0)
782e7be843bSPierre Pronchery return ret;
783e7be843bSPierre Pronchery
784b077aed3SPierre Pronchery p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);
785b077aed3SPierre Pronchery if (p != NULL) {
786b077aed3SPierre Pronchery char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname;
787b077aed3SPierre Pronchery char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops;
788b077aed3SPierre Pronchery const OSSL_PARAM *propsp =
789b077aed3SPierre Pronchery OSSL_PARAM_locate_const(params,
790b077aed3SPierre Pronchery OSSL_SIGNATURE_PARAM_PROPERTIES);
791b077aed3SPierre Pronchery
792b077aed3SPierre Pronchery if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname)))
793b077aed3SPierre Pronchery return 0;
794b077aed3SPierre Pronchery if (propsp != NULL
795b077aed3SPierre Pronchery && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops)))
796b077aed3SPierre Pronchery return 0;
797e7be843bSPierre Pronchery if (!ecdsa_setup_md(ctx, mdname, mdprops, "ECDSA Set Ctx"))
798b077aed3SPierre Pronchery return 0;
799b077aed3SPierre Pronchery }
800b077aed3SPierre Pronchery
801b077aed3SPierre Pronchery p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
802b077aed3SPierre Pronchery if (p != NULL) {
803b077aed3SPierre Pronchery if (!OSSL_PARAM_get_size_t(p, &mdsize)
804b077aed3SPierre Pronchery || (!ctx->flag_allow_md && mdsize != ctx->mdsize))
805b077aed3SPierre Pronchery return 0;
806b077aed3SPierre Pronchery ctx->mdsize = mdsize;
807b077aed3SPierre Pronchery }
808b077aed3SPierre Pronchery return 1;
809b077aed3SPierre Pronchery }
810b077aed3SPierre Pronchery
811b077aed3SPierre Pronchery static const OSSL_PARAM settable_ctx_params[] = {
812b077aed3SPierre Pronchery OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
813b077aed3SPierre Pronchery OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
814b077aed3SPierre Pronchery OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0),
815e7be843bSPierre Pronchery ECDSA_COMMON_SETTABLE_CTX_PARAMS
816b077aed3SPierre Pronchery };
817b077aed3SPierre Pronchery
818b077aed3SPierre Pronchery static const OSSL_PARAM *ecdsa_settable_ctx_params(void *vctx,
819b077aed3SPierre Pronchery ossl_unused void *provctx)
820b077aed3SPierre Pronchery {
821b077aed3SPierre Pronchery return settable_ctx_params;
822b077aed3SPierre Pronchery }
823b077aed3SPierre Pronchery
824b077aed3SPierre Pronchery static int ecdsa_get_ctx_md_params(void *vctx, OSSL_PARAM *params)
825b077aed3SPierre Pronchery {
826b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
827b077aed3SPierre Pronchery
828b077aed3SPierre Pronchery if (ctx->mdctx == NULL)
829b077aed3SPierre Pronchery return 0;
830b077aed3SPierre Pronchery
831b077aed3SPierre Pronchery return EVP_MD_CTX_get_params(ctx->mdctx, params);
832b077aed3SPierre Pronchery }
833b077aed3SPierre Pronchery
834b077aed3SPierre Pronchery static const OSSL_PARAM *ecdsa_gettable_ctx_md_params(void *vctx)
835b077aed3SPierre Pronchery {
836b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
837b077aed3SPierre Pronchery
838b077aed3SPierre Pronchery if (ctx->md == NULL)
839b077aed3SPierre Pronchery return 0;
840b077aed3SPierre Pronchery
841b077aed3SPierre Pronchery return EVP_MD_gettable_ctx_params(ctx->md);
842b077aed3SPierre Pronchery }
843b077aed3SPierre Pronchery
844b077aed3SPierre Pronchery static int ecdsa_set_ctx_md_params(void *vctx, const OSSL_PARAM params[])
845b077aed3SPierre Pronchery {
846b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
847b077aed3SPierre Pronchery
848b077aed3SPierre Pronchery if (ctx->mdctx == NULL)
849b077aed3SPierre Pronchery return 0;
850b077aed3SPierre Pronchery
851b077aed3SPierre Pronchery return EVP_MD_CTX_set_params(ctx->mdctx, params);
852b077aed3SPierre Pronchery }
853b077aed3SPierre Pronchery
854b077aed3SPierre Pronchery static const OSSL_PARAM *ecdsa_settable_ctx_md_params(void *vctx)
855b077aed3SPierre Pronchery {
856b077aed3SPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
857b077aed3SPierre Pronchery
858b077aed3SPierre Pronchery if (ctx->md == NULL)
859b077aed3SPierre Pronchery return 0;
860b077aed3SPierre Pronchery
861b077aed3SPierre Pronchery return EVP_MD_settable_ctx_params(ctx->md);
862b077aed3SPierre Pronchery }
863b077aed3SPierre Pronchery
864b077aed3SPierre Pronchery const OSSL_DISPATCH ossl_ecdsa_signature_functions[] = {
865b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))ecdsa_newctx },
866b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))ecdsa_sign_init },
867b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))ecdsa_sign },
868b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))ecdsa_verify_init },
869b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))ecdsa_verify },
870b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
871b077aed3SPierre Pronchery (void (*)(void))ecdsa_digest_sign_init },
872b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE,
873b077aed3SPierre Pronchery (void (*)(void))ecdsa_digest_signverify_update },
874b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL,
875b077aed3SPierre Pronchery (void (*)(void))ecdsa_digest_sign_final },
876b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
877b077aed3SPierre Pronchery (void (*)(void))ecdsa_digest_verify_init },
878b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE,
879b077aed3SPierre Pronchery (void (*)(void))ecdsa_digest_signverify_update },
880b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL,
881b077aed3SPierre Pronchery (void (*)(void))ecdsa_digest_verify_final },
882b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))ecdsa_freectx },
883b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))ecdsa_dupctx },
884b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))ecdsa_get_ctx_params },
885b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
886b077aed3SPierre Pronchery (void (*)(void))ecdsa_gettable_ctx_params },
887b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))ecdsa_set_ctx_params },
888b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
889b077aed3SPierre Pronchery (void (*)(void))ecdsa_settable_ctx_params },
890b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS,
891b077aed3SPierre Pronchery (void (*)(void))ecdsa_get_ctx_md_params },
892b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS,
893b077aed3SPierre Pronchery (void (*)(void))ecdsa_gettable_ctx_md_params },
894b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS,
895b077aed3SPierre Pronchery (void (*)(void))ecdsa_set_ctx_md_params },
896b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS,
897b077aed3SPierre Pronchery (void (*)(void))ecdsa_settable_ctx_md_params },
898e7be843bSPierre Pronchery OSSL_DISPATCH_END
899b077aed3SPierre Pronchery };
900e7be843bSPierre Pronchery
901e7be843bSPierre Pronchery /* ------------------------------------------------------------------ */
902e7be843bSPierre Pronchery
903e7be843bSPierre Pronchery /*
904e7be843bSPierre Pronchery * So called sigalgs (composite ECDSA+hash) implemented below. They
905e7be843bSPierre Pronchery * are pretty much hard coded.
906e7be843bSPierre Pronchery */
907e7be843bSPierre Pronchery
908e7be843bSPierre Pronchery static OSSL_FUNC_signature_query_key_types_fn ecdsa_sigalg_query_key_types;
909e7be843bSPierre Pronchery static OSSL_FUNC_signature_settable_ctx_params_fn ecdsa_sigalg_settable_ctx_params;
910e7be843bSPierre Pronchery static OSSL_FUNC_signature_set_ctx_params_fn ecdsa_sigalg_set_ctx_params;
911e7be843bSPierre Pronchery
912e7be843bSPierre Pronchery /*
913e7be843bSPierre Pronchery * ecdsa_sigalg_signverify_init() is almost like ecdsa_digest_signverify_init(),
914e7be843bSPierre Pronchery * just doesn't allow fetching an MD from whatever the user chooses.
915e7be843bSPierre Pronchery */
916e7be843bSPierre Pronchery static int ecdsa_sigalg_signverify_init(void *vctx, void *vec,
917e7be843bSPierre Pronchery OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params,
918e7be843bSPierre Pronchery const OSSL_PARAM params[],
919e7be843bSPierre Pronchery const char *mdname,
920e7be843bSPierre Pronchery int operation, const char *desc)
921e7be843bSPierre Pronchery {
922e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
923e7be843bSPierre Pronchery
924e7be843bSPierre Pronchery if (!ossl_prov_is_running())
925e7be843bSPierre Pronchery return 0;
926e7be843bSPierre Pronchery
927e7be843bSPierre Pronchery if (!ecdsa_signverify_init(vctx, vec, set_ctx_params, params, operation,
928e7be843bSPierre Pronchery desc))
929e7be843bSPierre Pronchery return 0;
930e7be843bSPierre Pronchery
931e7be843bSPierre Pronchery if (!ecdsa_setup_md(ctx, mdname, NULL, desc))
932e7be843bSPierre Pronchery return 0;
933e7be843bSPierre Pronchery
934e7be843bSPierre Pronchery ctx->flag_sigalg = 1;
935e7be843bSPierre Pronchery ctx->flag_allow_md = 0;
936e7be843bSPierre Pronchery
937e7be843bSPierre Pronchery if (ctx->mdctx == NULL) {
938e7be843bSPierre Pronchery ctx->mdctx = EVP_MD_CTX_new();
939e7be843bSPierre Pronchery if (ctx->mdctx == NULL)
940e7be843bSPierre Pronchery goto error;
941e7be843bSPierre Pronchery }
942e7be843bSPierre Pronchery
943e7be843bSPierre Pronchery if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params))
944e7be843bSPierre Pronchery goto error;
945e7be843bSPierre Pronchery
946e7be843bSPierre Pronchery return 1;
947e7be843bSPierre Pronchery
948e7be843bSPierre Pronchery error:
949e7be843bSPierre Pronchery EVP_MD_CTX_free(ctx->mdctx);
950e7be843bSPierre Pronchery ctx->mdctx = NULL;
951e7be843bSPierre Pronchery return 0;
952e7be843bSPierre Pronchery }
953e7be843bSPierre Pronchery
954e7be843bSPierre Pronchery static const char **ecdsa_sigalg_query_key_types(void)
955e7be843bSPierre Pronchery {
956e7be843bSPierre Pronchery static const char *keytypes[] = { "EC", NULL };
957e7be843bSPierre Pronchery
958e7be843bSPierre Pronchery return keytypes;
959e7be843bSPierre Pronchery }
960e7be843bSPierre Pronchery
961e7be843bSPierre Pronchery static const OSSL_PARAM settable_sigalg_ctx_params[] = {
962e7be843bSPierre Pronchery OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE, NULL, 0),
963e7be843bSPierre Pronchery ECDSA_COMMON_SETTABLE_CTX_PARAMS
964e7be843bSPierre Pronchery };
965e7be843bSPierre Pronchery
966e7be843bSPierre Pronchery static const OSSL_PARAM *ecdsa_sigalg_settable_ctx_params(void *vctx,
967e7be843bSPierre Pronchery ossl_unused void *provctx)
968e7be843bSPierre Pronchery {
969e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
970e7be843bSPierre Pronchery
971e7be843bSPierre Pronchery if (ctx != NULL && ctx->operation == EVP_PKEY_OP_VERIFYMSG)
972e7be843bSPierre Pronchery return settable_sigalg_ctx_params;
973e7be843bSPierre Pronchery return NULL;
974e7be843bSPierre Pronchery }
975e7be843bSPierre Pronchery
976e7be843bSPierre Pronchery static int ecdsa_sigalg_set_ctx_params(void *vctx, const OSSL_PARAM params[])
977e7be843bSPierre Pronchery {
978e7be843bSPierre Pronchery PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
979e7be843bSPierre Pronchery const OSSL_PARAM *p;
980e7be843bSPierre Pronchery int ret;
981e7be843bSPierre Pronchery
982e7be843bSPierre Pronchery if (ctx == NULL)
983e7be843bSPierre Pronchery return 0;
984e7be843bSPierre Pronchery if (ossl_param_is_empty(params))
985e7be843bSPierre Pronchery return 1;
986e7be843bSPierre Pronchery
987e7be843bSPierre Pronchery if ((ret = ecdsa_common_set_ctx_params(ctx, params)) <= 0)
988e7be843bSPierre Pronchery return ret;
989e7be843bSPierre Pronchery
990e7be843bSPierre Pronchery if (ctx->operation == EVP_PKEY_OP_VERIFYMSG) {
991e7be843bSPierre Pronchery p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_SIGNATURE);
992e7be843bSPierre Pronchery if (p != NULL) {
993e7be843bSPierre Pronchery OPENSSL_free(ctx->sig);
994e7be843bSPierre Pronchery ctx->sig = NULL;
995e7be843bSPierre Pronchery ctx->siglen = 0;
996e7be843bSPierre Pronchery if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->sig,
997e7be843bSPierre Pronchery 0, &ctx->siglen))
998e7be843bSPierre Pronchery return 0;
999e7be843bSPierre Pronchery }
1000e7be843bSPierre Pronchery }
1001e7be843bSPierre Pronchery return 1;
1002e7be843bSPierre Pronchery }
1003e7be843bSPierre Pronchery
1004e7be843bSPierre Pronchery #define IMPL_ECDSA_SIGALG(md, MD) \
1005e7be843bSPierre Pronchery static OSSL_FUNC_signature_sign_init_fn ecdsa_##md##_sign_init; \
1006e7be843bSPierre Pronchery static OSSL_FUNC_signature_sign_message_init_fn \
1007e7be843bSPierre Pronchery ecdsa_##md##_sign_message_init; \
1008e7be843bSPierre Pronchery static OSSL_FUNC_signature_verify_init_fn ecdsa_##md##_verify_init; \
1009e7be843bSPierre Pronchery static OSSL_FUNC_signature_verify_message_init_fn \
1010e7be843bSPierre Pronchery ecdsa_##md##_verify_message_init; \
1011e7be843bSPierre Pronchery \
1012e7be843bSPierre Pronchery static int \
1013e7be843bSPierre Pronchery ecdsa_##md##_sign_init(void *vctx, void *vec, \
1014e7be843bSPierre Pronchery const OSSL_PARAM params[]) \
1015e7be843bSPierre Pronchery { \
1016e7be843bSPierre Pronchery static const char desc[] = "ECDSA-" #MD " Sign Init"; \
1017e7be843bSPierre Pronchery \
1018e7be843bSPierre Pronchery return ecdsa_sigalg_signverify_init(vctx, vec, \
1019e7be843bSPierre Pronchery ecdsa_sigalg_set_ctx_params, \
1020e7be843bSPierre Pronchery params, #MD, \
1021e7be843bSPierre Pronchery EVP_PKEY_OP_SIGN, \
1022e7be843bSPierre Pronchery desc); \
1023e7be843bSPierre Pronchery } \
1024e7be843bSPierre Pronchery \
1025e7be843bSPierre Pronchery static int \
1026e7be843bSPierre Pronchery ecdsa_##md##_sign_message_init(void *vctx, void *vec, \
1027e7be843bSPierre Pronchery const OSSL_PARAM params[]) \
1028e7be843bSPierre Pronchery { \
1029e7be843bSPierre Pronchery static const char desc[] = "ECDSA-" #MD " Sign Message Init"; \
1030e7be843bSPierre Pronchery \
1031e7be843bSPierre Pronchery return ecdsa_sigalg_signverify_init(vctx, vec, \
1032e7be843bSPierre Pronchery ecdsa_sigalg_set_ctx_params, \
1033e7be843bSPierre Pronchery params, #MD, \
1034e7be843bSPierre Pronchery EVP_PKEY_OP_SIGNMSG, \
1035e7be843bSPierre Pronchery desc); \
1036e7be843bSPierre Pronchery } \
1037e7be843bSPierre Pronchery \
1038e7be843bSPierre Pronchery static int \
1039e7be843bSPierre Pronchery ecdsa_##md##_verify_init(void *vctx, void *vec, \
1040e7be843bSPierre Pronchery const OSSL_PARAM params[]) \
1041e7be843bSPierre Pronchery { \
1042e7be843bSPierre Pronchery static const char desc[] = "ECDSA-" #MD " Verify Init"; \
1043e7be843bSPierre Pronchery \
1044e7be843bSPierre Pronchery return ecdsa_sigalg_signverify_init(vctx, vec, \
1045e7be843bSPierre Pronchery ecdsa_sigalg_set_ctx_params, \
1046e7be843bSPierre Pronchery params, #MD, \
1047e7be843bSPierre Pronchery EVP_PKEY_OP_VERIFY, \
1048e7be843bSPierre Pronchery desc); \
1049e7be843bSPierre Pronchery } \
1050e7be843bSPierre Pronchery \
1051e7be843bSPierre Pronchery static int \
1052e7be843bSPierre Pronchery ecdsa_##md##_verify_message_init(void *vctx, void *vec, \
1053e7be843bSPierre Pronchery const OSSL_PARAM params[]) \
1054e7be843bSPierre Pronchery { \
1055e7be843bSPierre Pronchery static const char desc[] = "ECDSA-" #MD " Verify Message Init"; \
1056e7be843bSPierre Pronchery \
1057e7be843bSPierre Pronchery return ecdsa_sigalg_signverify_init(vctx, vec, \
1058e7be843bSPierre Pronchery ecdsa_sigalg_set_ctx_params, \
1059e7be843bSPierre Pronchery params, #MD, \
1060e7be843bSPierre Pronchery EVP_PKEY_OP_VERIFYMSG, \
1061e7be843bSPierre Pronchery desc); \
1062e7be843bSPierre Pronchery } \
1063e7be843bSPierre Pronchery \
1064e7be843bSPierre Pronchery const OSSL_DISPATCH ossl_ecdsa_##md##_signature_functions[] = { \
1065e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))ecdsa_newctx }, \
1066e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN_INIT, \
1067e7be843bSPierre Pronchery (void (*)(void))ecdsa_##md##_sign_init }, \
1068e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))ecdsa_sign }, \
1069e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT, \
1070e7be843bSPierre Pronchery (void (*)(void))ecdsa_##md##_sign_message_init }, \
1071e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_UPDATE, \
1072e7be843bSPierre Pronchery (void (*)(void))ecdsa_signverify_message_update }, \
1073e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_FINAL, \
1074e7be843bSPierre Pronchery (void (*)(void))ecdsa_sign_message_final }, \
1075e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY_INIT, \
1076e7be843bSPierre Pronchery (void (*)(void))ecdsa_##md##_verify_init }, \
1077e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY, \
1078e7be843bSPierre Pronchery (void (*)(void))ecdsa_verify }, \
1079e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT, \
1080e7be843bSPierre Pronchery (void (*)(void))ecdsa_##md##_verify_message_init }, \
1081e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_UPDATE, \
1082e7be843bSPierre Pronchery (void (*)(void))ecdsa_signverify_message_update }, \
1083e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_FINAL, \
1084e7be843bSPierre Pronchery (void (*)(void))ecdsa_verify_message_final }, \
1085e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))ecdsa_freectx }, \
1086e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))ecdsa_dupctx }, \
1087e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPES, \
1088e7be843bSPierre Pronchery (void (*)(void))ecdsa_sigalg_query_key_types }, \
1089e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \
1090e7be843bSPierre Pronchery (void (*)(void))ecdsa_get_ctx_params }, \
1091e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \
1092e7be843bSPierre Pronchery (void (*)(void))ecdsa_gettable_ctx_params }, \
1093e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \
1094e7be843bSPierre Pronchery (void (*)(void))ecdsa_sigalg_set_ctx_params }, \
1095e7be843bSPierre Pronchery { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \
1096e7be843bSPierre Pronchery (void (*)(void))ecdsa_sigalg_settable_ctx_params }, \
1097e7be843bSPierre Pronchery OSSL_DISPATCH_END \
1098e7be843bSPierre Pronchery }
1099e7be843bSPierre Pronchery
1100e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha1, SHA1);
1101e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha224, SHA2-224);
1102e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha256, SHA2-256);
1103e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha384, SHA2-384);
1104e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha512, SHA2-512);
1105e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha3_224, SHA3-224);
1106e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha3_256, SHA3-256);
1107e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha3_384, SHA3-384);
1108e7be843bSPierre Pronchery IMPL_ECDSA_SIGALG(sha3_512, SHA3-512);
1109