forked from rpms/openssh
		
	Merge evp related patches
Signed-off-by: Norbert Pocs <npocs@redhat.com>
This commit is contained in:
		
							parent
							
								
									141d7b2d4a
								
							
						
					
					
						commit
						fb40f0afda
					
				| @ -415,10 +415,10 @@ diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c | ||||
| diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c
 | ||||
| --- openssh-8.6p1/sshkey.c.fips	2021-05-06 12:08:36.493926838 +0200
 | ||||
| +++ openssh-8.6p1/sshkey.c	2021-05-06 12:08:36.502926908 +0200
 | ||||
| @@ -34,6 +34,7 @@
 | ||||
|  #include <openssl/evp.h> | ||||
|  #include <openssl/err.h> | ||||
| @@ -36,6 +36,7 @@
 | ||||
|  #include <openssl/pem.h> | ||||
|  #include <openssl/core_names.h> | ||||
|  #include <openssl/param_build.h> | ||||
| +#include <openssl/fips.h>
 | ||||
|  #endif | ||||
|   | ||||
| @ -540,10 +540,10 @@ diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c | ||||
| diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c
 | ||||
| --- openssh-9.3p1/ssh-rsa.c.evpgenrsa	2022-06-30 15:14:58.200518353 +0200
 | ||||
| +++ openssh-9.3p1/ssh-rsa.c	2022-06-30 15:24:31.499641196 +0200
 | ||||
| @@ -31,6 +31,7 @@
 | ||||
|   | ||||
|  #include <openssl/evp.h> | ||||
| @@ -33,6 +33,7 @@
 | ||||
|  #include <openssl/err.h> | ||||
|  #include <openssl/core_names.h> | ||||
|  #include <openssl/param_build.h> | ||||
| +#include <openssl/fips.h>
 | ||||
|   | ||||
|  #include <stdarg.h> | ||||
|  | ||||
| @ -1,720 +0,0 @@ | ||||
| From ed7ec0cdf577ffbb0b15145340cf51596ca3eb89 Mon Sep 17 00:00:00 2001 | ||||
| From: Jakub Jelen <jjelen@redhat.com> | ||||
| Date: Tue, 14 May 2019 10:45:45 +0200 | ||||
| Subject: [PATCH] Use high-level OpenSSL API for signatures | ||||
| 
 | ||||
| ---
 | ||||
|  digest-openssl.c |  16 ++++ | ||||
|  digest.h         |   6 ++ | ||||
|  ssh-dss.c        |  65 ++++++++++------ | ||||
|  ssh-ecdsa.c      |  69 ++++++++++------- | ||||
|  ssh-rsa.c        | 193 +++++++++-------------------------------------- | ||||
|  sshkey.c         |  77 +++++++++++++++++++ | ||||
|  sshkey.h         |   4 + | ||||
|  7 files changed, 221 insertions(+), 209 deletions(-) | ||||
| 
 | ||||
| diff --git a/digest-openssl.c b/digest-openssl.c
 | ||||
| index da7ed72bc..6a21d8adb 100644
 | ||||
| --- a/digest-openssl.c
 | ||||
| +++ b/digest-openssl.c
 | ||||
| @@ -63,6 +63,22 @@ const struct ssh_digest digests[] = {
 | ||||
|  	{ -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 --git a/digest.h b/digest.h
 | ||||
| index 274574d0e..c7ceeb36f 100644
 | ||||
| --- a/digest.h
 | ||||
| +++ b/digest.h
 | ||||
| @@ -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 --git a/ssh-dss.c b/ssh-dss.c
 | ||||
| index a23c383dc..ea45e7275 100644
 | ||||
| --- a/ssh-dss.c
 | ||||
| +++ b/ssh-dss.c
 | ||||
| @@ -52,11 +52,15 @@ int
 | ||||
|      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) | ||||
| @@ -67,17 +71,24 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  	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 ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_DSA(pkey, key->dsa) != 1)
 | ||||
| +		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +	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); | ||||
| @@ -110,7 +121,7 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		*lenp = len; | ||||
|  	ret = 0; | ||||
|   out: | ||||
| -	explicit_bzero(digest, sizeof(digest));
 | ||||
| +	free(sigb);
 | ||||
