Path: blob/main/crypto/openssl/providers/implementations/signature/ecdsa_sig.c
109934 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))217== 0);218219if (!ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND_GET(ctx),220OSSL_FIPS_IND_SETTABLE1,221ctx->libctx,222md_nid, sha1_allowed, 0, desc,223ossl_fips_config_signature_digest_check))224goto err;225}226#endif227228if (!ctx->flag_allow_md) {229if (ctx->mdname[0] != '\0' && !EVP_MD_is_a(md, ctx->mdname)) {230ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,231"digest %s != %s", mdname, ctx->mdname);232goto err;233}234EVP_MD_free(md);235return 1;236}237238EVP_MD_CTX_free(ctx->mdctx);239EVP_MD_free(ctx->md);240241ctx->aid_len = 0;242#ifndef FIPS_MODULE243if (md_nid != NID_undef) {244#else245{246#endif247if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf))248&& ossl_DER_w_algorithmIdentifier_ECDSA_with_MD(&pkt, -1, ctx->ec,249md_nid)250&& WPACKET_finish(&pkt)) {251WPACKET_get_total_written(&pkt, &ctx->aid_len);252aid = WPACKET_get_curr(&pkt);253}254WPACKET_cleanup(&pkt);255if (aid != NULL && ctx->aid_len != 0)256memmove(ctx->aid_buf, aid, ctx->aid_len);257}258259ctx->mdctx = NULL;260ctx->md = md;261ctx->mdsize = (size_t)md_size;262OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname));263264return 1;265err:266EVP_MD_free(md);267return 0;268}269270static int271ecdsa_signverify_init(PROV_ECDSA_CTX *ctx, void *ec,272OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params,273const OSSL_PARAM params[], int operation,274const char *desc)275{276if (!ossl_prov_is_running()277|| ctx == NULL)278return 0;279280if (ec == NULL && ctx->ec == NULL) {281ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);282return 0;283}284285if (ec != NULL) {286if (!EC_KEY_up_ref(ec))287return 0;288EC_KEY_free(ctx->ec);289ctx->ec = ec;290}291292ctx->operation = operation;293294OSSL_FIPS_IND_SET_APPROVED(ctx)295if (!set_ctx_params(ctx, params))296return 0;297#ifdef FIPS_MODULE298if (!ossl_fips_ind_ec_key_check(OSSL_FIPS_IND_GET(ctx),299OSSL_FIPS_IND_SETTABLE0, ctx->libctx,300EC_KEY_get0_group(ctx->ec), desc,301(operation & (EVP_PKEY_OP_SIGN | 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] = OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE,457(unsigned char *)sig, siglen);458params[1] = OSSL_PARAM_construct_end();459return ecdsa_sigalg_set_ctx_params(ctx, params);460}461462static int ecdsa_verify_message_final(void *vctx)463{464PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;465unsigned char digest[EVP_MAX_MD_SIZE];466unsigned int dlen = 0;467468if (!ossl_prov_is_running() || ctx == NULL || ctx->mdctx == NULL)469return 0;470471/*472* The digests used here are all known (see ecdsa_get_md_nid()), so they473* should not exceed the internal buffer size of EVP_MAX_MD_SIZE.474*/475if (!EVP_DigestFinal_ex(ctx->mdctx, digest, &dlen))476return 0;477478return ecdsa_verify_directly(vctx, ctx->sig, ctx->siglen,479digest, dlen);480}481482/*483* If verifying a message, digest tbs and verify the result.484* Otherwise, verify tbs directly.485*/486static int ecdsa_verify(void *vctx,487const unsigned char *sig, size_t siglen,488const unsigned char *tbs, size_t tbslen)489{490PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;491492if (ctx->operation == EVP_PKEY_OP_VERIFYMSG) {493if (ecdsa_verify_set_sig(ctx, sig, siglen) <= 0)494return 0;495if (ecdsa_signverify_message_update(ctx, tbs, tbslen) <= 0)496return 0;497return ecdsa_verify_message_final(ctx);498}499return ecdsa_verify_directly(ctx, sig, siglen, tbs, tbslen);500}501502/* DigestSign/DigestVerify wrappers */503504static int ecdsa_digest_signverify_init(void *vctx, const char *mdname,505void *ec, const OSSL_PARAM params[],506int operation, const char *desc)507{508PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;509510if (!ossl_prov_is_running())511return 0;512513#ifdef FIPS_MODULE514ctx->verify_message = 1;515#endif516if (!ecdsa_signverify_init(vctx, ec, ecdsa_set_ctx_params, params,517operation, desc))518return 0;519520if (mdname != NULL521/* was ecdsa_setup_md already called in ecdsa_signverify_init()? */522&& (mdname[0] == '\0' || OPENSSL_strcasecmp(ctx->mdname, mdname) != 0)523&& !ecdsa_setup_md(ctx, mdname, NULL, desc))524return 0;525526ctx->flag_allow_md = 0;527528if (ctx->mdctx == NULL) {529ctx->mdctx = EVP_MD_CTX_new();530if (ctx->mdctx == NULL)531goto error;532}533534if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params))535goto error;536return 1;537error:538EVP_MD_CTX_free(ctx->mdctx);539ctx->mdctx = NULL;540return 0;541}542543static int ecdsa_digest_sign_init(void *vctx, const char *mdname, void *ec,544const OSSL_PARAM params[])545{546return ecdsa_digest_signverify_init(vctx, mdname, ec, params,547EVP_PKEY_OP_SIGNMSG,548"ECDSA Digest Sign Init");549}550551static int ecdsa_digest_signverify_update(void *vctx, const unsigned char *data,552size_t datalen)553{554PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;555556if (ctx == NULL || ctx->mdctx == NULL)557return 0;558/* Sigalg implementations shouldn't do digest_sign */559if (ctx->flag_sigalg)560return 0;561562return ecdsa_signverify_message_update(vctx, data, datalen);563}564565int ecdsa_digest_sign_final(void *vctx, unsigned char *sig, size_t *siglen,566size_t sigsize)567{568PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;569int ok = 0;570571if (ctx == NULL)572return 0;573/* Sigalg implementations shouldn't do digest_sign */574if (ctx->flag_sigalg)575return 0;576577ok = ecdsa_sign_message_final(ctx, sig, siglen, sigsize);578579ctx->flag_allow_md = 1;580581return ok;582}583584static int ecdsa_digest_verify_init(void *vctx, const char *mdname, void *ec,585const OSSL_PARAM params[])586{587return ecdsa_digest_signverify_init(vctx, mdname, ec, params,588EVP_PKEY_OP_VERIFYMSG,589"ECDSA Digest Verify Init");590}591592int ecdsa_digest_verify_final(void *vctx, const unsigned char *sig,593size_t siglen)594{595PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;596int ok = 0;597598if (!ossl_prov_is_running() || ctx == NULL || ctx->mdctx == NULL)599return 0;600601/* Sigalg implementations shouldn't do digest_verify */602if (ctx->flag_sigalg)603return 0;604605if (ecdsa_verify_set_sig(ctx, sig, siglen))606ok = ecdsa_verify_message_final(ctx);607608ctx->flag_allow_md = 1;609610return ok;611}612613static void ecdsa_freectx(void *vctx)614{615PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;616617EVP_MD_CTX_free(ctx->mdctx);618EVP_MD_free(ctx->md);619OPENSSL_free(ctx->propq);620OPENSSL_free(ctx->sig);621EC_KEY_free(ctx->ec);622BN_clear_free(ctx->kinv);623BN_clear_free(ctx->r);624OPENSSL_free(ctx);625}626627static void *ecdsa_dupctx(void *vctx)628{629PROV_ECDSA_CTX *srcctx = (PROV_ECDSA_CTX *)vctx;630PROV_ECDSA_CTX *dstctx;631632if (!ossl_prov_is_running())633return NULL;634635dstctx = OPENSSL_zalloc(sizeof(*srcctx));636if (dstctx == NULL)637return NULL;638639*dstctx = *srcctx;640dstctx->ec = NULL;641dstctx->propq = NULL;642643if (srcctx->ec != NULL && !EC_KEY_up_ref(srcctx->ec))644goto err;645/* Test KATS should not need to be supported */646if (srcctx->kinv != NULL || srcctx->r != NULL)647goto err;648dstctx->ec = srcctx->ec;649650if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md))651goto err;652dstctx->md = srcctx->md;653654if (srcctx->mdctx != NULL) {655dstctx->mdctx = EVP_MD_CTX_new();656if (dstctx->mdctx == NULL657|| !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx))658goto err;659}660661if (srcctx->propq != NULL) {662dstctx->propq = OPENSSL_strdup(srcctx->propq);663if (dstctx->propq == NULL)664goto err;665}666667return dstctx;668err:669ecdsa_freectx(dstctx);670return NULL;671}672673static int ecdsa_get_ctx_params(void *vctx, OSSL_PARAM *params)674{675PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;676OSSL_PARAM *p;677678if (ctx == NULL)679return 0;680681p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);682if (p != NULL && !OSSL_PARAM_set_octet_string(p, ctx->aid_len == 0 ? NULL : ctx->aid_buf, ctx->aid_len))683return 0;684685p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);686if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->mdsize))687return 0;688689p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST);690if (p != NULL && !OSSL_PARAM_set_utf8_string(p, ctx->md == NULL ? ctx->mdname : EVP_MD_get0_name(ctx->md)))691return 0;692693p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE);694if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->nonce_type))695return 0;696697#ifdef FIPS_MODULE698p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_FIPS_VERIFY_MESSAGE);699if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->verify_message))700return 0;701#endif702703if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))704return 0;705return 1;706}707708static const OSSL_PARAM known_gettable_ctx_params[] = {709OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),710OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),711OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),712OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL),713#ifdef FIPS_MODULE714OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_FIPS_VERIFY_MESSAGE, NULL),715#endif716OSSL_FIPS_IND_GETTABLE_CTX_PARAM()717OSSL_PARAM_END718};719720static const OSSL_PARAM *ecdsa_gettable_ctx_params(ossl_unused void *vctx,721ossl_unused void *provctx)722{723return known_gettable_ctx_params;724}725726/**727* @brief Set up common params for ecdsa_set_ctx_params and728* ecdsa_sigalg_set_ctx_params. The caller is responsible for checking |vctx| is729* not NULL and |params| is not empty.730*/731static int ecdsa_common_set_ctx_params(void *vctx, const OSSL_PARAM params[])732{733PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;734const OSSL_PARAM *p;735736if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,737OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK))738return 0;739if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, params,740OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK))741return 0;742743#if !defined(OPENSSL_NO_ACVP_TESTS)744p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_KAT);745if (p != NULL && !OSSL_PARAM_get_uint(p, &ctx->kattest))746return 0;747#endif748749p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE);750if (p != NULL751&& !OSSL_PARAM_get_uint(p, &ctx->nonce_type))752return 0;753return 1;754}755756#define ECDSA_COMMON_SETTABLE_CTX_PARAMS \757OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_KAT, NULL), \758OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL), \759OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK) \760OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK) \761OSSL_PARAM_END762763static int ecdsa_set_ctx_params(void *vctx, const OSSL_PARAM params[])764{765PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;766const OSSL_PARAM *p;767size_t mdsize = 0;768int ret;769770if (ctx == NULL)771return 0;772if (ossl_param_is_empty(params))773return 1;774775if ((ret = ecdsa_common_set_ctx_params(ctx, params)) <= 0)776return ret;777778p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);779if (p != NULL) {780char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname;781char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops;782const OSSL_PARAM *propsp = OSSL_PARAM_locate_const(params,783OSSL_SIGNATURE_PARAM_PROPERTIES);784785if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname)))786return 0;787if (propsp != NULL788&& !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops)))789return 0;790if (!ecdsa_setup_md(ctx, mdname, mdprops, "ECDSA Set Ctx"))791return 0;792}793794p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);795if (p != NULL) {796if (!OSSL_PARAM_get_size_t(p, &mdsize)797|| (!ctx->flag_allow_md && mdsize != ctx->mdsize))798return 0;799ctx->mdsize = mdsize;800}801return 1;802}803804static const OSSL_PARAM settable_ctx_params[] = {805OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),806OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL),807OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0),808ECDSA_COMMON_SETTABLE_CTX_PARAMS809};810811static const OSSL_PARAM *ecdsa_settable_ctx_params(void *vctx,812ossl_unused void *provctx)813{814return settable_ctx_params;815}816817static int ecdsa_get_ctx_md_params(void *vctx, OSSL_PARAM *params)818{819PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;820821if (ctx->mdctx == NULL)822return 0;823824return EVP_MD_CTX_get_params(ctx->mdctx, params);825}826827static const OSSL_PARAM *ecdsa_gettable_ctx_md_params(void *vctx)828{829PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;830831if (ctx->md == NULL)832return 0;833834return EVP_MD_gettable_ctx_params(ctx->md);835}836837static int ecdsa_set_ctx_md_params(void *vctx, const OSSL_PARAM params[])838{839PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;840841if (ctx->mdctx == NULL)842return 0;843844return EVP_MD_CTX_set_params(ctx->mdctx, params);845}846847static const OSSL_PARAM *ecdsa_settable_ctx_md_params(void *vctx)848{849PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;850851if (ctx->md == NULL)852return 0;853854return EVP_MD_settable_ctx_params(ctx->md);855}856857const OSSL_DISPATCH ossl_ecdsa_signature_functions[] = {858{ OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))ecdsa_newctx },859{ OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))ecdsa_sign_init },860{ OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))ecdsa_sign },861{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))ecdsa_verify_init },862{ OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))ecdsa_verify },863{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,864(void (*)(void))ecdsa_digest_sign_init },865{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE,866(void (*)(void))ecdsa_digest_signverify_update },867{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL,868(void (*)(void))ecdsa_digest_sign_final },869{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,870(void (*)(void))ecdsa_digest_verify_init },871{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE,872(void (*)(void))ecdsa_digest_signverify_update },873{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL,874(void (*)(void))ecdsa_digest_verify_final },875{ OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))ecdsa_freectx },876{ OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))ecdsa_dupctx },877{ OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))ecdsa_get_ctx_params },878{ OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,879(void (*)(void))ecdsa_gettable_ctx_params },880{ OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))ecdsa_set_ctx_params },881{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,882(void (*)(void))ecdsa_settable_ctx_params },883{ OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS,884(void (*)(void))ecdsa_get_ctx_md_params },885{ OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS,886(void (*)(void))ecdsa_gettable_ctx_md_params },887{ OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS,888(void (*)(void))ecdsa_set_ctx_md_params },889{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS,890(void (*)(void))ecdsa_settable_ctx_md_params },891OSSL_DISPATCH_END892};893894/* ------------------------------------------------------------------ */895896/*897* So called sigalgs (composite ECDSA+hash) implemented below. They898* are pretty much hard coded.899*/900901static OSSL_FUNC_signature_query_key_types_fn ecdsa_sigalg_query_key_types;902static OSSL_FUNC_signature_settable_ctx_params_fn ecdsa_sigalg_settable_ctx_params;903static OSSL_FUNC_signature_set_ctx_params_fn ecdsa_sigalg_set_ctx_params;904905/*906* ecdsa_sigalg_signverify_init() is almost like ecdsa_digest_signverify_init(),907* just doesn't allow fetching an MD from whatever the user chooses.908*/909static int ecdsa_sigalg_signverify_init(void *vctx, void *vec,910OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params,911const OSSL_PARAM params[],912const char *mdname,913int operation, const char *desc)914{915PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;916917if (!ossl_prov_is_running())918return 0;919920if (!ecdsa_signverify_init(vctx, vec, set_ctx_params, params, operation,921desc))922return 0;923924if (!ecdsa_setup_md(ctx, mdname, NULL, desc))925return 0;926927ctx->flag_sigalg = 1;928ctx->flag_allow_md = 0;929930if (ctx->mdctx == NULL) {931ctx->mdctx = EVP_MD_CTX_new();932if (ctx->mdctx == NULL)933goto error;934}935936if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params))937goto error;938939return 1;940941error:942EVP_MD_CTX_free(ctx->mdctx);943ctx->mdctx = NULL;944return 0;945}946947static const char **ecdsa_sigalg_query_key_types(void)948{949static const char *keytypes[] = { "EC", NULL };950951return keytypes;952}953954static const OSSL_PARAM settable_sigalg_ctx_params[] = {955OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE, NULL, 0),956ECDSA_COMMON_SETTABLE_CTX_PARAMS957};958959static const OSSL_PARAM *ecdsa_sigalg_settable_ctx_params(void *vctx,960ossl_unused void *provctx)961{962PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;963964if (ctx != NULL && ctx->operation == EVP_PKEY_OP_VERIFYMSG)965return settable_sigalg_ctx_params;966return NULL;967}968969static int ecdsa_sigalg_set_ctx_params(void *vctx, const OSSL_PARAM params[])970{971PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;972const OSSL_PARAM *p;973int ret;974975if (ctx == NULL)976return 0;977if (ossl_param_is_empty(params))978return 1;979980if ((ret = ecdsa_common_set_ctx_params(ctx, params)) <= 0)981return ret;982983if (ctx->operation == EVP_PKEY_OP_VERIFYMSG) {984p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_SIGNATURE);985if (p != NULL) {986OPENSSL_free(ctx->sig);987ctx->sig = NULL;988ctx->siglen = 0;989if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->sig,9900, &ctx->siglen))991return 0;992}993}994return 1;995}996997#define IMPL_ECDSA_SIGALG(md, MD) \998static OSSL_FUNC_signature_sign_init_fn ecdsa_##md##_sign_init; \999static OSSL_FUNC_signature_sign_message_init_fn \1000ecdsa_##md##_sign_message_init; \1001static OSSL_FUNC_signature_verify_init_fn ecdsa_##md##_verify_init; \1002static OSSL_FUNC_signature_verify_message_init_fn \1003ecdsa_##md##_verify_message_init; \1004\1005static int \1006ecdsa_##md##_sign_init(void *vctx, void *vec, \1007const OSSL_PARAM params[]) \1008{ \1009static const char desc[] = "ECDSA-" #MD " Sign Init"; \1010\1011return ecdsa_sigalg_signverify_init(vctx, vec, \1012ecdsa_sigalg_set_ctx_params, \1013params, #MD, \1014EVP_PKEY_OP_SIGN, \1015desc); \1016} \1017\1018static int \1019ecdsa_##md##_sign_message_init(void *vctx, void *vec, \1020const OSSL_PARAM params[]) \1021{ \1022static const char desc[] = "ECDSA-" #MD " Sign Message Init"; \1023\1024return ecdsa_sigalg_signverify_init(vctx, vec, \1025ecdsa_sigalg_set_ctx_params, \1026params, #MD, \1027EVP_PKEY_OP_SIGNMSG, \1028desc); \1029} \1030\1031static int \1032ecdsa_##md##_verify_init(void *vctx, void *vec, \1033const OSSL_PARAM params[]) \1034{ \1035static const char desc[] = "ECDSA-" #MD " Verify Init"; \1036\1037return ecdsa_sigalg_signverify_init(vctx, vec, \1038ecdsa_sigalg_set_ctx_params, \1039params, #MD, \1040EVP_PKEY_OP_VERIFY, \1041desc); \1042} \1043\1044static int \1045ecdsa_##md##_verify_message_init(void *vctx, void *vec, \1046const OSSL_PARAM params[]) \1047{ \1048static const char desc[] = "ECDSA-" #MD " Verify Message Init"; \1049\1050return ecdsa_sigalg_signverify_init(vctx, vec, \1051ecdsa_sigalg_set_ctx_params, \1052params, #MD, \1053EVP_PKEY_OP_VERIFYMSG, \1054desc); \1055} \1056\1057const OSSL_DISPATCH ossl_ecdsa_##md##_signature_functions[] = { \1058{ OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))ecdsa_newctx }, \1059{ OSSL_FUNC_SIGNATURE_SIGN_INIT, \1060(void (*)(void))ecdsa_##md##_sign_init }, \1061{ OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))ecdsa_sign }, \1062{ OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT, \1063(void (*)(void))ecdsa_##md##_sign_message_init }, \1064{ OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_UPDATE, \1065(void (*)(void))ecdsa_signverify_message_update }, \1066{ OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_FINAL, \1067(void (*)(void))ecdsa_sign_message_final }, \1068{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, \1069(void (*)(void))ecdsa_##md##_verify_init }, \1070{ OSSL_FUNC_SIGNATURE_VERIFY, \1071(void (*)(void))ecdsa_verify }, \1072{ OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT, \1073(void (*)(void))ecdsa_##md##_verify_message_init }, \1074{ OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_UPDATE, \1075(void (*)(void))ecdsa_signverify_message_update }, \1076{ OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_FINAL, \1077(void (*)(void))ecdsa_verify_message_final }, \1078{ OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))ecdsa_freectx }, \1079{ OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))ecdsa_dupctx }, \1080{ OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPES, \1081(void (*)(void))ecdsa_sigalg_query_key_types }, \1082{ OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \1083(void (*)(void))ecdsa_get_ctx_params }, \1084{ OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \1085(void (*)(void))ecdsa_gettable_ctx_params }, \1086{ OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \1087(void (*)(void))ecdsa_sigalg_set_ctx_params }, \1088{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \1089(void (*)(void))ecdsa_sigalg_settable_ctx_params }, \1090OSSL_DISPATCH_END \1091}10921093/* clang-format off */1094IMPL_ECDSA_SIGALG(sha1, SHA1);1095IMPL_ECDSA_SIGALG(sha224, SHA2-224);1096IMPL_ECDSA_SIGALG(sha256, SHA2-256);1097IMPL_ECDSA_SIGALG(sha384, SHA2-384);1098IMPL_ECDSA_SIGALG(sha512, SHA2-512);1099IMPL_ECDSA_SIGALG(sha3_224, SHA3-224);1100IMPL_ECDSA_SIGALG(sha3_256, SHA3-256);1101IMPL_ECDSA_SIGALG(sha3_384, SHA3-384);1102IMPL_ECDSA_SIGALG(sha3_512, SHA3-512);1103/* clang-format on */110411051106