1 /* 2 * Copyright 2019-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 <openssl/core_dispatch.h> 17 #include <openssl/core_names.h> 18 #include <openssl/bn.h> 19 #include <openssl/err.h> 20 #include "prov/securitycheck.h" 21 #include "prov/providercommon.h" 22 #include "prov/implementations.h" 23 #include "prov/provider_ctx.h" 24 #include "crypto/dsa.h" 25 #include "internal/sizes.h" 26 #include "internal/nelem.h" 27 #include "internal/param_build_set.h" 28 29 static OSSL_FUNC_keymgmt_new_fn dsa_newdata; 30 static OSSL_FUNC_keymgmt_free_fn dsa_freedata; 31 static OSSL_FUNC_keymgmt_gen_init_fn dsa_gen_init; 32 static OSSL_FUNC_keymgmt_gen_set_template_fn dsa_gen_set_template; 33 static OSSL_FUNC_keymgmt_gen_set_params_fn dsa_gen_set_params; 34 static OSSL_FUNC_keymgmt_gen_settable_params_fn dsa_gen_settable_params; 35 static OSSL_FUNC_keymgmt_gen_get_params_fn dsa_gen_get_params; 36 static OSSL_FUNC_keymgmt_gen_gettable_params_fn dsa_gen_gettable_params; 37 static OSSL_FUNC_keymgmt_gen_fn dsa_gen; 38 static OSSL_FUNC_keymgmt_gen_cleanup_fn dsa_gen_cleanup; 39 static OSSL_FUNC_keymgmt_load_fn dsa_load; 40 static OSSL_FUNC_keymgmt_get_params_fn dsa_get_params; 41 static OSSL_FUNC_keymgmt_gettable_params_fn dsa_gettable_params; 42 static OSSL_FUNC_keymgmt_has_fn dsa_has; 43 static OSSL_FUNC_keymgmt_match_fn dsa_match; 44 static OSSL_FUNC_keymgmt_validate_fn dsa_validate; 45 static OSSL_FUNC_keymgmt_import_fn dsa_import; 46 static OSSL_FUNC_keymgmt_import_types_fn dsa_import_types; 47 static OSSL_FUNC_keymgmt_export_fn dsa_export; 48 static OSSL_FUNC_keymgmt_export_types_fn dsa_export_types; 49 static OSSL_FUNC_keymgmt_dup_fn dsa_dup; 50 51 #define DSA_DEFAULT_MD "SHA256" 52 #define DSA_POSSIBLE_SELECTIONS \ 53 (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) 54 55 struct dsa_gen_ctx { 56 OSSL_LIB_CTX *libctx; 57 58 FFC_PARAMS *ffc_params; 59 int selection; 60 /* All these parameters are used for parameter generation only */ 61 size_t pbits; 62 size_t qbits; 63 unsigned char *seed; /* optional FIPS186-4 param for testing */ 64 size_t seedlen; 65 int gindex; /* optional FIPS186-4 generator index (ignored if -1) */ 66 int gen_type; /* DSA_PARAMGEN_TYPE_FIPS_186_2 or DSA_PARAMGEN_TYPE_FIPS_186_4 */ 67 int pcounter; 68 int hindex; 69 char *mdname; 70 char *mdprops; 71 OSSL_CALLBACK *cb; 72 void *cbarg; 73 OSSL_FIPS_IND_DECLARE 74 }; 75 typedef struct dh_name2id_st{ 76 const char *name; 77 int id; 78 } DSA_GENTYPE_NAME2ID; 79 80 static const DSA_GENTYPE_NAME2ID dsatype2id[] = { 81 #ifdef FIPS_MODULE 82 { "default", DSA_PARAMGEN_TYPE_FIPS_186_4 }, 83 #else 84 { "default", DSA_PARAMGEN_TYPE_FIPS_DEFAULT }, 85 #endif 86 { "fips186_4", DSA_PARAMGEN_TYPE_FIPS_186_4 }, 87 { "fips186_2", DSA_PARAMGEN_TYPE_FIPS_186_2 }, 88 }; 89 90 static int dsa_gen_type_name2id(const char *name) 91 { 92 size_t i; 93 94 for (i = 0; i < OSSL_NELEM(dsatype2id); ++i) { 95 if (OPENSSL_strcasecmp(dsatype2id[i].name, name) == 0) 96 return dsatype2id[i].id; 97 } 98 return -1; 99 } 100 101 static int dsa_key_todata(DSA *dsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[], 102 int include_private) 103 { 104 const BIGNUM *priv = NULL, *pub = NULL; 105 106 if (dsa == NULL) 107 return 0; 108 109 DSA_get0_key(dsa, &pub, &priv); 110 if (include_private 111 && priv != NULL 112 && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PRIV_KEY, priv)) 113 return 0; 114 if (pub != NULL 115 && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PUB_KEY, pub)) 116 return 0; 117 118 return 1; 119 } 120 121 static void *dsa_newdata(void *provctx) 122 { 123 if (!ossl_prov_is_running()) 124 return NULL; 125 return ossl_dsa_new(PROV_LIBCTX_OF(provctx)); 126 } 127 128 static void dsa_freedata(void *keydata) 129 { 130 DSA_free(keydata); 131 } 132 133 static int dsa_has(const void *keydata, int selection) 134 { 135 const DSA *dsa = keydata; 136 int ok = 1; 137 138 if (!ossl_prov_is_running() || dsa == NULL) 139 return 0; 140 if ((selection & DSA_POSSIBLE_SELECTIONS) == 0) 141 return 1; /* the selection is not missing */ 142 143 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 144 ok = ok && (DSA_get0_pub_key(dsa) != NULL); 145 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 146 ok = ok && (DSA_get0_priv_key(dsa) != NULL); 147 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 148 ok = ok && (DSA_get0_p(dsa) != NULL && DSA_get0_g(dsa) != NULL); 149 return ok; 150 } 151 152 static int dsa_match(const void *keydata1, const void *keydata2, int selection) 153 { 154 const DSA *dsa1 = keydata1; 155 const DSA *dsa2 = keydata2; 156 int ok = 1; 157 158 if (!ossl_prov_is_running()) 159 return 0; 160 161 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 162 int key_checked = 0; 163 164 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 165 const BIGNUM *pa = DSA_get0_pub_key(dsa1); 166 const BIGNUM *pb = DSA_get0_pub_key(dsa2); 167 168 if (pa != NULL && pb != NULL) { 169 ok = ok && BN_cmp(pa, pb) == 0; 170 key_checked = 1; 171 } 172 } 173 if (!key_checked 174 && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 175 const BIGNUM *pa = DSA_get0_priv_key(dsa1); 176 const BIGNUM *pb = DSA_get0_priv_key(dsa2); 177 178 if (pa != NULL && pb != NULL) { 179 ok = ok && BN_cmp(pa, pb) == 0; 180 key_checked = 1; 181 } 182 } 183 ok = ok && key_checked; 184 } 185 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { 186 FFC_PARAMS *dsaparams1 = ossl_dsa_get0_params((DSA *)dsa1); 187 FFC_PARAMS *dsaparams2 = ossl_dsa_get0_params((DSA *)dsa2); 188 189 ok = ok && ossl_ffc_params_cmp(dsaparams1, dsaparams2, 1); 190 } 191 return ok; 192 } 193 194 static int dsa_import(void *keydata, int selection, const OSSL_PARAM params[]) 195 { 196 DSA *dsa = keydata; 197 int ok = 1; 198 199 if (!ossl_prov_is_running() || dsa == NULL) 200 return 0; 201 202 if ((selection & DSA_POSSIBLE_SELECTIONS) == 0) 203 return 0; 204 205 /* a key without parameters is meaningless */ 206 ok = ok && ossl_dsa_ffc_params_fromdata(dsa, params); 207 208 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 209 int include_private = 210 selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0; 211 212 ok = ok && ossl_dsa_key_fromdata(dsa, params, include_private); 213 } 214 215 return ok; 216 } 217 218 static int dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, 219 void *cbarg) 220 { 221 DSA *dsa = keydata; 222 OSSL_PARAM_BLD *tmpl; 223 OSSL_PARAM *params = NULL; 224 int ok = 1; 225 226 if (!ossl_prov_is_running() || dsa == NULL) 227 return 0; 228 229 if ((selection & DSA_POSSIBLE_SELECTIONS) == 0) 230 return 0; 231 232 tmpl = OSSL_PARAM_BLD_new(); 233 if (tmpl == NULL) 234 return 0; 235 236 if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) 237 ok = ok && ossl_ffc_params_todata(ossl_dsa_get0_params(dsa), tmpl, NULL); 238 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 239 int include_private = 240 selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0; 241 242 ok = ok && dsa_key_todata(dsa, tmpl, NULL, include_private); 243 } 244 245 if (!ok || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) { 246 ok = 0; 247 goto err; 248 } 249 250 ok = param_cb(params, cbarg); 251 OSSL_PARAM_free(params); 252 err: 253 OSSL_PARAM_BLD_free(tmpl); 254 return ok; 255 } 256 257 /* IMEXPORT = IMPORT + EXPORT */ 258 259 # define DSA_IMEXPORTABLE_PARAMETERS \ 260 OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, NULL, 0), \ 261 OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_Q, NULL, 0), \ 262 OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_G, NULL, 0), \ 263 OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_COFACTOR, NULL, 0), \ 264 OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL), \ 265 OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL), \ 266 OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL), \ 267 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0) 268 # define DSA_IMEXPORTABLE_PUBLIC_KEY \ 269 OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0) 270 # define DSA_IMEXPORTABLE_PRIVATE_KEY \ 271 OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0) 272 static const OSSL_PARAM dsa_all_types[] = { 273 DSA_IMEXPORTABLE_PARAMETERS, 274 DSA_IMEXPORTABLE_PUBLIC_KEY, 275 DSA_IMEXPORTABLE_PRIVATE_KEY, 276 OSSL_PARAM_END 277 }; 278 static const OSSL_PARAM dsa_parameter_types[] = { 279 DSA_IMEXPORTABLE_PARAMETERS, 280 OSSL_PARAM_END 281 }; 282 static const OSSL_PARAM dsa_key_types[] = { 283 DSA_IMEXPORTABLE_PUBLIC_KEY, 284 DSA_IMEXPORTABLE_PRIVATE_KEY, 285 OSSL_PARAM_END 286 }; 287 static const OSSL_PARAM *dsa_types[] = { 288 NULL, /* Index 0 = none of them */ 289 dsa_parameter_types, /* Index 1 = parameter types */ 290 dsa_key_types, /* Index 2 = key types */ 291 dsa_all_types /* Index 3 = 1 + 2 */ 292 }; 293 294 static const OSSL_PARAM *dsa_imexport_types(int selection) 295 { 296 int type_select = 0; 297 298 if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) 299 type_select += 1; 300 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) 301 type_select += 2; 302 return dsa_types[type_select]; 303 } 304 305 static const OSSL_PARAM *dsa_import_types(int selection) 306 { 307 return dsa_imexport_types(selection); 308 } 309 310 static const OSSL_PARAM *dsa_export_types(int selection) 311 { 312 return dsa_imexport_types(selection); 313 } 314 315 static ossl_inline int dsa_get_params(void *key, OSSL_PARAM params[]) 316 { 317 DSA *dsa = key; 318 OSSL_PARAM *p; 319 320 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL 321 && !OSSL_PARAM_set_int(p, DSA_bits(dsa))) 322 return 0; 323 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL 324 && !OSSL_PARAM_set_int(p, DSA_security_bits(dsa))) 325 return 0; 326 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL 327 && !OSSL_PARAM_set_int(p, DSA_size(dsa))) 328 return 0; 329 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL 330 && !OSSL_PARAM_set_utf8_string(p, DSA_DEFAULT_MD)) 331 return 0; 332 return ossl_ffc_params_todata(ossl_dsa_get0_params(dsa), NULL, params) 333 && dsa_key_todata(dsa, NULL, params, 1); 334 } 335 336 static const OSSL_PARAM dsa_params[] = { 337 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), 338 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), 339 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), 340 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0), 341 DSA_IMEXPORTABLE_PARAMETERS, 342 DSA_IMEXPORTABLE_PUBLIC_KEY, 343 DSA_IMEXPORTABLE_PRIVATE_KEY, 344 OSSL_PARAM_END 345 }; 346 347 static const OSSL_PARAM *dsa_gettable_params(void *provctx) 348 { 349 return dsa_params; 350 } 351 352 static int dsa_validate_domparams(const DSA *dsa, int checktype) 353 { 354 int status = 0; 355 356 return ossl_dsa_check_params(dsa, checktype, &status); 357 } 358 359 static int dsa_validate_public(const DSA *dsa) 360 { 361 int status = 0; 362 const BIGNUM *pub_key = NULL; 363 364 DSA_get0_key(dsa, &pub_key, NULL); 365 if (pub_key == NULL) 366 return 0; 367 return ossl_dsa_check_pub_key(dsa, pub_key, &status); 368 } 369 370 static int dsa_validate_private(const DSA *dsa) 371 { 372 int status = 0; 373 const BIGNUM *priv_key = NULL; 374 375 DSA_get0_key(dsa, NULL, &priv_key); 376 if (priv_key == NULL) 377 return 0; 378 return ossl_dsa_check_priv_key(dsa, priv_key, &status); 379 } 380 381 static int dsa_validate(const void *keydata, int selection, int checktype) 382 { 383 const DSA *dsa = keydata; 384 int ok = 1; 385 386 if (!ossl_prov_is_running()) 387 return 0; 388 389 if ((selection & DSA_POSSIBLE_SELECTIONS) == 0) 390 return 1; /* nothing to validate */ 391 392 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 393 ok = ok && dsa_validate_domparams(dsa, checktype); 394 395 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 396 ok = ok && dsa_validate_public(dsa); 397 398 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 399 ok = ok && dsa_validate_private(dsa); 400 401 /* If the whole key is selected, we do a pairwise validation */ 402 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) 403 == OSSL_KEYMGMT_SELECT_KEYPAIR) 404 ok = ok && ossl_dsa_check_pairwise(dsa); 405 return ok; 406 } 407 408 static void *dsa_gen_init(void *provctx, int selection, 409 const OSSL_PARAM params[]) 410 { 411 OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); 412 struct dsa_gen_ctx *gctx = NULL; 413 414 if (!ossl_prov_is_running() || (selection & DSA_POSSIBLE_SELECTIONS) == 0) 415 return NULL; 416 417 if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) { 418 gctx->selection = selection; 419 gctx->libctx = libctx; 420 gctx->pbits = 2048; 421 gctx->qbits = 224; 422 #ifdef FIPS_MODULE 423 gctx->gen_type = DSA_PARAMGEN_TYPE_FIPS_186_4; 424 #else 425 gctx->gen_type = DSA_PARAMGEN_TYPE_FIPS_DEFAULT; 426 #endif 427 gctx->gindex = -1; 428 gctx->pcounter = -1; 429 gctx->hindex = 0; 430 OSSL_FIPS_IND_INIT(gctx) 431 } 432 if (!dsa_gen_set_params(gctx, params)) { 433 dsa_gen_cleanup(gctx); 434 gctx = NULL; 435 } 436 return gctx; 437 } 438 439 static int dsa_gen_set_template(void *genctx, void *templ) 440 { 441 struct dsa_gen_ctx *gctx = genctx; 442 DSA *dsa = templ; 443 444 if (!ossl_prov_is_running() || gctx == NULL || dsa == NULL) 445 return 0; 446 gctx->ffc_params = ossl_dsa_get0_params(dsa); 447 return 1; 448 } 449 450 static int dsa_set_gen_seed(struct dsa_gen_ctx *gctx, unsigned char *seed, 451 size_t seedlen) 452 { 453 OPENSSL_clear_free(gctx->seed, gctx->seedlen); 454 gctx->seed = NULL; 455 gctx->seedlen = 0; 456 if (seed != NULL && seedlen > 0) { 457 gctx->seed = OPENSSL_memdup(seed, seedlen); 458 if (gctx->seed == NULL) 459 return 0; 460 gctx->seedlen = seedlen; 461 } 462 return 1; 463 } 464 465 static int dsa_gen_set_params(void *genctx, const OSSL_PARAM params[]) 466 { 467 struct dsa_gen_ctx *gctx = genctx; 468 const OSSL_PARAM *p; 469 int gen_type = -1; 470 471 if (gctx == NULL) 472 return 0; 473 if (ossl_param_is_empty(params)) 474 return 1; 475 476 if (!OSSL_FIPS_IND_SET_CTX_PARAM(gctx, OSSL_FIPS_IND_SETTABLE0, params, 477 OSSL_PKEY_PARAM_FIPS_SIGN_CHECK)) 478 return 0; 479 480 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_TYPE); 481 if (p != NULL) { 482 if (p->data_type != OSSL_PARAM_UTF8_STRING 483 || ((gen_type = dsa_gen_type_name2id(p->data)) == -1)) { 484 ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); 485 return 0; 486 } 487 488 /* 489 * Only assign context gen_type if it was set by dsa_gen_type_name2id 490 * must be in range: 491 * DSA_PARAMGEN_TYPE_FIPS_186_4 <= gen_type <= DSA_PARAMGEN_TYPE_FIPS_DEFAULT 492 */ 493 if (gen_type != -1) 494 gctx->gen_type = gen_type; 495 } 496 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GINDEX); 497 if (p != NULL 498 && !OSSL_PARAM_get_int(p, &gctx->gindex)) 499 return 0; 500 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PCOUNTER); 501 if (p != NULL 502 && !OSSL_PARAM_get_int(p, &gctx->pcounter)) 503 return 0; 504 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_H); 505 if (p != NULL 506 && !OSSL_PARAM_get_int(p, &gctx->hindex)) 507 return 0; 508 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_SEED); 509 if (p != NULL 510 && (p->data_type != OSSL_PARAM_OCTET_STRING 511 || !dsa_set_gen_seed(gctx, p->data, p->data_size))) 512 return 0; 513 if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PBITS)) != NULL 514 && !OSSL_PARAM_get_size_t(p, &gctx->pbits)) 515 return 0; 516 if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_QBITS)) != NULL 517 && !OSSL_PARAM_get_size_t(p, &gctx->qbits)) 518 return 0; 519 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST); 520 if (p != NULL) { 521 if (p->data_type != OSSL_PARAM_UTF8_STRING) 522 return 0; 523 OPENSSL_free(gctx->mdname); 524 gctx->mdname = OPENSSL_strdup(p->data); 525 if (gctx->mdname == NULL) 526 return 0; 527 } 528 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS); 529 if (p != NULL) { 530 if (p->data_type != OSSL_PARAM_UTF8_STRING) 531 return 0; 532 OPENSSL_free(gctx->mdprops); 533 gctx->mdprops = OPENSSL_strdup(p->data); 534 if (gctx->mdprops == NULL) 535 return 0; 536 } 537 return 1; 538 } 539 540 static const OSSL_PARAM *dsa_gen_settable_params(ossl_unused void *genctx, 541 ossl_unused void *provctx) 542 { 543 static OSSL_PARAM settable[] = { 544 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE, NULL, 0), 545 OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_PBITS, NULL), 546 OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_QBITS, NULL), 547 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST, NULL, 0), 548 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST_PROPS, NULL, 0), 549 OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL), 550 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0), 551 OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL), 552 OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL), 553 OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_PKEY_PARAM_FIPS_SIGN_CHECK) 554 OSSL_PARAM_END 555 }; 556 return settable; 557 } 558 559 static int dsa_gen_get_params(void *genctx, OSSL_PARAM *params) 560 { 561 struct dsa_gen_ctx *gctx = genctx; 562 563 if (gctx == NULL) 564 return 0; 565 if (ossl_param_is_empty(params)) 566 return 1; 567 if (!OSSL_FIPS_IND_GET_CTX_PARAM(gctx, params)) 568 return 0; 569 return 1; 570 } 571 572 static const OSSL_PARAM *dsa_gen_gettable_params(ossl_unused void *ctx, 573 ossl_unused void *provctx) 574 { 575 static const OSSL_PARAM dsa_gen_gettable_params_table[] = { 576 OSSL_FIPS_IND_GETTABLE_CTX_PARAM() 577 OSSL_PARAM_END 578 }; 579 580 return dsa_gen_gettable_params_table; 581 } 582 583 static int dsa_gencb(int p, int n, BN_GENCB *cb) 584 { 585 struct dsa_gen_ctx *gctx = BN_GENCB_get_arg(cb); 586 OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END }; 587 588 params[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL, &p); 589 params[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION, &n); 590 591 return gctx->cb(params, gctx->cbarg); 592 } 593 594 static void *dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) 595 { 596 struct dsa_gen_ctx *gctx = genctx; 597 DSA *dsa = NULL; 598 BN_GENCB *gencb = NULL; 599 int ret = 0; 600 FFC_PARAMS *ffc; 601 602 if (!ossl_prov_is_running() || gctx == NULL) 603 return NULL; 604 605 #ifdef FIPS_MODULE 606 /* 607 * DSA signing is not approved in FIPS 140-3, so there is no 608 * need for DSA keygen either. 609 */ 610 if (!OSSL_FIPS_IND_ON_UNAPPROVED(gctx, OSSL_FIPS_IND_SETTABLE0, 611 gctx->libctx, "DSA", "Keygen", 612 ossl_fips_config_dsa_sign_disallowed)) 613 return 0; 614 #endif 615 616 dsa = ossl_dsa_new(gctx->libctx); 617 if (dsa == NULL) 618 return NULL; 619 620 if (gctx->gen_type == DSA_PARAMGEN_TYPE_FIPS_DEFAULT) 621 gctx->gen_type = (gctx->pbits >= 2048 ? DSA_PARAMGEN_TYPE_FIPS_186_4 : 622 DSA_PARAMGEN_TYPE_FIPS_186_2); 623 624 /* 625 * Do a bounds check on context gen_type. Must be in range: 626 * DSA_PARAMGEN_TYPE_FIPS_186_4 <= gen_type <= DSA_PARAMGEN_TYPE_FIPS_DEFAULT 627 * Noted here as this needs to be adjusted if a new type is 628 * added. 629 */ 630 if (!ossl_assert((gctx->gen_type >= DSA_PARAMGEN_TYPE_FIPS_186_4) 631 && (gctx->gen_type <= DSA_PARAMGEN_TYPE_FIPS_DEFAULT))) { 632 ERR_raise_data(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR, 633 "gen_type set to unsupported value %d", gctx->gen_type); 634 goto end; 635 } 636 637 gctx->cb = osslcb; 638 gctx->cbarg = cbarg; 639 gencb = BN_GENCB_new(); 640 if (gencb != NULL) 641 BN_GENCB_set(gencb, dsa_gencb, genctx); 642 643 ffc = ossl_dsa_get0_params(dsa); 644 /* Copy the template value if one was passed */ 645 if (gctx->ffc_params != NULL 646 && !ossl_ffc_params_copy(ffc, gctx->ffc_params)) 647 goto end; 648 649 if (gctx->seed != NULL 650 && !ossl_ffc_params_set_seed(ffc, gctx->seed, gctx->seedlen)) 651 goto end; 652 if (gctx->gindex != -1) { 653 ossl_ffc_params_set_gindex(ffc, gctx->gindex); 654 if (gctx->pcounter != -1) 655 ossl_ffc_params_set_pcounter(ffc, gctx->pcounter); 656 } else if (gctx->hindex != 0) { 657 ossl_ffc_params_set_h(ffc, gctx->hindex); 658 } 659 if (gctx->mdname != NULL) 660 ossl_ffc_set_digest(ffc, gctx->mdname, gctx->mdprops); 661 662 if ((gctx->selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { 663 664 if (ossl_dsa_generate_ffc_parameters(dsa, gctx->gen_type, 665 gctx->pbits, gctx->qbits, 666 gencb) <= 0) 667 goto end; 668 } 669 ossl_ffc_params_enable_flags(ffc, FFC_PARAM_FLAG_VALIDATE_LEGACY, 670 gctx->gen_type == DSA_PARAMGEN_TYPE_FIPS_186_2); 671 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 672 if (ffc->p == NULL 673 || ffc->q == NULL 674 || ffc->g == NULL) 675 goto end; 676 if (DSA_generate_key(dsa) <= 0) 677 goto end; 678 } 679 ret = 1; 680 end: 681 if (ret <= 0) { 682 DSA_free(dsa); 683 dsa = NULL; 684 } 685 BN_GENCB_free(gencb); 686 return dsa; 687 } 688 689 static void dsa_gen_cleanup(void *genctx) 690 { 691 struct dsa_gen_ctx *gctx = genctx; 692 693 if (gctx == NULL) 694 return; 695 696 OPENSSL_free(gctx->mdname); 697 OPENSSL_free(gctx->mdprops); 698 OPENSSL_clear_free(gctx->seed, gctx->seedlen); 699 OPENSSL_free(gctx); 700 } 701 702 static void *dsa_load(const void *reference, size_t reference_sz) 703 { 704 DSA *dsa = NULL; 705 706 if (ossl_prov_is_running() && reference_sz == sizeof(dsa)) { 707 /* The contents of the reference is the address to our object */ 708 dsa = *(DSA **)reference; 709 /* We grabbed, so we detach it */ 710 *(DSA **)reference = NULL; 711 return dsa; 712 } 713 return NULL; 714 } 715 716 static void *dsa_dup(const void *keydata_from, int selection) 717 { 718 if (ossl_prov_is_running()) 719 return ossl_dsa_dup(keydata_from, selection); 720 return NULL; 721 } 722 723 const OSSL_DISPATCH ossl_dsa_keymgmt_functions[] = { 724 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dsa_newdata }, 725 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dsa_gen_init }, 726 { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))dsa_gen_set_template }, 727 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))dsa_gen_set_params }, 728 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, 729 (void (*)(void))dsa_gen_settable_params }, 730 { OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS, (void (*)(void))dsa_gen_get_params }, 731 { OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS, 732 (void (*)(void))dsa_gen_gettable_params }, 733 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))dsa_gen }, 734 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))dsa_gen_cleanup }, 735 { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))dsa_load }, 736 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))dsa_freedata }, 737 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))dsa_get_params }, 738 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))dsa_gettable_params }, 739 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))dsa_has }, 740 { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))dsa_match }, 741 { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))dsa_validate }, 742 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))dsa_import }, 743 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))dsa_import_types }, 744 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dsa_export }, 745 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dsa_export_types }, 746 { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dsa_dup }, 747 OSSL_DISPATCH_END 748 }; 749