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