1 /* $OpenBSD: dsa_ameth.c,v 1.18 2015/09/10 18:12:55 miod 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 #ifndef OPENSSL_NO_CMS 70 #include <openssl/cms.h> 71 #endif 72 73 #include "asn1_locl.h" 74 75 static int 76 dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) 77 { 78 const unsigned char *p, *pm; 79 int pklen, pmlen; 80 int ptype; 81 void *pval; 82 ASN1_STRING *pstr; 83 X509_ALGOR *palg; 84 ASN1_INTEGER *public_key = NULL; 85 86 DSA *dsa = NULL; 87 88 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) 89 return 0; 90 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 91 92 if (ptype == V_ASN1_SEQUENCE) { 93 pstr = pval; 94 pm = pstr->data; 95 pmlen = pstr->length; 96 97 if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) { 98 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); 99 goto err; 100 } 101 } else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) { 102 if (!(dsa = DSA_new())) { 103 DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE); 104 goto err; 105 } 106 } else { 107 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR); 108 goto err; 109 } 110 111 if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) { 112 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); 113 goto err; 114 } 115 116 if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { 117 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR); 118 goto err; 119 } 120 121 ASN1_INTEGER_free(public_key); 122 EVP_PKEY_assign_DSA(pkey, dsa); 123 return 1; 124 125 err: 126 if (public_key) 127 ASN1_INTEGER_free(public_key); 128 DSA_free(dsa); 129 return 0; 130 } 131 132 static int 133 dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 134 { 135 DSA *dsa; 136 void *pval = NULL; 137 int ptype; 138 unsigned char *penc = NULL; 139 int penclen; 140 141 dsa = pkey->pkey.dsa; 142 if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) { 143 ASN1_STRING *str; 144 145 str = ASN1_STRING_new(); 146 if (str == NULL) { 147 DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); 148 goto err; 149 } 150 str->length = i2d_DSAparams(dsa, &str->data); 151 if (str->length <= 0) { 152 DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); 153 ASN1_STRING_free(str); 154 goto err; 155 } 156 pval = str; 157 ptype = V_ASN1_SEQUENCE; 158 } else 159 ptype = V_ASN1_UNDEF; 160 161 dsa->write_params = 0; 162 163 penclen = i2d_DSAPublicKey(dsa, &penc); 164 165 if (penclen <= 0) { 166 DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); 167 goto err; 168 } 169 170 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval, 171 penc, penclen)) 172 return 1; 173 174 err: 175 free(penc); 176 ASN1_STRING_free(pval); 177 178 return 0; 179 } 180 181 /* In PKCS#8 DSA: you just get a private key integer and parameters in the 182 * AlgorithmIdentifier the pubkey must be recalculated. 183 */ 184 static int 185 dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) 186 { 187 const unsigned char *p, *pm; 188 int pklen, pmlen; 189 int ptype; 190 void *pval; 191 ASN1_STRING *pstr; 192 X509_ALGOR *palg; 193 ASN1_INTEGER *privkey = NULL; 194 BN_CTX *ctx = NULL; 195 DSA *dsa = NULL; 196 197 int ret = 0; 198 199 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) 200 return 0; 201 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 202 if (ptype != V_ASN1_SEQUENCE) 203 goto decerr; 204 205 if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) 206 goto decerr; 207 if (privkey->type == V_ASN1_NEG_INTEGER) 208 goto decerr; 209 210 pstr = pval; 211 pm = pstr->data; 212 pmlen = pstr->length; 213 if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) 214 goto decerr; 215 /* We have parameters now set private key */ 216 if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { 217 DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR); 218 goto dsaerr; 219 } 220 /* Calculate public key */ 221 if (!(dsa->pub_key = BN_new())) { 222 DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); 223 goto dsaerr; 224 } 225 if (!(ctx = BN_CTX_new())) { 226 DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); 227 goto dsaerr; 228 } 229 230 if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { 231 DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR); 232 goto dsaerr; 233 } 234 235 if (!EVP_PKEY_assign_DSA(pkey, dsa)) 236 goto decerr; 237 238 ret = 1; 239 goto done; 240 241 decerr: 242 DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_DECODE_ERROR); 243 dsaerr: 244 DSA_free(dsa); 245 done: 246 BN_CTX_free(ctx); 247 ASN1_INTEGER_free(privkey); 248 return ret; 249 } 250 251 static int 252 dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) 253 { 254 ASN1_STRING *params = NULL; 255 ASN1_INTEGER *prkey = NULL; 256 unsigned char *dp = NULL; 257 int dplen; 258 259 params = ASN1_STRING_new(); 260 if (!params) { 261 DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); 262 goto err; 263 } 264 265 params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data); 266 if (params->length <= 0) { 267 DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); 268 goto err; 269 } 270 params->type = V_ASN1_SEQUENCE; 271 272 /* Get private key into integer */ 273 prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL); 274 if (!prkey) { 275 DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_BN_ERROR); 276 goto err; 277 } 278 279 dplen = i2d_ASN1_INTEGER(prkey, &dp); 280 281 ASN1_INTEGER_free(prkey); 282 prkey = NULL; 283 284 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, V_ASN1_SEQUENCE, 285 params, dp, dplen)) 286 goto err; 287 288 return 1; 289 290 err: 291 free(dp); 292 ASN1_STRING_free(params); 293 ASN1_INTEGER_free(prkey); 294 return 0; 295 } 296 297 static int 298 int_dsa_size(const EVP_PKEY *pkey) 299 { 300 return DSA_size(pkey->pkey.dsa); 301 } 302 303 static int 304 dsa_bits(const EVP_PKEY *pkey) 305 { 306 return BN_num_bits(pkey->pkey.dsa->p); 307 } 308 309 static int 310 dsa_missing_parameters(const EVP_PKEY *pkey) 311 { 312 DSA *dsa; 313 314 dsa = pkey->pkey.dsa; 315 if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) 316 return 1; 317 return 0; 318 } 319 320 static int 321 dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) 322 { 323 BIGNUM *a; 324 325 if ((a = BN_dup(from->pkey.dsa->p)) == NULL) 326 return 0; 327 BN_free(to->pkey.dsa->p); 328 to->pkey.dsa->p = a; 329 330 if ((a = BN_dup(from->pkey.dsa->q)) == NULL) 331 return 0; 332 BN_free(to->pkey.dsa->q); 333 to->pkey.dsa->q = a; 334 335 if ((a = BN_dup(from->pkey.dsa->g)) == NULL) 336 return 0; 337 BN_free(to->pkey.dsa->g); 338 to->pkey.dsa->g = a; 339 return 1; 340 } 341 342 static int 343 dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 344 { 345 if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) || 346 BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) || 347 BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g)) 348 return 0; 349 else 350 return 1; 351 } 352 353 static int 354 dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 355 { 356 if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0) 357 return 0; 358 else 359 return 1; 360 } 361 362 static void 363 int_dsa_free(EVP_PKEY *pkey) 364 { 365 DSA_free(pkey->pkey.dsa); 366 } 367 368 static void 369 update_buflen(const BIGNUM *b, size_t *pbuflen) 370 { 371 size_t i; 372 373 if (!b) 374 return; 375 if (*pbuflen < (i = (size_t)BN_num_bytes(b))) 376 *pbuflen = i; 377 } 378 379 static int 380 do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) 381 { 382 unsigned char *m = NULL; 383 int ret = 0; 384 size_t buf_len = 0; 385 const char *ktype = NULL; 386 const BIGNUM *priv_key, *pub_key; 387 388 if (ptype == 2) 389 priv_key = x->priv_key; 390 else 391 priv_key = NULL; 392 393 if (ptype > 0) 394 pub_key = x->pub_key; 395 else 396 pub_key = NULL; 397 398 if (ptype == 2) 399 ktype = "Private-Key"; 400 else if (ptype == 1) 401 ktype = "Public-Key"; 402 else 403 ktype = "DSA-Parameters"; 404 405 update_buflen(x->p, &buf_len); 406 update_buflen(x->q, &buf_len); 407 update_buflen(x->g, &buf_len); 408 update_buflen(priv_key, &buf_len); 409 update_buflen(pub_key, &buf_len); 410 411 m = malloc(buf_len + 10); 412 if (m == NULL) { 413 DSAerr(DSA_F_DO_DSA_PRINT, ERR_R_MALLOC_FAILURE); 414 goto err; 415 } 416 417 if (priv_key) { 418 if (!BIO_indent(bp, off, 128)) 419 goto err; 420 if (BIO_printf(bp, "%s: (%d bit)\n", ktype, 421 BN_num_bits(x->p)) <= 0) 422 goto err; 423 } 424 425 if (!ASN1_bn_print(bp, "priv:", priv_key, m, off)) 426 goto err; 427 if (!ASN1_bn_print(bp, "pub: ", pub_key, m, off)) 428 goto err; 429 if (!ASN1_bn_print(bp, "P: ", x->p, m, off)) 430 goto err; 431 if (!ASN1_bn_print(bp, "Q: ", x->q, m, off)) 432 goto err; 433 if (!ASN1_bn_print(bp, "G: ", x->g, m, off)) 434 goto err; 435 ret = 1; 436 err: 437 free(m); 438 return(ret); 439 } 440 441 static int 442 dsa_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) 443 { 444 DSA *dsa; 445 446 if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) { 447 DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB); 448 return 0; 449 } 450 EVP_PKEY_assign_DSA(pkey, dsa); 451 return 1; 452 } 453 454 static int 455 dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 456 { 457 return i2d_DSAparams(pkey->pkey.dsa, pder); 458 } 459 460 static int 461 dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) 462 { 463 return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); 464 } 465 466 static int 467 dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) 468 { 469 return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); 470 } 471 472 static int 473 dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) 474 { 475 return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); 476 } 477 478 static int 479 old_dsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) 480 { 481 DSA *dsa; 482 BN_CTX *ctx = NULL; 483 BIGNUM *j, *p1, *newp1; 484 485 if (!(dsa = d2i_DSAPrivateKey(NULL, pder, derlen))) { 486 DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB); 487 return 0; 488 } 489 490 ctx = BN_CTX_new(); 491 if (ctx == NULL) 492 goto err; 493 494 /* 495 * Check that p and q are consistent with each other. 496 */ 497 498 j = BN_CTX_get(ctx); 499 p1 = BN_CTX_get(ctx); 500 newp1 = BN_CTX_get(ctx); 501 if (j == NULL || p1 == NULL || newp1 == NULL) 502 goto err; 503 /* p1 = p - 1 */ 504 if (BN_sub(p1, dsa->p, BN_value_one()) == 0) 505 goto err; 506 /* j = (p - 1) / q */ 507 if (BN_div(j, NULL, p1, dsa->q, ctx) == 0) 508 goto err; 509 /* q * j should == p - 1 */ 510 if (BN_mul(newp1, dsa->q, j, ctx) == 0) 511 goto err; 512 if (BN_cmp(newp1, p1) != 0) { 513 DSAerr(DSA_F_DSA_PARAM_DECODE, DSA_R_BAD_Q_VALUE); 514 goto err; 515 } 516 517 /* 518 * Check that q is not a composite number. 519 */ 520 521 if (BN_is_prime_ex(dsa->q, BN_prime_checks, ctx, NULL) == 0) { 522 DSAerr(DSA_F_DSA_PARAM_DECODE, DSA_R_BAD_Q_VALUE); 523 goto err; 524 } 525 526 BN_CTX_free(ctx); 527 528 EVP_PKEY_assign_DSA(pkey, dsa); 529 return 1; 530 531 err: 532 BN_CTX_free(ctx); 533 DSA_free(dsa); 534 return 0; 535 } 536 537 static int 538 old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) 539 { 540 return i2d_DSAPrivateKey(pkey->pkey.dsa, pder); 541 } 542 543 static int 544 dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig, 545 int indent, ASN1_PCTX *pctx) 546 { 547 DSA_SIG *dsa_sig; 548 const unsigned char *p; 549 550 if (!sig) { 551 if (BIO_puts(bp, "\n") <= 0) 552 return 0; 553 else 554 return 1; 555 } 556 p = sig->data; 557 dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); 558 if (dsa_sig) { 559 int rv = 0; 560 size_t buf_len = 0; 561 unsigned char *m = NULL; 562 563 update_buflen(dsa_sig->r, &buf_len); 564 update_buflen(dsa_sig->s, &buf_len); 565 m = malloc(buf_len + 10); 566 if (m == NULL) { 567 DSAerr(DSA_F_DSA_SIG_PRINT, ERR_R_MALLOC_FAILURE); 568 goto err; 569 } 570 571 if (BIO_write(bp, "\n", 1) != 1) 572 goto err; 573 574 if (!ASN1_bn_print(bp, "r: ", dsa_sig->r, m, indent)) 575 goto err; 576 if (!ASN1_bn_print(bp, "s: ", dsa_sig->s, m, indent)) 577 goto err; 578 rv = 1; 579 err: 580 free(m); 581 DSA_SIG_free(dsa_sig); 582 return rv; 583 } 584 return X509_signature_dump(bp, sig, indent); 585 } 586 587 static int 588 dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 589 { 590 switch (op) { 591 case ASN1_PKEY_CTRL_PKCS7_SIGN: 592 if (arg1 == 0) { 593 int snid, hnid; 594 X509_ALGOR *alg1, *alg2; 595 596 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); 597 if (alg1 == NULL || alg1->algorithm == NULL) 598 return -1; 599 hnid = OBJ_obj2nid(alg1->algorithm); 600 if (hnid == NID_undef) 601 return -1; 602 if (!OBJ_find_sigid_by_algs(&snid, hnid, 603 EVP_PKEY_id(pkey))) 604 return -1; 605 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 606 0); 607 } 608 return 1; 609 #ifndef OPENSSL_NO_CMS 610 case ASN1_PKEY_CTRL_CMS_SIGN: 611 if (arg1 == 0) { 612 int snid, hnid; 613 X509_ALGOR *alg1, *alg2; 614 615 CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); 616 if (alg1 == NULL || alg1->algorithm == NULL) 617 return -1; 618 hnid = OBJ_obj2nid(alg1->algorithm); 619 if (hnid == NID_undef) 620 return -1; 621 if (!OBJ_find_sigid_by_algs(&snid, hnid, 622 EVP_PKEY_id(pkey))) 623 return -1; 624 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 625 0); 626 } 627 return 1; 628 #endif 629 630 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 631 *(int *)arg2 = NID_sha1; 632 return 2; 633 634 default: 635 return -2; 636 } 637 } 638 639 /* NB these are sorted in pkey_id order, lowest first */ 640 641 const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = { 642 { 643 .pkey_id = EVP_PKEY_DSA2, 644 .pkey_base_id = EVP_PKEY_DSA, 645 .pkey_flags = ASN1_PKEY_ALIAS 646 }, 647 648 { 649 .pkey_id = EVP_PKEY_DSA1, 650 .pkey_base_id = EVP_PKEY_DSA, 651 .pkey_flags = ASN1_PKEY_ALIAS 652 }, 653 654 { 655 .pkey_id = EVP_PKEY_DSA4, 656 .pkey_base_id = EVP_PKEY_DSA, 657 .pkey_flags = ASN1_PKEY_ALIAS 658 }, 659 660 { 661 .pkey_id = EVP_PKEY_DSA3, 662 .pkey_base_id = EVP_PKEY_DSA, 663 .pkey_flags = ASN1_PKEY_ALIAS 664 }, 665 666 { 667 .pkey_id = EVP_PKEY_DSA, 668 .pkey_base_id = EVP_PKEY_DSA, 669 670 .pem_str = "DSA", 671 .info = "OpenSSL DSA method", 672 673 .pub_decode = dsa_pub_decode, 674 .pub_encode = dsa_pub_encode, 675 .pub_cmp = dsa_pub_cmp, 676 .pub_print = dsa_pub_print, 677 678 .priv_decode = dsa_priv_decode, 679 .priv_encode = dsa_priv_encode, 680 .priv_print = dsa_priv_print, 681 682 .pkey_size = int_dsa_size, 683 .pkey_bits = dsa_bits, 684 685 .param_decode = dsa_param_decode, 686 .param_encode = dsa_param_encode, 687 .param_missing = dsa_missing_parameters, 688 .param_copy = dsa_copy_parameters, 689 .param_cmp = dsa_cmp_parameters, 690 .param_print = dsa_param_print, 691 .sig_print = dsa_sig_print, 692 693 .pkey_free = int_dsa_free, 694 .pkey_ctrl = dsa_pkey_ctrl, 695 .old_priv_decode = old_dsa_priv_decode, 696 .old_priv_encode = old_dsa_priv_encode 697 } 698 }; 699