|  	DSA_SIG_free(sig); | ||||
|  	sshbuf_free(b); | ||||
|  	return ret; | ||||
| @@ -121,20 +132,20 @@ ssh_dss_verify(const struct sshkey *key,
 | ||||
|      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) | ||||
| @@ -176,25 +187,31 @@ ssh_dss_verify(const struct sshkey *key,
 | ||||
|  	} | ||||
|  	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 ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_DSA(pkey, key->dsa) != 1) {
 | ||||
| +		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
| +		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); | ||||
| diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
 | ||||
| index 599c7199d..b036796e8 100644
 | ||||
| --- a/ssh-ecdsa.c
 | ||||
| +++ b/ssh-ecdsa.c
 | ||||
| @@ -50,11 +50,13 @@ int
 | ||||
|      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; | ||||
|   | ||||
| @@ -67,18 +69,24 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  	    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)
 | ||||
| +
 | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1)
 | ||||
| +		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +	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; | ||||
| @@ -102,7 +110,7 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		*lenp = len; | ||||
|  	ret = 0; | ||||
|   out: | ||||
| -	explicit_bzero(digest, sizeof(digest));
 | ||||
| +	free(sigb);
 | ||||
|  	sshbuf_free(b); | ||||
|  	sshbuf_free(bb); | ||||
|  	ECDSA_SIG_free(esig); | ||||
| @@ -115,22 +123,21 @@ ssh_ecdsa_verify(const struct sshkey *key,
 | ||||
|      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 */ | ||||
| @@ -166,28 +173,36 @@ ssh_ecdsa_verify(const struct sshkey *key,
 | ||||
|  	} | ||||
|  	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 ((sigb = malloc(len)) == NULL) {
 | ||||
| +		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
|  		goto out; | ||||
|  	} | ||||
| -	if ((ret = ssh_digest_memory(hash_alg, data, dlen,
 | ||||
| -	    digest, sizeof(digest))) != 0)
 | ||||
| +	psig = sigb;
 | ||||
| +	if ((len = i2d_ECDSA_SIG(esig, &psig)) == 0) {
 | ||||
| +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
|  		goto out; | ||||
| +	}
 | ||||
|   | ||||
| -	switch (ECDSA_do_verify(digest, hlen, esig, key->ecdsa)) {
 | ||||
| -	case 1:
 | ||||
| -		ret = 0;
 | ||||
| -		break;
 | ||||
| -	case 0:
 | ||||
| -		ret = SSH_ERR_SIGNATURE_INVALID;
 | ||||
| +	if (sshbuf_len(sigbuf) != 0) {
 | ||||
| +		ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
 | ||||
|  		goto out; | ||||
| -	default:
 | ||||
| -		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) {
 | ||||
| +		ret =  SSH_ERR_ALLOC_FAIL;
 | ||||
|  		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); | ||||
| diff --git a/ssh-rsa.c b/ssh-rsa.c
 | ||||
| index 9b14f9a9a..8ef3a6aca 100644
 | ||||
| --- a/ssh-rsa.c
 | ||||
| +++ b/ssh-rsa.c
 | ||||
| @@ -37,7 +37,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) | ||||
| @@ -90,21 +90,6 @@ rsa_hash_id_from_keyname(const char *alg)
 | ||||
|  	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) | ||||
|  { | ||||
| @@ -164,11 +149,10 @@ int
 | ||||
|      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) | ||||
| @@ -180,33 +164,24 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		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;
 | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_RSA(pkey, key->rsa) != 1)
 | ||||
| +		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +	ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data,
 | ||||
| +	    datalen);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
| +	if (ret < 0) {
 | ||||
|  		goto out; | ||||
|  	} | ||||
|   | ||||
| -	if (RSA_sign(nid, digest, hlen, sig, &len, key->rsa) != 1) {
 | ||||
| -		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| -		goto out;
 | ||||
| -	}
 | ||||
|  	if (len < slen) { | ||||
|  		size_t diff = slen - len; | ||||
|  		memmove(sig + diff, sig, len); | ||||
| @@ -215,6 +190,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		ret = SSH_ERR_INTERNAL_ERROR; | ||||
|  		goto out; | ||||
|  	} | ||||
| +
 | ||||
