| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085 |
- /*
- * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
- /*
- * DSA low level APIs are deprecated for public use, but still ok for
- * internal use.
- */
- #include "internal/deprecated.h"
- #include <string.h>
- #include <openssl/crypto.h>
- #include <openssl/core_dispatch.h>
- #include <openssl/core_names.h>
- #include <openssl/err.h>
- #include <openssl/dsa.h>
- #include <openssl/params.h>
- #include <openssl/evp.h>
- #include <openssl/proverr.h>
- #include "internal/nelem.h"
- #include "internal/sizes.h"
- #include "internal/cryptlib.h"
- #include "prov/providercommon.h"
- #include "prov/implementations.h"
- #include "prov/provider_ctx.h"
- #include "prov/securitycheck.h"
- #include "prov/der_dsa.h"
- #include "crypto/dsa.h"
- static OSSL_FUNC_signature_newctx_fn dsa_newctx;
- static OSSL_FUNC_signature_sign_init_fn dsa_sign_init;
- static OSSL_FUNC_signature_verify_init_fn dsa_verify_init;
- static OSSL_FUNC_signature_sign_fn dsa_sign;
- static OSSL_FUNC_signature_sign_message_update_fn dsa_signverify_message_update;
- static OSSL_FUNC_signature_sign_message_final_fn dsa_sign_message_final;
- static OSSL_FUNC_signature_verify_fn dsa_verify;
- static OSSL_FUNC_signature_verify_message_update_fn dsa_signverify_message_update;
- static OSSL_FUNC_signature_verify_message_final_fn dsa_verify_message_final;
- static OSSL_FUNC_signature_digest_sign_init_fn dsa_digest_sign_init;
- static OSSL_FUNC_signature_digest_sign_update_fn dsa_digest_signverify_update;
- static OSSL_FUNC_signature_digest_sign_final_fn dsa_digest_sign_final;
- static OSSL_FUNC_signature_digest_verify_init_fn dsa_digest_verify_init;
- static OSSL_FUNC_signature_digest_verify_update_fn dsa_digest_signverify_update;
- static OSSL_FUNC_signature_digest_verify_final_fn dsa_digest_verify_final;
- static OSSL_FUNC_signature_freectx_fn dsa_freectx;
- static OSSL_FUNC_signature_dupctx_fn dsa_dupctx;
- static OSSL_FUNC_signature_query_key_types_fn dsa_sigalg_query_key_types;
- static OSSL_FUNC_signature_get_ctx_params_fn dsa_get_ctx_params;
- static OSSL_FUNC_signature_gettable_ctx_params_fn dsa_gettable_ctx_params;
- static OSSL_FUNC_signature_set_ctx_params_fn dsa_set_ctx_params;
- static OSSL_FUNC_signature_settable_ctx_params_fn dsa_settable_ctx_params;
- static OSSL_FUNC_signature_get_ctx_md_params_fn dsa_get_ctx_md_params;
- static OSSL_FUNC_signature_gettable_ctx_md_params_fn dsa_gettable_ctx_md_params;
- static OSSL_FUNC_signature_set_ctx_md_params_fn dsa_set_ctx_md_params;
- static OSSL_FUNC_signature_settable_ctx_md_params_fn dsa_settable_ctx_md_params;
- static OSSL_FUNC_signature_set_ctx_params_fn dsa_sigalg_set_ctx_params;
- static OSSL_FUNC_signature_settable_ctx_params_fn dsa_sigalg_settable_ctx_params;
- /*
- * What's passed as an actual key is defined by the KEYMGMT interface.
- * We happen to know that our KEYMGMT simply passes DSA structures, so
- * we use that here too.
- */
- typedef struct {
- OSSL_LIB_CTX *libctx;
- char *propq;
- DSA *dsa;
- /* |operation| reuses EVP's operation bitfield */
- int operation;
- /*
- * Flag to determine if a full sigalg is run (1) or if a composable
- * signature algorithm is run (0).
- *
- * When a full sigalg is run (1), this currently affects the following
- * other flags, which are to remain untouched after their initialization:
- *
- * - flag_allow_md (initialized to 0)
- */
- unsigned int flag_sigalg : 1;
- /*
- * Flag to determine if the hash function can be changed (1) or not (0)
- * Because it's dangerous to change during a DigestSign or DigestVerify
- * operation, this flag is cleared by their Init function, and set again
- * by their Final function.
- */
- unsigned int flag_allow_md : 1;
- /* If this is set to 1 then the generated k is not random */
- unsigned int nonce_type;
- /* The Algorithm Identifier of the combined signature algorithm */
- unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE];
- size_t aid_len;
- /* main digest */
- char mdname[OSSL_MAX_NAME_SIZE];
- EVP_MD *md;
- EVP_MD_CTX *mdctx;
- /* Signature, for verification */
- unsigned char *sig;
- size_t siglen;
- OSSL_FIPS_IND_DECLARE
- } PROV_DSA_CTX;
- static size_t dsa_get_md_size(const PROV_DSA_CTX *pdsactx)
- {
- int md_size;
- if (pdsactx->md != NULL) {
- md_size = EVP_MD_get_size(pdsactx->md);
- if (md_size <= 0)
- return 0;
- return (size_t)md_size;
- }
- return 0;
- }
- static void *dsa_newctx(void *provctx, const char *propq)
- {
- PROV_DSA_CTX *pdsactx;
- if (!ossl_prov_is_running())
- return NULL;
- pdsactx = OPENSSL_zalloc(sizeof(PROV_DSA_CTX));
- if (pdsactx == NULL)
- return NULL;
- pdsactx->libctx = PROV_LIBCTX_OF(provctx);
- pdsactx->flag_allow_md = 1;
- OSSL_FIPS_IND_INIT(pdsactx)
- if (propq != NULL && (pdsactx->propq = OPENSSL_strdup(propq)) == NULL) {
- OPENSSL_free(pdsactx);
- pdsactx = NULL;
- }
- return pdsactx;
- }
- static int dsa_setup_md(PROV_DSA_CTX *ctx,
- const char *mdname, const char *mdprops,
- const char *desc)
- {
- EVP_MD *md = NULL;
- if (mdprops == NULL)
- mdprops = ctx->propq;
- if (mdname != NULL) {
- WPACKET pkt;
- int md_nid;
- size_t mdname_len = strlen(mdname);
- unsigned char *aid = NULL;
- md = EVP_MD_fetch(ctx->libctx, mdname, mdprops);
- md_nid = ossl_digest_get_approved_nid(md);
- if (md == NULL) {
- ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
- "%s could not be fetched", mdname);
- goto err;
- }
- if (md_nid == NID_undef) {
- ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,
- "digest=%s", mdname);
- goto err;
- }
- if (mdname_len >= sizeof(ctx->mdname)) {
- ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
- "%s exceeds name buffer length", mdname);
- goto err;
- }
- /* XOF digests don't work */
- if (EVP_MD_xof(md)) {
- ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);
- goto err;
- }
- #ifdef FIPS_MODULE
- {
- int sha1_allowed
- = ((ctx->operation
- & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_SIGNMSG)) == 0);
- if (!ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND_GET(ctx),
- OSSL_FIPS_IND_SETTABLE1,
- ctx->libctx,
- md_nid, sha1_allowed, 0, desc,
- ossl_fips_config_signature_digest_check))
- goto err;
- }
- #endif
- if (!ctx->flag_allow_md) {
- if (ctx->mdname[0] != '\0'
- && !EVP_MD_is_a(md, ctx->mdname)) {
- ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,
- "digest %s != %s", mdname, ctx->mdname);
- goto err;
- }
- EVP_MD_free(md);
- return 1;
- }
- EVP_MD_CTX_free(ctx->mdctx);
- EVP_MD_free(ctx->md);
- /*
- * We do not care about DER writing errors.
- * All it really means is that for some reason, there's no
- * AlgorithmIdentifier to be had, but the operation itself is
- * still valid, just as long as it's not used to construct
- * anything that needs an AlgorithmIdentifier.
- */
- ctx->aid_len = 0;
- if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf))
- && ossl_DER_w_algorithmIdentifier_DSA_with_MD(&pkt, -1, ctx->dsa,
- md_nid)
- && WPACKET_finish(&pkt)) {
- WPACKET_get_total_written(&pkt, &ctx->aid_len);
- aid = WPACKET_get_curr(&pkt);
- }
- WPACKET_cleanup(&pkt);
- if (aid != NULL && ctx->aid_len != 0)
- memmove(ctx->aid_buf, aid, ctx->aid_len);
- ctx->mdctx = NULL;
- ctx->md = md;
- OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname));
- }
- return 1;
- err:
- EVP_MD_free(md);
- return 0;
- }
- #ifdef FIPS_MODULE
- static int dsa_sign_check_approved(PROV_DSA_CTX *ctx, int signing,
- const char *desc)
- {
- /* DSA Signing is not approved in FIPS 140-3 */
- if (signing
- && !OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE2,
- ctx->libctx, desc, "DSA",
- ossl_fips_config_dsa_sign_disallowed))
- return 0;
- return 1;
- }
- static int dsa_check_key(PROV_DSA_CTX *ctx, int sign, const char *desc)
- {
- int approved = ossl_dsa_check_key(ctx->dsa, sign);
- if (!approved) {
- if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
- ctx->libctx, desc, "DSA Key",
- ossl_fips_config_signature_digest_check)) {
- ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
- return 0;
- }
- }
- return 1;
- }
- #endif
- static int
- dsa_signverify_init(void *vpdsactx, void *vdsa,
- OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params,
- const OSSL_PARAM params[], int operation,
- const char *desc)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- if (!ossl_prov_is_running()
- || pdsactx == NULL)
- return 0;
- if (vdsa == NULL && pdsactx->dsa == NULL) {
- ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
- return 0;
- }
- if (vdsa != NULL) {
- if (!DSA_up_ref(vdsa))
- return 0;
- DSA_free(pdsactx->dsa);
- pdsactx->dsa = vdsa;
- }
- pdsactx->operation = operation;
- OSSL_FIPS_IND_SET_APPROVED(pdsactx)
- if (!set_ctx_params(pdsactx, params))
- return 0;
- #ifdef FIPS_MODULE
- {
- int operation_is_sign
- = (operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_SIGNMSG)) != 0;
- if (!dsa_sign_check_approved(pdsactx, operation_is_sign, desc))
- return 0;
- if (!dsa_check_key(pdsactx, operation_is_sign, desc))
- return 0;
- }
- #endif
- return 1;
- }
- static int dsa_sign_init(void *vpdsactx, void *vdsa, const OSSL_PARAM params[])
- {
- return dsa_signverify_init(vpdsactx, vdsa, dsa_set_ctx_params, params,
- EVP_PKEY_OP_SIGN, "DSA Sign Init");
- }
- /*
- * Sign tbs without digesting it first. This is suitable for "primitive"
- * signing and signing the digest of a message, i.e. should be used with
- * implementations of the keytype related algorithms.
- */
- static int dsa_sign_directly(void *vpdsactx,
- unsigned char *sig, size_t *siglen, size_t sigsize,
- const unsigned char *tbs, size_t tbslen)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- int ret;
- unsigned int sltmp;
- size_t dsasize = DSA_size(pdsactx->dsa);
- size_t mdsize = dsa_get_md_size(pdsactx);
- if (!ossl_prov_is_running())
- return 0;
- #ifdef FIPS_MODULE
- if (!dsa_sign_check_approved(pdsactx, 1, "Sign"))
- return 0;
- #endif
- if (sig == NULL) {
- *siglen = dsasize;
- return 1;
- }
- if (sigsize < dsasize)
- return 0;
- if (mdsize != 0 && tbslen != mdsize)
- return 0;
- ret = ossl_dsa_sign_int(0, tbs, tbslen, sig, &sltmp, pdsactx->dsa,
- pdsactx->nonce_type, pdsactx->mdname,
- pdsactx->libctx, pdsactx->propq);
- if (ret <= 0)
- return 0;
- *siglen = sltmp;
- return 1;
- }
- static int dsa_signverify_message_update(void *vpdsactx,
- const unsigned char *data,
- size_t datalen)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- if (pdsactx == NULL)
- return 0;
- return EVP_DigestUpdate(pdsactx->mdctx, data, datalen);
- }
- static int dsa_sign_message_final(void *vpdsactx, unsigned char *sig,
- size_t *siglen, size_t sigsize)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- unsigned char digest[EVP_MAX_MD_SIZE];
- unsigned int dlen = 0;
- if (!ossl_prov_is_running() || pdsactx == NULL || pdsactx->mdctx == NULL)
- return 0;
- /*
- * If sig is NULL then we're just finding out the sig size. Other fields
- * are ignored. Defer to dsa_sign.
- */
- if (sig != NULL) {
- /*
- * When this function is used through dsa_digest_sign_final(),
- * there is the possibility that some externally provided digests
- * exceed EVP_MAX_MD_SIZE. We should probably handle that
- * somehow but that problem is much larger than just in DSA.
- */
- if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen))
- return 0;
- }
- return dsa_sign_directly(vpdsactx, sig, siglen, sigsize, digest, dlen);
- }
- /*
- * If signing a message, digest tbs and sign the result.
- * Otherwise, sign tbs directly.
- */
- static int dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen,
- size_t sigsize, const unsigned char *tbs, size_t tbslen)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- if (pdsactx->operation == EVP_PKEY_OP_SIGNMSG) {
- /*
- * If |sig| is NULL, the caller is only looking for the sig length.
- * DO NOT update the input in this case.
- */
- if (sig == NULL)
- return dsa_sign_message_final(pdsactx, sig, siglen, sigsize);
- if (dsa_signverify_message_update(pdsactx, tbs, tbslen) <= 0)
- return 0;
- return dsa_sign_message_final(pdsactx, sig, siglen, sigsize);
- }
- return dsa_sign_directly(pdsactx, sig, siglen, sigsize, tbs, tbslen);
- }
- static int dsa_verify_init(void *vpdsactx, void *vdsa,
- const OSSL_PARAM params[])
- {
- return dsa_signverify_init(vpdsactx, vdsa, dsa_set_ctx_params, params,
- EVP_PKEY_OP_VERIFY, "DSA Verify Init");
- }
- static int dsa_verify_directly(void *vpdsactx,
- const unsigned char *sig, size_t siglen,
- const unsigned char *tbs, size_t tbslen)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- size_t mdsize = dsa_get_md_size(pdsactx);
- if (!ossl_prov_is_running() || (mdsize != 0 && tbslen != mdsize))
- return 0;
- return DSA_verify(0, tbs, tbslen, sig, siglen, pdsactx->dsa);
- }
- static int dsa_verify_set_sig(void *vpdsactx,
- const unsigned char *sig, size_t siglen)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- OSSL_PARAM params[2];
- params[0] =
- OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE,
- (unsigned char *)sig, siglen);
- params[1] = OSSL_PARAM_construct_end();
- return dsa_sigalg_set_ctx_params(pdsactx, params);
- }
- static int dsa_verify_message_final(void *vpdsactx)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- unsigned char digest[EVP_MAX_MD_SIZE];
- unsigned int dlen = 0;
- if (!ossl_prov_is_running())
- return 0;
- if (pdsactx == NULL || pdsactx->mdctx == NULL)
- return 0;
- /*
- * The digests used here are all known (see dsa_get_md_nid()), so they
- * should not exceed the internal buffer size of EVP_MAX_MD_SIZE.
- */
- if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen))
- return 0;
- return dsa_verify_directly(vpdsactx, pdsactx->sig, pdsactx->siglen,
- digest, dlen);
- }
- /*
- * If verifying a message, digest tbs and verify the result.
- * Otherwise, verify tbs directly.
- */
- static int dsa_verify(void *vpdsactx,
- const unsigned char *sig, size_t siglen,
- const unsigned char *tbs, size_t tbslen)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- if (pdsactx->operation == EVP_PKEY_OP_VERIFYMSG) {
- if (dsa_verify_set_sig(pdsactx, sig, siglen) <= 0)
- return 0;
- if (dsa_signverify_message_update(pdsactx, tbs, tbslen) <= 0)
- return 0;
- return dsa_verify_message_final(pdsactx);
- }
- return dsa_verify_directly(pdsactx, sig, siglen, tbs, tbslen);
- }
- /* DigestSign/DigestVerify wrappers */
- static int dsa_digest_signverify_init(void *vpdsactx, const char *mdname,
- void *vdsa, const OSSL_PARAM params[],
- int operation, const char *desc)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- if (!ossl_prov_is_running())
- return 0;
- if (!dsa_signverify_init(vpdsactx, vdsa, dsa_set_ctx_params, params,
- operation, desc))
- return 0;
- if (mdname != NULL
- /* was dsa_setup_md already called in dsa_signverify_init()? */
- && (mdname[0] == '\0' || OPENSSL_strcasecmp(pdsactx->mdname, mdname) != 0)
- && !dsa_setup_md(pdsactx, mdname, NULL, desc))
- return 0;
- pdsactx->flag_allow_md = 0;
- if (pdsactx->mdctx == NULL) {
- pdsactx->mdctx = EVP_MD_CTX_new();
- if (pdsactx->mdctx == NULL)
- goto error;
- }
- if (!EVP_DigestInit_ex2(pdsactx->mdctx, pdsactx->md, params))
- goto error;
- return 1;
- error:
- EVP_MD_CTX_free(pdsactx->mdctx);
- pdsactx->mdctx = NULL;
- return 0;
- }
- static int dsa_digest_sign_init(void *vpdsactx, const char *mdname,
- void *vdsa, const OSSL_PARAM params[])
- {
- return dsa_digest_signverify_init(vpdsactx, mdname, vdsa, params,
- EVP_PKEY_OP_SIGNMSG,
- "DSA Digest Sign Init");
- }
- static int dsa_digest_signverify_update(void *vpdsactx, const unsigned char *data,
- size_t datalen)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- if (pdsactx == NULL)
- return 0;
- /* Sigalg implementations shouldn't do digest_sign */
- if (pdsactx->flag_sigalg)
- return 0;
- return dsa_signverify_message_update(vpdsactx, data, datalen);
- }
- static int dsa_digest_sign_final(void *vpdsactx, unsigned char *sig,
- size_t *siglen, size_t sigsize)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- int ok = 0;
- if (pdsactx == NULL)
- return 0;
- /* Sigalg implementations shouldn't do digest_sign */
- if (pdsactx->flag_sigalg)
- return 0;
- ok = dsa_sign_message_final(pdsactx, sig, siglen, sigsize);
- pdsactx->flag_allow_md = 1;
- return ok;
- }
- static int dsa_digest_verify_init(void *vpdsactx, const char *mdname,
- void *vdsa, const OSSL_PARAM params[])
- {
- return dsa_digest_signverify_init(vpdsactx, mdname, vdsa, params,
- EVP_PKEY_OP_VERIFYMSG,
- "DSA Digest Verify Init");
- }
- int dsa_digest_verify_final(void *vpdsactx, const unsigned char *sig,
- size_t siglen)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- int ok = 0;
- if (pdsactx == NULL)
- return 0;
- /* Sigalg implementations shouldn't do digest_verify */
- if (pdsactx->flag_sigalg)
- return 0;
- if (dsa_verify_set_sig(pdsactx, sig, siglen))
- ok = dsa_verify_message_final(vpdsactx);
- pdsactx->flag_allow_md = 1;
- return ok;
- }
- static void dsa_freectx(void *vpdsactx)
- {
- PROV_DSA_CTX *ctx = (PROV_DSA_CTX *)vpdsactx;
- EVP_MD_CTX_free(ctx->mdctx);
- EVP_MD_free(ctx->md);
- OPENSSL_free(ctx->sig);
- OPENSSL_free(ctx->propq);
- DSA_free(ctx->dsa);
- OPENSSL_free(ctx);
- }
- static void *dsa_dupctx(void *vpdsactx)
- {
- PROV_DSA_CTX *srcctx = (PROV_DSA_CTX *)vpdsactx;
- PROV_DSA_CTX *dstctx;
- if (!ossl_prov_is_running())
- return NULL;
- dstctx = OPENSSL_zalloc(sizeof(*srcctx));
- if (dstctx == NULL)
- return NULL;
- *dstctx = *srcctx;
- dstctx->dsa = NULL;
- dstctx->propq = NULL;
- if (srcctx->dsa != NULL && !DSA_up_ref(srcctx->dsa))
- goto err;
- dstctx->dsa = srcctx->dsa;
- if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md))
- goto err;
- dstctx->md = srcctx->md;
- if (srcctx->mdctx != NULL) {
- dstctx->mdctx = EVP_MD_CTX_new();
- if (dstctx->mdctx == NULL
- || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx))
- goto err;
- }
- if (srcctx->propq != NULL) {
- dstctx->propq = OPENSSL_strdup(srcctx->propq);
- if (dstctx->propq == NULL)
- goto err;
- }
- return dstctx;
- err:
- dsa_freectx(dstctx);
- return NULL;
- }
- static int dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- OSSL_PARAM *p;
- if (pdsactx == NULL)
- return 0;
- p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
- if (p != NULL
- && !OSSL_PARAM_set_octet_string(p,
- pdsactx->aid_len == 0 ? NULL : pdsactx->aid_buf,
- pdsactx->aid_len))
- return 0;
- p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST);
- if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdsactx->mdname))
- return 0;
- p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE);
- if (p != NULL && !OSSL_PARAM_set_uint(p, pdsactx->nonce_type))
- return 0;
- if (!OSSL_FIPS_IND_GET_CTX_PARAM(pdsactx, params))
- return 0;
- return 1;
- }
- static const OSSL_PARAM known_gettable_ctx_params[] = {
- OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
- OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
- OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL),
- OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
- OSSL_PARAM_END
- };
- static const OSSL_PARAM *dsa_gettable_ctx_params(ossl_unused void *ctx,
- ossl_unused void *provctx)
- {
- return known_gettable_ctx_params;
- }
- /**
- * @brief Setup common params for dsa_set_ctx_params and dsa_sigalg_set_ctx_params
- * The caller is responsible for checking |vpdsactx| is not NULL and |params|
- * is not empty.
- */
- static int dsa_common_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[])
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- const OSSL_PARAM *p;
- if (!OSSL_FIPS_IND_SET_CTX_PARAM(pdsactx, OSSL_FIPS_IND_SETTABLE0, params,
- OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK))
- return 0;
- if (!OSSL_FIPS_IND_SET_CTX_PARAM(pdsactx, OSSL_FIPS_IND_SETTABLE1, params,
- OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK))
- return 0;
- if (!OSSL_FIPS_IND_SET_CTX_PARAM(pdsactx, OSSL_FIPS_IND_SETTABLE2, params,
- OSSL_SIGNATURE_PARAM_FIPS_SIGN_CHECK))
- return 0;
- p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE);
- if (p != NULL
- && !OSSL_PARAM_get_uint(p, &pdsactx->nonce_type))
- return 0;
- return 1;
- }
- #define DSA_COMMON_SETTABLE_CTX_PARAMS \
- OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL), \
- OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK) \
- OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK) \
- OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_SIGN_CHECK) \
- OSSL_PARAM_END
- static int dsa_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[])
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- const OSSL_PARAM *p;
- int ret;
- if (pdsactx == NULL)
- return 0;
- if (ossl_param_is_empty(params))
- return 1;
- if ((ret = dsa_common_set_ctx_params(pdsactx, params)) <= 0)
- return ret;
- p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);
- if (p != NULL) {
- char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname;
- char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops;
- const OSSL_PARAM *propsp =
- OSSL_PARAM_locate_const(params,
- OSSL_SIGNATURE_PARAM_PROPERTIES);
- if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname)))
- return 0;
- if (propsp != NULL
- && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops)))
- return 0;
- if (!dsa_setup_md(pdsactx, mdname, mdprops, "DSA Set Ctx"))
- return 0;
- }
- return 1;
- }
- static const OSSL_PARAM settable_ctx_params[] = {
- OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
- OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0),
- DSA_COMMON_SETTABLE_CTX_PARAMS
- };
- static const OSSL_PARAM settable_ctx_params_no_digest[] = {
- OSSL_PARAM_END
- };
- static const OSSL_PARAM *dsa_settable_ctx_params(void *vpdsactx,
- ossl_unused void *provctx)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- if (pdsactx != NULL && !pdsactx->flag_allow_md)
- return settable_ctx_params_no_digest;
- return settable_ctx_params;
- }
- static int dsa_get_ctx_md_params(void *vpdsactx, OSSL_PARAM *params)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- if (pdsactx->mdctx == NULL)
- return 0;
- return EVP_MD_CTX_get_params(pdsactx->mdctx, params);
- }
- static const OSSL_PARAM *dsa_gettable_ctx_md_params(void *vpdsactx)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- if (pdsactx->md == NULL)
- return 0;
- return EVP_MD_gettable_ctx_params(pdsactx->md);
- }
- static int dsa_set_ctx_md_params(void *vpdsactx, const OSSL_PARAM params[])
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- if (pdsactx->mdctx == NULL)
- return 0;
- return EVP_MD_CTX_set_params(pdsactx->mdctx, params);
- }
- static const OSSL_PARAM *dsa_settable_ctx_md_params(void *vpdsactx)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- if (pdsactx->md == NULL)
- return 0;
- return EVP_MD_settable_ctx_params(pdsactx->md);
- }
- const OSSL_DISPATCH ossl_dsa_signature_functions[] = {
- { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))dsa_newctx },
- { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))dsa_sign_init },
- { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))dsa_sign },
- { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))dsa_verify_init },
- { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))dsa_verify },
- { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
- (void (*)(void))dsa_digest_sign_init },
- { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE,
- (void (*)(void))dsa_digest_signverify_update },
- { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL,
- (void (*)(void))dsa_digest_sign_final },
- { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
- (void (*)(void))dsa_digest_verify_init },
- { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE,
- (void (*)(void))dsa_digest_signverify_update },
- { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL,
- (void (*)(void))dsa_digest_verify_final },
- { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))dsa_freectx },
- { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))dsa_dupctx },
- { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))dsa_get_ctx_params },
- { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
- (void (*)(void))dsa_gettable_ctx_params },
- { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))dsa_set_ctx_params },
- { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
- (void (*)(void))dsa_settable_ctx_params },
- { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS,
- (void (*)(void))dsa_get_ctx_md_params },
- { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS,
- (void (*)(void))dsa_gettable_ctx_md_params },
- { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS,
- (void (*)(void))dsa_set_ctx_md_params },
- { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS,
- (void (*)(void))dsa_settable_ctx_md_params },
- OSSL_DISPATCH_END
- };
- /* ------------------------------------------------------------------ */
- /*
- * So called sigalgs (composite DSA+hash) implemented below. They
- * are pretty much hard coded.
- */
- static OSSL_FUNC_signature_query_key_types_fn dsa_sigalg_query_key_types;
- static OSSL_FUNC_signature_settable_ctx_params_fn dsa_sigalg_settable_ctx_params;
- static OSSL_FUNC_signature_set_ctx_params_fn dsa_sigalg_set_ctx_params;
- /*
- * dsa_sigalg_signverify_init() is almost like dsa_digest_signverify_init(),
- * just doesn't allow fetching an MD from whatever the user chooses.
- */
- static int dsa_sigalg_signverify_init(void *vpdsactx, void *vdsa,
- OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params,
- const OSSL_PARAM params[],
- const char *mdname,
- int operation, const char *desc)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- if (!ossl_prov_is_running())
- return 0;
- if (!dsa_signverify_init(vpdsactx, vdsa, set_ctx_params, params, operation,
- desc))
- return 0;
- if (!dsa_setup_md(pdsactx, mdname, NULL, desc))
- return 0;
- pdsactx->flag_sigalg = 1;
- pdsactx->flag_allow_md = 0;
- if (pdsactx->mdctx == NULL) {
- pdsactx->mdctx = EVP_MD_CTX_new();
- if (pdsactx->mdctx == NULL)
- goto error;
- }
- if (!EVP_DigestInit_ex2(pdsactx->mdctx, pdsactx->md, params))
- goto error;
- return 1;
- error:
- EVP_MD_CTX_free(pdsactx->mdctx);
- pdsactx->mdctx = NULL;
- return 0;
- }
- static const char **dsa_sigalg_query_key_types(void)
- {
- static const char *keytypes[] = { "DSA", NULL };
- return keytypes;
- }
- static const OSSL_PARAM settable_sigalg_ctx_params[] = {
- OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE, NULL, 0),
- DSA_COMMON_SETTABLE_CTX_PARAMS
- };
- static const OSSL_PARAM *dsa_sigalg_settable_ctx_params(void *vpdsactx,
- ossl_unused void *provctx)
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- if (pdsactx != NULL && pdsactx->operation == EVP_PKEY_OP_VERIFYMSG)
- return settable_sigalg_ctx_params;
- return NULL;
- }
- static int dsa_sigalg_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[])
- {
- PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
- const OSSL_PARAM *p;
- int ret;
- if (pdsactx == NULL)
- return 0;
- if (ossl_param_is_empty(params))
- return 1;
- if ((ret = dsa_common_set_ctx_params(pdsactx, params)) <= 0)
- return ret;
- if (pdsactx->operation == EVP_PKEY_OP_VERIFYMSG) {
- p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_SIGNATURE);
- if (p != NULL) {
- OPENSSL_free(pdsactx->sig);
- pdsactx->sig = NULL;
- pdsactx->siglen = 0;
- if (!OSSL_PARAM_get_octet_string(p, (void **)&pdsactx->sig,
- 0, &pdsactx->siglen))
- return 0;
- }
- }
- return 1;
- }
- #define IMPL_DSA_SIGALG(md, MD) \
- static OSSL_FUNC_signature_sign_init_fn dsa_##md##_sign_init; \
- static OSSL_FUNC_signature_sign_message_init_fn \
- dsa_##md##_sign_message_init; \
- static OSSL_FUNC_signature_verify_init_fn dsa_##md##_verify_init; \
- static OSSL_FUNC_signature_verify_message_init_fn \
- dsa_##md##_verify_message_init; \
- \
- static int \
- dsa_##md##_sign_init(void *vpdsactx, void *vdsa, \
- const OSSL_PARAM params[]) \
- { \
- static const char desc[] = "DSA-" #MD " Sign Init"; \
- \
- return dsa_sigalg_signverify_init(vpdsactx, vdsa, \
- dsa_sigalg_set_ctx_params, \
- params, #MD, \
- EVP_PKEY_OP_SIGN, \
- desc); \
- } \
- \
- static int \
- dsa_##md##_sign_message_init(void *vpdsactx, void *vdsa, \
- const OSSL_PARAM params[]) \
- { \
- static const char desc[] = "DSA-" #MD " Sign Message Init"; \
- \
- return dsa_sigalg_signverify_init(vpdsactx, vdsa, \
- dsa_sigalg_set_ctx_params, \
- params, #MD, \
- EVP_PKEY_OP_SIGNMSG, \
- desc); \
- } \
- \
- static int \
- dsa_##md##_verify_init(void *vpdsactx, void *vdsa, \
- const OSSL_PARAM params[]) \
- { \
- static const char desc[] = "DSA-" #MD " Verify Init"; \
- \
- return dsa_sigalg_signverify_init(vpdsactx, vdsa, \
- dsa_sigalg_set_ctx_params, \
- params, #MD, \
- EVP_PKEY_OP_VERIFY, \
- desc); \
- } \
- \
- static int \
- dsa_##md##_verify_message_init(void *vpdsactx, void *vdsa, \
- const OSSL_PARAM params[]) \
- { \
- static const char desc[] = "DSA-" #MD " Verify Message Init"; \
- \
- return dsa_sigalg_signverify_init(vpdsactx, vdsa, \
- dsa_sigalg_set_ctx_params, \
- params, #MD, \
- EVP_PKEY_OP_VERIFYMSG, \
- desc); \
- } \
- \
- const OSSL_DISPATCH ossl_dsa_##md##_signature_functions[] = { \
- { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))dsa_newctx }, \
- { OSSL_FUNC_SIGNATURE_SIGN_INIT, \
- (void (*)(void))dsa_##md##_sign_init }, \
- { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))dsa_sign }, \
- { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT, \
- (void (*)(void))dsa_##md##_sign_message_init }, \
- { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_UPDATE, \
- (void (*)(void))dsa_signverify_message_update }, \
- { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_FINAL, \
- (void (*)(void))dsa_sign_message_final }, \
- { OSSL_FUNC_SIGNATURE_VERIFY_INIT, \
- (void (*)(void))dsa_##md##_verify_init }, \
- { OSSL_FUNC_SIGNATURE_VERIFY, \
- (void (*)(void))dsa_verify }, \
- { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT, \
- (void (*)(void))dsa_##md##_verify_message_init }, \
- { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_UPDATE, \
- (void (*)(void))dsa_signverify_message_update }, \
- { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_FINAL, \
- (void (*)(void))dsa_verify_message_final }, \
- { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))dsa_freectx }, \
- { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))dsa_dupctx }, \
- { OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPES, \
- (void (*)(void))dsa_sigalg_query_key_types }, \
- { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \
- (void (*)(void))dsa_get_ctx_params }, \
- { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \
- (void (*)(void))dsa_gettable_ctx_params }, \
- { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \
- (void (*)(void))dsa_sigalg_set_ctx_params }, \
- { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \
- (void (*)(void))dsa_sigalg_settable_ctx_params }, \
- OSSL_DISPATCH_END \
- }
- IMPL_DSA_SIGALG(sha1, SHA1);
- IMPL_DSA_SIGALG(sha224, SHA2-224);
- IMPL_DSA_SIGALG(sha256, SHA2-256);
- IMPL_DSA_SIGALG(sha384, SHA2-384);
- IMPL_DSA_SIGALG(sha512, SHA2-512);
- IMPL_DSA_SIGALG(sha3_224, SHA3-224);
- IMPL_DSA_SIGALG(sha3_256, SHA3-256);
- IMPL_DSA_SIGALG(sha3_384, SHA3-384);
- IMPL_DSA_SIGALG(sha3_512, SHA3-512);
|