1 /* 2 * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include <openssl/asn1t.h> 13 #include <openssl/x509.h> 14 #include <openssl/evp.h> 15 #include <openssl/bn.h> 16 #include "internal/evp_int.h" 17 #include "dsa_locl.h" 18 19 /* DSA pkey context structure */ 20 21 typedef struct { 22 /* Parameter gen parameters */ 23 int nbits; /* size of p in bits (default: 2048) */ 24 int qbits; /* size of q in bits (default: 224) */ 25 const EVP_MD *pmd; /* MD for parameter generation */ 26 /* Keygen callback info */ 27 int gentmp[2]; 28 /* message digest */ 29 const EVP_MD *md; /* MD for the signature */ 30 } DSA_PKEY_CTX; 31 32 static int pkey_dsa_init(EVP_PKEY_CTX *ctx) 33 { 34 DSA_PKEY_CTX *dctx = OPENSSL_malloc(sizeof(*dctx)); 35 36 if (dctx == NULL) 37 return 0; 38 dctx->nbits = 2048; 39 dctx->qbits = 224; 40 dctx->pmd = NULL; 41 dctx->md = NULL; 42 43 ctx->data = dctx; 44 ctx->keygen_info = dctx->gentmp; 45 ctx->keygen_info_count = 2; 46 47 return 1; 48 } 49 50 static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) 51 { 52 DSA_PKEY_CTX *dctx, *sctx; 53 54 if (!pkey_dsa_init(dst)) 55 return 0; 56 sctx = src->data; 57 dctx = dst->data; 58 dctx->nbits = sctx->nbits; 59 dctx->qbits = sctx->qbits; 60 dctx->pmd = sctx->pmd; 61 dctx->md = sctx->md; 62 return 1; 63 } 64 65 static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx) 66 { 67 DSA_PKEY_CTX *dctx = ctx->data; 68 OPENSSL_free(dctx); 69 } 70 71 static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, 72 size_t *siglen, const unsigned char *tbs, 73 size_t tbslen) 74 { 75 int ret; 76 unsigned int sltmp; 77 DSA_PKEY_CTX *dctx = ctx->data; 78 DSA *dsa = ctx->pkey->pkey.dsa; 79 80 if (dctx->md != NULL && tbslen != (size_t)EVP_MD_size(dctx->md)) 81 return 0; 82 83 ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, dsa); 84 85 if (ret <= 0) 86 return ret; 87 *siglen = sltmp; 88 return 1; 89 } 90 91 static int pkey_dsa_verify(EVP_PKEY_CTX *ctx, 92 const unsigned char *sig, size_t siglen, 93 const unsigned char *tbs, size_t tbslen) 94 { 95 int ret; 96 DSA_PKEY_CTX *dctx = ctx->data; 97 DSA *dsa = ctx->pkey->pkey.dsa; 98 99 if (dctx->md != NULL && tbslen != (size_t)EVP_MD_size(dctx->md)) 100 return 0; 101 102 ret = DSA_verify(0, tbs, tbslen, sig, siglen, dsa); 103 104 return ret; 105 } 106 107 static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 108 { 109 DSA_PKEY_CTX *dctx = ctx->data; 110 111 switch (type) { 112 case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS: 113 if (p1 < 256) 114 return -2; 115 dctx->nbits = p1; 116 return 1; 117 118 case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS: 119 if (p1 != 160 && p1 != 224 && p1 && p1 != 256) 120 return -2; 121 dctx->qbits = p1; 122 return 1; 123 124 case EVP_PKEY_CTRL_DSA_PARAMGEN_MD: 125 if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && 126 EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && 127 EVP_MD_type((const EVP_MD *)p2) != NID_sha256) { 128 DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); 129 return 0; 130 } 131 dctx->pmd = p2; 132 return 1; 133 134 case EVP_PKEY_CTRL_MD: 135 if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && 136 EVP_MD_type((const EVP_MD *)p2) != NID_dsa && 137 EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA && 138 EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && 139 EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && 140 EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && 141 EVP_MD_type((const EVP_MD *)p2) != NID_sha512 && 142 EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 && 143 EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 && 144 EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 && 145 EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512) { 146 DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); 147 return 0; 148 } 149 dctx->md = p2; 150 return 1; 151 152 case EVP_PKEY_CTRL_GET_MD: 153 *(const EVP_MD **)p2 = dctx->md; 154 return 1; 155 156 case EVP_PKEY_CTRL_DIGESTINIT: 157 case EVP_PKEY_CTRL_PKCS7_SIGN: 158 case EVP_PKEY_CTRL_CMS_SIGN: 159 return 1; 160 161 case EVP_PKEY_CTRL_PEER_KEY: 162 DSAerr(DSA_F_PKEY_DSA_CTRL, 163 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 164 return -2; 165 default: 166 return -2; 167 168 } 169 } 170 171 static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, 172 const char *type, const char *value) 173 { 174 if (strcmp(type, "dsa_paramgen_bits") == 0) { 175 int nbits; 176 nbits = atoi(value); 177 return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits); 178 } 179 if (strcmp(type, "dsa_paramgen_q_bits") == 0) { 180 int qbits = atoi(value); 181 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, 182 EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, 183 NULL); 184 } 185 if (strcmp(type, "dsa_paramgen_md") == 0) { 186 const EVP_MD *md = EVP_get_digestbyname(value); 187 188 if (md == NULL) { 189 DSAerr(DSA_F_PKEY_DSA_CTRL_STR, DSA_R_INVALID_DIGEST_TYPE); 190 return 0; 191 } 192 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, 193 EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, 194 (void *)md); 195 } 196 return -2; 197 } 198 199 static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 200 { 201 DSA *dsa = NULL; 202 DSA_PKEY_CTX *dctx = ctx->data; 203 BN_GENCB *pcb; 204 int ret; 205 206 if (ctx->pkey_gencb) { 207 pcb = BN_GENCB_new(); 208 if (pcb == NULL) 209 return 0; 210 evp_pkey_set_cb_translate(pcb, ctx); 211 } else 212 pcb = NULL; 213 dsa = DSA_new(); 214 if (dsa == NULL) { 215 BN_GENCB_free(pcb); 216 return 0; 217 } 218 ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, 219 NULL, 0, NULL, NULL, NULL, pcb); 220 BN_GENCB_free(pcb); 221 if (ret) 222 EVP_PKEY_assign_DSA(pkey, dsa); 223 else 224 DSA_free(dsa); 225 return ret; 226 } 227 228 static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 229 { 230 DSA *dsa = NULL; 231 232 if (ctx->pkey == NULL) { 233 DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET); 234 return 0; 235 } 236 dsa = DSA_new(); 237 if (dsa == NULL) 238 return 0; 239 EVP_PKEY_assign_DSA(pkey, dsa); 240 /* Note: if error return, pkey is freed by parent routine */ 241 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) 242 return 0; 243 return DSA_generate_key(pkey->pkey.dsa); 244 } 245 246 const EVP_PKEY_METHOD dsa_pkey_meth = { 247 EVP_PKEY_DSA, 248 EVP_PKEY_FLAG_AUTOARGLEN, 249 pkey_dsa_init, 250 pkey_dsa_copy, 251 pkey_dsa_cleanup, 252 253 0, 254 pkey_dsa_paramgen, 255 256 0, 257 pkey_dsa_keygen, 258 259 0, 260 pkey_dsa_sign, 261 262 0, 263 pkey_dsa_verify, 264 265 0, 0, 266 267 0, 0, 0, 0, 268 269 0, 0, 270 271 0, 0, 272 273 0, 0, 274 275 pkey_dsa_ctrl, 276 pkey_dsa_ctrl_str 277 }; 278