diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index 05b2907..704de05 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -81,7 +81,7 @@ diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c #include +#include #include - # ifdef HAVE_EVP_KDF_CTX_NEW_ID + # ifdef HAVE_EVP_KDF_CTX_NEW # include @@ -203,7 +203,10 @@ kex_names_valid(const char *names) for ((p = strsep(&cp, ",")); p && *p != '\0'; diff --git a/openssh-8.0p1-openssl-kdf.patch b/openssh-8.0p1-openssl-kdf.patch index 5d76a4f..e190472 100644 --- a/openssh-8.0p1-openssl-kdf.patch +++ b/openssh-8.0p1-openssl-kdf.patch @@ -12,7 +12,7 @@ index 2a455e4e..e01c3d43 100644 HMAC_CTX_init \ RSA_generate_key_ex \ RSA_get_default_method \ -+ EVP_KDF_CTX_new_id \ ++ EVP_KDF_CTX_new \ ]) # OpenSSL_add_all_algorithms may be a macro. @@ -20,33 +20,35 @@ diff --git a/kex.c b/kex.c index b6f041f4..1fbce2bb 100644 --- a/kex.c +++ b/kex.c -@@ -38,6 +38,9 @@ +@@ -38,6 +38,11 @@ #ifdef WITH_OPENSSL #include #include -+# ifdef HAVE_EVP_KDF_CTX_NEW_ID ++# ifdef HAVE_EVP_KDF_CTX_NEW +# include ++# include ++# include +# endif #endif #include "ssh.h" -@@ -942,6 +945,95 @@ kex_choose_conf(struct ssh *ssh) +@@ -942,6 +945,112 @@ kex_choose_conf(struct ssh *ssh) return r; } -+#ifdef HAVE_EVP_KDF_CTX_NEW_ID -+static const EVP_MD * ++#ifdef HAVE_EVP_KDF_CTX_NEW ++static const char * +digest_to_md(int digest_type) +{ + switch (digest_type) { + case SSH_DIGEST_SHA1: -+ return EVP_sha1(); ++ return SN_sha1; + case SSH_DIGEST_SHA256: -+ return EVP_sha256(); ++ return SN_sha256; + case SSH_DIGEST_SHA384: -+ return EVP_sha384(); ++ return SN_sha384; + case SSH_DIGEST_SHA512: -+ return EVP_sha512(); ++ return SN_sha512; + } + return NULL; +} @@ -56,52 +58,67 @@ index b6f041f4..1fbce2bb 100644 + const struct sshbuf *shared_secret, u_char **keyp) +{ + struct kex *kex = ssh->kex; -+ EVP_KDF_CTX *ctx = NULL; + u_char *key = NULL; + int r, key_len; + -+ if ((key_len = ssh_digest_bytes(kex->hash_alg)) == 0) -+ return SSH_ERR_INVALID_ARGUMENT; -+ key_len = ROUNDUP(need, key_len); -+ if ((key = calloc(1, key_len)) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; ++ EVP_KDF *kdf = EVP_KDF_fetch(NULL, "SSHKDF", NULL); ++ EVP_KDF_CTX *ctx = NULL; ++ OSSL_PARAM_BLD *param_bld = OSSL_PARAM_BLD_new(); ++ OSSL_PARAM *params = NULL; ++ const char *md = digest_to_md(kex->hash_alg); ++ char keytype = (char)id; ++ ++ if (!kdf) { ++ r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } -+ -+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF); ++ ctx = EVP_KDF_CTX_new(kdf); ++ EVP_KDF_free(kdf); + if (!ctx) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } -+ -+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest_to_md(kex->hash_alg)); -+ if (r != 1) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; ++ if (md == NULL) { ++ r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } -+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, -+ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret)); -+ if (r != 1) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; ++ ++ if (param_bld == NULL) { ++ EVP_KDF_CTX_free(ctx); ++ return -1; ++ } ++ if ((key_len = ssh_digest_bytes(kex->hash_alg)) == 0) { ++ r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } -+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, hash, hashlen); -+ if (r != 1) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; ++ ++ key_len = ROUNDUP(need, key_len); ++ if ((key = calloc(1, key_len)) == NULL) { ++ r = SSH_ERR_ALLOC_FAIL; + goto out; + } -+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, id); ++ ++ r = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_DIGEST, ++ md, strlen(md)) && /* SN */ ++ OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_KDF_PARAM_KEY, ++ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret)) && ++ OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_KDF_PARAM_SSHKDF_XCGHASH, ++ hash, hashlen) && ++ OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_KDF_PARAM_SSHKDF_SESSION_ID, ++ sshbuf_ptr(kex->session_id), sshbuf_len(kex->session_id)) && ++ OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_SSHKDF_TYPE, ++ &keytype, 1); + if (r != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } -+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID, -+ sshbuf_ptr(kex->session_id), sshbuf_len(kex->session_id)); -+ if (r != 1) { ++ ++ params = OSSL_PARAM_BLD_to_param(param_bld); ++ if (params == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } -+ r = EVP_KDF_derive(ctx, key, key_len); ++ r = EVP_KDF_derive(ctx, key, key_len, params); + if (r != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; @@ -115,6 +132,8 @@ index b6f041f4..1fbce2bb 100644 + r = 0; + +out: ++ OSSL_PARAM_BLD_free(param_bld); ++ OSSL_PARAM_free(params); + free (key); + EVP_KDF_CTX_free(ctx); + if (r < 0) { @@ -130,7 +149,7 @@ index b6f041f4..1fbce2bb 100644 ssh_digest_free(hashctx); return r; } -+#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID */ ++#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW */ #define NKEYS 6 int diff --git a/openssh.spec b/openssh.spec index 8a7a38e..de1e941 100644 --- a/openssh.spec +++ b/openssh.spec @@ -47,7 +47,7 @@ # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1 %global openssh_ver 8.7p1 -%global openssh_rel 38 +%global openssh_rel 39 %global pam_ssh_agent_ver 0.10.4 %global pam_ssh_agent_rel 5 @@ -798,6 +798,10 @@ test -f %{sysconfig_anaconda} && \ %endif %changelog +* Wed Apr 24 2024 Dmitry Belyavskiy - 8.7p1-39 +- Use FIPS-compatible API for key derivation + Resolves: RHEL-32809 + * Fri Jan 05 2024 Dmitry Belyavskiy - 8.7p1-38 - Fix Terrapin attack Resolves: CVE-2023-48795