1 /* 2 * Copyright 2006-2024 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (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 /* 11 * DSA low level APIs are deprecated for public use, but still ok for 12 * internal use. 13 */ 14 #include "internal/deprecated.h" 15 16 #include <stdio.h> 17 #include "internal/cryptlib.h" 18 #include <openssl/asn1t.h> 19 #include <openssl/x509.h> 20 #include <openssl/evp.h> 21 #include <openssl/bn.h> 22 #include "crypto/evp.h" 23 #include "dsa_local.h" 24 25 /* DSA pkey context structure */ 26 27 typedef struct { 28 /* Parameter gen parameters */ 29 int nbits; /* size of p in bits (default: 2048) */ 30 int qbits; /* size of q in bits (default: 224) */ 31 const EVP_MD *pmd; /* MD for parameter generation */ 32 /* Keygen callback info */ 33 int gentmp[2]; 34 /* message digest */ 35 const EVP_MD *md; /* MD for the signature */ 36 } DSA_PKEY_CTX; 37 38 static int pkey_dsa_init(EVP_PKEY_CTX *ctx) 39 { 40 DSA_PKEY_CTX *dctx = OPENSSL_malloc(sizeof(*dctx)); 41 42 if (dctx == NULL) 43 return 0; 44 dctx->nbits = 2048; 45 dctx->qbits = 224; 46 dctx->pmd = NULL; 47 dctx->md = NULL; 48 49 ctx->data = dctx; 50 ctx->keygen_info = dctx->gentmp; 51 ctx->keygen_info_count = 2; 52 53 return 1; 54 } 55 56 static int pkey_dsa_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) 57 { 58 DSA_PKEY_CTX *dctx, *sctx; 59 60 if (!pkey_dsa_init(dst)) 61 return 0; 62 sctx = src->data; 63 dctx = dst->data; 64 dctx->nbits = sctx->nbits; 65 dctx->qbits = sctx->qbits; 66 dctx->pmd = sctx->pmd; 67 dctx->md = sctx->md; 68 return 1; 69 } 70 71 static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx) 72 { 73 DSA_PKEY_CTX *dctx = ctx->data; 74 OPENSSL_free(dctx); 75 } 76 77 static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, 78 size_t *siglen, const unsigned char *tbs, 79 size_t tbslen) 80 { 81 int ret, md_size; 82 unsigned int sltmp; 83 DSA_PKEY_CTX *dctx = ctx->data; 84 /* 85 * Discard const. Its marked as const because this may be a cached copy of 86 * the "real" key. These calls don't make any modifications that need to 87 * be reflected back in the "original" key. 88 */ 89 DSA *dsa = (DSA *)EVP_PKEY_get0_DSA(ctx->pkey); 90 91 if (dctx->md != NULL) { 92 md_size = EVP_MD_get_size(dctx->md); 93 if (md_size <= 0) 94 return 0; 95 if (tbslen != (size_t)md_size) 96 return 0; 97 } 98 99 ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, dsa); 100 101 if (ret <= 0) 102 return ret; 103 *siglen = sltmp; 104 return 1; 105 } 106 107 static int pkey_dsa_verify(EVP_PKEY_CTX *ctx, 108 const unsigned char *sig, size_t siglen, 109 const unsigned char *tbs, size_t tbslen) 110 { 111 int ret, md_size; 112 DSA_PKEY_CTX *dctx = ctx->data; 113 /* 114 * Discard const. Its marked as const because this may be a cached copy of 115 * the "real" key. These calls don't make any modifications that need to 116 * be reflected back in the "original" key. 117 */ 118 DSA *dsa = (DSA *)EVP_PKEY_get0_DSA(ctx->pkey); 119 120 if (dctx->md != NULL) { 121 md_size = EVP_MD_get_size(dctx->md); 122 if (md_size <= 0) 123 return 0; 124 if (tbslen != (size_t)md_size) 125 return 0; 126 } 127 128 ret = DSA_verify(0, tbs, tbslen, sig, siglen, dsa); 129 130 return ret; 131 } 132 133 static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 134 { 135 DSA_PKEY_CTX *dctx = ctx->data; 136 137 switch (type) { 138 case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS: 139 if (p1 < 256) 140 return -2; 141 dctx->nbits = p1; 142 return 1; 143 144 case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS: 145 if (p1 != 160 && p1 != 224 && p1 && p1 != 256) 146 return -2; 147 dctx->qbits = p1; 148 return 1; 149 150 case EVP_PKEY_CTRL_DSA_PARAMGEN_MD: 151 if (EVP_MD_get_type((const EVP_MD *)p2) != NID_sha1 && 152 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha224 && 153 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha256) { 154 ERR_raise(ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE); 155 return 0; 156 } 157 dctx->pmd = p2; 158 return 1; 159 160 case EVP_PKEY_CTRL_MD: 161 if (EVP_MD_get_type((const EVP_MD *)p2) != NID_sha1 && 162 EVP_MD_get_type((const EVP_MD *)p2) != NID_dsa && 163 EVP_MD_get_type((const EVP_MD *)p2) != NID_dsaWithSHA && 164 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha224 && 165 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha256 && 166 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha384 && 167 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha512 && 168 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_224 && 169 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_256 && 170 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_384 && 171 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_512) { 172 ERR_raise(ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE); 173 return 0; 174 } 175 dctx->md = p2; 176 return 1; 177 178 case EVP_PKEY_CTRL_GET_MD: 179 *(const EVP_MD **)p2 = dctx->md; 180 return 1; 181 182 case EVP_PKEY_CTRL_DIGESTINIT: 183 case EVP_PKEY_CTRL_PKCS7_SIGN: 184 case EVP_PKEY_CTRL_CMS_SIGN: 185 return 1; 186 187 case EVP_PKEY_CTRL_PEER_KEY: 188 ERR_raise(ERR_LIB_DSA, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 189 return -2; 190 default: 191 return -2; 192 193 } 194 } 195 196 static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, 197 const char *type, const char *value) 198 { 199 if (strcmp(type, "dsa_paramgen_bits") == 0) { 200 int nbits; 201 nbits = atoi(value); 202 return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits); 203 } 204 if (strcmp(type, "dsa_paramgen_q_bits") == 0) { 205 int qbits = atoi(value); 206 return EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, qbits); 207 } 208 if (strcmp(type, "dsa_paramgen_md") == 0) { 209 const EVP_MD *md = EVP_get_digestbyname(value); 210 211 if (md == NULL) { 212 ERR_raise(ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE); 213 return 0; 214 } 215 return EVP_PKEY_CTX_set_dsa_paramgen_md(ctx, md); 216 } 217 return -2; 218 } 219 220 static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 221 { 222 DSA *dsa = NULL; 223 DSA_PKEY_CTX *dctx = ctx->data; 224 BN_GENCB *pcb; 225 int ret, res; 226 227 if (ctx->pkey_gencb) { 228 pcb = BN_GENCB_new(); 229 if (pcb == NULL) 230 return 0; 231 evp_pkey_set_cb_translate(pcb, ctx); 232 } else 233 pcb = NULL; 234 dsa = DSA_new(); 235 if (dsa == NULL) { 236 BN_GENCB_free(pcb); 237 return 0; 238 } 239 if (dctx->md != NULL) 240 ossl_ffc_set_digest(&dsa->params, EVP_MD_get0_name(dctx->md), NULL); 241 242 ret = ossl_ffc_params_FIPS186_4_generate(NULL, &dsa->params, 243 FFC_PARAM_TYPE_DSA, dctx->nbits, 244 dctx->qbits, &res, pcb); 245 BN_GENCB_free(pcb); 246 if (ret > 0) 247 EVP_PKEY_assign_DSA(pkey, dsa); 248 else 249 DSA_free(dsa); 250 return ret; 251 } 252 253 static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 254 { 255 DSA *dsa = NULL; 256 257 if (ctx->pkey == NULL) { 258 ERR_raise(ERR_LIB_DSA, DSA_R_NO_PARAMETERS_SET); 259 return 0; 260 } 261 dsa = DSA_new(); 262 if (dsa == NULL) 263 return 0; 264 EVP_PKEY_assign_DSA(pkey, dsa); 265 /* Note: if error return, pkey is freed by parent routine */ 266 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) 267 return 0; 268 return DSA_generate_key((DSA *)EVP_PKEY_get0_DSA(pkey)); 269 } 270 271 static const EVP_PKEY_METHOD dsa_pkey_meth = { 272 EVP_PKEY_DSA, 273 EVP_PKEY_FLAG_AUTOARGLEN, 274 pkey_dsa_init, 275 pkey_dsa_copy, 276 pkey_dsa_cleanup, 277 278 0, 279 pkey_dsa_paramgen, 280 281 0, 282 pkey_dsa_keygen, 283 284 0, 285 pkey_dsa_sign, 286 287 0, 288 pkey_dsa_verify, 289 290 0, 0, 291 292 0, 0, 0, 0, 293 294 0, 0, 295 296 0, 0, 297 298 0, 0, 299 300 pkey_dsa_ctrl, 301 pkey_dsa_ctrl_str 302 }; 303 304 const EVP_PKEY_METHOD *ossl_dsa_pkey_method(void) 305 { 306 return &dsa_pkey_meth; 307 } 308