crypto/evp: compensate for providers not adding error queue entries for keymgmt, sigver, and asymcipher

Reviewed-by: Nicola Tuveri <nic.tuv@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/27367)
This commit is contained in:
Dr. David von Oheimb 2025-04-13 07:25:46 +02:00 committed by Tomas Mraz
parent 1fc96a3cff
commit 72351b0d18
6 changed files with 146 additions and 33 deletions

View File

@ -803,6 +803,12 @@ EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED:179:\
pkey application asn1 method already registered
EVP_R_PRIVATE_KEY_DECODE_ERROR:145:private key decode error
EVP_R_PRIVATE_KEY_ENCODE_ERROR:146:private key encode error
EVP_R_PROVIDER_ASYM_CIPHER_FAILURE:232:provider asym cipher failure
EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED:235:provider asym cipher not supported
EVP_R_PROVIDER_KEYMGMT_FAILURE:233:provider keymgmt failure
EVP_R_PROVIDER_KEYMGMT_NOT_SUPPORTED:236:provider keymgmt not supported
EVP_R_PROVIDER_SIGNATURE_FAILURE:234:provider signature failure
EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED:237:provider signature not supported
EVP_R_PUBLIC_KEY_NOT_RSA:106:public key not rsa
EVP_R_SETTING_XOF_FAILED:227:setting xof failed
EVP_R_SET_DEFAULT_PROPERTY_FAILURE:209:set default property failure

View File

@ -33,6 +33,7 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation,
int ret = 0;
void *provkey = NULL;
EVP_ASYM_CIPHER *cipher = NULL;
const char *desc;
EVP_KEYMGMT *tmp_keymgmt = NULL;
const OSSL_PROVIDER *tmp_prov = NULL;
const char *supported_ciph = NULL;
@ -159,10 +160,12 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation,
goto err;
}
desc = cipher->description != NULL ? cipher->description : "";
switch (operation) {
case EVP_PKEY_OP_ENCRYPT:
if (cipher->encrypt_init == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED,
"%s encrypt_init:%s", cipher->type_name, desc);
ret = -2;
goto err;
}
@ -170,7 +173,8 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation,
break;
case EVP_PKEY_OP_DECRYPT:
if (cipher->decrypt_init == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED,
"%s decrypt_init:%s", cipher->type_name, desc);
ret = -2;
goto err;
}
@ -238,6 +242,8 @@ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen)
{
EVP_ASYM_CIPHER *cipher;
const char *desc;
int ret;
if (ctx == NULL) {
@ -253,8 +259,12 @@ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
if (ctx->op.ciph.algctx == NULL)
goto legacy;
ret = ctx->op.ciph.cipher->encrypt(ctx->op.ciph.algctx, out, outlen,
(out == NULL ? 0 : *outlen), in, inlen);
cipher = ctx->op.ciph.cipher;
desc = cipher->description != NULL ? cipher->description : "";
ret = cipher->encrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen);
if (ret <= 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE,
"%s encrypt:%s", cipher->type_name, desc);
return ret;
legacy:
@ -280,6 +290,8 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen)
{
EVP_ASYM_CIPHER *cipher;
const char *desc;
int ret;
if (ctx == NULL) {
@ -295,8 +307,13 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
if (ctx->op.ciph.algctx == NULL)
goto legacy;
ret = ctx->op.ciph.cipher->decrypt(ctx->op.ciph.algctx, out, outlen,
(out == NULL ? 0 : *outlen), in, inlen);
cipher = ctx->op.ciph.cipher;
desc = cipher->description != NULL ? cipher->description : "";
ret = cipher->decrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen);
if (ret <= 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE,
"%s decrypt:%s", cipher->type_name, desc);
return ret;
legacy:

View File

@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-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
@ -151,6 +151,18 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
"private key decode error"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PRIVATE_KEY_ENCODE_ERROR),
"private key encode error"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE),
"provider asym cipher failure"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED),
"provider asym cipher not supported"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_KEYMGMT_FAILURE),
"provider keymgmt failure"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_KEYMGMT_NOT_SUPPORTED),
"provider keymgmt not supported"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_SIGNATURE_FAILURE),
"provider signature failure"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED),
"provider signature not supported"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SETTING_XOF_FAILED), "setting xof failed"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SET_DEFAULT_PROPERTY_FAILURE),

