Dmitry Belyavskiy d0bf0e
diff -up openssh-8.7p1/sshkey.c.evpgenrsa openssh-8.7p1/sshkey.c
Dmitry Belyavskiy d0bf0e
--- openssh-8.7p1/sshkey.c.evpgenrsa	2022-06-30 15:14:58.200518353 +0200
Dmitry Belyavskiy d0bf0e
+++ openssh-8.7p1/sshkey.c	2022-06-30 15:24:31.499641196 +0200
Dmitry Belyavskiy d0bf0e
@@ -1657,7 +1657,8 @@ sshkey_cert_type(const struct sshkey *k)
Dmitry Belyavskiy d0bf0e
 static int
Dmitry Belyavskiy d0bf0e
 rsa_generate_private_key(u_int bits, RSA **rsap)
Dmitry Belyavskiy d0bf0e
 {
Dmitry Belyavskiy d0bf0e
-	RSA *private = NULL;
Dmitry Belyavskiy d0bf0e
+	EVP_PKEY_CTX *ctx = NULL;
Dmitry Belyavskiy d0bf0e
+	EVP_PKEY *res = NULL;
Dmitry Belyavskiy d0bf0e
 	BIGNUM *f4 = NULL;
Dmitry Belyavskiy d0bf0e
 	int ret = SSH_ERR_INTERNAL_ERROR;
Dmitry Belyavskiy d0bf0e
 
Dmitry Belyavskiy d0bf0e
@@ -1667,20 +1668,42 @@ rsa_generate_private_key(u_int bits, RSA
Dmitry Belyavskiy d0bf0e
 	    bits > SSHBUF_MAX_BIGNUM * 8)
Dmitry Belyavskiy d0bf0e
 		return SSH_ERR_KEY_LENGTH;
Dmitry Belyavskiy d0bf0e
 	*rsap = NULL;
Dmitry Belyavskiy d0bf0e
-	if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
Dmitry Belyavskiy d0bf0e
+
Dmitry Belyavskiy d0bf0e
+	if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL
Dmitry Belyavskiy d0bf0e
+		|| (f4 = BN_new()) == NULL || !BN_set_word(f4, RSA_F4)) {
Dmitry Belyavskiy d0bf0e
 		ret = SSH_ERR_ALLOC_FAIL;
Dmitry Belyavskiy d0bf0e
 		goto out;
Dmitry Belyavskiy d0bf0e
 	}
