Implement EVP_SIGNATURE_hash_message_update() and use it

Implement EVP_SIGNATURE_hash_message_update() to check for support
of EVP_PKEY_sign_message_update() and EVP_PKEY_verify_message_update() and
use this function to replace the has_msg_update column in CMS.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28923)
This commit is contained in:
Stefan Berger
2025-11-06 16:16:01 -06:00
committed by Tomas Mraz
parent de83e65580
commit 28a9d0e52d
5 changed files with 43 additions and 30 deletions

View File

@@ -347,39 +347,35 @@ static const struct {
int md_a_must; /* md is a 'MUST' */
int noattr_md_nid; /* in case of 'without signed attributes' */
int noattr_md_a_must; /* noattr_md is a 'MUST' not a 'SHOULD' */
int has_msg_update;
} key2data[] = {
{ "ML-DSA-44", NID_shake256, 0, NID_sha512, 0, 1, },
{ "ML-DSA-65", NID_shake256, 0, NID_sha512, 0, 1, },
{ "ML-DSA-87", NID_shake256, 0, NID_sha512, 0, 1, },
{ "ED25519", NID_sha512, 0, NID_sha512, 1, 0, }, /* RFC 8419 */
{ "ML-DSA-44", NID_shake256, 0, NID_sha512, 0, },
{ "ML-DSA-65", NID_shake256, 0, NID_sha512, 0, },
{ "ML-DSA-87", NID_shake256, 0, NID_sha512, 0, },
{ "ED25519", NID_sha512, 0, NID_sha512, 1, }, /* RFC 8419 */
/* RFC 8419 3.1 ED448: id-shake256-len MUST be used => NID_undef for now */
{ "ED448", NID_undef, 1, NID_shake256, 1, 0, },
{ "SLH-DSA-SHA2-128f", NID_sha256, 0, NID_sha256, 0, 0, }, /* RFC 9814 */
{ "SLH-DSA-SHA2-128s", NID_sha256, 0, NID_sha256, 0, 0, },
{ "SLH-DSA-SHA2-192f", NID_sha512, 0, NID_sha512, 0, 0, },
{ "SLH-DSA-SHA2-192s", NID_sha512, 0, NID_sha512, 0, 0, },
{ "SLH-DSA-SHA2-256f", NID_sha512, 0, NID_sha512, 0, 0, },
{ "SLH-DSA-SHA2-256s", NID_sha512, 0, NID_sha512, 0, 0, },
{ "SLH-DSA-SHAKE-128f", NID_shake128, 0, NID_shake128, 0, 0, },
{ "SLH-DSA-SHAKE-128s", NID_shake128, 0, NID_shake128, 0, 0, },
{ "SLH-DSA-SHAKE-192f", NID_shake256, 0, NID_shake256, 0, 0, },
{ "SLH-DSA-SHAKE-192s", NID_shake256, 0, NID_shake256, 0, 0, },
{ "SLH-DSA-SHAKE-256f", NID_shake256, 0, NID_shake256, 0, 0, },
{ "SLH-DSA-SHAKE-256s", NID_shake256, 0, NID_shake256, 0, 0, },
{ NULL, NID_undef, 0, NID_undef, 0, 0, } /* last */
{ "ED448", NID_undef, 1, NID_shake256, 1, },
{ "SLH-DSA-SHA2-128f", NID_sha256, 0, NID_sha256, 0, }, /* RFC 9814 */
{ "SLH-DSA-SHA2-128s", NID_sha256, 0, NID_sha256, 0, },
{ "SLH-DSA-SHA2-192f", NID_sha512, 0, NID_sha512, 0, },
{ "SLH-DSA-SHA2-192s", NID_sha512, 0, NID_sha512, 0, },
{ "SLH-DSA-SHA2-256f", NID_sha512, 0, NID_sha512, 0, },
{ "SLH-DSA-SHA2-256s", NID_sha512, 0, NID_sha512, 0, },
{ "SLH-DSA-SHAKE-128f", NID_shake128, 0, NID_shake128, 0, },
{ "SLH-DSA-SHAKE-128s", NID_shake128, 0, NID_shake128, 0, },
{ "SLH-DSA-SHAKE-192f", NID_shake256, 0, NID_shake256, 0, },
{ "SLH-DSA-SHAKE-192s", NID_shake256, 0, NID_shake256, 0, },
{ "SLH-DSA-SHAKE-256f", NID_shake256, 0, NID_shake256, 0, },
{ "SLH-DSA-SHAKE-256s", NID_shake256, 0, NID_shake256, 0, },
{ NULL, NID_undef, 0, NID_undef, 0, } /* last */
};
static const char *cms_mdless_signing(EVP_PKEY *pkey,
int *has_msg_update)
static const char *cms_mdless_signing(EVP_PKEY *pkey)
{
unsigned int i;
for (i = 0; key2data[i].name; i++) {
if (EVP_PKEY_is_a(pkey, key2data[i].name)) {
*has_msg_update = key2data[i].has_msg_update;
if (EVP_PKEY_is_a(pkey, key2data[i].name))
return key2data[i].name;
}
}
return NULL;
}
@@ -1020,8 +1016,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
if (siglen == 0 || (sig = OPENSSL_malloc(siglen)) == NULL)
goto err;
if ((algorithm = cms_mdless_signing(si->pkey,
&has_msg_update)) != NULL) {
if ((algorithm = cms_mdless_signing(si->pkey)) != NULL) {
size_t sig_len;
if (!data) {
@@ -1041,6 +1036,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
goto err;
sig_len = siglen;
has_msg_update = EVP_SIGNATURE_has_message_update(sig_alg);
if (cms_EVP_PKEY_sign(pctx, data, sig, &sig_len,
has_msg_update) != 1)
goto err;
@@ -1337,8 +1333,7 @@ int CMS_SignerInfo_verify_ex(CMS_SignerInfo *si, BIO *chain, BIO *data)
if (pkctx == NULL)
goto err;
if ((algorithm = cms_mdless_signing(si->pkey,
&has_msg_update)) != NULL) {
if ((algorithm = cms_mdless_signing(si->pkey)) != NULL) {
if (!data) {
ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT);
goto err;
@@ -1350,6 +1345,7 @@ int CMS_SignerInfo_verify_ex(CMS_SignerInfo *si, BIO *chain, BIO *data)
if (EVP_PKEY_verify_message_init(pkctx, sig_alg, NULL) != 1)
goto err;
has_msg_update = EVP_SIGNATURE_has_message_update(sig_alg);
r = cms_EVP_PKEY_verify(pkctx, data, si->signature->data,
si->signature->length, has_msg_update);
} else {

View File

@@ -510,6 +510,12 @@ int EVP_SIGNATURE_is_a(const EVP_SIGNATURE *signature, const char *name)
&& evp_is_a(signature->prov, signature->name_id, NULL, name);
}
int EVP_SIGNATURE_has_message_update(const EVP_SIGNATURE *signature)
{
return signature->verify_message_update != NULL
&& signature->sign_message_update != NULL;
}
int evp_signature_get_number(const EVP_SIGNATURE *signature)
{
return signature->name_id;

View File

@@ -7,7 +7,8 @@ EVP_SIGNATURE_fetch, EVP_SIGNATURE_free, EVP_SIGNATURE_up_ref,
EVP_SIGNATURE_is_a, EVP_SIGNATURE_get0_provider,
EVP_SIGNATURE_do_all_provided, EVP_SIGNATURE_names_do_all,
EVP_SIGNATURE_get0_name, EVP_SIGNATURE_get0_description,
EVP_SIGNATURE_gettable_ctx_params, EVP_SIGNATURE_settable_ctx_params
EVP_SIGNATURE_gettable_ctx_params, EVP_SIGNATURE_settable_ctx_params,
EVP_SIGNATURE_has_message_update
- Functions to manage EVP_SIGNATURE algorithm objects
=head1 SYNOPSIS
@@ -34,6 +35,7 @@ EVP_SIGNATURE_gettable_ctx_params, EVP_SIGNATURE_settable_ctx_params
const char *EVP_SIGNATURE_get0_description(const EVP_SIGNATURE *signature);
const OSSL_PARAM *EVP_SIGNATURE_gettable_ctx_params(const EVP_SIGNATURE *sig);
const OSSL_PARAM *EVP_SIGNATURE_settable_ctx_params(const EVP_SIGNATURE *sig);
int EVP_SIGNATURE_has_message_update(const EVP_SIGNATURE *sig);
=head1 DESCRIPTION
@@ -83,6 +85,9 @@ return a constant L<OSSL_PARAM(3)> array that describes the names and types of k
parameters that can be retrieved or set by a signature algorithm using
L<EVP_PKEY_CTX_get_params(3)> and L<EVP_PKEY_CTX_set_params(3)>.
EVP_SIGNATURE_has_message_update() checks whether EVP_PKEY_sign_message_update()
and EVP_PKEY_verify_message_update() are both supported.
=head1 RETURN VALUES
EVP_SIGNATURE_fetch() returns a pointer to an B<EVP_SIGNATURE> for success
@@ -96,13 +101,17 @@ A return value of 0 means that the callback was not called for any names.
EVP_SIGNATURE_gettable_ctx_params() and EVP_SIGNATURE_settable_ctx_params()
return a constant L<OSSL_PARAM(3)> array or NULL on error.
EVP_SIGNATURE_has_message_update() returns 1 if EVP_PKEY_sign_message_update()
and EVP_PKEY_verify_message_update() are both supported, 0 otherwise.
=head1 SEE ALSO
L<crypto(7)/ALGORITHM FETCHING>, L<OSSL_PROVIDER(3)>
=head1 HISTORY
The functions described here were added in OpenSSL 3.0.
Most functions described here were added in OpenSSL 3.0, except for
EVP_PKEY_verify_message_update(), which was added in OpenSSL 4.0.
=head1 COPYRIGHT

View File

@@ -1982,6 +1982,7 @@ int EVP_SIGNATURE_names_do_all(const EVP_SIGNATURE *signature,
void *data);
const OSSL_PARAM *EVP_SIGNATURE_gettable_ctx_params(const EVP_SIGNATURE *sig);
const OSSL_PARAM *EVP_SIGNATURE_settable_ctx_params(const EVP_SIGNATURE *sig);
int EVP_SIGNATURE_has_message_update(const EVP_SIGNATURE *sig);
void EVP_ASYM_CIPHER_free(EVP_ASYM_CIPHER *cipher);
int EVP_ASYM_CIPHER_up_ref(EVP_ASYM_CIPHER *cipher);

View File

@@ -5945,3 +5945,4 @@ OPENSSL_timegm ? 4_0_0 EXIST::FUNCTION:
OSSL_PARAM_clear_free ? 4_0_0 EXIST::FUNCTION:
CMS_dataFinal_ex ? 4_0_0 EXIST::FUNCTION:CMS
CMS_SignerInfo_verify_ex ? 4_0_0 EXIST::FUNCTION:CMS
EVP_SIGNATURE_has_message_update ? 4_0_0 EXIST::FUNCTION: