1*f5b1c8a1SJohn Marino /* $OpenBSD: dsa_pmeth.c,v 1.9 2014/07/10 13:58:22 jsing Exp $ */ 2*f5b1c8a1SJohn Marino /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3*f5b1c8a1SJohn Marino * project 2006. 4*f5b1c8a1SJohn Marino */ 5*f5b1c8a1SJohn Marino /* ==================================================================== 6*f5b1c8a1SJohn Marino * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 7*f5b1c8a1SJohn Marino * 8*f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without 9*f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions 10*f5b1c8a1SJohn Marino * are met: 11*f5b1c8a1SJohn Marino * 12*f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the above copyright 13*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer. 14*f5b1c8a1SJohn Marino * 15*f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 16*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in 17*f5b1c8a1SJohn Marino * the documentation and/or other materials provided with the 18*f5b1c8a1SJohn Marino * distribution. 19*f5b1c8a1SJohn Marino * 20*f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this 21*f5b1c8a1SJohn Marino * software must display the following acknowledgment: 22*f5b1c8a1SJohn Marino * "This product includes software developed by the OpenSSL Project 23*f5b1c8a1SJohn Marino * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24*f5b1c8a1SJohn Marino * 25*f5b1c8a1SJohn Marino * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26*f5b1c8a1SJohn Marino * endorse or promote products derived from this software without 27*f5b1c8a1SJohn Marino * prior written permission. For written permission, please contact 28*f5b1c8a1SJohn Marino * licensing@OpenSSL.org. 29*f5b1c8a1SJohn Marino * 30*f5b1c8a1SJohn Marino * 5. Products derived from this software may not be called "OpenSSL" 31*f5b1c8a1SJohn Marino * nor may "OpenSSL" appear in their names without prior written 32*f5b1c8a1SJohn Marino * permission of the OpenSSL Project. 33*f5b1c8a1SJohn Marino * 34*f5b1c8a1SJohn Marino * 6. Redistributions of any form whatsoever must retain the following 35*f5b1c8a1SJohn Marino * acknowledgment: 36*f5b1c8a1SJohn Marino * "This product includes software developed by the OpenSSL Project 37*f5b1c8a1SJohn Marino * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38*f5b1c8a1SJohn Marino * 39*f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40*f5b1c8a1SJohn Marino * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41*f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42*f5b1c8a1SJohn Marino * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43*f5b1c8a1SJohn Marino * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44*f5b1c8a1SJohn Marino * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45*f5b1c8a1SJohn Marino * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46*f5b1c8a1SJohn Marino * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47*f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48*f5b1c8a1SJohn Marino * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49*f5b1c8a1SJohn Marino * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50*f5b1c8a1SJohn Marino * OF THE POSSIBILITY OF SUCH DAMAGE. 51*f5b1c8a1SJohn Marino * ==================================================================== 52*f5b1c8a1SJohn Marino * 53*f5b1c8a1SJohn Marino * This product includes cryptographic software written by Eric Young 54*f5b1c8a1SJohn Marino * (eay@cryptsoft.com). This product includes software written by Tim 55*f5b1c8a1SJohn Marino * Hudson (tjh@cryptsoft.com). 56*f5b1c8a1SJohn Marino * 57*f5b1c8a1SJohn Marino */ 58*f5b1c8a1SJohn Marino 59*f5b1c8a1SJohn Marino #include <limits.h> 60*f5b1c8a1SJohn Marino #include <stdio.h> 61*f5b1c8a1SJohn Marino #include <string.h> 62*f5b1c8a1SJohn Marino 63*f5b1c8a1SJohn Marino #include <openssl/asn1t.h> 64*f5b1c8a1SJohn Marino #include <openssl/bn.h> 65*f5b1c8a1SJohn Marino #include <openssl/err.h> 66*f5b1c8a1SJohn Marino #include <openssl/evp.h> 67*f5b1c8a1SJohn Marino #include <openssl/x509.h> 68*f5b1c8a1SJohn Marino 69*f5b1c8a1SJohn Marino #include "dsa_locl.h" 70*f5b1c8a1SJohn Marino #include "evp_locl.h" 71*f5b1c8a1SJohn Marino 72*f5b1c8a1SJohn Marino /* DSA pkey context structure */ 73*f5b1c8a1SJohn Marino 74*f5b1c8a1SJohn Marino typedef struct { 75*f5b1c8a1SJohn Marino /* Parameter gen parameters */ 76*f5b1c8a1SJohn Marino int nbits; /* size of p in bits (default: 1024) */ 77*f5b1c8a1SJohn Marino int qbits; /* size of q in bits (default: 160) */ 78*f5b1c8a1SJohn Marino const EVP_MD *pmd; /* MD for parameter generation */ 79*f5b1c8a1SJohn Marino /* Keygen callback info */ 80*f5b1c8a1SJohn Marino int gentmp[2]; 81*f5b1c8a1SJohn Marino /* message digest */ 82*f5b1c8a1SJohn Marino const EVP_MD *md; /* MD for the signature */ 83*f5b1c8a1SJohn Marino } DSA_PKEY_CTX; 84*f5b1c8a1SJohn Marino 85*f5b1c8a1SJohn Marino static int 86*f5b1c8a1SJohn Marino pkey_dsa_init(EVP_PKEY_CTX *ctx) 87*f5b1c8a1SJohn Marino { 88*f5b1c8a1SJohn Marino DSA_PKEY_CTX *dctx; 89*f5b1c8a1SJohn Marino 90*f5b1c8a1SJohn Marino dctx = malloc(sizeof(DSA_PKEY_CTX)); 91*f5b1c8a1SJohn Marino if (!dctx) 92*f5b1c8a1SJohn Marino return 0; 93*f5b1c8a1SJohn Marino dctx->nbits = 1024; 94*f5b1c8a1SJohn Marino dctx->qbits = 160; 95*f5b1c8a1SJohn Marino dctx->pmd = NULL; 96*f5b1c8a1SJohn Marino dctx->md = NULL; 97*f5b1c8a1SJohn Marino 98*f5b1c8a1SJohn Marino ctx->data = dctx; 99*f5b1c8a1SJohn Marino ctx->keygen_info = dctx->gentmp; 100*f5b1c8a1SJohn Marino ctx->keygen_info_count = 2; 101*f5b1c8a1SJohn Marino 102*f5b1c8a1SJohn Marino return 1; 103*f5b1c8a1SJohn Marino } 104*f5b1c8a1SJohn Marino 105*f5b1c8a1SJohn Marino static int 106*f5b1c8a1SJohn Marino pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) 107*f5b1c8a1SJohn Marino { 108*f5b1c8a1SJohn Marino DSA_PKEY_CTX *dctx, *sctx; 109*f5b1c8a1SJohn Marino 110*f5b1c8a1SJohn Marino if (!pkey_dsa_init(dst)) 111*f5b1c8a1SJohn Marino return 0; 112*f5b1c8a1SJohn Marino sctx = src->data; 113*f5b1c8a1SJohn Marino dctx = dst->data; 114*f5b1c8a1SJohn Marino dctx->nbits = sctx->nbits; 115*f5b1c8a1SJohn Marino dctx->qbits = sctx->qbits; 116*f5b1c8a1SJohn Marino dctx->pmd = sctx->pmd; 117*f5b1c8a1SJohn Marino dctx->md = sctx->md; 118*f5b1c8a1SJohn Marino return 1; 119*f5b1c8a1SJohn Marino } 120*f5b1c8a1SJohn Marino 121*f5b1c8a1SJohn Marino static void 122*f5b1c8a1SJohn Marino pkey_dsa_cleanup(EVP_PKEY_CTX *ctx) 123*f5b1c8a1SJohn Marino { 124*f5b1c8a1SJohn Marino DSA_PKEY_CTX *dctx = ctx->data; 125*f5b1c8a1SJohn Marino 126*f5b1c8a1SJohn Marino free(dctx); 127*f5b1c8a1SJohn Marino } 128*f5b1c8a1SJohn Marino 129*f5b1c8a1SJohn Marino static int 130*f5b1c8a1SJohn Marino pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, 131*f5b1c8a1SJohn Marino const unsigned char *tbs, size_t tbslen) 132*f5b1c8a1SJohn Marino { 133*f5b1c8a1SJohn Marino int ret, type; 134*f5b1c8a1SJohn Marino unsigned int sltmp; 135*f5b1c8a1SJohn Marino DSA_PKEY_CTX *dctx = ctx->data; 136*f5b1c8a1SJohn Marino DSA *dsa = ctx->pkey->pkey.dsa; 137*f5b1c8a1SJohn Marino 138*f5b1c8a1SJohn Marino if (dctx->md) 139*f5b1c8a1SJohn Marino type = EVP_MD_type(dctx->md); 140*f5b1c8a1SJohn Marino else 141*f5b1c8a1SJohn Marino type = NID_sha1; 142*f5b1c8a1SJohn Marino 143*f5b1c8a1SJohn Marino ret = DSA_sign(type, tbs, tbslen, sig, &sltmp, dsa); 144*f5b1c8a1SJohn Marino 145*f5b1c8a1SJohn Marino if (ret <= 0) 146*f5b1c8a1SJohn Marino return ret; 147*f5b1c8a1SJohn Marino *siglen = sltmp; 148*f5b1c8a1SJohn Marino return 1; 149*f5b1c8a1SJohn Marino } 150*f5b1c8a1SJohn Marino 151*f5b1c8a1SJohn Marino static int 152*f5b1c8a1SJohn Marino pkey_dsa_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, 153*f5b1c8a1SJohn Marino const unsigned char *tbs, size_t tbslen) 154*f5b1c8a1SJohn Marino { 155*f5b1c8a1SJohn Marino int ret, type; 156*f5b1c8a1SJohn Marino DSA_PKEY_CTX *dctx = ctx->data; 157*f5b1c8a1SJohn Marino DSA *dsa = ctx->pkey->pkey.dsa; 158*f5b1c8a1SJohn Marino 159*f5b1c8a1SJohn Marino if (dctx->md) 160*f5b1c8a1SJohn Marino type = EVP_MD_type(dctx->md); 161*f5b1c8a1SJohn Marino else 162*f5b1c8a1SJohn Marino type = NID_sha1; 163*f5b1c8a1SJohn Marino 164*f5b1c8a1SJohn Marino ret = DSA_verify(type, tbs, tbslen, sig, siglen, dsa); 165*f5b1c8a1SJohn Marino 166*f5b1c8a1SJohn Marino return ret; 167*f5b1c8a1SJohn Marino } 168*f5b1c8a1SJohn Marino 169*f5b1c8a1SJohn Marino static int 170*f5b1c8a1SJohn Marino pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 171*f5b1c8a1SJohn Marino { 172*f5b1c8a1SJohn Marino DSA_PKEY_CTX *dctx = ctx->data; 173*f5b1c8a1SJohn Marino 174*f5b1c8a1SJohn Marino switch (type) { 175*f5b1c8a1SJohn Marino case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS: 176*f5b1c8a1SJohn Marino if (p1 < 256) 177*f5b1c8a1SJohn Marino return -2; 178*f5b1c8a1SJohn Marino dctx->nbits = p1; 179*f5b1c8a1SJohn Marino return 1; 180*f5b1c8a1SJohn Marino 181*f5b1c8a1SJohn Marino case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS: 182*f5b1c8a1SJohn Marino if (p1 != 160 && p1 != 224 && p1 && p1 != 256) 183*f5b1c8a1SJohn Marino return -2; 184*f5b1c8a1SJohn Marino dctx->qbits = p1; 185*f5b1c8a1SJohn Marino return 1; 186*f5b1c8a1SJohn Marino 187*f5b1c8a1SJohn Marino case EVP_PKEY_CTRL_DSA_PARAMGEN_MD: 188*f5b1c8a1SJohn Marino switch (EVP_MD_type((const EVP_MD *)p2)) { 189*f5b1c8a1SJohn Marino case NID_sha1: 190*f5b1c8a1SJohn Marino case NID_sha224: 191*f5b1c8a1SJohn Marino case NID_sha256: 192*f5b1c8a1SJohn Marino break; 193*f5b1c8a1SJohn Marino default: 194*f5b1c8a1SJohn Marino DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); 195*f5b1c8a1SJohn Marino return 0; 196*f5b1c8a1SJohn Marino } 197*f5b1c8a1SJohn Marino dctx->md = p2; 198*f5b1c8a1SJohn Marino return 1; 199*f5b1c8a1SJohn Marino 200*f5b1c8a1SJohn Marino case EVP_PKEY_CTRL_MD: 201*f5b1c8a1SJohn Marino switch (EVP_MD_type((const EVP_MD *)p2)) { 202*f5b1c8a1SJohn Marino case NID_sha1: 203*f5b1c8a1SJohn Marino case NID_dsa: 204*f5b1c8a1SJohn Marino case NID_dsaWithSHA: 205*f5b1c8a1SJohn Marino case NID_sha224: 206*f5b1c8a1SJohn Marino case NID_sha256: 207*f5b1c8a1SJohn Marino case NID_sha384: 208*f5b1c8a1SJohn Marino case NID_sha512: 209*f5b1c8a1SJohn Marino break; 210*f5b1c8a1SJohn Marino default: 211*f5b1c8a1SJohn Marino DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); 212*f5b1c8a1SJohn Marino return 0; 213*f5b1c8a1SJohn Marino } 214*f5b1c8a1SJohn Marino dctx->md = p2; 215*f5b1c8a1SJohn Marino return 1; 216*f5b1c8a1SJohn Marino 217*f5b1c8a1SJohn Marino case EVP_PKEY_CTRL_DIGESTINIT: 218*f5b1c8a1SJohn Marino case EVP_PKEY_CTRL_PKCS7_SIGN: 219*f5b1c8a1SJohn Marino case EVP_PKEY_CTRL_CMS_SIGN: 220*f5b1c8a1SJohn Marino return 1; 221*f5b1c8a1SJohn Marino 222*f5b1c8a1SJohn Marino case EVP_PKEY_CTRL_PEER_KEY: 223*f5b1c8a1SJohn Marino DSAerr(DSA_F_PKEY_DSA_CTRL, 224*f5b1c8a1SJohn Marino EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 225*f5b1c8a1SJohn Marino return -2; 226*f5b1c8a1SJohn Marino default: 227*f5b1c8a1SJohn Marino return -2; 228*f5b1c8a1SJohn Marino } 229*f5b1c8a1SJohn Marino } 230*f5b1c8a1SJohn Marino 231*f5b1c8a1SJohn Marino static int 232*f5b1c8a1SJohn Marino pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) 233*f5b1c8a1SJohn Marino { 234*f5b1c8a1SJohn Marino long lval; 235*f5b1c8a1SJohn Marino char *ep; 236*f5b1c8a1SJohn Marino 237*f5b1c8a1SJohn Marino if (!strcmp(type, "dsa_paramgen_bits")) { 238*f5b1c8a1SJohn Marino int nbits; 239*f5b1c8a1SJohn Marino 240*f5b1c8a1SJohn Marino errno = 0; 241*f5b1c8a1SJohn Marino lval = strtol(value, &ep, 10); 242*f5b1c8a1SJohn Marino if (value[0] == '\0' || *ep != '\0') 243*f5b1c8a1SJohn Marino goto not_a_number; 244*f5b1c8a1SJohn Marino if ((errno == ERANGE && 245*f5b1c8a1SJohn Marino (lval == LONG_MAX || lval == LONG_MIN)) || 246*f5b1c8a1SJohn Marino (lval > INT_MAX || lval < INT_MIN)) 247*f5b1c8a1SJohn Marino goto out_of_range; 248*f5b1c8a1SJohn Marino nbits = lval; 249*f5b1c8a1SJohn Marino return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits); 250*f5b1c8a1SJohn Marino } else if (!strcmp(type, "dsa_paramgen_q_bits")) { 251*f5b1c8a1SJohn Marino int qbits; 252*f5b1c8a1SJohn Marino 253*f5b1c8a1SJohn Marino errno = 0; 254*f5b1c8a1SJohn Marino lval = strtol(value, &ep, 10); 255*f5b1c8a1SJohn Marino if (value[0] == '\0' || *ep != '\0') 256*f5b1c8a1SJohn Marino goto not_a_number; 257*f5b1c8a1SJohn Marino if ((errno == ERANGE && 258*f5b1c8a1SJohn Marino (lval == LONG_MAX || lval == LONG_MIN)) || 259*f5b1c8a1SJohn Marino (lval > INT_MAX || lval < INT_MIN)) 260*f5b1c8a1SJohn Marino goto out_of_range; 261*f5b1c8a1SJohn Marino qbits = lval; 262*f5b1c8a1SJohn Marino return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, 263*f5b1c8a1SJohn Marino EVP_PKEY_OP_PARAMGEN, EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, 264*f5b1c8a1SJohn Marino qbits, NULL); 265*f5b1c8a1SJohn Marino } else if (!strcmp(type, "dsa_paramgen_md")) { 266*f5b1c8a1SJohn Marino return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, 267*f5b1c8a1SJohn Marino EVP_PKEY_OP_PARAMGEN, EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, 268*f5b1c8a1SJohn Marino (void *)EVP_get_digestbyname(value)); 269*f5b1c8a1SJohn Marino } 270*f5b1c8a1SJohn Marino not_a_number: 271*f5b1c8a1SJohn Marino out_of_range: 272*f5b1c8a1SJohn Marino return -2; 273*f5b1c8a1SJohn Marino } 274*f5b1c8a1SJohn Marino 275*f5b1c8a1SJohn Marino static int 276*f5b1c8a1SJohn Marino pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 277*f5b1c8a1SJohn Marino { 278*f5b1c8a1SJohn Marino DSA *dsa = NULL; 279*f5b1c8a1SJohn Marino DSA_PKEY_CTX *dctx = ctx->data; 280*f5b1c8a1SJohn Marino BN_GENCB *pcb, cb; 281*f5b1c8a1SJohn Marino int ret; 282*f5b1c8a1SJohn Marino 283*f5b1c8a1SJohn Marino if (ctx->pkey_gencb) { 284*f5b1c8a1SJohn Marino pcb = &cb; 285*f5b1c8a1SJohn Marino evp_pkey_set_cb_translate(pcb, ctx); 286*f5b1c8a1SJohn Marino } else 287*f5b1c8a1SJohn Marino pcb = NULL; 288*f5b1c8a1SJohn Marino dsa = DSA_new(); 289*f5b1c8a1SJohn Marino if (!dsa) 290*f5b1c8a1SJohn Marino return 0; 291*f5b1c8a1SJohn Marino ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, 292*f5b1c8a1SJohn Marino NULL, 0, NULL, NULL, NULL, pcb); 293*f5b1c8a1SJohn Marino if (ret) 294*f5b1c8a1SJohn Marino EVP_PKEY_assign_DSA(pkey, dsa); 295*f5b1c8a1SJohn Marino else 296*f5b1c8a1SJohn Marino DSA_free(dsa); 297*f5b1c8a1SJohn Marino return ret; 298*f5b1c8a1SJohn Marino } 299*f5b1c8a1SJohn Marino 300*f5b1c8a1SJohn Marino static int 301*f5b1c8a1SJohn Marino pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 302*f5b1c8a1SJohn Marino { 303*f5b1c8a1SJohn Marino DSA *dsa = NULL; 304*f5b1c8a1SJohn Marino 305*f5b1c8a1SJohn Marino if (ctx->pkey == NULL) { 306*f5b1c8a1SJohn Marino DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET); 307*f5b1c8a1SJohn Marino return 0; 308*f5b1c8a1SJohn Marino } 309*f5b1c8a1SJohn Marino dsa = DSA_new(); 310*f5b1c8a1SJohn Marino if (!dsa) 311*f5b1c8a1SJohn Marino return 0; 312*f5b1c8a1SJohn Marino EVP_PKEY_assign_DSA(pkey, dsa); 313*f5b1c8a1SJohn Marino /* Note: if error return, pkey is freed by parent routine */ 314*f5b1c8a1SJohn Marino if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) 315*f5b1c8a1SJohn Marino return 0; 316*f5b1c8a1SJohn Marino return DSA_generate_key(pkey->pkey.dsa); 317*f5b1c8a1SJohn Marino } 318*f5b1c8a1SJohn Marino 319*f5b1c8a1SJohn Marino const EVP_PKEY_METHOD dsa_pkey_meth = { 320*f5b1c8a1SJohn Marino .pkey_id = EVP_PKEY_DSA, 321*f5b1c8a1SJohn Marino .flags = EVP_PKEY_FLAG_AUTOARGLEN, 322*f5b1c8a1SJohn Marino 323*f5b1c8a1SJohn Marino .init = pkey_dsa_init, 324*f5b1c8a1SJohn Marino .copy = pkey_dsa_copy, 325*f5b1c8a1SJohn Marino .cleanup = pkey_dsa_cleanup, 326*f5b1c8a1SJohn Marino 327*f5b1c8a1SJohn Marino .paramgen = pkey_dsa_paramgen, 328*f5b1c8a1SJohn Marino 329*f5b1c8a1SJohn Marino .keygen = pkey_dsa_keygen, 330*f5b1c8a1SJohn Marino 331*f5b1c8a1SJohn Marino .sign = pkey_dsa_sign, 332*f5b1c8a1SJohn Marino 333*f5b1c8a1SJohn Marino .verify = pkey_dsa_verify, 334*f5b1c8a1SJohn Marino 335*f5b1c8a1SJohn Marino .ctrl = pkey_dsa_ctrl, 336*f5b1c8a1SJohn Marino .ctrl_str = pkey_dsa_ctrl_str 337*f5b1c8a1SJohn Marino }; 338