Dmitry Belyavskiy d0bf0e
-	if (!BN_set_word(f4, RSA_F4) ||
Dmitry Belyavskiy d0bf0e
-	    !RSA_generate_key_ex(private, bits, f4, NULL)) {
Dmitry Belyavskiy d0bf0e
+
Dmitry Belyavskiy d0bf0e
+	if (EVP_PKEY_keygen_init(ctx) <= 0) {
Dmitry Belyavskiy d0bf0e
+		ret = SSH_ERR_LIBCRYPTO_ERROR;
Dmitry Belyavskiy d0bf0e
+		goto out;
Dmitry Belyavskiy d0bf0e
+	}
Dmitry Belyavskiy d0bf0e
+
Dmitry Belyavskiy d0bf0e
+	if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) {
Dmitry Belyavskiy d0bf0e
+		ret = SSH_ERR_KEY_LENGTH;
Dmitry Belyavskiy d0bf0e
+		goto out;
Dmitry Belyavskiy d0bf0e
+	}
Dmitry Belyavskiy d0bf0e
+
Dmitry Belyavskiy d0bf0e
+	if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, f4) <= 0)
Dmitry Belyavskiy d0bf0e
+		goto out;
Dmitry Belyavskiy d0bf0e
+
Dmitry Belyavskiy d0bf0e
+	if (EVP_PKEY_keygen(ctx, &res) <= 0) {
Dmitry Belyavskiy d0bf0e
+		ret = SSH_ERR_LIBCRYPTO_ERROR;
Dmitry Belyavskiy d0bf0e
+		goto out;
Dmitry Belyavskiy d0bf0e
+	}
Dmitry Belyavskiy d0bf0e
+
Dmitry Belyavskiy d0bf0e
+	/* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/
Dmitry Belyavskiy d0bf0e
+	*rsap = EVP_PKEY_get1_RSA(res);
Dmitry Belyavskiy d0bf0e
+	if (*rsap) {
Dmitry Belyavskiy d0bf0e
+		ret = 0;
Dmitry Belyavskiy d0bf0e
+	} else {
Dmitry Belyavskiy d0bf0e
 		ret = SSH_ERR_LIBCRYPTO_ERROR;
Dmitry Belyavskiy d0bf0e
 		goto out;
Dmitry Belyavskiy d0bf0e
 	}
Dmitry Belyavskiy d0bf0e
-	*rsap = private;
Dmitry Belyavskiy d0bf0e
-	private = NULL;
Dmitry Belyavskiy d0bf0e
-	ret = 0;
Dmitry Belyavskiy d0bf0e
  out:
Dmitry Belyavskiy d0bf0e
-	RSA_free(private);
Dmitry Belyavskiy d0bf0e
+	EVP_PKEY_CTX_free(ctx);
Dmitry Belyavskiy d0bf0e
+	EVP_PKEY_free(res);
Dmitry Belyavskiy d0bf0e
 	BN_free(f4);
Dmitry Belyavskiy d0bf0e
 	return ret;
Dmitry Belyavskiy d0bf0e
 }
Dmitry Belyavskiy d0bf0e
@@ -1820,7 +1820,8 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k)
Dmitry Belyavskiy d0bf0e
 static int
Dmitry Belyavskiy d0bf0e
 ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap)
Dmitry Belyavskiy d0bf0e
 {
Dmitry Belyavskiy d0bf0e
-	EC_KEY *private;
Dmitry Belyavskiy d0bf0e
+	EVP_PKEY_CTX *ctx = NULL;
Dmitry Belyavskiy d0bf0e
+	EVP_PKEY *res = NULL;
Dmitry Belyavskiy d0bf0e
 	int ret = SSH_ERR_INTERNAL_ERROR;
Dmitry Belyavskiy d0bf0e
 
Dmitry Belyavskiy d0bf0e
 	if (nid == NULL || ecdsap == NULL)
Dmitry Belyavskiy d0bf0e
@@ -1828,20 +1829,29 @@ ecdsa_generate_private_key(u_int bits, i
Dmitry Belyavskiy d0bf0e
 	if ((*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
Dmitry Belyavskiy d0bf0e
 		return SSH_ERR_KEY_LENGTH;
Dmitry Belyavskiy d0bf0e
 	*ecdsap = NULL;
Dmitry Belyavskiy d0bf0e
-	if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) {
Dmitry Belyavskiy d0bf0e
+
Dmitry Belyavskiy d0bf0e
+	if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) {
Dmitry Belyavskiy d0bf0e
 		ret = SSH_ERR_ALLOC_FAIL;
Dmitry Belyavskiy d0bf0e
 		goto out;
Dmitry Belyavskiy d0bf0e
 	}
Dmitry Belyavskiy d0bf0e
-	if (EC_KEY_generate_key(private) != 1) {
Dmitry Belyavskiy d0bf0e
+
Dmitry Belyavskiy d0bf0e
+	if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(*nid)) <= 0
Dmitry Belyavskiy d0bf0e
+	   || EVP_PKEY_keygen(ctx, &res) <= 0) {
Dmitry Belyavskiy d0bf0e
+		ret = SSH_ERR_LIBCRYPTO_ERROR;
Dmitry Belyavskiy d0bf0e
+		goto out;
Dmitry Belyavskiy d0bf0e
+	}
Dmitry Belyavskiy d0bf0e
+	/* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/
Dmitry Belyavskiy d0bf0e
+	*ecdsap = EVP_PKEY_get1_EC_KEY(res);
Dmitry Belyavskiy d0bf0e
+	if (*ecdsap) {
Dmitry Belyavskiy d0bf0e
+		EC_KEY_set_asn1_flag(*ecdsap, OPENSSL_EC_NAMED_CURVE);
Dmitry Belyavskiy d0bf0e
+		ret = 0;
Dmitry Belyavskiy d0bf0e
+	} else {
Dmitry Belyavskiy d0bf0e
 		ret = SSH_ERR_LIBCRYPTO_ERROR;
Dmitry Belyavskiy d0bf0e
 		goto out;
Dmitry Belyavskiy d0bf0e
 	}
Dmitry Belyavskiy d0bf0e
-	EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
Dmitry Belyavskiy d0bf0e
-	*ecdsap = private;
Dmitry Belyavskiy d0bf0e
-	private = NULL;
Dmitry Belyavskiy d0bf0e
-	ret = 0;
Dmitry Belyavskiy d0bf0e
  out:
Dmitry Belyavskiy d0bf0e
-	EC_KEY_free(private);
Dmitry Belyavskiy d0bf0e
+	EVP_PKEY_CTX_free(ctx);
Dmitry Belyavskiy d0bf0e
+	EVP_PKEY_free(res);
Dmitry Belyavskiy d0bf0e
 	return ret;
Dmitry Belyavskiy d0bf0e
 }
Dmitry Belyavskiy d0bf0e
 # endif /* OPENSSL_HAS_ECC */