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