Use FIPS-compatible API for key derivation RHEL-10
Resolves: RHEL-43592
This commit is contained in:
parent
1c01acf847
commit
f1bd13208d
@ -12,7 +12,7 @@ index 2a455e4e..e01c3d43 100644
|
|||||||
HMAC_CTX_init \
|
HMAC_CTX_init \
|
||||||
RSA_generate_key_ex \
|
RSA_generate_key_ex \
|
||||||
RSA_get_default_method \
|
RSA_get_default_method \
|
||||||
+ EVP_KDF_CTX_new_id \
|
+ EVP_KDF_CTX_new \
|
||||||
])
|
])
|
||||||
|
|
||||||
# OpenSSL_add_all_algorithms may be a macro.
|
# OpenSSL_add_all_algorithms may be a macro.
|
||||||
@ -20,33 +20,35 @@ diff --git a/kex.c b/kex.c
|
|||||||
index b6f041f4..1fbce2bb 100644
|
index b6f041f4..1fbce2bb 100644
|
||||||
--- a/kex.c
|
--- a/kex.c
|
||||||
+++ b/kex.c
|
+++ b/kex.c
|
||||||
@@ -38,6 +38,9 @@
|
@@ -38,6 +38,11 @@
|
||||||
#ifdef WITH_OPENSSL
|
#ifdef WITH_OPENSSL
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#include <openssl/dh.h>
|
#include <openssl/dh.h>
|
||||||
+# ifdef HAVE_EVP_KDF_CTX_NEW_ID
|
+# ifdef HAVE_EVP_KDF_CTX_NEW
|
||||||
+# include <openssl/kdf.h>
|
+# include <openssl/kdf.h>
|
||||||
|
+# include <openssl/param_build.h>
|
||||||
|
+# include <openssl/core_names.h>
|
||||||
+# endif
|
+# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
@@ -942,6 +945,95 @@ kex_choose_conf(struct ssh *ssh)
|
@@ -942,6 +945,107 @@ kex_choose_conf(struct ssh *ssh)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
+#ifdef HAVE_EVP_KDF_CTX_NEW_ID
|
+#ifdef HAVE_EVP_KDF_CTX_NEW
|
||||||
+static const EVP_MD *
|
+static const char *
|
||||||
+digest_to_md(int digest_type)
|
+digest_to_md(int digest_type)
|
||||||
+{
|
+{
|
||||||
+ switch (digest_type) {
|
+ switch (digest_type) {
|
||||||
+ case SSH_DIGEST_SHA1:
|
+ case SSH_DIGEST_SHA1:
|
||||||
+ return EVP_sha1();
|
+ return SN_sha1;
|
||||||
+ case SSH_DIGEST_SHA256:
|
+ case SSH_DIGEST_SHA256:
|
||||||
+ return EVP_sha256();
|
+ return SN_sha256;
|
||||||
+ case SSH_DIGEST_SHA384:
|
+ case SSH_DIGEST_SHA384:
|
||||||
+ return EVP_sha384();
|
+ return SN_sha384;
|
||||||
+ case SSH_DIGEST_SHA512:
|
+ case SSH_DIGEST_SHA512:
|
||||||
+ return EVP_sha512();
|
+ return SN_sha512;
|
||||||
+ }
|
+ }
|
||||||
+ return NULL;
|
+ return NULL;
|
||||||
+}
|
+}
|
||||||
@ -56,52 +58,62 @@ index b6f041f4..1fbce2bb 100644
|
|||||||
+ const struct sshbuf *shared_secret, u_char **keyp)
|
+ const struct sshbuf *shared_secret, u_char **keyp)
|
||||||
+{
|
+{
|
||||||
+ struct kex *kex = ssh->kex;
|
+ struct kex *kex = ssh->kex;
|
||||||
+ EVP_KDF_CTX *ctx = NULL;
|
|
||||||
+ u_char *key = NULL;
|
+ u_char *key = NULL;
|
||||||
+ int r, key_len;
|
+ int r, key_len;
|
||||||
+
|
+
|
||||||
+ if ((key_len = ssh_digest_bytes(kex->hash_alg)) == 0)
|
+ EVP_KDF *kdf = EVP_KDF_fetch(NULL, "SSHKDF", NULL);
|
||||||
+ return SSH_ERR_INVALID_ARGUMENT;
|
+ EVP_KDF_CTX *ctx = EVP_KDF_CTX_new(kdf);
|
||||||
|
+ 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;
|
||||||
|
+
|
||||||
|
+ EVP_KDF_free(kdf);
|
||||||
|
+ if (!ctx) {
|
||||||
|
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ if (md == NULL) {
|
||||||
|
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ 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;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ key_len = ROUNDUP(need, key_len);
|
+ key_len = ROUNDUP(need, key_len);
|
||||||
+ if ((key = calloc(1, key_len)) == NULL) {
|
+ if ((key = calloc(1, key_len)) == NULL) {
|
||||||
+ r = SSH_ERR_ALLOC_FAIL;
|
+ r = SSH_ERR_ALLOC_FAIL;
|
||||||
+ goto out;
|
+ goto out;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF);
|
+ r = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_DIGEST,
|
||||||
+ if (!ctx) {
|
+ 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;
|
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||||
+ goto out;
|
+ goto out;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest_to_md(kex->hash_alg));
|
+ params = OSSL_PARAM_BLD_to_param(param_bld);
|
||||||
+ if (r != 1) {
|
+ if (params == NULL) {
|
||||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||||
+ goto out;
|
+ goto out;
|
||||||
+ }
|
+ }
|
||||||
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY,
|
+ r = EVP_KDF_derive(ctx, key, key_len, params);
|
||||||
+ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret));
|
|
||||||
+ if (r != 1) {
|
|
||||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, hash, hashlen);
|
|
||||||
+ if (r != 1) {
|
|
||||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+ r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, id);
|
|
||||||
+ 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) {
|
|
||||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+ r = EVP_KDF_derive(ctx, key, key_len);
|
|
||||||
+ if (r != 1) {
|
+ if (r != 1) {
|
||||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||||
+ goto out;
|
+ goto out;
|
||||||
@ -115,6 +127,8 @@ index b6f041f4..1fbce2bb 100644
|
|||||||
+ r = 0;
|
+ r = 0;
|
||||||
+
|
+
|
||||||
+out:
|
+out:
|
||||||
|
+ OSSL_PARAM_BLD_free(param_bld);
|
||||||
|
+ OSSL_PARAM_free(params);
|
||||||
+ free (key);
|
+ free (key);
|
||||||
+ EVP_KDF_CTX_free(ctx);
|
+ EVP_KDF_CTX_free(ctx);
|
||||||
+ if (r < 0) {
|
+ if (r < 0) {
|
||||||
@ -130,7 +144,7 @@ index b6f041f4..1fbce2bb 100644
|
|||||||
ssh_digest_free(hashctx);
|
ssh_digest_free(hashctx);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
+#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID */
|
+#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW */
|
||||||
|
|
||||||
#define NKEYS 6
|
#define NKEYS 6
|
||||||
int
|
int
|
||||||
|
@ -658,6 +658,8 @@ test -f %{sysconfig_anaconda} && \
|
|||||||
Related: RHEL-42635
|
Related: RHEL-42635
|
||||||
- Change ssh-keygen defaults in FIPS mode
|
- Change ssh-keygen defaults in FIPS mode
|
||||||
Resolves: RHEL-37324
|
Resolves: RHEL-37324
|
||||||
|
- Use FIPS-compatible API for key derivation RHEL-10
|
||||||
|
Resolves: RHEL-43592
|
||||||
|
|
||||||
* Thu Jul 25 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.8p1-1.0
|
* Thu Jul 25 2024 Dmitry Belyavskiy <dbelyavs@redhat.com> - 9.8p1-1.0
|
||||||
- Rebase OpenSSH to 9.8p1
|
- Rebase OpenSSH to 9.8p1
|
||||||
|
Loading…
Reference in New Issue
Block a user