Cleanup: move providers/common/include/internal/provider_args.h
[openssl.git] / providers / implementations / signature / dsa.c
1 /*
2  * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <openssl/crypto.h>
11 #include <openssl/core_numbers.h>
12 #include <openssl/core_names.h>
13 #include <openssl/dsa.h>
14 #include <openssl/params.h>
15 #include <openssl/evp.h>
16 #include "prov/implementations.h"
17 #include "internal/provider_ctx.h"
18
19 static OSSL_OP_signature_newctx_fn dsa_newctx;
20 static OSSL_OP_signature_sign_init_fn dsa_signature_init;
21 static OSSL_OP_signature_verify_init_fn dsa_signature_init;
22 static OSSL_OP_signature_sign_fn dsa_sign;
23 static OSSL_OP_signature_verify_fn dsa_verify;
24 static OSSL_OP_signature_digest_sign_init_fn dsa_digest_signverify_init;
25 static OSSL_OP_signature_digest_sign_update_fn dsa_digest_signverify_update;
26 static OSSL_OP_signature_digest_sign_final_fn dsa_digest_sign_final;
27 static OSSL_OP_signature_digest_verify_init_fn dsa_digest_signverify_init;
28 static OSSL_OP_signature_digest_verify_update_fn dsa_digest_signverify_update;
29 static OSSL_OP_signature_digest_verify_final_fn dsa_digest_verify_final;
30 static OSSL_OP_signature_freectx_fn dsa_freectx;
31 static OSSL_OP_signature_dupctx_fn dsa_dupctx;
32 static OSSL_OP_signature_get_ctx_params_fn dsa_get_ctx_params;
33 static OSSL_OP_signature_gettable_ctx_params_fn dsa_gettable_ctx_params;
34 static OSSL_OP_signature_set_ctx_params_fn dsa_set_ctx_params;
35 static OSSL_OP_signature_settable_ctx_params_fn dsa_settable_ctx_params;
36 static OSSL_OP_signature_get_ctx_md_params_fn dsa_get_ctx_md_params;
37 static OSSL_OP_signature_gettable_ctx_md_params_fn dsa_gettable_ctx_md_params;
38 static OSSL_OP_signature_set_ctx_md_params_fn dsa_set_ctx_md_params;
39 static OSSL_OP_signature_settable_ctx_md_params_fn dsa_settable_ctx_md_params;
40
41 /*
42  * What's passed as an actual key is defined by the KEYMGMT interface.
43  * We happen to know that our KEYMGMT simply passes DSA structures, so
44  * we use that here too.
45  */
46
47 typedef struct {
48     OPENSSL_CTX *libctx;
49     DSA *dsa;
50     size_t mdsize;
51     /* Should be big enough */
52     char mdname[80];
53     EVP_MD *md;
54     EVP_MD_CTX *mdctx;
55 } PROV_DSA_CTX;
56
57 static void *dsa_newctx(void *provctx)
58 {
59     PROV_DSA_CTX *pdsactx = OPENSSL_zalloc(sizeof(PROV_DSA_CTX));
60
61     if (pdsactx == NULL)
62         return NULL;
63
64     pdsactx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
65     return pdsactx;
66 }
67
68 static int dsa_signature_init(void *vpdsactx, void *vdsa)
69 {
70     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
71
72     if (pdsactx == NULL || vdsa == NULL || !DSA_up_ref(vdsa))
73         return 0;
74     DSA_free(pdsactx->dsa);
75     pdsactx->dsa = vdsa;
76     return 1;
77 }
78
79 static int dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen,
80                     size_t sigsize, const unsigned char *tbs, size_t tbslen)
81 {
82     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
83     int ret;
84     unsigned int sltmp;
85     size_t dsasize = DSA_size(pdsactx->dsa);
86
87     if (sig == NULL) {
88         *siglen = dsasize;
89         return 1;
90     }
91
92     if (sigsize < (size_t)dsasize)
93         return 0;
94
95     if (pdsactx->mdsize != 0 && tbslen != pdsactx->mdsize)
96         return 0;
97
98     ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, pdsactx->dsa);
99
100     if (ret <= 0)
101         return 0;
102
103     *siglen = sltmp;
104     return 1;
105 }
106
107 static int dsa_verify(void *vpdsactx, const unsigned char *sig, size_t siglen,
108                       const unsigned char *tbs, size_t tbslen)
109 {
110     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
111
112     if (pdsactx->mdsize != 0 && tbslen != pdsactx->mdsize)
113         return 0;
114
115     return DSA_verify(0, tbs, tbslen, sig, siglen, pdsactx->dsa);
116 }
117
118 static int dsa_digest_signverify_init(void *vpdsactx, const char *mdname,
119                                       const char *props, void *vdsa)
120 {
121     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
122     EVP_MD *md;
123
124     if (!dsa_signature_init(vpdsactx, vdsa))
125         return 0;
126
127     md = EVP_MD_fetch(pdsactx->libctx, mdname, props);
128     if (md == NULL)
129         return 0;
130     pdsactx->md = md;
131     pdsactx->mdsize = EVP_MD_size(md);
132     pdsactx->mdctx = EVP_MD_CTX_new();
133     if (pdsactx->mdctx == NULL)
134         return 0;
135
136     if (!EVP_DigestInit_ex(pdsactx->mdctx, md, NULL))
137         return 0;
138
139     return 1;
140 }
141
142 int dsa_digest_signverify_update(void *vpdsactx, const unsigned char *data,
143                                  size_t datalen)
144 {
145     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
146
147     if (pdsactx == NULL || pdsactx->mdctx == NULL)
148         return 0;
149
150     return EVP_DigestUpdate(pdsactx->mdctx, data, datalen);
151 }
152
153 int dsa_digest_sign_final(void *vpdsactx, unsigned char *sig, size_t *siglen,
154                           size_t sigsize)
155 {
156     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
157     unsigned char digest[EVP_MAX_MD_SIZE];
158     unsigned int dlen = 0;
159
160     if (pdsactx == NULL || pdsactx->mdctx == NULL)
161         return 0;
162
163     /*
164      * If sig is NULL then we're just finding out the sig size. Other fields
165      * are ignored. Defer to dsa_sign.
166      */
167     if (sig != NULL) {
168         /*
169          * TODO(3.0): There is the possibility that some externally provided
170          * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow -
171          * but that problem is much larger than just in DSA.
172          */
173         if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen))
174             return 0;
175     }
176
177     return dsa_sign(vpdsactx, sig, siglen, sigsize, digest, (size_t)dlen);
178 }
179
180
181 int dsa_digest_verify_final(void *vpdsactx, const unsigned char *sig,
182                             size_t siglen)
183 {
184     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
185     unsigned char digest[EVP_MAX_MD_SIZE];
186     unsigned int dlen = 0;
187
188     if (pdsactx == NULL || pdsactx->mdctx == NULL)
189         return 0;
190
191     /*
192      * TODO(3.0): There is the possibility that some externally provided
193      * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow -
194      * but that problem is much larger than just in DSA.
195      */
196     if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen))
197         return 0;
198
199     return dsa_verify(vpdsactx, sig, siglen, digest, (size_t)dlen);
200 }
201
202 static void dsa_freectx(void *vpdsactx)
203 {
204     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
205
206     DSA_free(pdsactx->dsa);
207     EVP_MD_CTX_free(pdsactx->mdctx);
208     EVP_MD_free(pdsactx->md);
209
210     OPENSSL_free(pdsactx);
211 }
212
213 static void *dsa_dupctx(void *vpdsactx)
214 {
215     PROV_DSA_CTX *srcctx = (PROV_DSA_CTX *)vpdsactx;
216     PROV_DSA_CTX *dstctx;
217
218     dstctx = OPENSSL_zalloc(sizeof(*srcctx));
219     if (dstctx == NULL)
220         return NULL;
221
222     *dstctx = *srcctx;
223     dstctx->dsa = NULL;
224     dstctx->md = NULL;
225     dstctx->mdctx = NULL;
226
227     if (srcctx->dsa != NULL && !DSA_up_ref(srcctx->dsa))
228         goto err;
229     dstctx->dsa = srcctx->dsa;
230
231     if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md))
232         goto err;
233     dstctx->md = srcctx->md;
234
235     if (srcctx->mdctx != NULL) {
236         dstctx->mdctx = EVP_MD_CTX_new();
237         if (dstctx->mdctx == NULL
238                 || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx))
239             goto err;
240     }
241
242     return dstctx;
243  err:
244     dsa_freectx(dstctx);
245     return NULL;
246 }
247
248 static int dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params)
249 {
250     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
251     OSSL_PARAM *p;
252
253     if (pdsactx == NULL || params == NULL)
254         return 0;
255
256     p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
257     if (p != NULL && !OSSL_PARAM_set_size_t(p, pdsactx->mdsize))
258         return 0;
259
260     p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST);
261     if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdsactx->md == NULL
262                                                     ? pdsactx->mdname
263                                                     : EVP_MD_name(pdsactx->md)))
264         return 0;
265
266     return 1;
267 }
268
269 static const OSSL_PARAM known_gettable_ctx_params[] = {
270     OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
271     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
272     OSSL_PARAM_END
273 };
274
275 static const OSSL_PARAM *dsa_gettable_ctx_params(void)
276 {
277     return known_gettable_ctx_params;
278 }
279
280 static int dsa_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[])
281 {
282     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
283     const OSSL_PARAM *p;
284     char *mdname;
285
286     if (pdsactx == NULL || params == NULL)
287         return 0;
288
289     if (pdsactx->md != NULL) {
290         /*
291          * You cannot set the digest name/size when doing a DigestSign or
292          * DigestVerify.
293          */
294         return 1;
295     }
296
297     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
298     if (p != NULL && !OSSL_PARAM_get_size_t(p, &pdsactx->mdsize))
299         return 0;
300
301     /*
302      * We never actually use the mdname, but we do support getting it later.
303      * This can be useful for applications that want to know the MD that they
304      * previously set.
305      */
306     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);
307     mdname = pdsactx->mdname;
308     if (p != NULL
309             && !OSSL_PARAM_get_utf8_string(p, &mdname, sizeof(pdsactx->mdname)))
310         return 0;
311
312     return 1;
313 }
314
315 static const OSSL_PARAM known_settable_ctx_params[] = {
316     OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),
317     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
318     OSSL_PARAM_END
319 };
320
321 static const OSSL_PARAM *dsa_settable_ctx_params(void)
322 {
323     /*
324      * TODO(3.0): Should this function return a different set of settable ctx
325      * params if the ctx is being used for a DigestSign/DigestVerify? In that
326      * case it is not allowed to set the digest size/digest name because the
327      * digest is explicitly set as part of the init.
328      */
329     return known_settable_ctx_params;
330 }
331
332 static int dsa_get_ctx_md_params(void *vpdsactx, OSSL_PARAM *params)
333 {
334     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
335
336     if (pdsactx->mdctx == NULL)
337         return 0;
338
339     return EVP_MD_CTX_get_params(pdsactx->mdctx, params);
340 }
341
342 static const OSSL_PARAM *dsa_gettable_ctx_md_params(void *vpdsactx)
343 {
344     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
345
346     if (pdsactx->md == NULL)
347         return 0;
348
349     return EVP_MD_gettable_ctx_params(pdsactx->md);
350 }
351
352 static int dsa_set_ctx_md_params(void *vpdsactx, const OSSL_PARAM params[])
353 {
354     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
355
356     if (pdsactx->mdctx == NULL)
357         return 0;
358
359     return EVP_MD_CTX_set_params(pdsactx->mdctx, params);
360 }
361
362 static const OSSL_PARAM *dsa_settable_ctx_md_params(void *vpdsactx)
363 {
364     PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
365
366     if (pdsactx->md == NULL)
367         return 0;
368
369     return EVP_MD_settable_ctx_params(pdsactx->md);
370 }
371
372 const OSSL_DISPATCH dsa_signature_functions[] = {
373     { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))dsa_newctx },
374     { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))dsa_signature_init },
375     { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))dsa_sign },
376     { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))dsa_signature_init },
377     { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))dsa_verify },
378     { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
379       (void (*)(void))dsa_digest_signverify_init },
380     { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE,
381       (void (*)(void))dsa_digest_signverify_update },
382     { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL,
383       (void (*)(void))dsa_digest_sign_final },
384     { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
385       (void (*)(void))dsa_digest_signverify_init },
386     { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE,
387       (void (*)(void))dsa_digest_signverify_update },
388     { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL,
389       (void (*)(void))dsa_digest_verify_final },
390     { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))dsa_freectx },
391     { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))dsa_dupctx },
392     { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))dsa_get_ctx_params },
393     { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
394       (void (*)(void))dsa_gettable_ctx_params },
395     { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))dsa_set_ctx_params },
396     { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
397       (void (*)(void))dsa_settable_ctx_params },
398     { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS,
399       (void (*)(void))dsa_get_ctx_md_params },
400     { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS,
401       (void (*)(void))dsa_gettable_ctx_md_params },
402     { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS,
403       (void (*)(void))dsa_set_ctx_md_params },
404     { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS,
405       (void (*)(void))dsa_settable_ctx_md_params },
406     { 0, NULL }
407 };