1 /* 2 * Copyright 2006-2021 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; 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 && tbslen != (size_t)EVP_MD_get_size(dctx->md)) 92 return 0; 93 94 ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, dsa); 95 96 if (ret <= 0) 97 return ret; 98 *siglen = sltmp; 99 return 1; 100 } 101 102 static int pkey_dsa_verify(EVP_PKEY_CTX *ctx, 103 const unsigned char *sig, size_t siglen, 104 const unsigned char *tbs, size_t tbslen) 105 { 106 int ret; 107 DSA_PKEY_CTX *dctx = ctx->data; 108 /* 109 * Discard const. Its marked as const because this may be a cached copy of 110 * the "real" key. These calls don't make any modifications that need to 111 * be reflected back in the "original" key. 112 */ 113 DSA *dsa = (DSA *)EVP_PKEY_get0_DSA(ctx->pkey); 114 115 if (dctx->md != NULL && tbslen != (size_t)EVP_MD_get_size(dctx->md)) 116 return 0; 117 118 ret = DSA_verify(0, tbs, tbslen, sig, siglen, dsa); 119 120 return ret; 121 } 122 123 static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 124 { 125 DSA_PKEY_CTX *dctx = ctx->data; 126 127 switch (type) { 128 case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS: 129 if (p1 < 256) 130 return -2; 131 dctx->nbits = p1; 132 return 1; 133 134 case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS: 135 if (p1 != 160 && p1 != 224 && p1 && p1 != 256) 136 return -2; 137 dctx->qbits = p1; 138 return 1; 139 140 case EVP_PKEY_CTRL_DSA_PARAMGEN_MD: 141 if (EVP_MD_get_type((const EVP_MD *)p2) != NID_sha1 && 142 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha224 && 143 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha256) { 144 ERR_raise(ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE); 145 return 0; 146 } 147 dctx->pmd = p2; 148 return 1; 149 150 case EVP_PKEY_CTRL_MD: 151 if (EVP_MD_get_type((const EVP_MD *)p2) != NID_sha1 && 152 EVP_MD_get_type((const EVP_MD *)p2) != NID_dsa && 153 EVP_MD_get_type((const EVP_MD *)p2) != NID_dsaWithSHA && 154 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha224 && 155 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha256 && 156 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha384 && 157 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha512 && 158 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_224 && 159 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_256 && 160 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_384 && 161 EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_512) { 162 ERR_raise(ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE); 163 return 0; 164 } 165 dctx->md = p2; 166 return 1; 167 168 case EVP_PKEY_CTRL_GET_MD: 169 *(const EVP_MD **)p2 = dctx->md; 170 return 1; 171 172 case EVP_PKEY_CTRL_DIGESTINIT: 173 case EVP_PKEY_CTRL_PKCS7_SIGN: 174 case EVP_PKEY_CTRL_CMS_SIGN: 175 return 1; 176 177 case EVP_PKEY_CTRL_PEER_KEY: 178 ERR_raise(ERR_LIB_DSA, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 179 return -2; 180 default: 181 return -2; 182 183 } 184 } 185 186 static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, 187 const char *type, const char *value) 188 { 189 if (strcmp(type, "dsa_paramgen_bits") == 0) { 190 int nbits; 191 nbits = atoi(value); 192 return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits); 193 } 194 if (strcmp(type, "dsa_paramgen_q_bits") == 0) { 195 int qbits = atoi(value); 196 return EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, qbits); 197 } 198 if (strcmp(type, "dsa_paramgen_md") == 0) { 199 const EVP_MD *md = EVP_get_digestbyname(value); 200 201 if (md == NULL) { 202 ERR_raise(ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE); 203 return 0; 204 } 205 return EVP_PKEY_CTX_set_dsa_paramgen_md(ctx, md); 206 } 207 return -2; 208 } 209 210 static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 211 { 212 DSA *dsa = NULL; 213 DSA_PKEY_CTX *dctx = ctx->data; 214 BN_GENCB *pcb; 215 int ret, res; 216 217 if (ctx->pkey_gencb) { 218 pcb = BN_GENCB_new(); 219 if (pcb == NULL) 220 return 0; 221 evp_pkey_set_cb_translate(pcb, ctx); 222 } else 223 pcb = NULL; 224 dsa = DSA_new(); 225 if (dsa == NULL) { 226 BN_GENCB_free(pcb); 227 return 0; 228 } 229 if (dctx->md != NULL) 230 ossl_ffc_set_digest(&dsa->params, EVP_MD_get0_name(dctx->md), NULL); 231 232 ret = ossl_ffc_params_FIPS186_4_generate(NULL, &dsa->params, 233 FFC_PARAM_TYPE_DSA, dctx->nbits, 234 dctx->qbits, &res, pcb); 235 BN_GENCB_free(pcb); 236 if (ret > 0) 237 EVP_PKEY_assign_DSA(pkey, dsa); 238 else 239 DSA_free(dsa); 240 return ret; 241 } 242 243 static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 244 { 245 DSA *dsa = NULL; 246 247 if (ctx->pkey == NULL) { 248 ERR_raise(ERR_LIB_DSA, DSA_R_NO_PARAMETERS_SET); 249 return 0; 250 } 251 dsa = DSA_new(); 252 if (dsa == NULL) 253 return 0; 254 EVP_PKEY_assign_DSA(pkey, dsa); 255 /* Note: if error return, pkey is freed by parent routine */ 256 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) 257 return 0; 258 return DSA_generate_key((DSA *)EVP_PKEY_get0_DSA(pkey)); 259 } 260 261 static const EVP_PKEY_METHOD dsa_pkey_meth = { 262 EVP_PKEY_DSA, 263 EVP_PKEY_FLAG_AUTOARGLEN, 264 pkey_dsa_init, 265 pkey_dsa_copy, 266 pkey_dsa_cleanup, 267 268 0, 269 pkey_dsa_paramgen, 270 271 0, 272 pkey_dsa_keygen, 273 274 0, 275 pkey_dsa_sign, 276 277 0, 278 pkey_dsa_verify, 279 280 0, 0, 281 282 0, 0, 0, 0, 283 284 0, 0, 285 286 0, 0, 287 288 0, 0, 289 290 pkey_dsa_ctrl, 291 pkey_dsa_ctrl_str 292 }; 293 294 const EVP_PKEY_METHOD *ossl_dsa_pkey_method(void) 295 { 296 return &dsa_pkey_meth; 297 } 298