Path: blob/main/crypto/openssl/providers/implementations/signature/ecdsa_sig.c
48383 views
/*1* Copyright 2020-2025 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* ECDSA low level APIs are deprecated for public use, but still ok for11* internal use.12*/13#include "internal/deprecated.h"1415#include <string.h> /* memcpy */16#include <openssl/crypto.h>17#include <openssl/core_dispatch.h>18#include <openssl/core_names.h>19#include <openssl/dsa.h>20#include <openssl/params.h>21#include <openssl/evp.h>22#include <openssl/err.h>23#include <openssl/proverr.h>24#include "internal/nelem.h"25#include "internal/sizes.h"26#include "internal/cryptlib.h"27#include "internal/deterministic_nonce.h"28#include "prov/providercommon.h"29#include "prov/implementations.h"30#include "prov/provider_ctx.h"31#include "prov/securitycheck.h"32#include "prov/der_ec.h"33#include "crypto/ec.h"3435static OSSL_FUNC_signature_newctx_fn ecdsa_newctx;36static OSSL_FUNC_signature_sign_init_fn ecdsa_sign_init;37static OSSL_FUNC_signature_verify_init_fn ecdsa_verify_init;38static OSSL_FUNC_signature_sign_fn ecdsa_sign;39static OSSL_FUNC_signature_sign_message_update_fn ecdsa_signverify_message_update;40static OSSL_FUNC_signature_sign_message_final_fn ecdsa_sign_message_final;41static OSSL_FUNC_signature_verify_fn ecdsa_verify;42static OSSL_FUNC_signature_verify_message_update_fn ecdsa_signverify_message_update;43static OSSL_FUNC_signature_verify_message_final_fn ecdsa_verify_message_final;44static OSSL_FUNC_signature_digest_sign_init_fn ecdsa_digest_sign_init;45static OSSL_FUNC_signature_digest_sign_update_fn ecdsa_digest_signverify_update;46static OSSL_FUNC_signature_digest_sign_final_fn ecdsa_digest_sign_final;47static OSSL_FUNC_signature_digest_verify_init_fn ecdsa_digest_verify_init;48static OSSL_FUNC_signature_digest_verify_update_fn ecdsa_digest_signverify_update;49static OSSL_FUNC_signature_digest_verify_final_fn ecdsa_digest_verify_final;50static OSSL_FUNC_signature_freectx_fn ecdsa_freectx;51static OSSL_FUNC_signature_dupctx_fn ecdsa_dupctx;52static OSSL_FUNC_signature_query_key_types_fn ecdsa_sigalg_query_key_types;53static OSSL_FUNC_signature_get_ctx_params_fn ecdsa_get_ctx_params;54static OSSL_FUNC_signature_gettable_ctx_params_fn ecdsa_gettable_ctx_params;55static OSSL_FUNC_signature_set_ctx_params_fn ecdsa_set_ctx_params;56static OSSL_FUNC_signature_settable_ctx_params_fn ecdsa_settable_ctx_params;57static OSSL_FUNC_signature_get_ctx_md_params_fn ecdsa_get_ctx_md_params;58static OSSL_FUNC_signature_gettable_ctx_md_params_fn ecdsa_gettable_ctx_md_params;59static OSSL_FUNC_signature_set_ctx_md_params_fn ecdsa_set_ctx_md_params;60static OSSL_FUNC_signature_settable_ctx_md_params_fn ecdsa_settable_ctx_md_params;61static OSSL_FUNC_signature_set_ctx_params_fn ecdsa_sigalg_set_ctx_params;62static OSSL_FUNC_signature_settable_ctx_params_fn ecdsa_sigalg_settable_ctx_params;6364/*65* What's passed as an actual key is defined by the KEYMGMT interface.66* We happen to know that our KEYMGMT simply passes DSA structures, so67* we use that here too.68*/6970typedef struct {71OSSL_LIB_CTX *libctx;72char *propq;73EC_KEY *ec;74/* |operation| reuses EVP's operation bitfield */75int operation;7677/*78* Flag to determine if a full sigalg is run (1) or if a composable79* signature algorithm is run (0).80*81* When a full sigalg is run (1), this currently affects the following82* other flags, which are to remain untouched after their initialization:83*84* - flag_allow_md (initialized to 0)85*/86unsigned int flag_sigalg : 1;87/*88* Flag to determine if the hash function can be changed (1) or not (0)89* Because it's dangerous to change during a DigestSign or DigestVerify90* operation, this flag is cleared by their Init function, and set again91* by their Final function.92*/93unsigned int flag_allow_md : 1;9495/* The Algorithm Identifier of the combined signature algorithm */96unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE];97size_t aid_len;9899/* main digest */100char mdname[OSSL_MAX_NAME_SIZE];101EVP_MD *md;102EVP_MD_CTX *mdctx;103size_t mdsize;104105/* Signature, for verification */106unsigned char *sig;107size_t siglen;108109/*110* Internally used to cache the results of calling the EC group111* sign_setup() methods which are then passed to the sign operation.112* This is used by CAVS failure tests to terminate a loop if the signature113* is not valid.114* This could of also been done with a simple flag.115*/116BIGNUM *kinv;117BIGNUM *r;118#if !defined(OPENSSL_NO_ACVP_TESTS)119/*120* This indicates that KAT (CAVS) test is running. Externally an app will121* override the random callback such that the generated private key and k122* are known.123* Normal operation will loop to choose a new k if the signature is not124* valid - but for this mode of operation it forces a failure instead.125*/126unsigned int kattest;127#endif128#ifdef FIPS_MODULE129/*130* FIPS 140-3 IG 2.4.B mandates that verification based on a digest of a131* message is not permitted. However, signing based on a digest is still132* permitted.133*/134int verify_message;135#endif136/* If this is set then the generated k is not random */137unsigned int nonce_type;138OSSL_FIPS_IND_DECLARE139} PROV_ECDSA_CTX;140141static void *ecdsa_newctx(void *provctx, const char *propq)142{143PROV_ECDSA_CTX *ctx;144145if (!ossl_prov_is_running())146return NULL;147148ctx = OPENSSL_zalloc(sizeof(PROV_ECDSA_CTX));149if (ctx == NULL)150return NULL;151152OSSL_FIPS_IND_INIT(ctx)153ctx->flag_allow_md = 1;154#ifdef FIPS_MODULE155ctx->verify_message = 1;156#endif157ctx->libctx = PROV_LIBCTX_OF(provctx);158if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) {159OPENSSL_free(ctx);160ctx = NULL;161}162return ctx;163}164165static int ecdsa_setup_md(PROV_ECDSA_CTX *ctx,166const char *mdname, const char *mdprops,167const char *desc)168{169EVP_MD *md = NULL;170size_t mdname_len;171int md_nid, md_size;172WPACKET pkt;173unsigned char *aid = NULL;174175if (mdname == NULL)176return 1;177178mdname_len = strlen(mdname);179if (mdname_len >= sizeof(ctx->mdname)) {180ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,181"%s exceeds name buffer length", mdname);182return 0;183}184if (mdprops == NULL)185mdprops = ctx->propq;186md = EVP_MD_fetch(ctx->libctx, mdname, mdprops);187if (md == NULL) {188ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,189"%s could not be fetched", mdname);190return 0;191}192md_size = EVP_MD_get_size(md);193if (md_size <= 0) {194ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,195"%s has invalid md size %d", mdname, md_size);196goto err;197}198md_nid = ossl_digest_get_approved_nid(md);199#ifdef FIPS_MODULE200if (md_nid == NID_undef) {201ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,202"digest=%s", mdname);203goto err;204}205#endif206/* XOF digests don't work */207if (EVP_MD_xof(md)) {208ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);209goto err;210}211212#ifdef FIPS_MODULE213{214int sha1_allowed215= ((ctx->operation216& (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_SIGNMSG)) == 0);217218if (!ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND_GET(ctx),219OSSL_FIPS_IND_SETTABLE1,220ctx->libctx,221md_nid, sha1_allowed, 0, desc,222ossl_fips_config_signature_digest_check))223goto err;224}225#endif226227if (!ctx->flag_allow_md) {228if (ctx->mdname[0] != '\0' && !EVP_MD_is_a(md, ctx->mdname)) {229ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,230"digest %s != %s", mdname, ctx->mdname);231goto err;232}233EVP_MD_free(md);234return 1;235}236237EVP_MD_CTX_free(ctx->mdctx);238EVP_MD_free(ctx->md);239240ctx->aid_len = 0;241#ifndef FIPS_MODULE242if (md_nid != NID_undef) {243#else244{245#endif246if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf))247&& ossl_DER_w_algorithmIdentifier_ECDSA_with_MD(&pkt, -1, ctx->ec,248md_nid)249&& WPACKET_finish(&pkt)) {250WPACKET_get_total_written(&pkt, &ctx->aid_len);251aid = WPACKET_get_curr(&pkt);252}253WPACKET_cleanup(&pkt);254if (aid != NULL && ctx->aid_len != 0)255memmove(ctx->aid_buf, aid, ctx->aid_len);256}257258ctx->mdctx = NULL;259ctx->md = md;260ctx->mdsize = (size_t)md_size;261OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname));262263return 1;264err:265EVP_MD_free(md);266return 0;267}268269static int270ecdsa_signverify_init(PROV_ECDSA_CTX *ctx, void *ec,271OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params,272const OSSL_PARAM params[], int operation,273const char *desc)274{275if (!ossl_prov_is_running()276|| ctx == NULL)277return 0;278279if (ec == NULL && ctx->ec == NULL) {280ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);281return 0;282}283284if (ec != NULL) {285if (!EC_KEY_up_ref(ec))286return 0;287EC_KEY_free(ctx->ec);288ctx->ec = ec;289}290291ctx->operation = operation;292293OSSL_FIPS_IND_SET_APPROVED(ctx)294if (!set_ctx_params(ctx, params))295return 0;296#ifdef FIPS_MODULE297if (!ossl_fips_ind_ec_key_check(OSSL_FIPS_IND_GET(ctx),298OSSL_FIPS_IND_SETTABLE0, ctx->libctx,299EC_KEY_get0_group(ctx->ec), desc,300(operation & (EVP_PKEY_OP_SIGN301| EVP_PKEY_OP_SIGNMSG)) != 0))302return 0;303#endif304return 1;305}306307static int ecdsa_sign_init(void *vctx, void *ec, const OSSL_PARAM params[])308{309PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;310311#ifdef FIPS_MODULE312ctx->verify_message = 1;313#endif314return ecdsa_signverify_init(ctx, ec, ecdsa_set_ctx_params, params,315EVP_PKEY_OP_SIGN, "ECDSA Sign Init");316}317318/*319* Sign tbs without digesting it first. This is suitable for "primitive"320* signing and signing the digest of a message.321*/322static int ecdsa_sign_directly(void *vctx,323unsigned char *sig, size_t *siglen, size_t sigsize,324const unsigned char *tbs, size_t tbslen)325{326PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;327int ret;328unsigned int sltmp;329size_t ecsize = ECDSA_size(ctx->ec);330331if (!ossl_prov_is_running())332return 0;333334if (sig == NULL) {335*siglen = ecsize;336return 1;337}338339#if !defined(OPENSSL_NO_ACVP_TESTS)340if (ctx->kattest && !ECDSA_sign_setup(ctx->ec, NULL, &ctx->kinv, &ctx->r))341return 0;342#endif343344if (sigsize < (size_t)ecsize)345return 0;346347if (ctx->mdsize != 0 && tbslen != ctx->mdsize)348return 0;349350if (ctx->nonce_type != 0) {351const char *mdname = NULL;352353if (ctx->mdname[0] != '\0')354mdname = ctx->mdname;355ret = ossl_ecdsa_deterministic_sign(tbs, tbslen, sig, &sltmp,356ctx->ec, ctx->nonce_type,357mdname,358ctx->libctx, ctx->propq);359} else {360ret = ECDSA_sign_ex(0, tbs, tbslen, sig, &sltmp, ctx->kinv, ctx->r,361ctx->ec);362}363if (ret <= 0)364return 0;365366*siglen = sltmp;367return 1;368}369370static int ecdsa_signverify_message_update(void *vctx,371const unsigned char *data,372size_t datalen)373{374PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;375376if (ctx == NULL)377return 0;378379return EVP_DigestUpdate(ctx->mdctx, data, datalen);380}381382static int ecdsa_sign_message_final(void *vctx, unsigned char *sig,383size_t *siglen, size_t sigsize)384{385PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;386unsigned char digest[EVP_MAX_MD_SIZE];387unsigned int dlen = 0;388389if (!ossl_prov_is_running() || ctx == NULL)390return 0;391if (ctx->mdctx == NULL)392return 0;393/*394* If sig is NULL then we're just finding out the sig size. Other fields395* are ignored. Defer to ecdsa_sign.396*/397if (sig != NULL398&& !EVP_DigestFinal_ex(ctx->mdctx, digest, &dlen))399return 0;400return ecdsa_sign_directly(vctx, sig, siglen, sigsize, digest, dlen);401}402403/*404* If signing a message, digest tbs and sign the result.405* Otherwise, sign tbs directly.406*/407static int ecdsa_sign(void *vctx, unsigned char *sig, size_t *siglen,408size_t sigsize, const unsigned char *tbs, size_t tbslen)409{410PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;411412if (ctx->operation == EVP_PKEY_OP_SIGNMSG) {413/*414* If |sig| is NULL, the caller is only looking for the sig length.415* DO NOT update the input in this case.416*/417if (sig == NULL)418return ecdsa_sign_message_final(ctx, sig, siglen, sigsize);419420if (ecdsa_signverify_message_update(ctx, tbs, tbslen) <= 0)421return 0;422return ecdsa_sign_message_final(ctx, sig, siglen, sigsize);423}424return ecdsa_sign_directly(ctx, sig, siglen, sigsize, tbs, tbslen);425}426427static int ecdsa_verify_init(void *vctx, void *ec, const OSSL_PARAM params[])428{429PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;430431#ifdef FIPS_MODULE432ctx->verify_message = 0;433#endif434return ecdsa_signverify_init(ctx, ec, ecdsa_set_ctx_params, params,435EVP_PKEY_OP_VERIFY, "ECDSA Verify Init");436}437438static int ecdsa_verify_directly(void *vctx,439const unsigned char *sig, size_t siglen,440const unsigned char *tbs, size_t tbslen)441{442PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;443444if (!ossl_prov_is_running() || (ctx->mdsize != 0 && tbslen != ctx->mdsize))445return 0;446447return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->ec);448}449450static int ecdsa_verify_set_sig(void *vctx,451const unsigned char *sig, size_t siglen)452{453PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;454OSSL_PARAM params[2];455456params[0] =457OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE,458(unsigned char *)sig, siglen);459params[1] = OSSL_PARAM_construct_end();460return ecdsa_sigalg_set_ctx_params(ctx, params);461}462463static int ecdsa_verify_message_final(void *vctx)464{465PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;466unsigned char digest[EVP_MAX_MD_SIZE];467unsigned int dlen = 0;468469if (!ossl_prov_is_running() || ctx == NULL || ctx->mdctx == NULL)470return 0;471472/*473* The digests used here are all known (see ecdsa_get_md_nid()), so they474* should not exceed the internal buffer size of EVP_MAX_MD_SIZE.475*/476if (!EVP_DigestFinal_ex(ctx->mdctx, digest, &dlen))477return 0;478479return ecdsa_verify_directly(vctx, ctx->sig, ctx->siglen,480digest, dlen);481}482483/*484* If verifying a message, digest tbs and verify the result.485* Otherwise, verify tbs directly.486*/487static int ecdsa_verify(void *vctx,488const unsigned char *sig, size_t siglen,489const unsigned char *tbs, size_t tbslen)490{491PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;492493if (ctx->operation == EVP_PKEY_OP_VERIFYMSG) {494if (ecdsa_verify_set_sig(ctx, sig, siglen) <= 0)495return 0;496if (ecdsa_signverify_message_update(ctx, tbs, tbslen) <= 0)497return 0;498return ecdsa_verify_message_final(ctx);499}500return ecdsa_verify_directly(ctx, sig, siglen, tbs, tbslen);501}502503/* DigestSign/DigestVerify wrappers */504505static int ecdsa_digest_signverify_init(void *vctx, const char *mdname,506void *ec, const OSSL_PARAM params[],507int operation, const char *desc)508{509PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;510511if (!ossl_prov_is_running())512return 0;513514#ifdef FIPS_MODULE515ctx->verify_message = 1;516#endif517if (!ecdsa_signverify_init(vctx, ec, ecdsa_set_ctx_params, params,518operation, desc))519return 0;520521if (mdname != NULL522/* was ecdsa_setup_md already called in ecdsa_signverify_init()? */523&& (mdname[0] == '\0' || OPENSSL_strcasecmp(ctx->mdname, mdname) != 0)524&& !ecdsa_setup_md(ctx, mdname, NULL, desc))525return 0;526527ctx->flag_allow_md = 0;528529if (ctx->mdctx == NULL) {530ctx->mdctx = EVP_MD_CTX_new();531if (ctx->mdctx == NULL)532goto error;533}534535if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params))536goto error;537return 1;538error:539EVP_MD_CTX_free(ctx->mdctx);540ctx->mdctx = NULL;541return 0;542}543544static int ecdsa_digest_sign_init(void *vctx, const char *mdname, void *ec,545const OSSL_PARAM params[])546{547return ecdsa_digest_signverify_init(vctx, mdname, ec, params,548EVP_PKEY_OP_SIGNMSG,549"ECDSA Digest Sign Init");550}551552static int ecdsa_digest_signverify_update(void *vctx, const unsigned char *data,553size_t datalen)554{555PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;556557if (ctx == NULL || ctx->mdctx == NULL)558return 0;559/* Sigalg implementations shouldn't do digest_sign */560if (ctx->flag_sigalg)561return 0;562563return ecdsa_signverify_message_update(vctx, data, datalen);564}565566int ecdsa_digest_sign_final(void *vctx, unsigned char *sig, size_t *siglen,567size_t sigsize)568{569PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;570int ok = 0;571572if (ctx == NULL)573return 0;574/* Sigalg implementations shouldn't do digest_sign */575if (ctx->flag_sigalg)576return 0;577578ok = ecdsa_sign_message_final(ctx, sig, siglen, sigsize);579580ctx->flag_allow_md = 1;581582return ok;583}584585static int ecdsa_digest_verify_init(void *vctx, const char *mdname, void *ec,586const OSSL_PARAM params[])587{588return ecdsa_digest_signverify_init(vctx, mdname, ec, params,589EVP_PKEY_OP_VERIFYMSG,590"ECDSA Digest Verify Init");591}592593int ecdsa_digest_verify_final(void *vctx, const unsigned char *sig,594size_t siglen)595{596PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;597int ok = 0;598599if (!ossl_prov_is_running() || ctx == NULL || ctx->mdctx == NULL)600return 0;601602/* Sigalg implementations shouldn't do digest_verify */603if (ctx->flag_sigalg)604return 0;605606if (ecdsa_verify_set_sig(ctx, sig, siglen))607ok = ecdsa_verify_message_final(ctx);608609ctx->flag_allow_md = 1;610611return ok;612}613614static void ecdsa_freectx(void *vctx)615{616PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;617618EVP_MD_CTX_free(ctx->mdctx);619EVP_MD_free(ctx->md);620OPENSSL_free(ctx->propq);621OPENSSL_free(ctx->sig);622EC_KEY_free(ctx->ec);623BN_clear_free(ctx->kinv);624BN_clear_free(ctx->r);625OPENSSL_free(ctx);626}627628static void *ecdsa_dupctx(void *vctx)629{630PROV_ECDSA_CTX *srcctx = (PROV_ECDSA_CTX *)vctx;631PROV_ECDSA_CTX *dstctx;632633if (!ossl_prov_is_running())634return NULL;635636dstctx = OPENSSL_zalloc(sizeof(*srcctx));637if (dstctx == NULL)638return NULL;639640*dstctx = *srcctx;641dstctx->ec = NULL;642dstctx->propq = NULL;643644if (srcctx->ec != NULL && !EC_KEY_up_ref(srcctx->ec))645goto err;646/* Test KATS should not need to be supported */647if (srcctx->kinv != NULL || srcctx->r != NULL)648goto err;649dstctx->ec = srcctx->ec;650651if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md))652goto err;653dstctx->md = srcctx->md;654655if (srcctx->mdctx != NULL) {656dstctx->mdctx = EVP_MD_CTX_new();657if (dstctx->mdctx == NULL658|| !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx))659goto err;660}661662if (srcctx->propq != NULL) {663dstctx->propq = OPENSSL_strdup(srcctx->propq);664if (dstctx->propq == NULL)665goto err;666}667668return dstctx;669err:670ecdsa_freectx(dstctx);671return NULL;672}673674static int ecdsa_get_ctx_params(void *vctx, OSSL_PARAM *params)675{676PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;677OSSL_PARAM *p;678679if (ctx == NULL)680return 0;681682p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);683if (p != NULL && !OSSL_PARAM_set_octet_string(p,684ctx->aid_len == 0 ? NULL : ctx->aid_buf,685ctx->aid_len))686return 0;687688p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);689if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->mdsize))690return 0;691692p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST);693if (p != NULL && !OSSL_PARAM_set_utf8_string(p, ctx->md == NULL694? ctx->mdname695: EVP_MD_get0_name(ctx->md)))696return 0;697698p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE);699if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->nonce_type))700return 0;701702#ifdef FIPS_MODULE703p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_FIPS_VERIFY_MESSAGE);704if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->verify_message))705return 0;706#endif707708if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))709return 0;710return 1;711}712713static const OSSL_PARAM known_gettable_ctx_params[] = {714OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),715OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),716OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),717OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL),718#ifdef FIPS_MODULE719OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_FIPS_VERIFY_MESSAGE, NULL),720#endif721OSSL_FIPS_IND_GETTABLE_CTX_PARAM()722OSSL_PARAM_END723};724725static const OSSL_PARAM *ecdsa_gettable_ctx_params(ossl_unused void *vctx,726ossl_unused void *provctx)727{728return known_gettable_ctx_params;729}730731/**732* @brief Set up common params for ecdsa_set_ctx_params and733* ecdsa_sigalg_set_ctx_params. The caller is responsible for checking |vctx| is734* not NULL and |params| is not empty.735*/736static int ecdsa_common_set_ctx_params(void *vctx, const OSSL_PARAM params[])737{738PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;739const OSSL_PARAM *p;740741if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,742OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK))743return 0;744if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, params,745OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK))746return 0;747748#if !defined(OPENSSL_NO_ACVP_TESTS)749p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_KAT);750if (p != NULL && !OSSL_PARAM_get_uint(p, &ctx->kattest))751return 0;752#endif753754p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE);755if (p != NULL756&& !OSSL_PARAM_get_uint(p, &ctx->nonce_type))757return 0;758return 1;759}760761#define ECDSA_COMMON_SETTABLE_CTX_PARAMS \762OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_KAT, NULL), \763OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL), \764OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK) \765OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK) \766OSSL_PARAM_END767768static int ecdsa_set_ctx_params(void *vctx, const OSSL_PARAM params[])769{770PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;771const OSSL_PARAM *p;772size_t mdsize = 0;773int ret;774775if (ctx == NULL)776return 0;777if (ossl_param_is_empty(params))778return 1;779780if ((ret = ecdsa_common_set_ctx_params(ctx, params)) <= 0)781return ret;782783p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);784if (p != NULL) {785char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname;786char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops;787const OSSL_PARAM *propsp =788OSSL_PARAM_locate_const(params,789OSSL_SIGNATURE_PARAM_PROPERTIES);790791if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname)))792return 0;793if (propsp != NULL794&& !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops)))795return 0;796if (!ecdsa_setup_md(ctx, mdname, mdprops, "ECDSA Set Ctx"))797return 0;798}799800p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);801if (p != NULL) {802if (!OSSL_PARAM_get_size_t(p, &mdsize)803|| (!ctx->flag_allow_md && mdsize != ctx->mdsize))804return 0;805ctx->mdsize = mdsize;806}807return 1;808}809810static const OSSL_PARAM settable_ctx_params[] = {811OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),812OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),813OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0),814ECDSA_COMMON_SETTABLE_CTX_PARAMS815};816817static const OSSL_PARAM *ecdsa_settable_ctx_params(void *vctx,818ossl_unused void *provctx)819{820return settable_ctx_params;821}822823static int ecdsa_get_ctx_md_params(void *vctx, OSSL_PARAM *params)824{825PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;826827if (ctx->mdctx == NULL)828return 0;829830return EVP_MD_CTX_get_params(ctx->mdctx, params);831}832833static const OSSL_PARAM *ecdsa_gettable_ctx_md_params(void *vctx)834{835PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;836837if (ctx->md == NULL)838return 0;839840return EVP_MD_gettable_ctx_params(ctx->md);841}842843static int ecdsa_set_ctx_md_params(void *vctx, const OSSL_PARAM params[])844{845PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;846847if (ctx->mdctx == NULL)848return 0;849850return EVP_MD_CTX_set_params(ctx->mdctx, params);851}852853static const OSSL_PARAM *ecdsa_settable_ctx_md_params(void *vctx)854{855PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;856857if (ctx->md == NULL)858return 0;859860return EVP_MD_settable_ctx_params(ctx->md);861}862863const OSSL_DISPATCH ossl_ecdsa_signature_functions[] = {864{ OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))ecdsa_newctx },865{ OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))ecdsa_sign_init },866{ OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))ecdsa_sign },867{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))ecdsa_verify_init },868{ OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))ecdsa_verify },869{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,870(void (*)(void))ecdsa_digest_sign_init },871{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE,872(void (*)(void))ecdsa_digest_signverify_update },873{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL,874(void (*)(void))ecdsa_digest_sign_final },875{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,876(void (*)(void))ecdsa_digest_verify_init },877{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE,878(void (*)(void))ecdsa_digest_signverify_update },879{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL,880(void (*)(void))ecdsa_digest_verify_final },881{ OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))ecdsa_freectx },882{ OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))ecdsa_dupctx },883{ OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))ecdsa_get_ctx_params },884{ OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,885(void (*)(void))ecdsa_gettable_ctx_params },886{ OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))ecdsa_set_ctx_params },887{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,888(void (*)(void))ecdsa_settable_ctx_params },889{ OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS,890(void (*)(void))ecdsa_get_ctx_md_params },891{ OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS,892(void (*)(void))ecdsa_gettable_ctx_md_params },893{ OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS,894(void (*)(void))ecdsa_set_ctx_md_params },895{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS,896(void (*)(void))ecdsa_settable_ctx_md_params },897OSSL_DISPATCH_END898};899900/* ------------------------------------------------------------------ */901902/*903* So called sigalgs (composite ECDSA+hash) implemented below. They904* are pretty much hard coded.905*/906907static OSSL_FUNC_signature_query_key_types_fn ecdsa_sigalg_query_key_types;908static OSSL_FUNC_signature_settable_ctx_params_fn ecdsa_sigalg_settable_ctx_params;909static OSSL_FUNC_signature_set_ctx_params_fn ecdsa_sigalg_set_ctx_params;910911/*912* ecdsa_sigalg_signverify_init() is almost like ecdsa_digest_signverify_init(),913* just doesn't allow fetching an MD from whatever the user chooses.914*/915static int ecdsa_sigalg_signverify_init(void *vctx, void *vec,916OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params,917const OSSL_PARAM params[],918const char *mdname,919int operation, const char *desc)920{921PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;922923if (!ossl_prov_is_running())924return 0;925926if (!ecdsa_signverify_init(vctx, vec, set_ctx_params, params, operation,927desc))928return 0;929930if (!ecdsa_setup_md(ctx, mdname, NULL, desc))931return 0;932933ctx->flag_sigalg = 1;934ctx->flag_allow_md = 0;935936if (ctx->mdctx == NULL) {937ctx->mdctx = EVP_MD_CTX_new();938if (ctx->mdctx == NULL)939goto error;940}941942if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params))943goto error;944945return 1;946947error:948EVP_MD_CTX_free(ctx->mdctx);949ctx->mdctx = NULL;950return 0;951}952953static const char **ecdsa_sigalg_query_key_types(void)954{955static const char *keytypes[] = { "EC", NULL };956957return keytypes;958}959960static const OSSL_PARAM settable_sigalg_ctx_params[] = {961OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE, NULL, 0),962ECDSA_COMMON_SETTABLE_CTX_PARAMS963};964965static const OSSL_PARAM *ecdsa_sigalg_settable_ctx_params(void *vctx,966ossl_unused void *provctx)967{968PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;969970if (ctx != NULL && ctx->operation == EVP_PKEY_OP_VERIFYMSG)971return settable_sigalg_ctx_params;972return NULL;973}974975static int ecdsa_sigalg_set_ctx_params(void *vctx, const OSSL_PARAM params[])976{977PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;978const OSSL_PARAM *p;979int ret;980981if (ctx == NULL)982return 0;983if (ossl_param_is_empty(params))984return 1;985986if ((ret = ecdsa_common_set_ctx_params(ctx, params)) <= 0)987return ret;988989if (ctx->operation == EVP_PKEY_OP_VERIFYMSG) {990p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_SIGNATURE);991if (p != NULL) {992OPENSSL_free(ctx->sig);993ctx->sig = NULL;994ctx->siglen = 0;995if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->sig,9960, &ctx->siglen))997return 0;998}999}1000return 1;1001}10021003#define IMPL_ECDSA_SIGALG(md, MD) \1004static OSSL_FUNC_signature_sign_init_fn ecdsa_##md##_sign_init; \1005static OSSL_FUNC_signature_sign_message_init_fn \1006ecdsa_##md##_sign_message_init; \1007static OSSL_FUNC_signature_verify_init_fn ecdsa_##md##_verify_init; \1008static OSSL_FUNC_signature_verify_message_init_fn \1009ecdsa_##md##_verify_message_init; \1010\1011static int \1012ecdsa_##md##_sign_init(void *vctx, void *vec, \1013const OSSL_PARAM params[]) \1014{ \1015static const char desc[] = "ECDSA-" #MD " Sign Init"; \1016\1017return ecdsa_sigalg_signverify_init(vctx, vec, \1018ecdsa_sigalg_set_ctx_params, \1019params, #MD, \1020EVP_PKEY_OP_SIGN, \1021desc); \1022} \1023\1024static int \1025ecdsa_##md##_sign_message_init(void *vctx, void *vec, \1026const OSSL_PARAM params[]) \1027{ \1028static const char desc[] = "ECDSA-" #MD " Sign Message Init"; \1029\1030return ecdsa_sigalg_signverify_init(vctx, vec, \1031ecdsa_sigalg_set_ctx_params, \1032params, #MD, \1033EVP_PKEY_OP_SIGNMSG, \1034desc); \1035} \1036\1037static int \1038ecdsa_##md##_verify_init(void *vctx, void *vec, \1039const OSSL_PARAM params[]) \1040{ \1041static const char desc[] = "ECDSA-" #MD " Verify Init"; \1042\1043return ecdsa_sigalg_signverify_init(vctx, vec, \1044ecdsa_sigalg_set_ctx_params, \1045params, #MD, \1046EVP_PKEY_OP_VERIFY, \1047desc); \1048} \1049\1050static int \1051ecdsa_##md##_verify_message_init(void *vctx, void *vec, \1052const OSSL_PARAM params[]) \1053{ \1054static const char desc[] = "ECDSA-" #MD " Verify Message Init"; \1055\1056return ecdsa_sigalg_signverify_init(vctx, vec, \1057ecdsa_sigalg_set_ctx_params, \1058params, #MD, \1059EVP_PKEY_OP_VERIFYMSG, \1060desc); \1061} \1062\1063const OSSL_DISPATCH ossl_ecdsa_##md##_signature_functions[] = { \1064{ OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))ecdsa_newctx }, \1065{ OSSL_FUNC_SIGNATURE_SIGN_INIT, \1066(void (*)(void))ecdsa_##md##_sign_init }, \1067{ OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))ecdsa_sign }, \1068{ OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT, \1069(void (*)(void))ecdsa_##md##_sign_message_init }, \1070{ OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_UPDATE, \1071(void (*)(void))ecdsa_signverify_message_update }, \1072{ OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_FINAL, \1073(void (*)(void))ecdsa_sign_message_final }, \1074{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, \1075(void (*)(void))ecdsa_##md##_verify_init }, \1076{ OSSL_FUNC_SIGNATURE_VERIFY, \1077(void (*)(void))ecdsa_verify }, \1078{ OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT, \1079(void (*)(void))ecdsa_##md##_verify_message_init }, \1080{ OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_UPDATE, \1081(void (*)(void))ecdsa_signverify_message_update }, \1082{ OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_FINAL, \1083(void (*)(void))ecdsa_verify_message_final }, \1084{ OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))ecdsa_freectx }, \1085{ OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))ecdsa_dupctx }, \1086{ OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPES, \1087(void (*)(void))ecdsa_sigalg_query_key_types }, \1088{ OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \1089(void (*)(void))ecdsa_get_ctx_params }, \1090{ OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \1091(void (*)(void))ecdsa_gettable_ctx_params }, \1092{ OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \1093(void (*)(void))ecdsa_sigalg_set_ctx_params }, \1094{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \1095(void (*)(void))ecdsa_sigalg_settable_ctx_params }, \1096OSSL_DISPATCH_END \1097}10981099IMPL_ECDSA_SIGALG(sha1, SHA1);1100IMPL_ECDSA_SIGALG(sha224, SHA2-224);1101IMPL_ECDSA_SIGALG(sha256, SHA2-256);1102IMPL_ECDSA_SIGALG(sha384, SHA2-384);1103IMPL_ECDSA_SIGALG(sha512, SHA2-512);1104IMPL_ECDSA_SIGALG(sha3_224, SHA3-224);1105IMPL_ECDSA_SIGALG(sha3_256, SHA3-256);1106IMPL_ECDSA_SIGALG(sha3_384, SHA3-384);1107IMPL_ECDSA_SIGALG(sha3_512, SHA3-512);110811091110