summaryrefslogtreecommitdiff
path: root/openssh-9.3p1-merged-openssl-evp.patch
diff options
context:
space:
mode:
Diffstat (limited to 'openssh-9.3p1-merged-openssl-evp.patch')
-rw-r--r--openssh-9.3p1-merged-openssl-evp.patch1228
1 files changed, 0 insertions, 1228 deletions
diff --git a/openssh-9.3p1-merged-openssl-evp.patch b/openssh-9.3p1-merged-openssl-evp.patch
deleted file mode 100644
index d8c2ca3..0000000
--- a/openssh-9.3p1-merged-openssl-evp.patch
+++ /dev/null
@@ -1,1228 +0,0 @@
-diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/digest.h openssh-9.3p1-patched/digest.h
---- openssh-9.3p1/digest.h 2023-03-15 22:28:19.000000000 +0100
-+++ openssh-9.3p1-patched/digest.h 2023-06-06 15:52:25.602551466 +0200
-@@ -32,6 +32,12 @@
- struct sshbuf;
- struct ssh_digest_ctx;
-
-+#ifdef WITH_OPENSSL
-+#include <openssl/evp.h>
-+/* Converts internal digest representation to the OpenSSL one */
-+const EVP_MD *ssh_digest_to_md(int digest_type);
-+#endif
-+
- /* Looks up a digest algorithm by name */
- int ssh_digest_alg_by_name(const char *name);
-
-diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/digest-openssl.c openssh-9.3p1-patched/digest-openssl.c
---- openssh-9.3p1/digest-openssl.c 2023-03-15 22:28:19.000000000 +0100
-+++ openssh-9.3p1-patched/digest-openssl.c 2023-06-06 15:52:25.601551454 +0200
-@@ -64,6 +64,22 @@
- { -1, NULL, 0, NULL },
- };
-
-+const EVP_MD *
-+ssh_digest_to_md(int digest_type)
-+{
-+ switch (digest_type) {
-+ case SSH_DIGEST_SHA1:
-+ return EVP_sha1();
-+ case SSH_DIGEST_SHA256:
-+ return EVP_sha256();
-+ case SSH_DIGEST_SHA384:
-+ return EVP_sha384();
-+ case SSH_DIGEST_SHA512:
-+ return EVP_sha512();
-+ }
-+ return NULL;
-+}
-+
- static const struct ssh_digest *
- ssh_digest_by_alg(int alg)
- {
-diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-dss.c openssh-9.3p1-patched/ssh-dss.c
---- openssh-9.3p1/ssh-dss.c 2023-03-15 22:28:19.000000000 +0100
-+++ openssh-9.3p1-patched/ssh-dss.c 2023-06-06 15:52:25.624551743 +0200
-@@ -32,6 +32,8 @@
- #include <openssl/bn.h>
- #include <openssl/dsa.h>
- #include <openssl/evp.h>
-+#include <openssl/core_names.h>
-+#include <openssl/param_build.h>
-
- #include <stdarg.h>
- #include <string.h>
-@@ -261,11 +263,15 @@
- const u_char *data, size_t datalen,
- const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
- {
-+ EVP_PKEY *pkey = NULL;
- DSA_SIG *sig = NULL;
- const BIGNUM *sig_r, *sig_s;
-- u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
-- size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
-+ u_char sigblob[SIGBLOB_LEN];
-+ size_t rlen, slen;
-+ int len;
- struct sshbuf *b = NULL;
-+ u_char *sigb = NULL;
-+ const u_char *psig = NULL;
- int ret = SSH_ERR_INVALID_ARGUMENT;
-
- if (lenp != NULL)
-@@ -276,17 +282,23 @@
- if (key == NULL || key->dsa == NULL ||
- sshkey_type_plain(key->type) != KEY_DSA)
- return SSH_ERR_INVALID_ARGUMENT;
-- if (dlen == 0)
-- return SSH_ERR_INTERNAL_ERROR;
-
-- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
-- digest, sizeof(digest))) != 0)
-+ if ((ret = ssh_create_evp_dss(key, &pkey)) != 0)
-+ return ret;
-+ ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len,
-+ data, datalen);
-+ EVP_PKEY_free(pkey);
-+ if (ret < 0) {
- goto out;
-+ }
-
-- if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) {
-+ psig = sigb;
-+ if ((sig = d2i_DSA_SIG(NULL, &psig, len)) == NULL) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
-+ free(sigb);
-+ sigb = NULL;
-
- DSA_SIG_get0(sig, &sig_r, &sig_s);
- rlen = BN_num_bytes(sig_r);
-@@ -319,7 +331,7 @@
- *lenp = len;
- ret = 0;
- out:
-- explicit_bzero(digest, sizeof(digest));
-+ free(sigb);
- DSA_SIG_free(sig);
- sshbuf_free(b);
- return ret;
-@@ -331,20 +343,20 @@
- const u_char *data, size_t dlen, const char *alg, u_int compat,
- struct sshkey_sig_details **detailsp)
- {
-+ EVP_PKEY *pkey = NULL;
- DSA_SIG *dsig = NULL;
- BIGNUM *sig_r = NULL, *sig_s = NULL;
-- u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL;
-- size_t len, hlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
-+ u_char *sigblob = NULL;
-+ size_t len, slen;
- int ret = SSH_ERR_INTERNAL_ERROR;
- struct sshbuf *b = NULL;
- char *ktype = NULL;
-+ u_char *sigb = NULL, *psig = NULL;
-
- if (key == NULL || key->dsa == NULL ||
- sshkey_type_plain(key->type) != KEY_DSA ||
- sig == NULL || siglen == 0)
- return SSH_ERR_INVALID_ARGUMENT;
-- if (hlen == 0)
-- return SSH_ERR_INTERNAL_ERROR;
-
- /* fetch signature */
- if ((b = sshbuf_from(sig, siglen)) == NULL)
-@@ -386,25 +398,28 @@
- }
- sig_r = sig_s = NULL; /* transferred */
-
-- /* sha1 the data */
-- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, dlen,
-- digest, sizeof(digest))) != 0)
-+ if ((slen = i2d_DSA_SIG(dsig, NULL)) == 0) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
--
-- switch (DSA_do_verify(digest, hlen, dsig, key->dsa)) {
-- case 1:
-- ret = 0;
-- break;
-- case 0:
-- ret = SSH_ERR_SIGNATURE_INVALID;
-+ }
-+ if ((sigb = malloc(slen)) == NULL) {
-+ ret = SSH_ERR_ALLOC_FAIL;
- goto out;
-- default:
-+ }
-+ psig = sigb;
-+ if ((slen = i2d_DSA_SIG(dsig, &psig)) == 0) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
-
-+ if ((ret = ssh_create_evp_dss(key, &pkey)) != 0)
-+ goto out;
-+ ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, dlen,
-+ sigb, slen);
-+ EVP_PKEY_free(pkey);
-+
- out:
-- explicit_bzero(digest, sizeof(digest));
-+ free(sigb);
- DSA_SIG_free(dsig);
- BN_clear_free(sig_r);
- BN_clear_free(sig_s);
-@@ -415,6 +430,65 @@
- return ret;
- }
-
-+int
-+ssh_create_evp_dss(const struct sshkey *k, EVP_PKEY **pkey)
-+{
-+ OSSL_PARAM_BLD *param_bld = NULL;
-+ EVP_PKEY_CTX *ctx = NULL;
-+ const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *priv = NULL;
-+ int ret = 0;
-+
-+ if (k == NULL)
-+ return SSH_ERR_INVALID_ARGUMENT;
-+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL)) == NULL ||
-+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
-+ ret = SSH_ERR_ALLOC_FAIL;
-+ goto out;
-+ }
-+
-+ DSA_get0_pqg(k->dsa, &p, &q, &g);
-+ DSA_get0_key(k->dsa, &pub, &priv);
-+
-+ if (p != NULL &&
-+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ if (q != NULL &&
-+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ if (g != NULL &&
-+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ if (pub != NULL &&
-+ OSSL_PARAM_BLD_push_BN(param_bld,
-+ OSSL_PKEY_PARAM_PUB_KEY,
-+ pub) != 1) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ if (priv != NULL &&
-+ OSSL_PARAM_BLD_push_BN(param_bld,
-+ OSSL_PKEY_PARAM_PRIV_KEY,
-+ priv) != 1) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+
-+out:
-+ OSSL_PARAM_BLD_free(param_bld);
-+ EVP_PKEY_CTX_free(ctx);
-+ return ret;
-+}
-+
- static const struct sshkey_impl_funcs sshkey_dss_funcs = {
- /* .size = */ ssh_dss_size,
- /* .alloc = */ ssh_dss_alloc,
-diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-ecdsa.c openssh-9.3p1-patched/ssh-ecdsa.c
---- openssh-9.3p1/ssh-ecdsa.c 2023-03-15 22:28:19.000000000 +0100
-+++ openssh-9.3p1-patched/ssh-ecdsa.c 2023-06-06 15:52:25.626551768 +0200
-@@ -34,6 +34,8 @@
- #include <openssl/ec.h>
- #include <openssl/ecdsa.h>
- #include <openssl/evp.h>
-+#include <openssl/core_names.h>
-+#include <openssl/param_build.h>
-
- #include <string.h>
-
-@@ -126,19 +128,29 @@
- static int
- ssh_ecdsa_generate(struct sshkey *k, int bits)
- {
-- EC_KEY *private;
-+ EVP_PKEY_CTX *ctx = NULL;
-+ EVP_PKEY *res = NULL;
-
- if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
- return SSH_ERR_KEY_LENGTH;
-- if ((private = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL)
-+
-+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL)
- return SSH_ERR_ALLOC_FAIL;
-- if (EC_KEY_generate_key(private) != 1) {
-- EC_KEY_free(private);
-+
-+ if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(k->ecdsa_nid)) <= 0
-+ || EVP_PKEY_keygen(ctx, &res) <= 0) {
-+ EVP_PKEY_CTX_free(ctx);
-+ EVP_PKEY_free(res);
- return SSH_ERR_LIBCRYPTO_ERROR;
- }
-- EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
-- k->ecdsa = private;
-- return 0;
-+ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/
-+ k->ecdsa = EVP_PKEY_get1_EC_KEY(res);
-+ if (k->ecdsa)
-+ EC_KEY_set_asn1_flag(k->ecdsa, OPENSSL_EC_NAMED_CURVE);
-+
-+ EVP_PKEY_CTX_free(ctx);
-+ EVP_PKEY_free(res);
-+ return (k->ecdsa) ? 0 : SSH_ERR_LIBCRYPTO_ERROR;
- }
-
- static int
-@@ -228,11 +240,13 @@
- const u_char *data, size_t dlen,
- const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
- {
-+ EVP_PKEY *pkey = NULL;
- ECDSA_SIG *esig = NULL;
-+ unsigned char *sigb = NULL;
-+ const unsigned char *psig;
- const BIGNUM *sig_r, *sig_s;
- int hash_alg;
-- u_char digest[SSH_DIGEST_MAX_LENGTH];
-- size_t len, hlen;
-+ int len;
- struct sshbuf *b = NULL, *bb = NULL;
- int ret = SSH_ERR_INTERNAL_ERROR;
-
-@@ -245,18 +259,33 @@
- sshkey_type_plain(key->type) != KEY_ECDSA)
- return SSH_ERR_INVALID_ARGUMENT;
-
-- if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
-- (hlen = ssh_digest_bytes(hash_alg)) == 0)
-+ if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
- return SSH_ERR_INTERNAL_ERROR;
-- if ((ret = ssh_digest_memory(hash_alg, data, dlen,
-- digest, sizeof(digest))) != 0)
-+
-+#ifdef ENABLE_PKCS11
-+ if (is_ecdsa_pkcs11(key->ecdsa)) {
-+ if ((pkey = EVP_PKEY_new()) == NULL ||
-+ EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1)
-+ return SSH_ERR_ALLOC_FAIL;
-+ } else {
-+#endif
-+ if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0)
-+ return ret;
-+#ifdef ENABLE_PKCS11
-+ }
-+#endif
-+ ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data,
-+ dlen);
-+ EVP_PKEY_free(pkey);
-+ if (ret < 0) {
- goto out;
-+ }
-
-- if ((esig = ECDSA_do_sign(digest, hlen, key->ecdsa)) == NULL) {
-+ psig = sigb;
-+ if (d2i_ECDSA_SIG(&esig, &psig, len) == NULL) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
--
- if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
-@@ -280,7 +309,7 @@
- *lenp = len;
- ret = 0;
- out:
-- explicit_bzero(digest, sizeof(digest));
-+ free(sigb);
- sshbuf_free(b);
- sshbuf_free(bb);
- ECDSA_SIG_free(esig);
-@@ -293,22 +322,21 @@
- const u_char *data, size_t dlen, const char *alg, u_int compat,
- struct sshkey_sig_details **detailsp)
- {
-+ EVP_PKEY *pkey = NULL;
- ECDSA_SIG *esig = NULL;
- BIGNUM *sig_r = NULL, *sig_s = NULL;
-- int hash_alg;
-- u_char digest[SSH_DIGEST_MAX_LENGTH];
-- size_t hlen;
-+ int hash_alg, len;
- int ret = SSH_ERR_INTERNAL_ERROR;
- struct sshbuf *b = NULL, *sigbuf = NULL;
- char *ktype = NULL;
-+ unsigned char *sigb = NULL, *psig = NULL;
-
- if (key == NULL || key->ecdsa == NULL ||
- sshkey_type_plain(key->type) != KEY_ECDSA ||
- sig == NULL || siglen == 0)
- return SSH_ERR_INVALID_ARGUMENT;
-
-- if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
-- (hlen = ssh_digest_bytes(hash_alg)) == 0)
-+ if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
- return SSH_ERR_INTERNAL_ERROR;
-
- /* fetch signature */
-@@ -344,28 +372,33 @@
- }
- sig_r = sig_s = NULL; /* transferred */
-
-- if (sshbuf_len(sigbuf) != 0) {
-- ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
-+ /* Figure out the length */
-+ if ((len = i2d_ECDSA_SIG(esig, NULL)) == 0) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
-- if ((ret = ssh_digest_memory(hash_alg, data, dlen,
-- digest, sizeof(digest))) != 0)
-- goto out;
--
-- switch (ECDSA_do_verify(digest, hlen, esig, key->ecdsa)) {
-- case 1:
-- ret = 0;
-- break;
-- case 0:
-- ret = SSH_ERR_SIGNATURE_INVALID;
-+ if ((sigb = malloc(len)) == NULL) {
-+ ret = SSH_ERR_ALLOC_FAIL;
- goto out;
-- default:
-+ }
-+ psig = sigb;
-+ if ((len = i2d_ECDSA_SIG(esig, &psig)) == 0) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
-
-+ if (sshbuf_len(sigbuf) != 0) {
-+ ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
-+ goto out;
-+ }
-+
-+ if (ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey) != 0)
-+ goto out;
-+ ret = sshkey_verify_signature(pkey, hash_alg, data, dlen, sigb, len);
-+ EVP_PKEY_free(pkey);
-+
- out:
-- explicit_bzero(digest, sizeof(digest));
-+ free(sigb);
- sshbuf_free(sigbuf);
- sshbuf_free(b);
- ECDSA_SIG_free(esig);
-@@ -375,6 +408,79 @@
- return ret;
- }
-
-+int
-+ssh_create_evp_ec(EC_KEY *k, int ecdsa_nid, EVP_PKEY **pkey)
-+{
-+ OSSL_PARAM_BLD *param_bld = NULL;
-+ EVP_PKEY_CTX *ctx = NULL;
-+ BN_CTX *bn_ctx = NULL;
-+ uint8_t *pub_ser = NULL;
-+ const char *group_name;
-+ const EC_POINT *pub = NULL;
-+ const BIGNUM *priv = NULL;
-+ int ret = 0;
-+
-+ if (k == NULL)
-+ return SSH_ERR_INVALID_ARGUMENT;
-+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL ||
-+ (param_bld = OSSL_PARAM_BLD_new()) == NULL ||
-+ (bn_ctx = BN_CTX_new()) == NULL) {
-+ ret = SSH_ERR_ALLOC_FAIL;
-+ goto out;
-+ }
-+
-+ if ((group_name = OSSL_EC_curve_nid2name(ecdsa_nid)) == NULL ||
-+ OSSL_PARAM_BLD_push_utf8_string(param_bld,
-+ OSSL_PKEY_PARAM_GROUP_NAME,
-+ group_name,
-+ strlen(group_name)) != 1) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ if ((pub = EC_KEY_get0_public_key(k)) != NULL) {
-+ const EC_GROUP *group;
-+ size_t len;
-+
-+ group = EC_KEY_get0_group(k);
-+ len = EC_POINT_point2oct(group, pub,
-+ POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
-+ if ((pub_ser = malloc(len)) == NULL) {
-+ ret = SSH_ERR_ALLOC_FAIL;
-+ goto out;
-+ }
-+ EC_POINT_point2oct(group,
-+ pub,
-+ POINT_CONVERSION_UNCOMPRESSED,
-+ pub_ser,
-+ len,
-+ bn_ctx);
-+ if (OSSL_PARAM_BLD_push_octet_string(param_bld,
-+ OSSL_PKEY_PARAM_PUB_KEY,
-+ pub_ser,
-+ len) != 1) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ }
-+ if ((priv = EC_KEY_get0_private_key(k)) != NULL &&
-+ OSSL_PARAM_BLD_push_BN(param_bld,
-+ OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+
-+out:
-+ OSSL_PARAM_BLD_free(param_bld);
-+ EVP_PKEY_CTX_free(ctx);
-+ BN_CTX_free(bn_ctx);
-+ free(pub_ser);
-+ return ret;
-+}
-+
- /* NB. not static; used by ECDSA-SK */
- const struct sshkey_impl_funcs sshkey_ecdsa_funcs = {
- /* .size = */ ssh_ecdsa_size,
-diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/sshkey.c openssh-9.3p1-patched/sshkey.c
---- openssh-9.3p1/sshkey.c 2023-06-06 15:53:36.608444190 +0200
-+++ openssh-9.3p1-patched/sshkey.c 2023-06-06 15:52:25.625551756 +0200
-@@ -34,6 +34,8 @@
- #include <openssl/evp.h>
- #include <openssl/err.h>
- #include <openssl/pem.h>
-+#include <openssl/core_names.h>
-+#include <openssl/param_build.h>
- #endif
-
- #include "crypto_api.h"
-@@ -57,6 +59,7 @@
- #define SSHKEY_INTERNAL
- #include "sshkey.h"
- #include "match.h"
-+#include "log.h"
- #include "ssh-sk.h"
-
- #ifdef WITH_XMSS
-@@ -575,6 +577,86 @@
- }
-
- #ifdef WITH_OPENSSL
-+int
-+sshkey_calculate_signature(EVP_PKEY *pkey, int hash_alg, u_char **sigp,
-+ int *lenp, const u_char *data, size_t datalen)
-+{
-+ EVP_MD_CTX *ctx = NULL;
-+ u_char *sig = NULL;
-+ int ret, slen;
-+ size_t len;
-+
-+ if (sigp == NULL || lenp == NULL) {
-+ return SSH_ERR_INVALID_ARGUMENT;
-+ }
-+
-+ slen = EVP_PKEY_get_size(pkey);
-+ if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
-+ return SSH_ERR_INVALID_ARGUMENT;
-+
-+ len = slen;
-+ if ((sig = malloc(slen)) == NULL) {
-+ return SSH_ERR_ALLOC_FAIL;
-+ }
-+
-+ if ((ctx = EVP_MD_CTX_new()) == NULL) {
-+ ret = SSH_ERR_ALLOC_FAIL;
-+ goto error;
-+ }
-+ if (EVP_DigestSignInit(ctx, NULL, ssh_digest_to_md(hash_alg),
-+ NULL, pkey) != 1 ||
-+ EVP_DigestSignUpdate(ctx, data, datalen) != 1 ||
-+ EVP_DigestSignFinal(ctx, sig, &len) != 1) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto error;
-+ }
-+
-+ *sigp = sig;
-+ *lenp = len;
-+ /* Now owned by the caller */
-+ sig = NULL;
-+ ret = 0;
-+
-+error:
-+ EVP_MD_CTX_free(ctx);
-+ free(sig);
-+ return ret;
-+}
-+
-+int
-+sshkey_verify_signature(EVP_PKEY *pkey, int hash_alg, const u_char *data,
-+ size_t datalen, u_char *sigbuf, int siglen)
-+{
-+ EVP_MD_CTX *ctx = NULL;
-+ int ret;
-+
-+ if ((ctx = EVP_MD_CTX_new()) == NULL) {
-+ return SSH_ERR_ALLOC_FAIL;
-+ }
-+ if (EVP_DigestVerifyInit(ctx, NULL, ssh_digest_to_md(hash_alg),
-+ NULL, pkey) != 1 ||
-+ EVP_DigestVerifyUpdate(ctx, data, datalen) != 1) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto done;
-+ }
-+ ret = EVP_DigestVerifyFinal(ctx, sigbuf, siglen);
-+ switch (ret) {
-+ case 1:
-+ ret = 0;
-+ break;
-+ case 0:
-+ ret = SSH_ERR_SIGNATURE_INVALID;
-+ break;
-+ default:
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ break;
-+ }
-+
-+done:
-+ EVP_MD_CTX_free(ctx);
-+ return ret;
-+}
-+
- /* XXX: these are really begging for a table-driven approach */
- int
- sshkey_curve_name_to_nid(const char *name)
-@@ -3763,3 +3845,27 @@
- return 0;
- }
- #endif /* WITH_XMSS */
-+
-+#ifdef WITH_OPENSSL
-+EVP_PKEY *
-+sshkey_create_evp(OSSL_PARAM_BLD *param_bld, EVP_PKEY_CTX *ctx)
-+{
-+ EVP_PKEY *ret = NULL;
-+ OSSL_PARAM *params = NULL;
-+ if (param_bld == NULL || ctx == NULL) {
-+ debug2_f("param_bld or ctx is NULL");
-+ return NULL;
-+ }
-+ if ((params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
-+ debug2_f("Could not build param list");
-+ return NULL;
-+ }
-+ if (EVP_PKEY_fromdata_init(ctx) != 1 ||
-+ EVP_PKEY_fromdata(ctx, &ret, EVP_PKEY_KEYPAIR, params) != 1) {
-+ debug2_f("EVP_PKEY_fromdata failed");
-+ OSSL_PARAM_free(params);
-+ return NULL;
-+ }
-+ return ret;
-+}
-+#endif /* WITH_OPENSSL */
-diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/sshkey.h openssh-9.3p1-patched/sshkey.h
---- openssh-9.3p1/sshkey.h 2023-06-06 15:53:36.608444190 +0200
-+++ openssh-9.3p1-patched/sshkey.h 2023-06-06 15:52:25.626551768 +0200
-@@ -31,6 +31,9 @@
- #ifdef WITH_OPENSSL
- #include <openssl/rsa.h>
- #include <openssl/dsa.h>
-+#include <openssl/evp.h>
-+#include <openssl/param_build.h>
-+#include <openssl/core_names.h>
- # ifdef OPENSSL_HAS_ECC
- # include <openssl/ec.h>
- # include <openssl/ecdsa.h>
-@@ -268,6 +271,10 @@
- const char *sshkey_ssh_name_plain(const struct sshkey *);
- int sshkey_names_valid2(const char *, int);
- char *sshkey_alg_list(int, int, int, char);
-+int sshkey_calculate_signature(EVP_PKEY*, int, u_char **,
-+ int *, const u_char *, size_t);
-+int sshkey_verify_signature(EVP_PKEY *, int, const u_char *,
-+ size_t, u_char *, int);
-
- int sshkey_from_blob(const u_char *, size_t, struct sshkey **);
- int sshkey_fromb(struct sshbuf *, struct sshkey **);
-@@ -324,6 +331,13 @@
-
- void sshkey_sig_details_free(struct sshkey_sig_details *);
-
-+#ifdef WITH_OPENSSL
-+EVP_PKEY *sshkey_create_evp(OSSL_PARAM_BLD *, EVP_PKEY_CTX *);
-+int ssh_create_evp_dss(const struct sshkey *, EVP_PKEY **);
-+int ssh_create_evp_rsa(const struct sshkey *, EVP_PKEY **);
-+int ssh_create_evp_ec(EC_KEY *, int, EVP_PKEY **);
-+#endif /* WITH_OPENSSL */
-+
- #ifdef SSHKEY_INTERNAL
- int sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b);
- void sshkey_sk_cleanup(struct sshkey *k);
-@@ -338,6 +352,10 @@
- #endif
- #endif
-
-+#ifdef ENABLE_PKCS11
-+int pkcs11_get_ecdsa_idx(void);
-+#endif
-+
- #if !defined(WITH_OPENSSL)
- # undef RSA
- # undef DSA
-diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-pkcs11.c openssh-9.3p1-patched/ssh-pkcs11.c
---- openssh-9.3p1/ssh-pkcs11.c 2023-06-06 15:53:36.592443989 +0200
-+++ openssh-9.3p1-patched/ssh-pkcs11.c 2023-06-06 15:52:25.626551768 +0200
-@@ -777,8 +777,24 @@
-
- return (0);
- }
-+
-+int
-+is_ecdsa_pkcs11(EC_KEY *ecdsa)
-+{
-+ if (EC_KEY_get_ex_data(ecdsa, ec_key_idx) != NULL)
-+ return 1;
-+ return 0;
-+}
- #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
-
-+int
-+is_rsa_pkcs11(RSA *rsa)
-+{
-+ if (RSA_get_ex_data(rsa, rsa_idx) != NULL)
-+ return 1;
-+ return 0;
-+}
-+
- /* remove trailing spaces */
- static void
- rmspace(u_char *buf, size_t len)
-diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-pkcs11-client.c openssh-9.3p1-patched/ssh-pkcs11-client.c
---- openssh-9.3p1/ssh-pkcs11-client.c 2023-06-06 15:53:36.591443976 +0200
-+++ openssh-9.3p1-patched/ssh-pkcs11-client.c 2023-06-06 15:52:25.626551768 +0200
-@@ -225,8 +225,36 @@
- static RSA_METHOD *helper_rsa;
- #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
- static EC_KEY_METHOD *helper_ecdsa;
-+
-+int
-+is_ecdsa_pkcs11(EC_KEY *ecdsa)
-+{
-+ const EC_KEY_METHOD *meth;
-+ ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgstlen,
-+ const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey) = NULL;
-+
-+ meth = EC_KEY_get_method(ecdsa);
-+ EC_KEY_METHOD_get_sign(meth, NULL, NULL, &sign_sig);
-+ if (sign_sig == ecdsa_do_sign)
-+ return 1;
-+ return 0;
-+}
- #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
-
-+int
-+is_rsa_pkcs11(RSA *rsa)
-+{
-+ const RSA_METHOD *meth;
-+ int (*priv_enc)(int flen, const unsigned char *from,
-+ unsigned char *to, RSA *rsa, int padding) = NULL;
-+
-+ meth = RSA_get_method(rsa);
-+ priv_enc = RSA_meth_get_priv_enc(meth);
-+ if (priv_enc == rsa_encrypt)
-+ return 1;
-+ return 0;
-+}
-+
- /* redirect private key crypto operations to the ssh-pkcs11-helper */
- static void
- wrap_key(struct sshkey *k)
-diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-pkcs11.h openssh-9.3p1-patched/ssh-pkcs11.h
---- openssh-9.3p1/ssh-pkcs11.h 2023-06-06 15:53:36.592443989 +0200
-+++ openssh-9.3p1-patched/ssh-pkcs11.h 2023-06-06 15:52:25.626551768 +0200
-@@ -39,6 +39,11 @@
- u_int32_t *);
- #endif
-
-+#ifdef HAVE_EC_KEY_METHOD_NEW
-+int is_ecdsa_pkcs11(EC_KEY *ecdsa);
-+#endif
-+int is_rsa_pkcs11(RSA *rsa);
-+
- #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11)
- #undef ENABLE_PKCS11
- #endif
-diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.3p1/ssh-rsa.c openssh-9.3p1-patched/ssh-rsa.c
---- openssh-9.3p1/ssh-rsa.c 2023-03-15 22:28:19.000000000 +0100
-+++ openssh-9.3p1-patched/ssh-rsa.c 2023-06-06 15:52:25.627551781 +0200
-@@ -23,6 +23,8 @@
-
- #include <openssl/evp.h>
- #include <openssl/err.h>
-+#include <openssl/core_names.h>
-+#include <openssl/param_build.h>
-
- #include <stdarg.h>
- #include <string.h>
-@@ -36,7 +38,7 @@
-
- #include "openbsd-compat/openssl-compat.h"
-
--static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
-+static int openssh_RSA_verify(int, const u_char *, size_t, u_char *, size_t, EVP_PKEY *);
-
- static u_int
- ssh_rsa_size(const struct sshkey *key)
-@@ -131,27 +133,50 @@
- static int
- ssh_rsa_generate(struct sshkey *k, int bits)
- {
-- RSA *private = NULL;
-+ EVP_PKEY_CTX *ctx = NULL;
-+ EVP_PKEY *res = NULL;
- BIGNUM *f4 = NULL;
- int ret = SSH_ERR_INTERNAL_ERROR;
-
- if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
- bits > SSHBUF_MAX_BIGNUM * 8)
- return SSH_ERR_KEY_LENGTH;
-- if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
-+
-+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL
-+ || (f4 = BN_new()) == NULL || !BN_set_word(f4, RSA_F4)) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
-- if (!BN_set_word(f4, RSA_F4) ||
-- !RSA_generate_key_ex(private, bits, f4, NULL)) {
-+
-+ if (EVP_PKEY_keygen_init(ctx) <= 0) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+
-+ if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) {
-+ ret = SSH_ERR_KEY_LENGTH;
-+ goto out;
-+ }
-+
-+ if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, f4) <= 0)
-+ goto out;
-+
-+ if (EVP_PKEY_keygen(ctx, &res) <= 0) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+
-+ /* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/
-+ k->rsa = EVP_PKEY_get1_RSA(res);
-+ if (k->rsa) {
-+ ret = 0;
-+ } else {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
-- k->rsa = private;
-- private = NULL;
-- ret = 0;
- out:
-- RSA_free(private);
-+ EVP_PKEY_CTX_free(ctx);
-+ EVP_PKEY_free(res);
- BN_free(f4);
- return ret;
- }
-@@ -317,21 +342,6 @@
- return -1;
- }
-
--static int
--rsa_hash_alg_nid(int type)
--{
-- switch (type) {
-- case SSH_DIGEST_SHA1:
-- return NID_sha1;
-- case SSH_DIGEST_SHA256:
-- return NID_sha256;
-- case SSH_DIGEST_SHA512:
-- return NID_sha512;
-- default:
-- return -1;
-- }
--}
--
- int
- ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp)
- {
-@@ -393,11 +403,10 @@
- const u_char *data, size_t datalen,
- const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
- {
-- const BIGNUM *rsa_n;
-- u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
-- size_t slen = 0;
-- u_int hlen, len;
-- int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
-+ EVP_PKEY *pkey = NULL;
-+ u_char *sig = NULL;
-+ int len, slen = 0;
-+ int hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
- struct sshbuf *b = NULL;
-
- if (lenp != NULL)
-@@ -409,33 +418,33 @@
- hash_alg = SSH_DIGEST_SHA1;
- else
- hash_alg = rsa_hash_id_from_keyname(alg);
-+
- if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
- sshkey_type_plain(key->type) != KEY_RSA)
- return SSH_ERR_INVALID_ARGUMENT;
-- RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
-- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
-- return SSH_ERR_KEY_LENGTH;
- slen = RSA_size(key->rsa);
-- if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
-- return SSH_ERR_INVALID_ARGUMENT;
--
-- /* hash the data */
-- nid = rsa_hash_alg_nid(hash_alg);
-- if ((hlen = ssh_digest_bytes(hash_alg)) == 0)
-- return SSH_ERR_INTERNAL_ERROR;
-- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
-- digest, sizeof(digest))) != 0)
-- goto out;
-+ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
-+ return SSH_ERR_KEY_LENGTH;
-
-- if ((sig = malloc(slen)) == NULL) {
-- ret = SSH_ERR_ALLOC_FAIL;
-- goto out;
-+#ifdef ENABLE_PKCS11
-+ if (is_rsa_pkcs11(key->rsa)) {
-+ if ((pkey = EVP_PKEY_new()) == NULL ||
-+ EVP_PKEY_set1_RSA(pkey, key->rsa) != 1)
-+ return SSH_ERR_ALLOC_FAIL;
-+ } else {
-+#endif
-+ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0)
-+ return ret;
-+#ifdef ENABLE_PKCS11
- }
--
-- if (RSA_sign(nid, digest, hlen, sig, &len, key->rsa) != 1) {
-- ret = SSH_ERR_LIBCRYPTO_ERROR;
-+#endif
-+ ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data,
-+ datalen);
-+ EVP_PKEY_free(pkey);
-+ if (ret < 0) {
- goto out;
- }
-+
- if (len < slen) {
- size_t diff = slen - len;
- memmove(sig + diff, sig, len);
-@@ -444,6 +453,7 @@
- ret = SSH_ERR_INTERNAL_ERROR;
- goto out;
- }
-+
- /* encode signature */
- if ((b = sshbuf_new()) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
-@@ -464,7 +474,6 @@
- *lenp = len;
- ret = 0;
- out:
-- explicit_bzero(digest, sizeof(digest));
- freezero(sig, slen);
- sshbuf_free(b);
- return ret;
-@@ -476,10 +485,10 @@
- const u_char *data, size_t dlen, const char *alg, u_int compat,
- struct sshkey_sig_details **detailsp)
- {
-- const BIGNUM *rsa_n;
-+ EVP_PKEY *pkey = NULL;
- char *sigtype = NULL;
- int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;
-- size_t len = 0, diff, modlen, hlen;
-+ size_t len = 0, diff, modlen;
- struct sshbuf *b = NULL;
- u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
-
-@@ -487,8 +496,7 @@
- sshkey_type_plain(key->type) != KEY_RSA ||
- sig == NULL || siglen == 0)
- return SSH_ERR_INVALID_ARGUMENT;
-- RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
-- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
-+ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
- return SSH_ERR_KEY_LENGTH;
-
- if ((b = sshbuf_from(sig, siglen)) == NULL)
-@@ -540,16 +548,13 @@
- explicit_bzero(sigblob, diff);
- len = modlen;
- }
-- if ((hlen = ssh_digest_bytes(hash_alg)) == 0) {
-- ret = SSH_ERR_INTERNAL_ERROR;
-- goto out;
-- }
-- if ((ret = ssh_digest_memory(hash_alg, data, dlen,
-- digest, sizeof(digest))) != 0)
-+
-+ if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0)
- goto out;
-
-- ret = openssh_RSA_verify(hash_alg, digest, hlen, sigblob, len,
-- key->rsa);
-+ ret = openssh_RSA_verify(hash_alg, data, dlen, sigblob, len, pkey);
-+ EVP_PKEY_free(pkey);
-+
- out:
- freezero(sigblob, len);
- free(sigtype);
-@@ -558,125 +563,110 @@
- return ret;
- }
-
--/*
-- * See:
-- * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
-- * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
-- */
--
--/*
-- * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
-- * oiw(14) secsig(3) algorithms(2) 26 }
-- */
--static const u_char id_sha1[] = {
-- 0x30, 0x21, /* type Sequence, length 0x21 (33) */
-- 0x30, 0x09, /* type Sequence, length 0x09 */
-- 0x06, 0x05, /* type OID, length 0x05 */
-- 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
-- 0x05, 0x00, /* NULL */
-- 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
--};
--
--/*
-- * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
-- * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
-- * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
-- * id-sha256(1) }
-- */
--static const u_char id_sha256[] = {
-- 0x30, 0x31, /* type Sequence, length 0x31 (49) */
-- 0x30, 0x0d, /* type Sequence, length 0x0d (13) */
-- 0x06, 0x09, /* type OID, length 0x09 */
-- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */
-- 0x05, 0x00, /* NULL */
-- 0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */
--};
--
--/*
-- * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
-- * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
-- * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
-- * id-sha256(3) }
-- */
--static const u_char id_sha512[] = {
-- 0x30, 0x51, /* type Sequence, length 0x51 (81) */
-- 0x30, 0x0d, /* type Sequence, length 0x0d (13) */
-- 0x06, 0x09, /* type OID, length 0x09 */
-- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */
-- 0x05, 0x00, /* NULL */
-- 0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */
--};
--
- static int
--rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp)
-+openssh_RSA_verify(int hash_alg, const u_char *data, size_t datalen,
-+ u_char *sigbuf, size_t siglen, EVP_PKEY *pkey)
- {
-- switch (hash_alg) {
-- case SSH_DIGEST_SHA1:
-- *oidp = id_sha1;
-- *oidlenp = sizeof(id_sha1);
-- break;
-- case SSH_DIGEST_SHA256:
-- *oidp = id_sha256;
-- *oidlenp = sizeof(id_sha256);
-- break;
-- case SSH_DIGEST_SHA512:
-- *oidp = id_sha512;
-- *oidlenp = sizeof(id_sha512);
-- break;
-- default:
-- return SSH_ERR_INVALID_ARGUMENT;
-- }
-- return 0;
--}
-+ size_t rsasize = 0;
-+ int ret;
-
--static int
--openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen,
-- u_char *sigbuf, size_t siglen, RSA *rsa)
--{
-- size_t rsasize = 0, oidlen = 0, hlen = 0;
-- int ret, len, oidmatch, hashmatch;
-- const u_char *oid = NULL;
-- u_char *decrypted = NULL;
--
-- if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0)
-- return ret;
-- ret = SSH_ERR_INTERNAL_ERROR;
-- hlen = ssh_digest_bytes(hash_alg);
-- if (hashlen != hlen) {
-- ret = SSH_ERR_INVALID_ARGUMENT;
-- goto done;
-- }
-- rsasize = RSA_size(rsa);
-+ rsasize = EVP_PKEY_get_size(pkey);
- if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM ||
- siglen == 0 || siglen > rsasize) {
- ret = SSH_ERR_INVALID_ARGUMENT;
- goto done;
- }
-- if ((decrypted = malloc(rsasize)) == NULL) {
-- ret = SSH_ERR_ALLOC_FAIL;
-- goto done;
-- }
-- if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
-- RSA_PKCS1_PADDING)) < 0) {
-- ret = SSH_ERR_LIBCRYPTO_ERROR;
-- goto done;
-- }
-- if (len < 0 || (size_t)len != hlen + oidlen) {
-- ret = SSH_ERR_INVALID_FORMAT;
-- goto done;
-- }
-- oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0;
-- hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0;
-- if (!oidmatch || !hashmatch) {
-- ret = SSH_ERR_SIGNATURE_INVALID;
-- goto done;
-- }
-- ret = 0;
-+
-+ ret = sshkey_verify_signature(pkey, hash_alg, data, datalen,
-+ sigbuf, siglen);
-+
- done:
-- freezero(decrypted, rsasize);
- return ret;
- }
-
-+int
-+ssh_create_evp_rsa(const struct sshkey *k, EVP_PKEY **pkey)
-+{
-+ OSSL_PARAM_BLD *param_bld = NULL;
-+ EVP_PKEY_CTX *ctx = NULL;
-+ int ret = 0;
-+ const BIGNUM *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL;
-+ const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
-+
-+ if (k == NULL)
-+ return SSH_ERR_INVALID_ARGUMENT;
-+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL ||
-+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
-+ ret = SSH_ERR_ALLOC_FAIL;
-+ goto out;
-+ }
-+
-+ RSA_get0_key(k->rsa, &n, &e, &d);
-+ RSA_get0_factors(k->rsa, &p, &q);
-+ RSA_get0_crt_params(k->rsa, &dmp1, &dmq1, &iqmp);
-+
-+ if (n != NULL &&
-+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, n) != 1) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ if (e != NULL &&
-+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, e) != 1) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ if (d != NULL &&
-+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_D, d) != 1) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+
-+ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) {
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+
-+ /* setting this to param_build makes the creation process fail */
-+ if (p != NULL &&
-+ EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, p) != 1) {
-+ debug2_f("failed to add 'p' param");
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ if (q != NULL &&
-+ EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, q) != 1) {
-+ debug2_f("failed to add 'q' param");
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ if (dmp1 != NULL &&
-+ EVP_PKEY_set_bn_param(*pkey,
-+ OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1) != 1) {
-+ debug2_f("failed to add 'dmp1' param");
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ if (dmq1 != NULL &&
-+ EVP_PKEY_set_bn_param(*pkey,
-+ OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1) != 1) {
-+ debug2_f("failed to add 'dmq1' param");
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+ if (iqmp != NULL &&
-+ EVP_PKEY_set_bn_param(*pkey,
-+ OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp) != 1) {
-+ debug2_f("failed to add 'iqmp' param");
-+ ret = SSH_ERR_LIBCRYPTO_ERROR;
-+ goto out;
-+ }
-+
-+out:
-+ OSSL_PARAM_BLD_free(param_bld);
-+ EVP_PKEY_CTX_free(ctx);
-+ return ret;
-+}
-+
- static const struct sshkey_impl_funcs sshkey_rsa_funcs = {
- /* .size = */ ssh_rsa_size,
- /* .alloc = */ ssh_rsa_alloc,