xref: /freebsd/crypto/openssl/crypto/dsa/dsa_pmeth.c (revision aa1a8ff2d6dbc51ef058f46f3db5a8bb77967145)
1 /*
2  * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 /*
11  * DSA low level APIs are deprecated for public use, but still ok for
12  * internal use.
13  */
14 #include "internal/deprecated.h"
15 
16 #include <stdio.h>
17 #include "internal/cryptlib.h"
18 #include <openssl/asn1t.h>
19 #include <openssl/x509.h>
20 #include <openssl/evp.h>
21 #include <openssl/bn.h>
22 #include "crypto/evp.h"
23 #include "dsa_local.h"
24 
25 /* DSA pkey context structure */
26 
27 typedef struct {
28     /* Parameter gen parameters */
29     int nbits;                  /* size of p in bits (default: 2048) */
30     int qbits;                  /* size of q in bits (default: 224) */
31     const EVP_MD *pmd;          /* MD for parameter generation */
32     /* Keygen callback info */
33     int gentmp[2];
34     /* message digest */
35     const EVP_MD *md;           /* MD for the signature */
36 } DSA_PKEY_CTX;
37 
38 static int pkey_dsa_init(EVP_PKEY_CTX *ctx)
39 {
40     DSA_PKEY_CTX *dctx = OPENSSL_malloc(sizeof(*dctx));
41 
42     if (dctx == NULL)
43         return 0;
44     dctx->nbits = 2048;
45     dctx->qbits = 224;
46     dctx->pmd = NULL;
47     dctx->md = NULL;
48 
49     ctx->data = dctx;
50     ctx->keygen_info = dctx->gentmp;
51     ctx->keygen_info_count = 2;
52 
53     return 1;
54 }
55 
56 static int pkey_dsa_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
57 {
58     DSA_PKEY_CTX *dctx, *sctx;
59 
60     if (!pkey_dsa_init(dst))
61         return 0;
62     sctx = src->data;
63     dctx = dst->data;
64     dctx->nbits = sctx->nbits;
65     dctx->qbits = sctx->qbits;
66     dctx->pmd = sctx->pmd;
67     dctx->md = sctx->md;
68     return 1;
69 }
70 
71 static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx)
72 {
73     DSA_PKEY_CTX *dctx = ctx->data;
74     OPENSSL_free(dctx);
75 }
76 
77 static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
78                          size_t *siglen, const unsigned char *tbs,
79                          size_t tbslen)
80 {
81     int ret;
82     unsigned int sltmp;
83     DSA_PKEY_CTX *dctx = ctx->data;
84     /*
85      * Discard const. Its marked as const because this may be a cached copy of
86      * the "real" key. These calls don't make any modifications that need to
87      * be reflected back in the "original" key.
88      */
89     DSA *dsa = (DSA *)EVP_PKEY_get0_DSA(ctx->pkey);
90 
91     if (dctx->md != NULL && tbslen != (size_t)EVP_MD_get_size(dctx->md))
92         return 0;
93 
94     ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, dsa);
95 
96     if (ret <= 0)
97         return ret;
98     *siglen = sltmp;
99     return 1;
100 }
101 
102 static int pkey_dsa_verify(EVP_PKEY_CTX *ctx,
103                            const unsigned char *sig, size_t siglen,
104                            const unsigned char *tbs, size_t tbslen)
105 {
106     int ret;
107     DSA_PKEY_CTX *dctx = ctx->data;
108     /*
109      * Discard const. Its marked as const because this may be a cached copy of
110      * the "real" key. These calls don't make any modifications that need to
111      * be reflected back in the "original" key.
112      */
113     DSA *dsa = (DSA *)EVP_PKEY_get0_DSA(ctx->pkey);
114 
115     if (dctx->md != NULL && tbslen != (size_t)EVP_MD_get_size(dctx->md))
116         return 0;
117 
118     ret = DSA_verify(0, tbs, tbslen, sig, siglen, dsa);
119 
120     return ret;
121 }
122 
123 static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
124 {
125     DSA_PKEY_CTX *dctx = ctx->data;
126 
127     switch (type) {
128     case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS:
129         if (p1 < 256)
130             return -2;
131         dctx->nbits = p1;
132         return 1;
133 
134     case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS:
135         if (p1 != 160 && p1 != 224 && p1 && p1 != 256)
136             return -2;
137         dctx->qbits = p1;
138         return 1;
139 
140     case EVP_PKEY_CTRL_DSA_PARAMGEN_MD:
141         if (EVP_MD_get_type((const EVP_MD *)p2) != NID_sha1 &&
142             EVP_MD_get_type((const EVP_MD *)p2) != NID_sha224 &&
143             EVP_MD_get_type((const EVP_MD *)p2) != NID_sha256) {
144             ERR_raise(ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE);
145             return 0;
146         }
147         dctx->pmd = p2;
148         return 1;
149 
150     case EVP_PKEY_CTRL_MD:
151         if (EVP_MD_get_type((const EVP_MD *)p2) != NID_sha1 &&
152             EVP_MD_get_type((const EVP_MD *)p2) != NID_dsa &&
153             EVP_MD_get_type((const EVP_MD *)p2) != NID_dsaWithSHA &&
154             EVP_MD_get_type((const EVP_MD *)p2) != NID_sha224 &&
155             EVP_MD_get_type((const EVP_MD *)p2) != NID_sha256 &&
156             EVP_MD_get_type((const EVP_MD *)p2) != NID_sha384 &&
157             EVP_MD_get_type((const EVP_MD *)p2) != NID_sha512 &&
158             EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_224 &&
159             EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_256 &&
160             EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_384 &&
161             EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_512) {
162             ERR_raise(ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE);
163             return 0;
164         }
165         dctx->md = p2;
166         return 1;
167 
168     case EVP_PKEY_CTRL_GET_MD:
169         *(const EVP_MD **)p2 = dctx->md;
170         return 1;
171 
172     case EVP_PKEY_CTRL_DIGESTINIT:
173     case EVP_PKEY_CTRL_PKCS7_SIGN:
174     case EVP_PKEY_CTRL_CMS_SIGN:
175         return 1;
176 
177     case EVP_PKEY_CTRL_PEER_KEY:
178         ERR_raise(ERR_LIB_DSA, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
179         return -2;
180     default:
181         return -2;
182 
183     }
184 }
185 
186 static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx,
187                              const char *type, const char *value)
188 {
189     if (strcmp(type, "dsa_paramgen_bits") == 0) {
190         int nbits;
191         nbits = atoi(value);
192         return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits);
193     }
194     if (strcmp(type, "dsa_paramgen_q_bits") == 0) {
195         int qbits = atoi(value);
196         return EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, qbits);
197     }
198     if (strcmp(type, "dsa_paramgen_md") == 0) {
199         const EVP_MD *md = EVP_get_digestbyname(value);
200 
201         if (md == NULL) {
202             ERR_raise(ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE);
203             return 0;
204         }
205         return EVP_PKEY_CTX_set_dsa_paramgen_md(ctx, md);
206     }
207     return -2;
208 }
209 
210 static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
211 {
212     DSA *dsa = NULL;
213     DSA_PKEY_CTX *dctx = ctx->data;
214     BN_GENCB *pcb;
215     int ret, res;
216 
217     if (ctx->pkey_gencb) {
218         pcb = BN_GENCB_new();
219         if (pcb == NULL)
220             return 0;
221         evp_pkey_set_cb_translate(pcb, ctx);
222     } else
223         pcb = NULL;
224     dsa = DSA_new();
225     if (dsa == NULL) {
226         BN_GENCB_free(pcb);
227         return 0;
228     }
229     if (dctx->md != NULL)
230         ossl_ffc_set_digest(&dsa->params, EVP_MD_get0_name(dctx->md), NULL);
231 
232     ret = ossl_ffc_params_FIPS186_4_generate(NULL, &dsa->params,
233                                              FFC_PARAM_TYPE_DSA, dctx->nbits,
234                                              dctx->qbits, &res, pcb);
235     BN_GENCB_free(pcb);
236     if (ret > 0)
237         EVP_PKEY_assign_DSA(pkey, dsa);
238     else
239         DSA_free(dsa);
240     return ret;
241 }
242 
243 static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
244 {
245     DSA *dsa = NULL;
246 
247     if (ctx->pkey == NULL) {
248         ERR_raise(ERR_LIB_DSA, DSA_R_NO_PARAMETERS_SET);
249         return 0;
250     }
251     dsa = DSA_new();
252     if (dsa == NULL)
253         return 0;
254     EVP_PKEY_assign_DSA(pkey, dsa);
255     /* Note: if error return, pkey is freed by parent routine */
256     if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
257         return 0;
258     return DSA_generate_key((DSA *)EVP_PKEY_get0_DSA(pkey));
259 }
260 
261 static const EVP_PKEY_METHOD dsa_pkey_meth = {
262     EVP_PKEY_DSA,
263     EVP_PKEY_FLAG_AUTOARGLEN,
264     pkey_dsa_init,
265     pkey_dsa_copy,
266     pkey_dsa_cleanup,
267 
268     0,
269     pkey_dsa_paramgen,
270 
271     0,
272     pkey_dsa_keygen,
273 
274     0,
275     pkey_dsa_sign,
276 
277     0,
278     pkey_dsa_verify,
279 
280     0, 0,
281 
282     0, 0, 0, 0,
283 
284     0, 0,
285 
286     0, 0,
287 
288     0, 0,
289 
290     pkey_dsa_ctrl,
291     pkey_dsa_ctrl_str
292 };
293 
294 const EVP_PKEY_METHOD *ossl_dsa_pkey_method(void)
295 {
296     return &dsa_pkey_meth;
297 }
298