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