|  	/* encode signature */ | ||||
|  	if ((b = sshbuf_new()) == NULL) { | ||||
|  		ret = SSH_ERR_ALLOC_FAIL; | ||||
| @@ -235,7 +211,6 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		*lenp = len; | ||||
|  	ret = 0; | ||||
|   out: | ||||
| -	explicit_bzero(digest, sizeof(digest));
 | ||||
|  	freezero(sig, slen); | ||||
|  	sshbuf_free(b); | ||||
|  	return ret; | ||||
| @@ -246,10 +221,10 @@ ssh_rsa_verify(const struct sshkey *key,
 | ||||
|      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; | ||||
|   | ||||
| @@ -257,8 +232,7 @@ ssh_rsa_verify(const struct sshkey *key,
 | ||||
|  	    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) | ||||
| @@ -310,16 +284,15 @@ ssh_rsa_verify(const struct sshkey *key,
 | ||||
|  		explicit_bzero(sigblob, diff); | ||||
|  		len = modlen; | ||||
|  	} | ||||
| -	if ((hlen = ssh_digest_bytes(hash_alg)) == 0) {
 | ||||
| -		ret = SSH_ERR_INTERNAL_ERROR;
 | ||||
| +
 | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) {
 | ||||
| +		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
|  		goto out; | ||||
|  	} | ||||
| -	if ((ret = ssh_digest_memory(hash_alg, data, dlen,
 | ||||
| -	    digest, sizeof(digest))) != 0)
 | ||||
| -		goto out;
 | ||||
| +	ret = openssh_RSA_verify(hash_alg, data, dlen, sigblob, len, pkey);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
|   | ||||
| -	ret = openssh_RSA_verify(hash_alg, digest, hlen, sigblob, len,
 | ||||
| -	    key->rsa);
 | ||||
|   out: | ||||
|  	freezero(sigblob, len); | ||||
|  	free(sigtype); | ||||
| @@ -328,122 +301,26 @@ ssh_rsa_verify(const struct sshkey *key,
 | ||||
|  	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;
 | ||||
| +	const RSA *rsa;
 | ||||
| +	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;
 | ||||
| -	}
 | ||||
| +	rsa = EVP_PKEY_get0_RSA(pkey);
 | ||||
|  	rsasize = RSA_size(rsa); | ||||
|  	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; | ||||
|  } | ||||
|   | ||||
| diff --git a/sshkey.c b/sshkey.c
 | ||||
| index ad1957762..b95ed0b10 100644
 | ||||
| --- a/sshkey.c
 | ||||
| +++ b/sshkey.c
 | ||||
| @@ -358,6 +358,83 @@ sshkey_type_plain(int type)
 | ||||
|  } | ||||
|   | ||||
|  #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, len;
 | ||||
| +
 | ||||
| +	if (sigp == NULL || lenp == NULL) {
 | ||||
| +		return SSH_ERR_INVALID_ARGUMENT;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	slen = EVP_PKEY_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_SignInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
 | ||||
| +	    EVP_SignUpdate(ctx, data, datalen) <= 0 ||
 | ||||
| +	    EVP_SignFinal(ctx, sig, &len, pkey) <= 0) {
 | ||||
| +		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_VerifyInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
 | ||||
| +	    EVP_VerifyUpdate(ctx, data, datalen) <= 0) {
 | ||||
| +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto done;
 | ||||
| +	}
 | ||||
| +	ret = EVP_VerifyFinal(ctx, sigbuf, siglen, pkey);
 | ||||
| +	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) | ||||
| diff --git a/sshkey.h b/sshkey.h
 | ||||
| index a91e60436..270901a87 100644
 | ||||
| --- a/sshkey.h
 | ||||
| +++ b/sshkey.h
 | ||||
| @@ -179,6 +179,10 @@ const char	*sshkey_ssh_name(const struct sshkey *);
 | ||||
|  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 **); | ||||
| 
 | ||||
| @ -1,109 +0,0 @@ | ||||
| diff -up openssh-9.3p1/ssh-rsa.c.evpgenrsa openssh-9.3p1/ssh-rsa.c
 | ||||
| --- openssh-9.3p1/ssh-rsa.c.evpgenrsa	2022-06-30 15:14:58.200518353 +0200
 | ||||
| +++ openssh-9.3p1/ssh-rsa.c	2022-06-30 15:24:31.499641196 +0200
 | ||||
| @@ -1657,7 +1657,8 @@ sshkey_cert_type(const struct sshkey *k)
 | ||||
