Path: blob/main/crypto/openssl/providers/implementations/keymgmt/dsa_kmgmt.c
48292 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 =209selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;210211ok = ok && ossl_dsa_key_fromdata(dsa, params, include_private);212}213214return ok;215}216217static int dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,218void *cbarg)219{220DSA *dsa = keydata;221OSSL_PARAM_BLD *tmpl;222OSSL_PARAM *params = NULL;223int ok = 1;224225if (!ossl_prov_is_running() || dsa == NULL)226return 0;227228if ((selection & DSA_POSSIBLE_SELECTIONS) == 0)229return 0;230231tmpl = OSSL_PARAM_BLD_new();232if (tmpl == NULL)233return 0;234235if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0)236ok = ok && ossl_ffc_params_todata(ossl_dsa_get0_params(dsa), tmpl, NULL);237if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {238int include_private =239selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;240241ok = ok && dsa_key_todata(dsa, tmpl, NULL, include_private);242}243244if (!ok || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {245ok = 0;246goto err;247}248249ok = param_cb(params, cbarg);250OSSL_PARAM_free(params);251err:252OSSL_PARAM_BLD_free(tmpl);253return ok;254}255256/* IMEXPORT = IMPORT + EXPORT */257258# define DSA_IMEXPORTABLE_PARAMETERS \259OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, NULL, 0), \260OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_Q, NULL, 0), \261OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_G, NULL, 0), \262OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_COFACTOR, NULL, 0), \263OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL), \264OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL), \265OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL), \266OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0)267# define DSA_IMEXPORTABLE_PUBLIC_KEY \268OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0)269# define DSA_IMEXPORTABLE_PRIVATE_KEY \270OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)271static const OSSL_PARAM dsa_all_types[] = {272DSA_IMEXPORTABLE_PARAMETERS,273DSA_IMEXPORTABLE_PUBLIC_KEY,274DSA_IMEXPORTABLE_PRIVATE_KEY,275OSSL_PARAM_END276};277static const OSSL_PARAM dsa_parameter_types[] = {278DSA_IMEXPORTABLE_PARAMETERS,279OSSL_PARAM_END280};281static const OSSL_PARAM dsa_key_types[] = {282DSA_IMEXPORTABLE_PUBLIC_KEY,283DSA_IMEXPORTABLE_PRIVATE_KEY,284OSSL_PARAM_END285};286static const OSSL_PARAM *dsa_types[] = {287NULL, /* Index 0 = none of them */288dsa_parameter_types, /* Index 1 = parameter types */289dsa_key_types, /* Index 2 = key types */290dsa_all_types /* Index 3 = 1 + 2 */291};292293static const OSSL_PARAM *dsa_imexport_types(int selection)294{295int type_select = 0;296297if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0)298type_select += 1;299if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)300type_select += 2;301return dsa_types[type_select];302}303304static const OSSL_PARAM *dsa_import_types(int selection)305{306return dsa_imexport_types(selection);307}308309static const OSSL_PARAM *dsa_export_types(int selection)310{311return dsa_imexport_types(selection);312}313314static ossl_inline int dsa_get_params(void *key, OSSL_PARAM params[])315{316DSA *dsa = key;317OSSL_PARAM *p;318319if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL320&& !OSSL_PARAM_set_int(p, DSA_bits(dsa)))321return 0;322if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL323&& !OSSL_PARAM_set_int(p, DSA_security_bits(dsa)))324return 0;325if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL326&& !OSSL_PARAM_set_int(p, DSA_size(dsa)))327return 0;328if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL329&& !OSSL_PARAM_set_utf8_string(p, DSA_DEFAULT_MD))330return 0;331return ossl_ffc_params_todata(ossl_dsa_get0_params(dsa), NULL, params)332&& dsa_key_todata(dsa, NULL, params, 1);333}334335static const OSSL_PARAM dsa_params[] = {336OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),337OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),338OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),339OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0),340DSA_IMEXPORTABLE_PARAMETERS,341DSA_IMEXPORTABLE_PUBLIC_KEY,342DSA_IMEXPORTABLE_PRIVATE_KEY,343OSSL_PARAM_END344};345346static const OSSL_PARAM *dsa_gettable_params(void *provctx)347{348return dsa_params;349}350351static int dsa_validate_domparams(const DSA *dsa, int checktype)352{353int status = 0;354355return ossl_dsa_check_params(dsa, checktype, &status);356}357358static int dsa_validate_public(const DSA *dsa)359{360int status = 0;361const BIGNUM *pub_key = NULL;362363DSA_get0_key(dsa, &pub_key, NULL);364if (pub_key == NULL)365return 0;366return ossl_dsa_check_pub_key(dsa, pub_key, &status);367}368369static int dsa_validate_private(const DSA *dsa)370{371int status = 0;372const BIGNUM *priv_key = NULL;373374DSA_get0_key(dsa, NULL, &priv_key);375if (priv_key == NULL)376return 0;377return ossl_dsa_check_priv_key(dsa, priv_key, &status);378}379380static int dsa_validate(const void *keydata, int selection, int checktype)381{382const DSA *dsa = keydata;383int ok = 1;384385if (!ossl_prov_is_running())386return 0;387388if ((selection & DSA_POSSIBLE_SELECTIONS) == 0)389return 1; /* nothing to validate */390391if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)392ok = ok && dsa_validate_domparams(dsa, checktype);393394if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)395ok = ok && dsa_validate_public(dsa);396397if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)398ok = ok && dsa_validate_private(dsa);399400/* If the whole key is selected, we do a pairwise validation */401if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR)402== OSSL_KEYMGMT_SELECT_KEYPAIR)403ok = ok && ossl_dsa_check_pairwise(dsa);404return ok;405}406407static void *dsa_gen_init(void *provctx, int selection,408const OSSL_PARAM params[])409{410OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);411struct dsa_gen_ctx *gctx = NULL;412413if (!ossl_prov_is_running() || (selection & DSA_POSSIBLE_SELECTIONS) == 0)414return NULL;415416if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {417gctx->selection = selection;418gctx->libctx = libctx;419gctx->pbits = 2048;420gctx->qbits = 224;421#ifdef FIPS_MODULE422gctx->gen_type = DSA_PARAMGEN_TYPE_FIPS_186_4;423#else424gctx->gen_type = DSA_PARAMGEN_TYPE_FIPS_DEFAULT;425#endif426gctx->gindex = -1;427gctx->pcounter = -1;428gctx->hindex = 0;429OSSL_FIPS_IND_INIT(gctx)430}431if (!dsa_gen_set_params(gctx, params)) {432dsa_gen_cleanup(gctx);433gctx = NULL;434}435return gctx;436}437438static int dsa_gen_set_template(void *genctx, void *templ)439{440struct dsa_gen_ctx *gctx = genctx;441DSA *dsa = templ;442443if (!ossl_prov_is_running() || gctx == NULL || dsa == NULL)444return 0;445gctx->ffc_params = ossl_dsa_get0_params(dsa);446return 1;447}448449static int dsa_set_gen_seed(struct dsa_gen_ctx *gctx, unsigned char *seed,450size_t seedlen)451{452OPENSSL_clear_free(gctx->seed, gctx->seedlen);453gctx->seed = NULL;454gctx->seedlen = 0;455if (seed != NULL && seedlen > 0) {456gctx->seed = OPENSSL_memdup(seed, seedlen);457if (gctx->seed == NULL)458return 0;459gctx->seedlen = seedlen;460}461return 1;462}463464static int dsa_gen_set_params(void *genctx, const OSSL_PARAM params[])465{466struct dsa_gen_ctx *gctx = genctx;467const OSSL_PARAM *p;468int gen_type = -1;469470if (gctx == NULL)471return 0;472if (ossl_param_is_empty(params))473return 1;474475if (!OSSL_FIPS_IND_SET_CTX_PARAM(gctx, OSSL_FIPS_IND_SETTABLE0, params,476OSSL_PKEY_PARAM_FIPS_SIGN_CHECK))477return 0;478479p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_TYPE);480if (p != NULL) {481if (p->data_type != OSSL_PARAM_UTF8_STRING482|| ((gen_type = dsa_gen_type_name2id(p->data)) == -1)) {483ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);484return 0;485}486487/*488* Only assign context gen_type if it was set by dsa_gen_type_name2id489* must be in range:490* DSA_PARAMGEN_TYPE_FIPS_186_4 <= gen_type <= DSA_PARAMGEN_TYPE_FIPS_DEFAULT491*/492if (gen_type != -1)493gctx->gen_type = gen_type;494}495p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GINDEX);496if (p != NULL497&& !OSSL_PARAM_get_int(p, &gctx->gindex))498return 0;499p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PCOUNTER);500if (p != NULL501&& !OSSL_PARAM_get_int(p, &gctx->pcounter))502return 0;503p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_H);504if (p != NULL505&& !OSSL_PARAM_get_int(p, &gctx->hindex))506return 0;507p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_SEED);508if (p != NULL509&& (p->data_type != OSSL_PARAM_OCTET_STRING510|| !dsa_set_gen_seed(gctx, p->data, p->data_size)))511return 0;512if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PBITS)) != NULL513&& !OSSL_PARAM_get_size_t(p, &gctx->pbits))514return 0;515if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_QBITS)) != NULL516&& !OSSL_PARAM_get_size_t(p, &gctx->qbits))517return 0;518p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST);519if (p != NULL) {520if (p->data_type != OSSL_PARAM_UTF8_STRING)521return 0;522OPENSSL_free(gctx->mdname);523gctx->mdname = OPENSSL_strdup(p->data);524if (gctx->mdname == NULL)525return 0;526}527p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);528if (p != NULL) {529if (p->data_type != OSSL_PARAM_UTF8_STRING)530return 0;531OPENSSL_free(gctx->mdprops);532gctx->mdprops = OPENSSL_strdup(p->data);533if (gctx->mdprops == NULL)534return 0;535}536return 1;537}538539static const OSSL_PARAM *dsa_gen_settable_params(ossl_unused void *genctx,540ossl_unused void *provctx)541{542static OSSL_PARAM settable[] = {543OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE, NULL, 0),544OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_PBITS, NULL),545OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_QBITS, NULL),546OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST, NULL, 0),547OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST_PROPS, NULL, 0),548OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL),549OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0),550OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL),551OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL),552OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_PKEY_PARAM_FIPS_SIGN_CHECK)553OSSL_PARAM_END554};555return settable;556}557558static int dsa_gen_get_params(void *genctx, OSSL_PARAM *params)559{560struct dsa_gen_ctx *gctx = genctx;561562if (gctx == NULL)563return 0;564if (ossl_param_is_empty(params))565return 1;566if (!OSSL_FIPS_IND_GET_CTX_PARAM(gctx, params))567return 0;568return 1;569}570571static const OSSL_PARAM *dsa_gen_gettable_params(ossl_unused void *ctx,572ossl_unused void *provctx)573{574static const OSSL_PARAM dsa_gen_gettable_params_table[] = {575OSSL_FIPS_IND_GETTABLE_CTX_PARAM()576OSSL_PARAM_END577};578579return dsa_gen_gettable_params_table;580}581582static int dsa_gencb(int p, int n, BN_GENCB *cb)583{584struct dsa_gen_ctx *gctx = BN_GENCB_get_arg(cb);585OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };586587params[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL, &p);588params[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION, &n);589590return gctx->cb(params, gctx->cbarg);591}592593static void *dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)594{595struct dsa_gen_ctx *gctx = genctx;596DSA *dsa = NULL;597BN_GENCB *gencb = NULL;598int ret = 0;599FFC_PARAMS *ffc;600601if (!ossl_prov_is_running() || gctx == NULL)602return NULL;603604#ifdef FIPS_MODULE605/*606* DSA signing is not approved in FIPS 140-3, so there is no607* need for DSA keygen either.608*/609if (!OSSL_FIPS_IND_ON_UNAPPROVED(gctx, OSSL_FIPS_IND_SETTABLE0,610gctx->libctx, "DSA", "Keygen",611ossl_fips_config_dsa_sign_disallowed))612return 0;613#endif614615dsa = ossl_dsa_new(gctx->libctx);616if (dsa == NULL)617return NULL;618619if (gctx->gen_type == DSA_PARAMGEN_TYPE_FIPS_DEFAULT)620gctx->gen_type = (gctx->pbits >= 2048 ? DSA_PARAMGEN_TYPE_FIPS_186_4 :621DSA_PARAMGEN_TYPE_FIPS_186_2);622623/*624* Do a bounds check on context gen_type. Must be in range:625* DSA_PARAMGEN_TYPE_FIPS_186_4 <= gen_type <= DSA_PARAMGEN_TYPE_FIPS_DEFAULT626* Noted here as this needs to be adjusted if a new type is627* added.628*/629if (!ossl_assert((gctx->gen_type >= DSA_PARAMGEN_TYPE_FIPS_186_4)630&& (gctx->gen_type <= DSA_PARAMGEN_TYPE_FIPS_DEFAULT))) {631ERR_raise_data(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR,632"gen_type set to unsupported value %d", gctx->gen_type);633goto end;634}635636gctx->cb = osslcb;637gctx->cbarg = cbarg;638gencb = BN_GENCB_new();639if (gencb != NULL)640BN_GENCB_set(gencb, dsa_gencb, genctx);641642ffc = ossl_dsa_get0_params(dsa);643/* Copy the template value if one was passed */644if (gctx->ffc_params != NULL645&& !ossl_ffc_params_copy(ffc, gctx->ffc_params))646goto end;647648if (gctx->seed != NULL649&& !ossl_ffc_params_set_seed(ffc, gctx->seed, gctx->seedlen))650goto end;651if (gctx->gindex != -1) {652ossl_ffc_params_set_gindex(ffc, gctx->gindex);653if (gctx->pcounter != -1)654ossl_ffc_params_set_pcounter(ffc, gctx->pcounter);655} else if (gctx->hindex != 0) {656ossl_ffc_params_set_h(ffc, gctx->hindex);657}658if (gctx->mdname != NULL)659ossl_ffc_set_digest(ffc, gctx->mdname, gctx->mdprops);660661if ((gctx->selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {662663if (ossl_dsa_generate_ffc_parameters(dsa, gctx->gen_type,664gctx->pbits, gctx->qbits,665gencb) <= 0)666goto end;667}668ossl_ffc_params_enable_flags(ffc, FFC_PARAM_FLAG_VALIDATE_LEGACY,669gctx->gen_type == DSA_PARAMGEN_TYPE_FIPS_186_2);670if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {671if (ffc->p == NULL672|| ffc->q == NULL673|| ffc->g == NULL)674goto end;675if (DSA_generate_key(dsa) <= 0)676goto end;677}678ret = 1;679end:680if (ret <= 0) {681DSA_free(dsa);682dsa = NULL;683}684BN_GENCB_free(gencb);685return dsa;686}687688static void dsa_gen_cleanup(void *genctx)689{690struct dsa_gen_ctx *gctx = genctx;691692if (gctx == NULL)693return;694695OPENSSL_free(gctx->mdname);696OPENSSL_free(gctx->mdprops);697OPENSSL_clear_free(gctx->seed, gctx->seedlen);698OPENSSL_free(gctx);699}700701static void *dsa_load(const void *reference, size_t reference_sz)702{703DSA *dsa = NULL;704705if (ossl_prov_is_running() && reference_sz == sizeof(dsa)) {706/* The contents of the reference is the address to our object */707dsa = *(DSA **)reference;708/* We grabbed, so we detach it */709*(DSA **)reference = NULL;710return dsa;711}712return NULL;713}714715static void *dsa_dup(const void *keydata_from, int selection)716{717if (ossl_prov_is_running())718return ossl_dsa_dup(keydata_from, selection);719return NULL;720}721722const OSSL_DISPATCH ossl_dsa_keymgmt_functions[] = {723{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dsa_newdata },724{ OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dsa_gen_init },725{ OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))dsa_gen_set_template },726{ OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))dsa_gen_set_params },727{ OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,728(void (*)(void))dsa_gen_settable_params },729{ OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS, (void (*)(void))dsa_gen_get_params },730{ OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS,731(void (*)(void))dsa_gen_gettable_params },732{ OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))dsa_gen },733{ OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))dsa_gen_cleanup },734{ OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))dsa_load },735{ OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))dsa_freedata },736{ OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))dsa_get_params },737{ OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))dsa_gettable_params },738{ OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))dsa_has },739{ OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))dsa_match },740{ OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))dsa_validate },741{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))dsa_import },742{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))dsa_import_types },743{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dsa_export },744{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dsa_export_types },745{ OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dsa_dup },746OSSL_DISPATCH_END747};748749750