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