Path: blob/main/crypto/openssl/providers/implementations/keymgmt/dsa_kmgmt.c
108728 views
/*1* Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89/*10* DSA low level APIs are deprecated for public use, but still ok for11* internal use.12*/13#include "internal/deprecated.h"1415#include <openssl/core_dispatch.h>16#include <openssl/core_names.h>17#include <openssl/bn.h>18#include <openssl/err.h>19#include "prov/securitycheck.h"20#include "prov/providercommon.h"21#include "prov/implementations.h"22#include "prov/provider_ctx.h"23#include "crypto/dsa.h"24#include "internal/sizes.h"25#include "internal/nelem.h"26#include "internal/param_build_set.h"2728static OSSL_FUNC_keymgmt_new_fn dsa_newdata;29static OSSL_FUNC_keymgmt_free_fn dsa_freedata;30static OSSL_FUNC_keymgmt_gen_init_fn dsa_gen_init;31static OSSL_FUNC_keymgmt_gen_set_template_fn dsa_gen_set_template;32static OSSL_FUNC_keymgmt_gen_set_params_fn dsa_gen_set_params;33static OSSL_FUNC_keymgmt_gen_settable_params_fn dsa_gen_settable_params;34static OSSL_FUNC_keymgmt_gen_get_params_fn dsa_gen_get_params;35static OSSL_FUNC_keymgmt_gen_gettable_params_fn dsa_gen_gettable_params;36static OSSL_FUNC_keymgmt_gen_fn dsa_gen;37static OSSL_FUNC_keymgmt_gen_cleanup_fn dsa_gen_cleanup;38static OSSL_FUNC_keymgmt_load_fn dsa_load;39static OSSL_FUNC_keymgmt_get_params_fn dsa_get_params;40static OSSL_FUNC_keymgmt_gettable_params_fn dsa_gettable_params;41static OSSL_FUNC_keymgmt_has_fn dsa_has;42static OSSL_FUNC_keymgmt_match_fn dsa_match;43static OSSL_FUNC_keymgmt_validate_fn dsa_validate;44static OSSL_FUNC_keymgmt_import_fn dsa_import;45static OSSL_FUNC_keymgmt_import_types_fn dsa_import_types;46static OSSL_FUNC_keymgmt_export_fn dsa_export;47static OSSL_FUNC_keymgmt_export_types_fn dsa_export_types;48static OSSL_FUNC_keymgmt_dup_fn dsa_dup;4950#define DSA_DEFAULT_MD "SHA256"51#define DSA_POSSIBLE_SELECTIONS \52(OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)5354struct dsa_gen_ctx {55OSSL_LIB_CTX *libctx;5657FFC_PARAMS *ffc_params;58int selection;59/* All these parameters are used for parameter generation only */60size_t pbits;61size_t qbits;62unsigned char *seed; /* optional FIPS186-4 param for testing */63size_t seedlen;64int gindex; /* optional FIPS186-4 generator index (ignored if -1) */65int gen_type; /* DSA_PARAMGEN_TYPE_FIPS_186_2 or DSA_PARAMGEN_TYPE_FIPS_186_4 */66int pcounter;67int hindex;68char *mdname;69char *mdprops;70OSSL_CALLBACK *cb;71void *cbarg;72OSSL_FIPS_IND_DECLARE73};74typedef struct dh_name2id_st {75const char *name;76int id;77} DSA_GENTYPE_NAME2ID;7879static const DSA_GENTYPE_NAME2ID dsatype2id[] = {80#ifdef FIPS_MODULE81{ "default", DSA_PARAMGEN_TYPE_FIPS_186_4 },82#else83{ "default", DSA_PARAMGEN_TYPE_FIPS_DEFAULT },84#endif85{ "fips186_4", DSA_PARAMGEN_TYPE_FIPS_186_4 },86{ "fips186_2", DSA_PARAMGEN_TYPE_FIPS_186_2 },87};8889static int dsa_gen_type_name2id(const char *name)90{91size_t i;9293for (i = 0; i < OSSL_NELEM(dsatype2id); ++i) {94if (OPENSSL_strcasecmp(dsatype2id[i].name, name) == 0)95return dsatype2id[i].id;96}97return -1;98}99100static int dsa_key_todata(DSA *dsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[],101int include_private)102{103const BIGNUM *priv = NULL, *pub = NULL;104105if (dsa == NULL)106return 0;107108DSA_get0_key(dsa, &pub, &priv);109if (include_private110&& priv != NULL111&& !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PRIV_KEY, priv))112return 0;113if (pub != NULL114&& !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PUB_KEY, pub))115return 0;116117return 1;118}119120static void *dsa_newdata(void *provctx)121{122if (!ossl_prov_is_running())123return NULL;124return ossl_dsa_new(PROV_LIBCTX_OF(provctx));125}126127static void dsa_freedata(void *keydata)128{129DSA_free(keydata);130}131132static int dsa_has(const void *keydata, int selection)133{134const DSA *dsa = keydata;135int ok = 1;136137if (!ossl_prov_is_running() || dsa == NULL)138return 0;139if ((selection & DSA_POSSIBLE_SELECTIONS) == 0)140return 1; /* the selection is not missing */141142if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)143ok = ok && (DSA_get0_pub_key(dsa) != NULL);144if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)145ok = ok && (DSA_get0_priv_key(dsa) != NULL);146if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)147ok = ok && (DSA_get0_p(dsa) != NULL && DSA_get0_g(dsa) != NULL);148return ok;149}150151static int dsa_match(const void *keydata1, const void *keydata2, int selection)152{153const DSA *dsa1 = keydata1;154const DSA *dsa2 = keydata2;155int ok = 1;156157if (!ossl_prov_is_running())158return 0;159160if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {161int key_checked = 0;162163if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {164const BIGNUM *pa = DSA_get0_pub_key(dsa1);165const BIGNUM *pb = DSA_get0_pub_key(dsa2);166167if (pa != NULL && pb != NULL) {168ok = ok && BN_cmp(pa, pb) == 0;169key_checked = 1;170}171}172if (!key_checked173&& (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {174const BIGNUM *pa = DSA_get0_priv_key(dsa1);175const BIGNUM *pb = DSA_get0_priv_key(dsa2);176177if (pa != NULL && pb != NULL) {178ok = ok && BN_cmp(pa, pb) == 0;179key_checked = 1;180}181}182ok = ok && key_checked;183}184if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {185FFC_PARAMS *dsaparams1 = ossl_dsa_get0_params((DSA *)dsa1);186FFC_PARAMS *dsaparams2 = ossl_dsa_get0_params((DSA *)dsa2);187188ok = ok && ossl_ffc_params_cmp(dsaparams1, dsaparams2, 1);189}190return ok;191}192193static int dsa_import(void *keydata, int selection, const OSSL_PARAM params[])194{195DSA *dsa = keydata;196int ok = 1;197198if (!ossl_prov_is_running() || dsa == NULL)199return 0;200201if ((selection & DSA_POSSIBLE_SELECTIONS) == 0)202return 0;203204/* a key without parameters is meaningless */205ok = ok && ossl_dsa_ffc_params_fromdata(dsa, params);206207if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {208int include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;209210ok = ok && ossl_dsa_key_fromdata(dsa, params, include_private);211}212213return ok;214}215216static int dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,217void *cbarg)218{219DSA *dsa = keydata;220OSSL_PARAM_BLD *tmpl;221OSSL_PARAM *params = NULL;222int ok = 1;223224if (!ossl_prov_is_running() || dsa == NULL)225return 0;226227if ((selection & DSA_POSSIBLE_SELECTIONS) == 0)228return 0;229230tmpl = OSSL_PARAM_BLD_new();231if (tmpl == NULL)232return 0;233234if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0)235ok = ok && ossl_ffc_params_todata(ossl_dsa_get0_params(dsa), tmpl, NULL);236if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {237int include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;238239ok = ok && dsa_key_todata(dsa, tmpl, NULL, include_private);240}241242if (!ok || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {243ok = 0;244goto err;245}246247ok = param_cb(params, cbarg);248OSSL_PARAM_free(params);249err:250OSSL_PARAM_BLD_free(tmpl);251return ok;252}253254/* IMEXPORT = IMPORT + EXPORT */255256#define DSA_IMEXPORTABLE_PARAMETERS \257OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, NULL, 0), \258OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_Q, NULL, 0), \259OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_G, NULL, 0), \260OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_COFACTOR, NULL, 0), \261OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL), \262OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL), \263OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL), \264OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0)265#define DSA_IMEXPORTABLE_PUBLIC_KEY \266OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0)267#define DSA_IMEXPORTABLE_PRIVATE_KEY \268OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)269static const OSSL_PARAM dsa_all_types[] = {270DSA_IMEXPORTABLE_PARAMETERS,271DSA_IMEXPORTABLE_PUBLIC_KEY,272DSA_IMEXPORTABLE_PRIVATE_KEY,273OSSL_PARAM_END274};275static const OSSL_PARAM dsa_parameter_types[] = {276DSA_IMEXPORTABLE_PARAMETERS,277OSSL_PARAM_END278};279static const OSSL_PARAM dsa_key_types[] = {280DSA_IMEXPORTABLE_PUBLIC_KEY,281DSA_IMEXPORTABLE_PRIVATE_KEY,282OSSL_PARAM_END283};284static const OSSL_PARAM *dsa_types[] = {285NULL, /* Index 0 = none of them */286dsa_parameter_types, /* Index 1 = parameter types */287dsa_key_types, /* Index 2 = key types */288dsa_all_types /* Index 3 = 1 + 2 */289};290291static const OSSL_PARAM *dsa_imexport_types(int selection)292{293int type_select = 0;294295if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0)296type_select += 1;297if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)298type_select += 2;299return dsa_types[type_select];300}301302static const OSSL_PARAM *dsa_import_types(int selection)303{304return dsa_imexport_types(selection);305}306307static const OSSL_PARAM *dsa_export_types(int selection)308{309return dsa_imexport_types(selection);310}311312static ossl_inline int dsa_get_params(void *key, OSSL_PARAM params[])313{314DSA *dsa = key;315OSSL_PARAM *p;316317if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL318&& !OSSL_PARAM_set_int(p, DSA_bits(dsa)))319return 0;320if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL321&& !OSSL_PARAM_set_int(p, DSA_security_bits(dsa)))322return 0;323if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL324&& !OSSL_PARAM_set_int(p, DSA_size(dsa)))325return 0;326if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL327&& !OSSL_PARAM_set_utf8_string(p, DSA_DEFAULT_MD))328return 0;329return ossl_ffc_params_todata(ossl_dsa_get0_params(dsa), NULL, params)330&& dsa_key_todata(dsa, NULL, params, 1);331}332333static const OSSL_PARAM dsa_params[] = {334OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),335OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),336OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),337OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0),338DSA_IMEXPORTABLE_PARAMETERS,339DSA_IMEXPORTABLE_PUBLIC_KEY,340DSA_IMEXPORTABLE_PRIVATE_KEY,341OSSL_PARAM_END342};343344static const OSSL_PARAM *dsa_gettable_params(void *provctx)345{346return dsa_params;347}348349static int dsa_validate_domparams(const DSA *dsa, int checktype)350{351int status = 0;352353return ossl_dsa_check_params(dsa, checktype, &status);354}355356static int dsa_validate_public(const DSA *dsa)357{358int status = 0;359const BIGNUM *pub_key = NULL;360361DSA_get0_key(dsa, &pub_key, NULL);362if (pub_key == NULL)363return 0;364return ossl_dsa_check_pub_key(dsa, pub_key, &status);365}366367static int dsa_validate_private(const DSA *dsa)368{369int status = 0;370const BIGNUM *priv_key = NULL;371372DSA_get0_key(dsa, NULL, &priv_key);373if (priv_key == NULL)374return 0;375return ossl_dsa_check_priv_key(dsa, priv_key, &status);376}377378static int dsa_validate(const void *keydata, int selection, int checktype)379{380const DSA *dsa = keydata;381int ok = 1;382383if (!ossl_prov_is_running())384return 0;385386if ((selection & DSA_POSSIBLE_SELECTIONS) == 0)387return 1; /* nothing to validate */388389if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)390ok = ok && dsa_validate_domparams(dsa, checktype);391392if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)393ok = ok && dsa_validate_public(dsa);394395if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)396ok = ok && dsa_validate_private(dsa);397398/* If the whole key is selected, we do a pairwise validation */399if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR)400== OSSL_KEYMGMT_SELECT_KEYPAIR)401ok = ok && ossl_dsa_check_pairwise(dsa);402return ok;403}404405static void *dsa_gen_init(void *provctx, int selection,406const OSSL_PARAM params[])407{408OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);409struct dsa_gen_ctx *gctx = NULL;410411if (!ossl_prov_is_running() || (selection & DSA_POSSIBLE_SELECTIONS) == 0)412return NULL;413414if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {415gctx->selection = selection;416gctx->libctx = libctx;417gctx->pbits = 2048;418gctx->qbits = 224;419#ifdef FIPS_MODULE420gctx->gen_type = DSA_PARAMGEN_TYPE_FIPS_186_4;421#else422gctx->gen_type = DSA_PARAMGEN_TYPE_FIPS_DEFAULT;423#endif424gctx->gindex = -1;425gctx->pcounter = -1;426gctx->hindex = 0;427OSSL_FIPS_IND_INIT(gctx)428}429if (!dsa_gen_set_params(gctx, params)) {430dsa_gen_cleanup(gctx);431gctx = NULL;432}433return gctx;434}435436static int dsa_gen_set_template(void *genctx, void *templ)437{438struct dsa_gen_ctx *gctx = genctx;439DSA *dsa = templ;440441if (!ossl_prov_is_running() || gctx == NULL || dsa == NULL)442return 0;443gctx->ffc_params = ossl_dsa_get0_params(dsa);444return 1;445}446447static int dsa_set_gen_seed(struct dsa_gen_ctx *gctx, unsigned char *seed,448size_t seedlen)449{450OPENSSL_clear_free(gctx->seed, gctx->seedlen);451gctx->seed = NULL;452gctx->seedlen = 0;453if (seed != NULL && seedlen > 0) {454gctx->seed = OPENSSL_memdup(seed, seedlen);455if (gctx->seed == NULL)456return 0;457gctx->seedlen = seedlen;458}459return 1;460}461462static int dsa_gen_set_params(void *genctx, const OSSL_PARAM params[])463{464struct dsa_gen_ctx *gctx = genctx;465const OSSL_PARAM *p;466int gen_type = -1;467468if (gctx == NULL)469return 0;470if (ossl_param_is_empty(params))471return 1;472473if (!OSSL_FIPS_IND_SET_CTX_PARAM(gctx, OSSL_FIPS_IND_SETTABLE0, params,474OSSL_PKEY_PARAM_FIPS_SIGN_CHECK))475return 0;476477p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_TYPE);478if (p != NULL) {479if (p->data_type != OSSL_PARAM_UTF8_STRING480|| ((gen_type = dsa_gen_type_name2id(p->data)) == -1)) {481ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);482return 0;483}484485/*486* Only assign context gen_type if it was set by dsa_gen_type_name2id487* must be in range:488* DSA_PARAMGEN_TYPE_FIPS_186_4 <= gen_type <= DSA_PARAMGEN_TYPE_FIPS_DEFAULT489*/490if (gen_type != -1)491gctx->gen_type = gen_type;492}493p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GINDEX);494if (p != NULL495&& !OSSL_PARAM_get_int(p, &gctx->gindex))496return 0;497p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PCOUNTER);498if (p != NULL499&& !OSSL_PARAM_get_int(p, &gctx->pcounter))500return 0;501p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_H);502if (p != NULL503&& !OSSL_PARAM_get_int(p, &gctx->hindex))504return 0;505p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_SEED);506if (p != NULL507&& (p->data_type != OSSL_PARAM_OCTET_STRING508|| !dsa_set_gen_seed(gctx, p->data, p->data_size)))509return 0;510if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PBITS)) != NULL511&& !OSSL_PARAM_get_size_t(p, &gctx->pbits))512return 0;513if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_QBITS)) != NULL514&& !OSSL_PARAM_get_size_t(p, &gctx->qbits))515return 0;516p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST);517if (p != NULL) {518if (p->data_type != OSSL_PARAM_UTF8_STRING)519return 0;520OPENSSL_free(gctx->mdname);521gctx->mdname = OPENSSL_strdup(p->data);522if (gctx->mdname == NULL)523return 0;524}525p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);526if (p != NULL) {527if (p->data_type != OSSL_PARAM_UTF8_STRING)528return 0;529OPENSSL_free(gctx->mdprops);530gctx->mdprops = OPENSSL_strdup(p->data);531if (gctx->mdprops == NULL)532return 0;533}534return 1;535}536537static const OSSL_PARAM *dsa_gen_settable_params(ossl_unused void *genctx,538ossl_unused void *provctx)539{540static OSSL_PARAM settable[] = {541OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE, NULL, 0),542OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_PBITS, NULL),543OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_QBITS, NULL),544OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST, NULL, 0),545OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST_PROPS, NULL, 0),546OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL),547OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0),548OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL),549OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL),550OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_PKEY_PARAM_FIPS_SIGN_CHECK)551OSSL_PARAM_END552};553return settable;554}555556static int dsa_gen_get_params(void *genctx, OSSL_PARAM *params)557{558struct dsa_gen_ctx *gctx = genctx;559560if (gctx == NULL)561return 0;562if (ossl_param_is_empty(params))563return 1;564if (!OSSL_FIPS_IND_GET_CTX_PARAM(gctx, params))565return 0;566return 1;567}568569static const OSSL_PARAM *dsa_gen_gettable_params(ossl_unused void *ctx,570ossl_unused void *provctx)571{572static const OSSL_PARAM dsa_gen_gettable_params_table[] = {573OSSL_FIPS_IND_GETTABLE_CTX_PARAM()574OSSL_PARAM_END575};576577return dsa_gen_gettable_params_table;578}579580static int dsa_gencb(int p, int n, BN_GENCB *cb)581{582struct dsa_gen_ctx *gctx = BN_GENCB_get_arg(cb);583OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };584585params[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL, &p);586params[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION, &n);587588return gctx->cb(params, gctx->cbarg);589}590591static void *dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)592{593struct dsa_gen_ctx *gctx = genctx;594DSA *dsa = NULL;595BN_GENCB *gencb = NULL;596int ret = 0;597FFC_PARAMS *ffc;598599if (!ossl_prov_is_running() || gctx == NULL)600return NULL;601602#ifdef FIPS_MODULE603/*604* DSA signing is not approved in FIPS 140-3, so there is no605* need for DSA keygen either.606*/607if (!OSSL_FIPS_IND_ON_UNAPPROVED(gctx, OSSL_FIPS_IND_SETTABLE0,608gctx->libctx, "DSA", "Keygen",609ossl_fips_config_dsa_sign_disallowed))610return 0;611#endif612613dsa = ossl_dsa_new(gctx->libctx);614if (dsa == NULL)615return NULL;616617if (gctx->gen_type == DSA_PARAMGEN_TYPE_FIPS_DEFAULT)618gctx->gen_type = (gctx->pbits >= 2048 ? DSA_PARAMGEN_TYPE_FIPS_186_4 : DSA_PARAMGEN_TYPE_FIPS_186_2);619620/*621* Do a bounds check on context gen_type. Must be in range:622* DSA_PARAMGEN_TYPE_FIPS_186_4 <= gen_type <= DSA_PARAMGEN_TYPE_FIPS_DEFAULT623* Noted here as this needs to be adjusted if a new type is624* added.625*/626if (!ossl_assert((gctx->gen_type >= DSA_PARAMGEN_TYPE_FIPS_186_4)627&& (gctx->gen_type <= DSA_PARAMGEN_TYPE_FIPS_DEFAULT))) {628ERR_raise_data(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR,629"gen_type set to unsupported value %d", gctx->gen_type);630goto end;631}632633gctx->cb = osslcb;634gctx->cbarg = cbarg;635gencb = BN_GENCB_new();636if (gencb != NULL)637BN_GENCB_set(gencb, dsa_gencb, genctx);638639ffc = ossl_dsa_get0_params(dsa);640/* Copy the template value if one was passed */641if (gctx->ffc_params != NULL642&& !ossl_ffc_params_copy(ffc, gctx->ffc_params))643goto end;644645if (gctx->seed != NULL646&& !ossl_ffc_params_set_seed(ffc, gctx->seed, gctx->seedlen))647goto end;648if (gctx->gindex != -1) {649ossl_ffc_params_set_gindex(ffc, gctx->gindex);650if (gctx->pcounter != -1)651ossl_ffc_params_set_pcounter(ffc, gctx->pcounter);652} else if (gctx->hindex != 0) {653ossl_ffc_params_set_h(ffc, gctx->hindex);654}655if (gctx->mdname != NULL)656ossl_ffc_set_digest(ffc, gctx->mdname, gctx->mdprops);657658if ((gctx->selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {659660if (ossl_dsa_generate_ffc_parameters(dsa, gctx->gen_type,661gctx->pbits, gctx->qbits,662gencb)663<= 0)664goto end;665}666ossl_ffc_params_enable_flags(ffc, FFC_PARAM_FLAG_VALIDATE_LEGACY,667gctx->gen_type == DSA_PARAMGEN_TYPE_FIPS_186_2);668if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {669if (ffc->p == NULL670|| ffc->q == NULL671|| ffc->g == NULL)672goto end;673if (DSA_generate_key(dsa) <= 0)674goto end;675}676ret = 1;677end:678if (ret <= 0) {679DSA_free(dsa);680dsa = NULL;681}682BN_GENCB_free(gencb);683return dsa;684}685686static void dsa_gen_cleanup(void *genctx)687{688struct dsa_gen_ctx *gctx = genctx;689690if (gctx == NULL)691return;692693OPENSSL_free(gctx->mdname);694OPENSSL_free(gctx->mdprops);695OPENSSL_clear_free(gctx->seed, gctx->seedlen);696OPENSSL_free(gctx);697}698699static void *dsa_load(const void *reference, size_t reference_sz)700{701DSA *dsa = NULL;702703if (ossl_prov_is_running() && reference_sz == sizeof(dsa)) {704/* The contents of the reference is the address to our object */705dsa = *(DSA **)reference;706/* We grabbed, so we detach it */707*(DSA **)reference = NULL;708return dsa;709}710return NULL;711}712713static void *dsa_dup(const void *keydata_from, int selection)714{715if (ossl_prov_is_running())716return ossl_dsa_dup(keydata_from, selection);717return NULL;718}719720const OSSL_DISPATCH ossl_dsa_keymgmt_functions[] = {721{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dsa_newdata },722{ OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dsa_gen_init },723{ OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))dsa_gen_set_template },724{ OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))dsa_gen_set_params },725{ OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,726(void (*)(void))dsa_gen_settable_params },727{ OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS, (void (*)(void))dsa_gen_get_params },728{ OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS,729(void (*)(void))dsa_gen_gettable_params },730{ OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))dsa_gen },731{ OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))dsa_gen_cleanup },732{ OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))dsa_load },733{ OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))dsa_freedata },734{ OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))dsa_get_params },735{ OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))dsa_gettable_params },736{ OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))dsa_has },737{ OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))dsa_match },738{ OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))dsa_validate },739{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))dsa_import },740{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))dsa_import_types },741{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dsa_export },742{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dsa_export_types },743{ OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dsa_dup },744OSSL_DISPATCH_END745};746747748