View File

@ -451,9 +451,20 @@ const OSSL_PARAM *EVP_KEYMGMT_gen_gettable_params(const EVP_KEYMGMT *keymgmt)
void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx,
OSSL_CALLBACK *cb, void *cbarg)
{
if (keymgmt->gen == NULL)
void *ret;
const char *desc = keymgmt->description != NULL ? keymgmt->description : "";
if (keymgmt->gen == NULL) {
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_KEYMGMT_NOT_SUPPORTED,
"%s key generation:%s", keymgmt->type_name, desc);
return NULL;
return keymgmt->gen(genctx, cb, cbarg);
}
ret = keymgmt->gen(genctx, cb, cbarg);
if (ret == NULL)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_KEYMGMT_FAILURE,
"%s key generation:%s", keymgmt->type_name, desc);
return ret;
}
void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx)

View File

@ -42,6 +42,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
{
EVP_PKEY_CTX *locpctx = NULL;
EVP_SIGNATURE *signature = NULL;
const char *desc;
EVP_KEYMGMT *tmp_keymgmt = NULL;
const OSSL_PROVIDER *tmp_prov = NULL;
const char *supported_sig = NULL;
@ -251,16 +252,19 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
}
}
desc = signature->description != NULL ? signature->description : "";
if (ver) {
if (signature->digest_verify_init == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
"%s digest_verify_init:%s", signature->type_name, desc);
goto err;
}
ret = signature->digest_verify_init(locpctx->op.sig.algctx,
mdname, provkey, params);
} else {
if (signature->digest_sign_init == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
"%s digest_sign_init:%s", signature->type_name, desc);
goto err;
}
ret = signature->digest_sign_init(locpctx->op.sig.algctx,
@ -275,6 +279,9 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
goto end;
if (type == NULL) /* This check is redundant but clarifies matters */
ERR_raise(ERR_LIB_EVP, EVP_R_NO_DEFAULT_DIGEST);
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
ver ? "%s digest_verify_init:%s" : "%s digest_sign_init:%s",
signature->type_name, desc);
err:
evp_pkey_ctx_free_old_ops(locpctx);
@ -395,7 +402,10 @@ int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
{
EVP_SIGNATURE *signature;
const char *desc;
EVP_PKEY_CTX *pctx = ctx->pctx;
int ret;
if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
@ -408,13 +418,19 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
|| pctx->op.sig.signature == NULL)
goto legacy;
if (pctx->op.sig.signature->digest_sign_update == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
signature = pctx->op.sig.signature;
desc = signature->description != NULL ? signature->description : "";
if (signature->digest_sign_update == NULL) {
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
"%s digest_sign_update:%s", signature->type_name, desc);
return 0;
}
return pctx->op.sig.signature->digest_sign_update(pctx->op.sig.algctx,
data, dsize);
ret = signature->digest_sign_update(pctx->op.sig.algctx, data, dsize);
if (ret <= 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
"%s digest_sign_update:%s", signature->type_name, desc);
return ret;
legacy:
if (pctx != NULL) {
@ -430,7 +446,10 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
{
EVP_SIGNATURE *signature;
const char *desc;
EVP_PKEY_CTX *pctx = ctx->pctx;
int ret;
if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
@ -443,13 +462,19 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
|| pctx->op.sig.signature == NULL)
goto legacy;
if (pctx->op.sig.signature->digest_verify_update == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
signature = pctx->op.sig.signature;
desc = signature->description != NULL ? signature->description : "";
if (signature->digest_verify_update == NULL) {
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
"%s digest_verify_update:%s", signature->type_name, desc);
return 0;
}
return pctx->op.sig.signature->digest_verify_update(pctx->op.sig.algctx,
data, dsize);
ret = signature->digest_verify_update(pctx->op.sig.algctx, data, dsize);
if (ret <= 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
"%s digest_verify_update:%s", signature->type_name, desc);
return ret;
legacy:
if (pctx != NULL) {
@ -466,6 +491,8 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
size_t *siglen)
{
EVP_SIGNATURE *signature;
const char *desc;
int sctx = 0;
int r = 0;
EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx;
@ -487,9 +514,18 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
if (dctx != NULL)
pctx = dctx;
}
r = pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx,
sigret, siglen,
sigret == NULL ? 0 : *siglen);
signature = pctx->op.sig.signature;
desc = signature->description != NULL ? signature->description : "";
if (signature->digest_sign_final == NULL) {
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
"%s digest_sign_final:%s", signature->type_name, desc);
return 0;
}
r = signature->digest_sign_final(pctx->op.sig.algctx, sigret, siglen,
sigret == NULL ? 0 : *siglen);
if (!r)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
"%s digest_sign_final:%s", signature->type_name, desc);
if (dctx == NULL && sigret != NULL)
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
else
@ -574,6 +610,7 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
const unsigned char *tbs, size_t tbslen)
{
EVP_PKEY_CTX *pctx = ctx->pctx;
int ret;
if (pctx == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
@ -588,13 +625,19 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
if (pctx->operation == EVP_PKEY_OP_SIGNCTX
&& pctx->op.sig.algctx != NULL
&& pctx->op.sig.signature != NULL) {
if (pctx->op.sig.signature->digest_sign != NULL) {
EVP_SIGNATURE *signature = pctx->op.sig.signature;
if (signature->digest_sign != NULL) {
const char *desc = signature->description != NULL ? signature->description : "";
if (sigret != NULL)
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
return pctx->op.sig.signature->digest_sign(pctx->op.sig.algctx,
sigret, siglen,
sigret == NULL ? 0 : *siglen,
tbs, tbslen);
ret = signature->digest_sign(pctx->op.sig.algctx, sigret, siglen,
sigret == NULL ? 0 : *siglen, tbs, tbslen);
if (ret <= 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
"%s digest_sign:%s", signature->type_name, desc);
return ret;
}
} else {
/* legacy */
@ -610,6 +653,8 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
size_t siglen)
{
EVP_SIGNATURE *signature;
const char *desc;
int vctx = 0;
unsigned int mdlen = 0;
unsigned char md[EVP_MAX_MD_SIZE];
@ -633,8 +678,18 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
if (dctx != NULL)
pctx = dctx;
}
r = pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx,
sig, siglen);
signature = pctx->op.sig.signature;
desc = signature->description != NULL ? signature->description : "";
if (signature->digest_verify_final == NULL) {
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
"%s digest_verify_final:%s", signature->type_name, desc);
return 0;
}
r = signature->digest_verify_final(pctx->op.sig.algctx, sig, siglen);
if (!r)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
"%s digest_verify_final:%s", signature->type_name, desc);
if (dctx == NULL)
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
else
@ -702,10 +757,16 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
&& pctx->op.sig.algctx != NULL
&& pctx->op.sig.signature != NULL) {
if (pctx->op.sig.signature->digest_verify != NULL) {
EVP_SIGNATURE *signature = pctx->op.sig.signature;
const char *desc = signature->description != NULL ? signature->description : "";
int ret;
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
return pctx->op.sig.signature->digest_verify(pctx->op.sig.algctx,
sigret, siglen,
tbs, tbslen);
ret = signature->digest_verify(pctx->op.sig.algctx, sigret, siglen, tbs, tbslen);
if (ret <= 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
"%s digest_verify:%s", signature->type_name, desc);
return ret;
}
} else {
/* legacy */

View File

@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-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
@ -104,6 +104,12 @@
# define EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED 179
# define EVP_R_PRIVATE_KEY_DECODE_ERROR 145
# define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146
# define EVP_R_PROVIDER_ASYM_CIPHER_FAILURE 232
# define EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED 235
# define EVP_R_PROVIDER_KEYMGMT_FAILURE 233
# define EVP_R_PROVIDER_KEYMGMT_NOT_SUPPORTED 236
# define EVP_R_PROVIDER_SIGNATURE_FAILURE 234
# define EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED 237
# define EVP_R_PUBLIC_KEY_NOT_RSA 106
# define EVP_R_SETTING_XOF_FAILED 227
# define EVP_R_SET_DEFAULT_PROPERTY_FAILURE 209