|  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; | ||||
|   | ||||
| @@ -1667,20 +1668,42 @@ ssh_rsa_generate(u_int bits, RSA
 | ||||
| 	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; | ||||
|  } | ||||
| diff -up openssh-9.3p1/ssh-ecdsa.c.evpgenrsa openssh-9.3p1/ssh-ecdsa.c
 | ||||
| --- openssh-9.3p1/ssh-ecdsa.c.evpgenrsa	2022-06-30 15:14:58.200518353 +0200
 | ||||
| +++ openssh-9.3p1/ssh-ecdsa.c	2022-06-30 15:24:31.499641196 +0200
 | ||||
| @@ -1820,7 +1820,8 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k)
 | ||||
|  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; | ||||
| @@ -1828,15 +1829,24 @@ ssh_ecdsa_generate(u_int bits, i
 | ||||
| 
 | ||||
|  	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);
 | ||||
| -		return SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| -	}
 | ||||
| +
 | ||||
| +	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;
 | ||||
| +	}
 | ||||
| +	/* 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);
 | ||||
| +
 | ||||
| -	EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
 | ||||
| -	k->ecdsa = private;
 | ||||
| -	return 0;
 | ||||
| +	EVP_PKEY_CTX_free(ctx);
 | ||||
| +	EVP_PKEY_free(res);
 | ||||
| + 	return (k->ecdsa) ? 0 : SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
|  } | ||||
|   | ||||
|  static int | ||||
| @ -1,476 +0,0 @@ | ||||
| diff -up openssh-9.3p1/ssh-dss.c.evp-fips-sign openssh-9.3p1/ssh-dss.c
 | ||||
| --- openssh-9.3p1/ssh-dss.c.evp-fips-sign	2023-04-27 16:46:17.115809116 +0200
 | ||||
| +++ openssh-9.3p1/ssh-dss.c	2023-04-27 17:07:40.117253665 +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> | ||||
| @@ -281,9 +283,8 @@ ssh_dss_sign(struct sshkey *key,
 | ||||
|  	    sshkey_type_plain(key->type) != KEY_DSA) | ||||
|  		return SSH_ERR_INVALID_ARGUMENT; | ||||
|   | ||||
| -	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| -	    EVP_PKEY_set1_DSA(pkey, key->dsa) != 1)
 | ||||
| -		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +  	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); | ||||
| @@ -411,11 +412,8 @@ ssh_dss_verify(const struct sshkey *key,
 | ||||
|  		goto out; | ||||
|  	} | ||||
|   | ||||
| -	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| -	    EVP_PKEY_set1_DSA(pkey, key->dsa) != 1) {
 | ||||
| -		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
| +  	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); | ||||
| @@ -432,6 +430,65 @@ ssh_dss_verify(const struct sshkey *key,
 | ||||
|  	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 -up openssh-9.3p1/ssh-ecdsa.c.evp-fips-sign openssh-9.3p1/ssh-ecdsa.c
 | ||||
| --- openssh-9.3p1/ssh-ecdsa.c.evp-fips-sign	2023-04-27 16:46:17.127809401 +0200
 | ||||
| +++ openssh-9.3p1/ssh-ecdsa.c	2023-04-27 17:08:28.557396513 +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> | ||||
|   | ||||
| @@ -260,9 +262,8 @@ ssh_ecdsa_sign(struct sshkey *key,
 | ||||
|  	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) | ||||
|  		return SSH_ERR_INTERNAL_ERROR; | ||||
|   | ||||
| -	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| -	    EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1)
 | ||||
| -		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +  	if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0)
 | ||||
| +		return ret;
 | ||||
|  	ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data, | ||||
|  	    dlen); | ||||
|  	EVP_PKEY_free(pkey); | ||||
| @@ -381,11 +382,8 @@ ssh_ecdsa_verify(const struct sshkey *ke
 | ||||
|  		goto out; | ||||
|  	} | ||||
|   | ||||
| -	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| -	    EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) {
 | ||||
| -		ret =  SSH_ERR_ALLOC_FAIL;
 | ||||
| +  	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); | ||||
|   | ||||
| @@ -400,6 +398,79 @@ ssh_ecdsa_verify(const struct sshkey *ke
 | ||||
|  	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 -up openssh-9.3p1/sshkey.c.evp-fips-sign openssh-9.3p1/sshkey.c
 | ||||
| --- openssh-9.3p1/sshkey.c.evp-fips-sign	2023-04-27 16:46:17.139809686 +0200
 | ||||
| +++ openssh-9.3p1/sshkey.c	2023-04-27 16:46:17.144809804 +0200
 | ||||
| @@ -35,6 +35,8 @@
 | ||||
|  #include <openssl/err.h> | ||||
|  #include <openssl/pem.h> | ||||
|  #include <openssl/fips.h> | ||||
| +#include <openssl/core_names.h>
 | ||||
| +#include <openssl/param_build.h>
 | ||||
|  #endif | ||||
|   | ||||
|  #include "crypto_api.h" | ||||
| @@ -527,13 +529,14 @@ sshkey_calculate_signature(EVP_PKEY *pke
 | ||||
|  { | ||||
|  	EVP_MD_CTX *ctx = NULL; | ||||
|  	u_char *sig = NULL; | ||||
| -	int ret, slen, len;
 | ||||
| +	int ret, slen;
 | ||||
| +	size_t len;
 | ||||
|   | ||||
|  	if (sigp == NULL || lenp == NULL) { | ||||
|  		return SSH_ERR_INVALID_ARGUMENT; | ||||
|  	} | ||||
|   | ||||
| -	slen = EVP_PKEY_size(pkey);
 | ||||
| +	slen = EVP_PKEY_get_size(pkey);
 | ||||
|  	if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) | ||||
|  		return SSH_ERR_INVALID_ARGUMENT; | ||||
|   | ||||
| @@ -546,9 +549,10 @@ sshkey_calculate_signature(EVP_PKEY *pke
 | ||||
|  		ret = SSH_ERR_ALLOC_FAIL; | ||||
|  		goto error; | ||||
|  	} | ||||
| -	if (EVP_SignInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
 | ||||
| -	    EVP_SignUpdate(ctx, data, datalen) <= 0 ||
 | ||||
| -	    EVP_SignFinal(ctx, sig, &len, pkey) <= 0) {
 | ||||
| +	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; | ||||
|  	} | ||||
| @@ -575,12 +579,13 @@ sshkey_verify_signature(EVP_PKEY *pkey,
 | ||||
|  	if ((ctx = EVP_MD_CTX_new()) == NULL) { | ||||
|  		return SSH_ERR_ALLOC_FAIL; | ||||
|  	} | ||||
| -	if (EVP_VerifyInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
 | ||||
| -	    EVP_VerifyUpdate(ctx, data, datalen) <= 0) {
 | ||||
| +	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_VerifyFinal(ctx, sigbuf, siglen, pkey);
 | ||||
| +	ret = EVP_DigestVerifyFinal(ctx, sigbuf, siglen);
 | ||||
|  	switch (ret) { | ||||
|  	case 1: | ||||
|  		ret = 0; | ||||
| @@ -3809,3 +3814,27 @@ sshkey_set_filename(struct sshkey *k, co
 | ||||
|  	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 -up openssh-9.3p1/sshkey.h.evp-fips-sign openssh-9.3p1/sshkey.h
 | ||||
| --- openssh-9.3p1/sshkey.h.evp-fips-sign	2023-04-27 16:46:17.133809543 +0200
 | ||||
| +++ openssh-9.3p1/sshkey.h	2023-04-27 16:46:17.144809804 +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> | ||||
| @@ -328,6 +331,13 @@ int	 sshkey_private_serialize_maxsign(st
 | ||||
|   | ||||
|  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); | ||||
| diff -up openssh-9.3p1/ssh-rsa.c.evp-fips-sign openssh-9.3p1/ssh-rsa.c
 | ||||
| --- openssh-9.3p1/ssh-rsa.c.evp-fips-sign	2023-04-27 16:46:17.139809686 +0200
 | ||||
| +++ openssh-9.3p1/ssh-rsa.c	2023-04-27 17:10:30.376270565 +0200
 | ||||
| @@ -23,6 +23,8 @@
 | ||||
|  #include <openssl/evp.h> | ||||
|  #include <openssl/err.h> | ||||
|  #include <openssl/fips.h> | ||||
| +#include <openssl/core_names.h>
 | ||||
| +#include <openssl/param_build.h>
 | ||||
|   | ||||
|  #include <stdarg.h> | ||||
|  #include <string.h> | ||||
| @@ -426,9 +428,8 @@ ssh_rsa_sign(struct sshkey *key,
 | ||||
|  	if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) | ||||
|  		return SSH_ERR_KEY_LENGTH; | ||||
|   | ||||
| -	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| -	    EVP_PKEY_set1_RSA(pkey, key->rsa) != 1)
 | ||||
| -		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +  	if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0)
 | ||||
| +		return ret;
 | ||||
|  	ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data, | ||||
|  	    datalen); | ||||
|  	EVP_PKEY_free(pkey); | ||||
| @@ -540,11 +541,9 @@ ssh_rsa_verify(const struct sshkey *key,
 | ||||
|  		len = modlen; | ||||
|  	} | ||||
|   | ||||
| -	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| -	    EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) {
 | ||||
| -		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
| +  	if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0)
 | ||||
|  		goto out; | ||||
| -	}
 | ||||
| +
 | ||||
|  	ret = openssh_RSA_verify(hash_alg, data, dlen, sigblob, len, pkey); | ||||
|  	EVP_PKEY_free(pkey); | ||||
|   | ||||
| @@ -561,11 +560,9 @@ openssh_RSA_verify(int hash_alg, const u
 | ||||
|      u_char *sigbuf, size_t siglen, EVP_PKEY *pkey) | ||||
|  { | ||||
|  	size_t rsasize = 0; | ||||
| -	const RSA *rsa;
 | ||||
|  	int ret; | ||||
|   | ||||
| -	rsa = EVP_PKEY_get0_RSA(pkey);
 | ||||
| -	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; | ||||
| @@ -579,6 +576,89 @@ done:
 | ||||
|  	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, | ||||
| @ -1,145 +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.0p1/ssh-ecdsa.c openssh-9.0p1-patched/ssh-ecdsa.c
 | ||||
| --- openssh-9.0p1/ssh-ecdsa.c	2023-05-24 08:54:03.926443958 +0200
 | ||||
| +++ openssh-9.0p1-patched/ssh-ecdsa.c	2023-05-24 09:46:19.082925921 +0200
 | ||||
| @@ -74,8 +74,18 @@
 | ||||
|  	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) | ||||
|  		return SSH_ERR_INTERNAL_ERROR; | ||||
|   | ||||
| -  	if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0)
 | ||||
| -		return ret;
 | ||||
| +#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); | ||||
| diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-9.0p1/sshkey.h openssh-9.0p1-patched/sshkey.h
 | ||||
| --- openssh-9.0p1/sshkey.h	2023-05-24 08:54:03.926443958 +0200
 | ||||
| +++ openssh-9.0p1-patched/sshkey.h	2023-05-24 08:57:22.930642788 +0200
 | ||||
| @@ -340,6 +340,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.0p1/ssh-pkcs11.c openssh-9.0p1-patched/ssh-pkcs11.c
 | ||||
| --- openssh-9.0p1/ssh-pkcs11.c	2023-05-24 08:54:03.888443542 +0200
 | ||||
| +++ openssh-9.0p1-patched/ssh-pkcs11.c	2023-05-24 09:48:13.101168512 +0200
 | ||||
| @@ -776,8 +776,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.0p1/ssh-pkcs11-client.c openssh-9.0p1-patched/ssh-pkcs11-client.c
 | ||||
| --- openssh-9.0p1/ssh-pkcs11-client.c	2023-05-24 08:54:03.887443531 +0200
 | ||||
| +++ openssh-9.0p1-patched/ssh-pkcs11-client.c	2023-05-24 09:49:41.741134514 +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.0p1/ssh-pkcs11.h openssh-9.0p1-patched/ssh-pkcs11.h
 | ||||
| --- openssh-9.0p1/ssh-pkcs11.h	2023-05-24 08:54:03.888443542 +0200
 | ||||
| +++ openssh-9.0p1-patched/ssh-pkcs11.h	2023-05-24 09:50:03.981376886 +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.0p1/ssh-rsa.c openssh-9.0p1-patched/ssh-rsa.c
 | ||||
| --- openssh-9.0p1/ssh-rsa.c	2023-05-24 08:54:03.927443969 +0200
 | ||||
| +++ openssh-9.0p1-patched/ssh-rsa.c	2023-05-24 09:51:50.358536178 +0200
 | ||||
| @@ -174,8 +174,18 @@
 | ||||
|  	if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) | ||||
|  		return SSH_ERR_KEY_LENGTH; | ||||
|   | ||||
| -  	if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0)
 | ||||
| -		return ret;
 | ||||
| +#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
 | ||||
| +	}
 | ||||
| +#endif
 | ||||
|  	ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data, | ||||
|  	    datalen); | ||||
|  	EVP_PKEY_free(pkey); | ||||
							
								
								
									
										1220
									
								
								openssh-9.3p1-merged-openssl-evp.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1220
									
								
								openssh-9.3p1-merged-openssl-evp.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										11
									
								
								openssh.spec
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								openssh.spec
									
									
									
									
									
								
							| @ -183,7 +183,8 @@ Patch953: openssh-7.8p1-scp-ipv6.patch | ||||
| # Mention crypto-policies in manual pages (#1668325) | ||||
| Patch962: openssh-8.0p1-crypto-policies.patch | ||||
| # Use OpenSSL high-level API to produce and verify signatures (#1707485) | ||||
| Patch963: openssh-8.0p1-openssl-evp.patch | ||||
| # TODO fix the comment above ^ | ||||
| Patch963: openssh-9.3p1-merged-openssl-evp.patch | ||||
| # Use OpenSSL KDF (#1631761) | ||||
| Patch964: openssh-8.0p1-openssl-kdf.patch | ||||
| # sk-dummy.so built with -fvisibility=hidden does not work | ||||
| @ -205,8 +206,6 @@ Patch977: openssh-8.7p1-scp-kill-switch.patch | ||||
| Patch981: openssh-8.7p1-recursive-scp.patch | ||||
| # https://github.com/djmdjm/openssh-wip/pull/13 | ||||
| Patch982: openssh-8.7p1-minrsabits.patch | ||||
| # downstream only | ||||
| Patch983: openssh-8.7p1-evpgenkey.patch | ||||
| # downstream only, IBMCA tentative fix | ||||
| # From https://bugzilla.redhat.com/show_bug.cgi?id=1976202#c14 | ||||
| Patch984: openssh-8.7p1-ibmca.patch | ||||
| @ -225,11 +224,9 @@ Patch1004: openssh-8.7p1-gssapi-auth.patch | ||||
| # https://github.com/openssh/openssh-portable/pull/323 | ||||
| Patch1006: openssh-8.7p1-negotiate-supported-algs.patch | ||||
| 
 | ||||
| Patch1011: openssh-9.0p1-evp-fips-sign.patch | ||||
| Patch1012: openssh-9.0p1-evp-fips-dh.patch | ||||
| Patch1013: openssh-9.0p1-evp-fips-ecdh.patch | ||||
| Patch1014: openssh-8.7p1-nohostsha1proof.patch | ||||
| Patch1015: openssh-9.0p1-evp-pkcs11.patch | ||||
| 
 | ||||
| # clarify rhbz#2068423 on the man page of ssh_config | ||||
| Patch1016: openssh-9.0p1-man-hostkeyalgos.patch | ||||
| @ -421,7 +418,6 @@ popd | ||||
| 
 | ||||
| %patch -P 981 -p1 -b .scp-sftpdirs | ||||
| %patch -P 982 -p1 -b .minrsabits | ||||
| %patch -P 983 -p1 -b .evpgenrsa | ||||
| %patch -P 984 -p1 -b .ibmca | ||||
| 
 | ||||
| %patch -P 200 -p1 -b .audit | ||||
| @ -434,11 +430,9 @@ popd | ||||
| 
 | ||||
| %patch -P 1006 -p1 -b .negotiate-supported-algs | ||||
| 
 | ||||
| %patch -P 1011 -p1 -b .evp-fips-sign | ||||
| %patch -P 1012 -p1 -b .evp-fips-dh | ||||
| %patch -P 1013 -p1 -b .evp-fips-ecdh | ||||
| %patch -P 1014 -p1 -b .nosha1hostproof | ||||
| %patch -P 1015 -p1 -b .evp-pkcs11 | ||||
| 
 | ||||
| %patch -P 1016 -p1 -b .man-hostkeyalgos | ||||
| 
 | ||||
| @ -750,6 +744,7 @@ test -f %{sysconfig_anaconda} && \ | ||||
| %changelog | ||||
| * Thu Jun 08 2023 Norbert Pocs <npocs@redhat.com> - 9.3p1-4 | ||||
| - Fix deprecated %patchN syntax | ||||
| - Reduce the number of patches by merging related patches | ||||
| 
 | ||||
| * Wed Jun 07 2023 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.3p1-3 | ||||
| - Fix DSS verification problem | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user