xref: /dflybsd-src/crypto/libressl/crypto/dsa/dsa_ameth.c (revision cca6fc5243d2098262ea81f83ad5b28d3b800f4a)
1*cca6fc52SDaniel Fojt /* $OpenBSD: dsa_ameth.c,v 1.28 2019/11/01 15:15:35 jsing Exp $ */
2f5b1c8a1SJohn Marino /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3f5b1c8a1SJohn Marino  * project 2006.
4f5b1c8a1SJohn Marino  */
5f5b1c8a1SJohn Marino /* ====================================================================
6f5b1c8a1SJohn Marino  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7f5b1c8a1SJohn Marino  *
8f5b1c8a1SJohn Marino  * Redistribution and use in source and binary forms, with or without
9f5b1c8a1SJohn Marino  * modification, are permitted provided that the following conditions
10f5b1c8a1SJohn Marino  * are met:
11f5b1c8a1SJohn Marino  *
12f5b1c8a1SJohn Marino  * 1. Redistributions of source code must retain the above copyright
13f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer.
14f5b1c8a1SJohn Marino  *
15f5b1c8a1SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
16f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer in
17f5b1c8a1SJohn Marino  *    the documentation and/or other materials provided with the
18f5b1c8a1SJohn Marino  *    distribution.
19f5b1c8a1SJohn Marino  *
20f5b1c8a1SJohn Marino  * 3. All advertising materials mentioning features or use of this
21f5b1c8a1SJohn Marino  *    software must display the following acknowledgment:
22f5b1c8a1SJohn Marino  *    "This product includes software developed by the OpenSSL Project
23f5b1c8a1SJohn Marino  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24f5b1c8a1SJohn Marino  *
25f5b1c8a1SJohn Marino  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26f5b1c8a1SJohn Marino  *    endorse or promote products derived from this software without
27f5b1c8a1SJohn Marino  *    prior written permission. For written permission, please contact
28f5b1c8a1SJohn Marino  *    licensing@OpenSSL.org.
29f5b1c8a1SJohn Marino  *
30f5b1c8a1SJohn Marino  * 5. Products derived from this software may not be called "OpenSSL"
31f5b1c8a1SJohn Marino  *    nor may "OpenSSL" appear in their names without prior written
32f5b1c8a1SJohn Marino  *    permission of the OpenSSL Project.
33f5b1c8a1SJohn Marino  *
34f5b1c8a1SJohn Marino  * 6. Redistributions of any form whatsoever must retain the following
35f5b1c8a1SJohn Marino  *    acknowledgment:
36f5b1c8a1SJohn Marino  *    "This product includes software developed by the OpenSSL Project
37f5b1c8a1SJohn Marino  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38f5b1c8a1SJohn Marino  *
39f5b1c8a1SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40f5b1c8a1SJohn Marino  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41f5b1c8a1SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42f5b1c8a1SJohn Marino  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43f5b1c8a1SJohn Marino  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44f5b1c8a1SJohn Marino  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45f5b1c8a1SJohn Marino  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46f5b1c8a1SJohn Marino  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47f5b1c8a1SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48f5b1c8a1SJohn Marino  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49f5b1c8a1SJohn Marino  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50f5b1c8a1SJohn Marino  * OF THE POSSIBILITY OF SUCH DAMAGE.
51f5b1c8a1SJohn Marino  * ====================================================================
52f5b1c8a1SJohn Marino  *
53f5b1c8a1SJohn Marino  * This product includes cryptographic software written by Eric Young
54f5b1c8a1SJohn Marino  * (eay@cryptsoft.com).  This product includes software written by Tim
55f5b1c8a1SJohn Marino  * Hudson (tjh@cryptsoft.com).
56f5b1c8a1SJohn Marino  *
57f5b1c8a1SJohn Marino  */
58f5b1c8a1SJohn Marino 
59f5b1c8a1SJohn Marino #include <stdio.h>
60f5b1c8a1SJohn Marino 
61f5b1c8a1SJohn Marino #include <openssl/opensslconf.h>
62f5b1c8a1SJohn Marino 
63f5b1c8a1SJohn Marino #include <openssl/asn1.h>
64f5b1c8a1SJohn Marino #include <openssl/bn.h>
65*cca6fc52SDaniel Fojt #include <openssl/cms.h>
66f5b1c8a1SJohn Marino #include <openssl/dsa.h>
67f5b1c8a1SJohn Marino #include <openssl/err.h>
68f5b1c8a1SJohn Marino #include <openssl/x509.h>
69f5b1c8a1SJohn Marino 
70f5b1c8a1SJohn Marino #include "asn1_locl.h"
7172c33676SMaxim Ag #include "bn_lcl.h"
72f5b1c8a1SJohn Marino 
73f5b1c8a1SJohn Marino static int
74f5b1c8a1SJohn Marino dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
75f5b1c8a1SJohn Marino {
76f5b1c8a1SJohn Marino 	const unsigned char *p, *pm;
77f5b1c8a1SJohn Marino 	int pklen, pmlen;
78f5b1c8a1SJohn Marino 	int ptype;
7972c33676SMaxim Ag 	const void *pval;
8072c33676SMaxim Ag 	const ASN1_STRING *pstr;
81f5b1c8a1SJohn Marino 	X509_ALGOR *palg;
82f5b1c8a1SJohn Marino 	ASN1_INTEGER *public_key = NULL;
83f5b1c8a1SJohn Marino 
84f5b1c8a1SJohn Marino 	DSA *dsa = NULL;
85f5b1c8a1SJohn Marino 
86f5b1c8a1SJohn Marino 	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
87f5b1c8a1SJohn Marino 		return 0;
88f5b1c8a1SJohn Marino 	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
89f5b1c8a1SJohn Marino 
90f5b1c8a1SJohn Marino 	if (ptype == V_ASN1_SEQUENCE) {
91f5b1c8a1SJohn Marino 		pstr = pval;
92f5b1c8a1SJohn Marino 		pm = pstr->data;
93f5b1c8a1SJohn Marino 		pmlen = pstr->length;
94f5b1c8a1SJohn Marino 
95f5b1c8a1SJohn Marino 		if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) {
9672c33676SMaxim Ag 			DSAerror(DSA_R_DECODE_ERROR);
97f5b1c8a1SJohn Marino 			goto err;
98f5b1c8a1SJohn Marino 		}
99f5b1c8a1SJohn Marino 	} else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) {
100f5b1c8a1SJohn Marino 		if (!(dsa = DSA_new())) {
10172c33676SMaxim Ag 			DSAerror(ERR_R_MALLOC_FAILURE);
102f5b1c8a1SJohn Marino 			goto err;
103f5b1c8a1SJohn Marino 			}
104f5b1c8a1SJohn Marino 	} else {
10572c33676SMaxim Ag 		DSAerror(DSA_R_PARAMETER_ENCODING_ERROR);
106f5b1c8a1SJohn Marino 		goto err;
107f5b1c8a1SJohn Marino 	}
108f5b1c8a1SJohn Marino 
109f5b1c8a1SJohn Marino 	if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) {
11072c33676SMaxim Ag 		DSAerror(DSA_R_DECODE_ERROR);
111f5b1c8a1SJohn Marino 		goto err;
112f5b1c8a1SJohn Marino 	}
113f5b1c8a1SJohn Marino 
114f5b1c8a1SJohn Marino 	if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) {
11572c33676SMaxim Ag 		DSAerror(DSA_R_BN_DECODE_ERROR);
116f5b1c8a1SJohn Marino 		goto err;
117f5b1c8a1SJohn Marino 	}
118f5b1c8a1SJohn Marino 
119f5b1c8a1SJohn Marino 	ASN1_INTEGER_free(public_key);
120f5b1c8a1SJohn Marino 	EVP_PKEY_assign_DSA(pkey, dsa);
121f5b1c8a1SJohn Marino 	return 1;
122f5b1c8a1SJohn Marino 
123f5b1c8a1SJohn Marino err:
124f5b1c8a1SJohn Marino 	if (public_key)
125f5b1c8a1SJohn Marino 		ASN1_INTEGER_free(public_key);
126f5b1c8a1SJohn Marino 	DSA_free(dsa);
127f5b1c8a1SJohn Marino 	return 0;
128f5b1c8a1SJohn Marino }
129f5b1c8a1SJohn Marino 
130f5b1c8a1SJohn Marino static int
131f5b1c8a1SJohn Marino dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
132f5b1c8a1SJohn Marino {
133f5b1c8a1SJohn Marino 	DSA *dsa;
134f5b1c8a1SJohn Marino 	void *pval = NULL;
135f5b1c8a1SJohn Marino 	int ptype;
136f5b1c8a1SJohn Marino 	unsigned char *penc = NULL;
137f5b1c8a1SJohn Marino 	int penclen;
138f5b1c8a1SJohn Marino 
139f5b1c8a1SJohn Marino 	dsa = pkey->pkey.dsa;
140f5b1c8a1SJohn Marino 	if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) {
141f5b1c8a1SJohn Marino 		ASN1_STRING *str;
142f5b1c8a1SJohn Marino 
143f5b1c8a1SJohn Marino 		str = ASN1_STRING_new();
144f5b1c8a1SJohn Marino 		if (str == NULL) {
14572c33676SMaxim Ag 			DSAerror(ERR_R_MALLOC_FAILURE);
146f5b1c8a1SJohn Marino 			goto err;
147f5b1c8a1SJohn Marino 		}
148f5b1c8a1SJohn Marino 		str->length = i2d_DSAparams(dsa, &str->data);
149f5b1c8a1SJohn Marino 		if (str->length <= 0) {
15072c33676SMaxim Ag 			DSAerror(ERR_R_MALLOC_FAILURE);
151f5b1c8a1SJohn Marino 			ASN1_STRING_free(str);
152f5b1c8a1SJohn Marino 			goto err;
153f5b1c8a1SJohn Marino 		}
154f5b1c8a1SJohn Marino 		pval = str;
155f5b1c8a1SJohn Marino 		ptype = V_ASN1_SEQUENCE;
156f5b1c8a1SJohn Marino 	} else
157f5b1c8a1SJohn Marino 		ptype = V_ASN1_UNDEF;
158f5b1c8a1SJohn Marino 
159f5b1c8a1SJohn Marino 	dsa->write_params = 0;
160f5b1c8a1SJohn Marino 
161f5b1c8a1SJohn Marino 	penclen = i2d_DSAPublicKey(dsa, &penc);
162f5b1c8a1SJohn Marino 
163f5b1c8a1SJohn Marino 	if (penclen <= 0) {
16472c33676SMaxim Ag 		DSAerror(ERR_R_MALLOC_FAILURE);
165f5b1c8a1SJohn Marino 		goto err;
166f5b1c8a1SJohn Marino 	}
167f5b1c8a1SJohn Marino 
168f5b1c8a1SJohn Marino 	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval,
169f5b1c8a1SJohn Marino 	    penc, penclen))
170f5b1c8a1SJohn Marino 		return 1;
171f5b1c8a1SJohn Marino 
172f5b1c8a1SJohn Marino err:
173f5b1c8a1SJohn Marino 	free(penc);
174f5b1c8a1SJohn Marino 	ASN1_STRING_free(pval);
175f5b1c8a1SJohn Marino 
176f5b1c8a1SJohn Marino 	return 0;
177f5b1c8a1SJohn Marino }
178f5b1c8a1SJohn Marino 
179f5b1c8a1SJohn Marino /* In PKCS#8 DSA: you just get a private key integer and parameters in the
180f5b1c8a1SJohn Marino  * AlgorithmIdentifier the pubkey must be recalculated.
181f5b1c8a1SJohn Marino  */
182f5b1c8a1SJohn Marino static int
18372c33676SMaxim Ag dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
184f5b1c8a1SJohn Marino {
185f5b1c8a1SJohn Marino 	const unsigned char *p, *pm;
186f5b1c8a1SJohn Marino 	int pklen, pmlen;
187f5b1c8a1SJohn Marino 	int ptype;
18872c33676SMaxim Ag 	const void *pval;
18972c33676SMaxim Ag 	const ASN1_STRING *pstr;
19072c33676SMaxim Ag 	const X509_ALGOR *palg;
191f5b1c8a1SJohn Marino 	ASN1_INTEGER *privkey = NULL;
192f5b1c8a1SJohn Marino 	BN_CTX *ctx = NULL;
193f5b1c8a1SJohn Marino 	DSA *dsa = NULL;
194f5b1c8a1SJohn Marino 
195f5b1c8a1SJohn Marino 	int ret = 0;
196f5b1c8a1SJohn Marino 
197f5b1c8a1SJohn Marino 	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
198f5b1c8a1SJohn Marino 		return 0;
199f5b1c8a1SJohn Marino 	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
200f5b1c8a1SJohn Marino 	if (ptype != V_ASN1_SEQUENCE)
201f5b1c8a1SJohn Marino 		goto decerr;
202f5b1c8a1SJohn Marino 
203f5b1c8a1SJohn Marino 	if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL)
204f5b1c8a1SJohn Marino 		goto decerr;
205f5b1c8a1SJohn Marino 	if (privkey->type == V_ASN1_NEG_INTEGER)
206f5b1c8a1SJohn Marino 		goto decerr;
207f5b1c8a1SJohn Marino 
208f5b1c8a1SJohn Marino 	pstr = pval;
209f5b1c8a1SJohn Marino 	pm = pstr->data;
210f5b1c8a1SJohn Marino 	pmlen = pstr->length;
211f5b1c8a1SJohn Marino 	if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
212f5b1c8a1SJohn Marino 		goto decerr;
213f5b1c8a1SJohn Marino 	/* We have parameters now set private key */
214f5b1c8a1SJohn Marino 	if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
21572c33676SMaxim Ag 		DSAerror(DSA_R_BN_ERROR);
216f5b1c8a1SJohn Marino 		goto dsaerr;
217f5b1c8a1SJohn Marino 	}
218f5b1c8a1SJohn Marino 	/* Calculate public key */
219f5b1c8a1SJohn Marino 	if (!(dsa->pub_key = BN_new())) {
22072c33676SMaxim Ag 		DSAerror(ERR_R_MALLOC_FAILURE);
221f5b1c8a1SJohn Marino 		goto dsaerr;
222f5b1c8a1SJohn Marino 	}
223f5b1c8a1SJohn Marino 	if (!(ctx = BN_CTX_new())) {
22472c33676SMaxim Ag 		DSAerror(ERR_R_MALLOC_FAILURE);
225f5b1c8a1SJohn Marino 		goto dsaerr;
226f5b1c8a1SJohn Marino 	}
227f5b1c8a1SJohn Marino 
22872c33676SMaxim Ag 	if (!BN_mod_exp_ct(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
22972c33676SMaxim Ag 		DSAerror(DSA_R_BN_ERROR);
230f5b1c8a1SJohn Marino 		goto dsaerr;
231f5b1c8a1SJohn Marino 	}
232f5b1c8a1SJohn Marino 
233f5b1c8a1SJohn Marino 	if (!EVP_PKEY_assign_DSA(pkey, dsa))
234f5b1c8a1SJohn Marino 		goto decerr;
235f5b1c8a1SJohn Marino 
236f5b1c8a1SJohn Marino 	ret = 1;
237f5b1c8a1SJohn Marino 	goto done;
238f5b1c8a1SJohn Marino 
239f5b1c8a1SJohn Marino decerr:
24072c33676SMaxim Ag 	DSAerror(DSA_R_DECODE_ERROR);
241f5b1c8a1SJohn Marino dsaerr:
242f5b1c8a1SJohn Marino 	DSA_free(dsa);
243f5b1c8a1SJohn Marino done:
244f5b1c8a1SJohn Marino 	BN_CTX_free(ctx);
245f5b1c8a1SJohn Marino 	ASN1_INTEGER_free(privkey);
246f5b1c8a1SJohn Marino 	return ret;
247f5b1c8a1SJohn Marino }
248f5b1c8a1SJohn Marino 
249f5b1c8a1SJohn Marino static int
250f5b1c8a1SJohn Marino dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
251f5b1c8a1SJohn Marino {
252f5b1c8a1SJohn Marino 	ASN1_STRING *params = NULL;
253f5b1c8a1SJohn Marino 	ASN1_INTEGER *prkey = NULL;
254f5b1c8a1SJohn Marino 	unsigned char *dp = NULL;
255f5b1c8a1SJohn Marino 	int dplen;
256f5b1c8a1SJohn Marino 
257f5b1c8a1SJohn Marino 	params = ASN1_STRING_new();
258f5b1c8a1SJohn Marino 	if (!params) {
25972c33676SMaxim Ag 		DSAerror(ERR_R_MALLOC_FAILURE);
260f5b1c8a1SJohn Marino 		goto err;
261f5b1c8a1SJohn Marino 	}
262f5b1c8a1SJohn Marino 
263f5b1c8a1SJohn Marino 	params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
264f5b1c8a1SJohn Marino 	if (params->length <= 0) {
26572c33676SMaxim Ag 		DSAerror(ERR_R_MALLOC_FAILURE);
266f5b1c8a1SJohn Marino 		goto err;
267f5b1c8a1SJohn Marino 	}
268f5b1c8a1SJohn Marino 	params->type = V_ASN1_SEQUENCE;
269f5b1c8a1SJohn Marino 
270f5b1c8a1SJohn Marino 	/* Get private key into integer */
271f5b1c8a1SJohn Marino 	prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
272f5b1c8a1SJohn Marino 	if (!prkey) {
27372c33676SMaxim Ag 		DSAerror(DSA_R_BN_ERROR);
274f5b1c8a1SJohn Marino 		goto err;
275f5b1c8a1SJohn Marino 	}
276f5b1c8a1SJohn Marino 
277f5b1c8a1SJohn Marino 	dplen = i2d_ASN1_INTEGER(prkey, &dp);
278f5b1c8a1SJohn Marino 
279f5b1c8a1SJohn Marino 	ASN1_INTEGER_free(prkey);
280f5b1c8a1SJohn Marino 	prkey = NULL;
281f5b1c8a1SJohn Marino 
282f5b1c8a1SJohn Marino 	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, V_ASN1_SEQUENCE,
283f5b1c8a1SJohn Marino 	    params, dp, dplen))
284f5b1c8a1SJohn Marino 		goto err;
285f5b1c8a1SJohn Marino 
286f5b1c8a1SJohn Marino 	return 1;
287f5b1c8a1SJohn Marino 
288f5b1c8a1SJohn Marino err:
289f5b1c8a1SJohn Marino 	free(dp);
290f5b1c8a1SJohn Marino 	ASN1_STRING_free(params);
291f5b1c8a1SJohn Marino 	ASN1_INTEGER_free(prkey);
292f5b1c8a1SJohn Marino 	return 0;
293f5b1c8a1SJohn Marino }
294f5b1c8a1SJohn Marino 
295f5b1c8a1SJohn Marino static int
296f5b1c8a1SJohn Marino int_dsa_size(const EVP_PKEY *pkey)
297f5b1c8a1SJohn Marino {
298f5b1c8a1SJohn Marino 	return DSA_size(pkey->pkey.dsa);
299f5b1c8a1SJohn Marino }
300f5b1c8a1SJohn Marino 
301f5b1c8a1SJohn Marino static int
302f5b1c8a1SJohn Marino dsa_bits(const EVP_PKEY *pkey)
303f5b1c8a1SJohn Marino {
304f5b1c8a1SJohn Marino 	return BN_num_bits(pkey->pkey.dsa->p);
305f5b1c8a1SJohn Marino }
306f5b1c8a1SJohn Marino 
307f5b1c8a1SJohn Marino static int
308f5b1c8a1SJohn Marino dsa_missing_parameters(const EVP_PKEY *pkey)
309f5b1c8a1SJohn Marino {
310f5b1c8a1SJohn Marino 	DSA *dsa;
311f5b1c8a1SJohn Marino 
312f5b1c8a1SJohn Marino 	dsa = pkey->pkey.dsa;
313f5b1c8a1SJohn Marino 	if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL)
314f5b1c8a1SJohn Marino 		return 1;
315f5b1c8a1SJohn Marino 	return 0;
316f5b1c8a1SJohn Marino }
317f5b1c8a1SJohn Marino 
318f5b1c8a1SJohn Marino static int
319f5b1c8a1SJohn Marino dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
320f5b1c8a1SJohn Marino {
321f5b1c8a1SJohn Marino 	BIGNUM *a;
322f5b1c8a1SJohn Marino 
323f5b1c8a1SJohn Marino 	if ((a = BN_dup(from->pkey.dsa->p)) == NULL)
324f5b1c8a1SJohn Marino 		return 0;
325f5b1c8a1SJohn Marino 	BN_free(to->pkey.dsa->p);
326f5b1c8a1SJohn Marino 	to->pkey.dsa->p = a;
327f5b1c8a1SJohn Marino 
328f5b1c8a1SJohn Marino 	if ((a = BN_dup(from->pkey.dsa->q)) == NULL)
329f5b1c8a1SJohn Marino 		return 0;
330f5b1c8a1SJohn Marino 	BN_free(to->pkey.dsa->q);
331f5b1c8a1SJohn Marino 	to->pkey.dsa->q = a;
332f5b1c8a1SJohn Marino 
333f5b1c8a1SJohn Marino 	if ((a = BN_dup(from->pkey.dsa->g)) == NULL)
334f5b1c8a1SJohn Marino 		return 0;
335f5b1c8a1SJohn Marino 	BN_free(to->pkey.dsa->g);
336f5b1c8a1SJohn Marino 	to->pkey.dsa->g = a;
337f5b1c8a1SJohn Marino 	return 1;
338f5b1c8a1SJohn Marino }
339f5b1c8a1SJohn Marino 
340f5b1c8a1SJohn Marino static int
341f5b1c8a1SJohn Marino dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
342f5b1c8a1SJohn Marino {
343f5b1c8a1SJohn Marino 	if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) ||
344f5b1c8a1SJohn Marino 	    BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) ||
345f5b1c8a1SJohn Marino 	    BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g))
346f5b1c8a1SJohn Marino 		return 0;
347f5b1c8a1SJohn Marino 	else
348f5b1c8a1SJohn Marino 		return 1;
349f5b1c8a1SJohn Marino }
350f5b1c8a1SJohn Marino 
351f5b1c8a1SJohn Marino static int
352f5b1c8a1SJohn Marino dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
353f5b1c8a1SJohn Marino {
354f5b1c8a1SJohn Marino 	if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0)
355f5b1c8a1SJohn Marino 		return 0;
356f5b1c8a1SJohn Marino 	else
357f5b1c8a1SJohn Marino 		return 1;
358f5b1c8a1SJohn Marino }
359f5b1c8a1SJohn Marino 
360f5b1c8a1SJohn Marino static void
361f5b1c8a1SJohn Marino int_dsa_free(EVP_PKEY *pkey)
362f5b1c8a1SJohn Marino {
363f5b1c8a1SJohn Marino 	DSA_free(pkey->pkey.dsa);
364f5b1c8a1SJohn Marino }
365f5b1c8a1SJohn Marino 
366f5b1c8a1SJohn Marino static void
367f5b1c8a1SJohn Marino update_buflen(const BIGNUM *b, size_t *pbuflen)
368f5b1c8a1SJohn Marino {
369f5b1c8a1SJohn Marino 	size_t i;
370f5b1c8a1SJohn Marino 
371f5b1c8a1SJohn Marino 	if (!b)
372f5b1c8a1SJohn Marino 		return;
373f5b1c8a1SJohn Marino 	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
374f5b1c8a1SJohn Marino 		*pbuflen = i;
375f5b1c8a1SJohn Marino }
376f5b1c8a1SJohn Marino 
377f5b1c8a1SJohn Marino static int
378f5b1c8a1SJohn Marino do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
379f5b1c8a1SJohn Marino {
380f5b1c8a1SJohn Marino 	unsigned char *m = NULL;
381f5b1c8a1SJohn Marino 	int ret = 0;
382f5b1c8a1SJohn Marino 	size_t buf_len = 0;
383f5b1c8a1SJohn Marino 	const char *ktype = NULL;
384f5b1c8a1SJohn Marino 	const BIGNUM *priv_key, *pub_key;
385f5b1c8a1SJohn Marino 
386f5b1c8a1SJohn Marino 	if (ptype == 2)
387f5b1c8a1SJohn Marino 		priv_key = x->priv_key;
388f5b1c8a1SJohn Marino 	else
389f5b1c8a1SJohn Marino 		priv_key = NULL;
390f5b1c8a1SJohn Marino 
391f5b1c8a1SJohn Marino 	if (ptype > 0)
392f5b1c8a1SJohn Marino 		pub_key = x->pub_key;
393f5b1c8a1SJohn Marino 	else
394f5b1c8a1SJohn Marino 		pub_key = NULL;
395f5b1c8a1SJohn Marino 
396f5b1c8a1SJohn Marino 	if (ptype == 2)
397f5b1c8a1SJohn Marino 		ktype = "Private-Key";
398f5b1c8a1SJohn Marino 	else if (ptype == 1)
399f5b1c8a1SJohn Marino 		ktype = "Public-Key";
400f5b1c8a1SJohn Marino 	else
401f5b1c8a1SJohn Marino 		ktype = "DSA-Parameters";
402f5b1c8a1SJohn Marino 
403f5b1c8a1SJohn Marino 	update_buflen(x->p, &buf_len);
404f5b1c8a1SJohn Marino 	update_buflen(x->q, &buf_len);
405f5b1c8a1SJohn Marino 	update_buflen(x->g, &buf_len);
406f5b1c8a1SJohn Marino 	update_buflen(priv_key, &buf_len);
407f5b1c8a1SJohn Marino 	update_buflen(pub_key, &buf_len);
408f5b1c8a1SJohn Marino 
409f5b1c8a1SJohn Marino 	m = malloc(buf_len + 10);
410f5b1c8a1SJohn Marino 	if (m == NULL) {
41172c33676SMaxim Ag 		DSAerror(ERR_R_MALLOC_FAILURE);
412f5b1c8a1SJohn Marino 		goto err;
413f5b1c8a1SJohn Marino 	}
414f5b1c8a1SJohn Marino 
415f5b1c8a1SJohn Marino 	if (priv_key) {
416f5b1c8a1SJohn Marino 		if (!BIO_indent(bp, off, 128))
417f5b1c8a1SJohn Marino 			goto err;
418f5b1c8a1SJohn Marino 		if (BIO_printf(bp, "%s: (%d bit)\n", ktype,
419f5b1c8a1SJohn Marino 		    BN_num_bits(x->p)) <= 0)
420f5b1c8a1SJohn Marino 			goto err;
421f5b1c8a1SJohn Marino 	}
422f5b1c8a1SJohn Marino 
423f5b1c8a1SJohn Marino 	if (!ASN1_bn_print(bp, "priv:", priv_key, m, off))
424f5b1c8a1SJohn Marino 		goto err;
425f5b1c8a1SJohn Marino 	if (!ASN1_bn_print(bp, "pub: ", pub_key, m, off))
426f5b1c8a1SJohn Marino 		goto err;
427f5b1c8a1SJohn Marino 	if (!ASN1_bn_print(bp, "P:   ", x->p, m, off))
428f5b1c8a1SJohn Marino 		goto err;
429f5b1c8a1SJohn Marino 	if (!ASN1_bn_print(bp, "Q:   ", x->q, m, off))
430f5b1c8a1SJohn Marino 		goto err;
431f5b1c8a1SJohn Marino 	if (!ASN1_bn_print(bp, "G:   ", x->g, m, off))
432f5b1c8a1SJohn Marino 		goto err;
433f5b1c8a1SJohn Marino 	ret = 1;
434f5b1c8a1SJohn Marino err:
435f5b1c8a1SJohn Marino 	free(m);
436f5b1c8a1SJohn Marino 	return(ret);
437f5b1c8a1SJohn Marino }
438f5b1c8a1SJohn Marino 
439f5b1c8a1SJohn Marino static int
440f5b1c8a1SJohn Marino dsa_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
441f5b1c8a1SJohn Marino {
442f5b1c8a1SJohn Marino 	DSA *dsa;
443f5b1c8a1SJohn Marino 
444f5b1c8a1SJohn Marino 	if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) {
44572c33676SMaxim Ag 		DSAerror(ERR_R_DSA_LIB);
446f5b1c8a1SJohn Marino 		return 0;
447f5b1c8a1SJohn Marino 	}
448f5b1c8a1SJohn Marino 	EVP_PKEY_assign_DSA(pkey, dsa);
449f5b1c8a1SJohn Marino 	return 1;
450f5b1c8a1SJohn Marino }
451f5b1c8a1SJohn Marino 
452f5b1c8a1SJohn Marino static int
453f5b1c8a1SJohn Marino dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
454f5b1c8a1SJohn Marino {
455f5b1c8a1SJohn Marino 	return i2d_DSAparams(pkey->pkey.dsa, pder);
456f5b1c8a1SJohn Marino }
457f5b1c8a1SJohn Marino 
458f5b1c8a1SJohn Marino static int
459f5b1c8a1SJohn Marino dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
460f5b1c8a1SJohn Marino {
461f5b1c8a1SJohn Marino 	return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
462f5b1c8a1SJohn Marino }
463f5b1c8a1SJohn Marino 
464f5b1c8a1SJohn Marino static int
465f5b1c8a1SJohn Marino dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
466f5b1c8a1SJohn Marino {
467f5b1c8a1SJohn Marino 	return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
468f5b1c8a1SJohn Marino }
469f5b1c8a1SJohn Marino 
470f5b1c8a1SJohn Marino static int
471f5b1c8a1SJohn Marino dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
472f5b1c8a1SJohn Marino {
473f5b1c8a1SJohn Marino 	return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
474f5b1c8a1SJohn Marino }
475f5b1c8a1SJohn Marino 
476f5b1c8a1SJohn Marino static int
477f5b1c8a1SJohn Marino old_dsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
478f5b1c8a1SJohn Marino {
479f5b1c8a1SJohn Marino 	DSA *dsa;
480f5b1c8a1SJohn Marino 	BN_CTX *ctx = NULL;
481f5b1c8a1SJohn Marino 	BIGNUM *j, *p1, *newp1;
482f5b1c8a1SJohn Marino 
483f5b1c8a1SJohn Marino 	if (!(dsa = d2i_DSAPrivateKey(NULL, pder, derlen))) {
48472c33676SMaxim Ag 		DSAerror(ERR_R_DSA_LIB);
485f5b1c8a1SJohn Marino 		return 0;
486f5b1c8a1SJohn Marino 	}
487f5b1c8a1SJohn Marino 
488f5b1c8a1SJohn Marino 	ctx = BN_CTX_new();
489f5b1c8a1SJohn Marino 	if (ctx == NULL)
490f5b1c8a1SJohn Marino 		goto err;
491f5b1c8a1SJohn Marino 
492f5b1c8a1SJohn Marino 	/*
493f5b1c8a1SJohn Marino 	 * Check that p and q are consistent with each other.
494f5b1c8a1SJohn Marino 	 */
495f5b1c8a1SJohn Marino 
496f5b1c8a1SJohn Marino 	j = BN_CTX_get(ctx);
497f5b1c8a1SJohn Marino 	p1 = BN_CTX_get(ctx);
498f5b1c8a1SJohn Marino 	newp1 = BN_CTX_get(ctx);
499f5b1c8a1SJohn Marino 	if (j == NULL || p1 == NULL || newp1 == NULL)
500f5b1c8a1SJohn Marino 		goto err;
501f5b1c8a1SJohn Marino 	/* p1 = p - 1 */
502f5b1c8a1SJohn Marino 	if (BN_sub(p1, dsa->p, BN_value_one()) == 0)
503f5b1c8a1SJohn Marino 		goto err;
504f5b1c8a1SJohn Marino 	/* j = (p - 1) / q */
50572c33676SMaxim Ag 	if (BN_div_ct(j, NULL, p1, dsa->q, ctx) == 0)
506f5b1c8a1SJohn Marino 		goto err;
507f5b1c8a1SJohn Marino 	/* q * j should == p - 1 */
508f5b1c8a1SJohn Marino 	if (BN_mul(newp1, dsa->q, j, ctx) == 0)
509f5b1c8a1SJohn Marino 		goto err;
510f5b1c8a1SJohn Marino 	if (BN_cmp(newp1, p1) != 0) {
51172c33676SMaxim Ag 		DSAerror(DSA_R_BAD_Q_VALUE);
512f5b1c8a1SJohn Marino 		goto err;
513f5b1c8a1SJohn Marino 	}
514f5b1c8a1SJohn Marino 
515f5b1c8a1SJohn Marino 	/*
516f5b1c8a1SJohn Marino 	 * Check that q is not a composite number.
517f5b1c8a1SJohn Marino 	 */
518f5b1c8a1SJohn Marino 
51972c33676SMaxim Ag 	if (BN_is_prime_ex(dsa->q, BN_prime_checks, ctx, NULL) <= 0) {
52072c33676SMaxim Ag 		DSAerror(DSA_R_BAD_Q_VALUE);
521f5b1c8a1SJohn Marino 		goto err;
522f5b1c8a1SJohn Marino 	}
523f5b1c8a1SJohn Marino 
524f5b1c8a1SJohn Marino 	BN_CTX_free(ctx);
525f5b1c8a1SJohn Marino 
526f5b1c8a1SJohn Marino 	EVP_PKEY_assign_DSA(pkey, dsa);
527f5b1c8a1SJohn Marino 	return 1;
528f5b1c8a1SJohn Marino 
529f5b1c8a1SJohn Marino  err:
530f5b1c8a1SJohn Marino 	BN_CTX_free(ctx);
531f5b1c8a1SJohn Marino 	DSA_free(dsa);
532f5b1c8a1SJohn Marino 	return 0;
533f5b1c8a1SJohn Marino }
534f5b1c8a1SJohn Marino 
535f5b1c8a1SJohn Marino static int
536f5b1c8a1SJohn Marino old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
537f5b1c8a1SJohn Marino {
538f5b1c8a1SJohn Marino 	return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
539f5b1c8a1SJohn Marino }
540f5b1c8a1SJohn Marino 
541f5b1c8a1SJohn Marino static int
542f5b1c8a1SJohn Marino dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig,
543f5b1c8a1SJohn Marino     int indent, ASN1_PCTX *pctx)
544f5b1c8a1SJohn Marino {
545f5b1c8a1SJohn Marino 	DSA_SIG *dsa_sig;
546f5b1c8a1SJohn Marino 	const unsigned char *p;
547f5b1c8a1SJohn Marino 
548f5b1c8a1SJohn Marino 	if (!sig) {
549f5b1c8a1SJohn Marino 		if (BIO_puts(bp, "\n") <= 0)
550f5b1c8a1SJohn Marino 			return 0;
551f5b1c8a1SJohn Marino 		else
552f5b1c8a1SJohn Marino 			return 1;
553f5b1c8a1SJohn Marino 	}
554f5b1c8a1SJohn Marino 	p = sig->data;
555f5b1c8a1SJohn Marino 	dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
556f5b1c8a1SJohn Marino 	if (dsa_sig) {
557f5b1c8a1SJohn Marino 		int rv = 0;
558f5b1c8a1SJohn Marino 		size_t buf_len = 0;
559f5b1c8a1SJohn Marino 		unsigned char *m = NULL;
560f5b1c8a1SJohn Marino 
561f5b1c8a1SJohn Marino 		update_buflen(dsa_sig->r, &buf_len);
562f5b1c8a1SJohn Marino 		update_buflen(dsa_sig->s, &buf_len);
563f5b1c8a1SJohn Marino 		m = malloc(buf_len + 10);
564f5b1c8a1SJohn Marino 		if (m == NULL) {
56572c33676SMaxim Ag 			DSAerror(ERR_R_MALLOC_FAILURE);
566f5b1c8a1SJohn Marino 			goto err;
567f5b1c8a1SJohn Marino 		}
568f5b1c8a1SJohn Marino 
569f5b1c8a1SJohn Marino 		if (BIO_write(bp, "\n", 1) != 1)
570f5b1c8a1SJohn Marino 			goto err;
571f5b1c8a1SJohn Marino 
572f5b1c8a1SJohn Marino 		if (!ASN1_bn_print(bp, "r:   ", dsa_sig->r, m, indent))
573f5b1c8a1SJohn Marino 			goto err;
574f5b1c8a1SJohn Marino 		if (!ASN1_bn_print(bp, "s:   ", dsa_sig->s, m, indent))
575f5b1c8a1SJohn Marino 			goto err;
576f5b1c8a1SJohn Marino 		rv = 1;
577f5b1c8a1SJohn Marino err:
578f5b1c8a1SJohn Marino 		free(m);
579f5b1c8a1SJohn Marino 		DSA_SIG_free(dsa_sig);
580f5b1c8a1SJohn Marino 		return rv;
581f5b1c8a1SJohn Marino 	}
582f5b1c8a1SJohn Marino 	return X509_signature_dump(bp, sig, indent);
583f5b1c8a1SJohn Marino }
584f5b1c8a1SJohn Marino 
585f5b1c8a1SJohn Marino static int
586f5b1c8a1SJohn Marino dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
587f5b1c8a1SJohn Marino {
588f5b1c8a1SJohn Marino 	switch (op) {
589f5b1c8a1SJohn Marino 	case ASN1_PKEY_CTRL_PKCS7_SIGN:
590f5b1c8a1SJohn Marino 		if (arg1 == 0) {
591f5b1c8a1SJohn Marino 			int snid, hnid;
592f5b1c8a1SJohn Marino 			X509_ALGOR *alg1, *alg2;
593f5b1c8a1SJohn Marino 
594f5b1c8a1SJohn Marino 			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
595f5b1c8a1SJohn Marino 			if (alg1 == NULL || alg1->algorithm == NULL)
596f5b1c8a1SJohn Marino 				return -1;
597f5b1c8a1SJohn Marino 			hnid = OBJ_obj2nid(alg1->algorithm);
598f5b1c8a1SJohn Marino 			if (hnid == NID_undef)
599f5b1c8a1SJohn Marino 				return -1;
600f5b1c8a1SJohn Marino 			if (!OBJ_find_sigid_by_algs(&snid, hnid,
601f5b1c8a1SJohn Marino 			    EVP_PKEY_id(pkey)))
602f5b1c8a1SJohn Marino 				return -1;
603f5b1c8a1SJohn Marino 			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF,
604f5b1c8a1SJohn Marino 			    0);
605f5b1c8a1SJohn Marino 		}
606f5b1c8a1SJohn Marino 		return 1;
607f5b1c8a1SJohn Marino 
608*cca6fc52SDaniel Fojt #ifndef OPENSSL_NO_CMS
609*cca6fc52SDaniel Fojt 	case ASN1_PKEY_CTRL_CMS_SIGN:
610*cca6fc52SDaniel Fojt 		if (arg1 == 0) {
611*cca6fc52SDaniel Fojt 			int snid, hnid;
612*cca6fc52SDaniel Fojt 			X509_ALGOR *alg1, *alg2;
613*cca6fc52SDaniel Fojt 
614*cca6fc52SDaniel Fojt 			CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
615*cca6fc52SDaniel Fojt 			if (alg1 == NULL || alg1->algorithm == NULL)
616*cca6fc52SDaniel Fojt 				return -1;
617*cca6fc52SDaniel Fojt 			hnid = OBJ_obj2nid(alg1->algorithm);
618*cca6fc52SDaniel Fojt 			if (hnid == NID_undef)
619*cca6fc52SDaniel Fojt 				return -1;
620*cca6fc52SDaniel Fojt 			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
621*cca6fc52SDaniel Fojt 				return -1;
622*cca6fc52SDaniel Fojt 			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
623*cca6fc52SDaniel Fojt 		}
624*cca6fc52SDaniel Fojt 		return 1;
625*cca6fc52SDaniel Fojt 
626*cca6fc52SDaniel Fojt 	case ASN1_PKEY_CTRL_CMS_RI_TYPE:
627*cca6fc52SDaniel Fojt 		*(int *)arg2 = CMS_RECIPINFO_NONE;
628*cca6fc52SDaniel Fojt 		return 1;
629*cca6fc52SDaniel Fojt #endif
630*cca6fc52SDaniel Fojt 
631f5b1c8a1SJohn Marino 	case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
632f5b1c8a1SJohn Marino 		*(int *)arg2 = NID_sha1;
633f5b1c8a1SJohn Marino 		return 2;
634f5b1c8a1SJohn Marino 
635f5b1c8a1SJohn Marino 	default:
636f5b1c8a1SJohn Marino 		return -2;
637f5b1c8a1SJohn Marino 	}
638f5b1c8a1SJohn Marino }
639f5b1c8a1SJohn Marino 
640f5b1c8a1SJohn Marino /* NB these are sorted in pkey_id order, lowest first */
641f5b1c8a1SJohn Marino 
642f5b1c8a1SJohn Marino const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = {
643f5b1c8a1SJohn Marino 	{
644f5b1c8a1SJohn Marino 		.pkey_id = EVP_PKEY_DSA2,
645f5b1c8a1SJohn Marino 		.pkey_base_id = EVP_PKEY_DSA,
646f5b1c8a1SJohn Marino 		.pkey_flags = ASN1_PKEY_ALIAS
647f5b1c8a1SJohn Marino 	},
648f5b1c8a1SJohn Marino 
649f5b1c8a1SJohn Marino 	{
650f5b1c8a1SJohn Marino 		.pkey_id = EVP_PKEY_DSA1,
651f5b1c8a1SJohn Marino 		.pkey_base_id = EVP_PKEY_DSA,
652f5b1c8a1SJohn Marino 		.pkey_flags = ASN1_PKEY_ALIAS
653f5b1c8a1SJohn Marino 	},
654f5b1c8a1SJohn Marino 
655f5b1c8a1SJohn Marino 	{
656f5b1c8a1SJohn Marino 		.pkey_id = EVP_PKEY_DSA4,
657f5b1c8a1SJohn Marino 		.pkey_base_id = EVP_PKEY_DSA,
658f5b1c8a1SJohn Marino 		.pkey_flags = ASN1_PKEY_ALIAS
659f5b1c8a1SJohn Marino 	},
660f5b1c8a1SJohn Marino 
661f5b1c8a1SJohn Marino 	{
662f5b1c8a1SJohn Marino 		.pkey_id = EVP_PKEY_DSA3,
663f5b1c8a1SJohn Marino 		.pkey_base_id = EVP_PKEY_DSA,
664f5b1c8a1SJohn Marino 		.pkey_flags = ASN1_PKEY_ALIAS
665f5b1c8a1SJohn Marino 	},
666f5b1c8a1SJohn Marino 
667f5b1c8a1SJohn Marino 	{
668f5b1c8a1SJohn Marino 		.pkey_id = EVP_PKEY_DSA,
669f5b1c8a1SJohn Marino 		.pkey_base_id = EVP_PKEY_DSA,
670f5b1c8a1SJohn Marino 
671f5b1c8a1SJohn Marino 		.pem_str = "DSA",
672f5b1c8a1SJohn Marino 		.info = "OpenSSL DSA method",
673f5b1c8a1SJohn Marino 
674f5b1c8a1SJohn Marino 		.pub_decode = dsa_pub_decode,
675f5b1c8a1SJohn Marino 		.pub_encode = dsa_pub_encode,
676f5b1c8a1SJohn Marino 		.pub_cmp = dsa_pub_cmp,
677f5b1c8a1SJohn Marino 		.pub_print = dsa_pub_print,
678f5b1c8a1SJohn Marino 
679f5b1c8a1SJohn Marino 		.priv_decode = dsa_priv_decode,
680f5b1c8a1SJohn Marino 		.priv_encode = dsa_priv_encode,
681f5b1c8a1SJohn Marino 		.priv_print = dsa_priv_print,
682f5b1c8a1SJohn Marino 
683f5b1c8a1SJohn Marino 		.pkey_size = int_dsa_size,
684f5b1c8a1SJohn Marino 		.pkey_bits = dsa_bits,
685f5b1c8a1SJohn Marino 
686f5b1c8a1SJohn Marino 		.param_decode = dsa_param_decode,
687f5b1c8a1SJohn Marino 		.param_encode = dsa_param_encode,
688f5b1c8a1SJohn Marino 		.param_missing = dsa_missing_parameters,
689f5b1c8a1SJohn Marino 		.param_copy = dsa_copy_parameters,
690f5b1c8a1SJohn Marino 		.param_cmp = dsa_cmp_parameters,
691f5b1c8a1SJohn Marino 		.param_print = dsa_param_print,
692f5b1c8a1SJohn Marino 		.sig_print = dsa_sig_print,
693f5b1c8a1SJohn Marino 
694f5b1c8a1SJohn Marino 		.pkey_free = int_dsa_free,
695f5b1c8a1SJohn Marino 		.pkey_ctrl = dsa_pkey_ctrl,
696f5b1c8a1SJohn Marino 		.old_priv_decode = old_dsa_priv_decode,
697f5b1c8a1SJohn Marino 		.old_priv_encode = old_dsa_priv_encode
698f5b1c8a1SJohn Marino 	}
699f5b1c8a1SJohn Marino };
700