]> git.ipfire.org Git - thirdparty/openssl.git/blob - providers/common/signature/dsa.c
Implement DSA in the default provider
[thirdparty/openssl.git] / providers / common / 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 "internal/provider_algs.h"
16
17 static OSSL_OP_signature_newctx_fn dsa_newctx;
18 static OSSL_OP_signature_sign_init_fn dsa_sign_init;
19 static OSSL_OP_signature_sign_fn dsa_sign;
20 static OSSL_OP_signature_freectx_fn dsa_freectx;
21 static OSSL_OP_signature_dupctx_fn dsa_dupctx;
22 static OSSL_OP_signature_set_params_fn dsa_set_params;
23
24 /*
25 * What's passed as an actual key is defined by the KEYMGMT interface.
26 * We happen to know that our KEYMGMT simply passes DSA structures, so
27 * we use that here too.
28 */
29
30 typedef struct {
31 DSA *dsa;
32 size_t mdsize;
33 } PROV_DSA_CTX;
34
35 static void *dsa_newctx(void *provctx)
36 {
37 return OPENSSL_zalloc(sizeof(PROV_DSA_CTX));
38 }
39
40 static int dsa_sign_init(void *vpdsactx, void *vdsa)
41 {
42 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
43
44 if (pdsactx == NULL || vdsa == NULL || !DSA_up_ref(vdsa))
45 return 0;
46 DSA_free(pdsactx->dsa);
47 pdsactx->dsa = vdsa;
48 return 1;
49 }
50
51 static int dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen,
52 size_t sigsize, const unsigned char *tbs, size_t tbslen)
53 {
54 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
55 int ret;
56 unsigned int sltmp;
57 size_t dsasize = DSA_size(pdsactx->dsa);
58
59 if (sig == NULL) {
60 *siglen = dsasize;
61 return 1;
62 }
63
64 if (sigsize < (size_t)dsasize)
65 return 0;
66
67 if (pdsactx->mdsize != 0 && tbslen != pdsactx->mdsize)
68 return 0;
69
70 ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, pdsactx-> dsa);
71
72 if (ret <= 0)
73 return 0;
74
75 *siglen = sltmp;
76 return 1;
77 }
78
79 static void dsa_freectx(void *vpdsactx)
80 {
81 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
82
83 DSA_free(pdsactx->dsa);
84
85 OPENSSL_free(pdsactx);
86 }
87
88 static void *dsa_dupctx(void *vpdsactx)
89 {
90 PROV_DSA_CTX *srcctx = (PROV_DSA_CTX *)vpdsactx;
91 PROV_DSA_CTX *dstctx;
92
93 dstctx = OPENSSL_zalloc(sizeof(*srcctx));
94 if (dstctx == NULL)
95 return NULL;
96
97 *dstctx = *srcctx;
98 if (dstctx->dsa != NULL && !DSA_up_ref(dstctx->dsa)) {
99 OPENSSL_free(dstctx);
100 return NULL;
101 }
102
103 return dstctx;
104 }
105
106 static int dsa_set_params(void *vpdsactx, const OSSL_PARAM params[])
107 {
108 PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
109 const OSSL_PARAM *p;
110 size_t mdsize;
111
112 if (pdsactx == NULL || params == NULL)
113 return 0;
114
115 p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
116 if (p == NULL || !OSSL_PARAM_get_size_t(p, &mdsize))
117 return 0;
118
119 pdsactx->mdsize = mdsize;
120
121 return 1;
122 }
123
124 const OSSL_DISPATCH dsa_signature_functions[] = {
125 { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))dsa_newctx },
126 { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))dsa_sign_init },
127 { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))dsa_sign },
128 { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))dsa_freectx },
129 { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))dsa_dupctx },
130 { OSSL_FUNC_SIGNATURE_SET_PARAMS, (void (*)(void))dsa_set_params },
131 { 0, NULL }
132 };