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