vishalmishra434 / rpms / openssh

Forked from rpms/openssh a month ago
Clone
Jakub Jelen f726e5
commit 2c3ef499bfffce3cfd315edeebf202850ba4e00a
Jakub Jelen f726e5
Author: Jakub Jelen <jjelen@redhat.com>
Jakub Jelen f726e5
Date:   Tue Apr 16 15:35:18 2019 +0200
Jakub Jelen f726e5
Jakub Jelen f726e5
    Use the new OpenSSL KDF
Jakub Jelen f726e5
Jakub Jelen f726e5
diff --git a/configure.ac b/configure.ac
Jakub Jelen f726e5
index 2a455e4e..e01c3d43 100644
Jakub Jelen f726e5
--- a/configure.ac
Jakub Jelen f726e5
+++ b/configure.ac
Jakub Jelen f726e5
@@ -2712,6 +2712,7 @@ if test "x$openssl" = "xyes" ; then
Jakub Jelen f726e5
 		HMAC_CTX_init \
Jakub Jelen f726e5
 		RSA_generate_key_ex \
Jakub Jelen f726e5
 		RSA_get_default_method \
Jakub Jelen f726e5
+		EVP_KDF_CTX_new_id \
Jakub Jelen f726e5
 	])
Jakub Jelen f726e5
 
Jakub Jelen f726e5
 	# OpenSSL_add_all_algorithms may be a macro.
Jakub Jelen f726e5
diff --git a/kex.c b/kex.c
Jakub Jelen f726e5
index b6f041f4..1fbce2bb 100644
Jakub Jelen f726e5
--- a/kex.c
Jakub Jelen f726e5
+++ b/kex.c
Jakub Jelen f726e5
@@ -38,6 +38,9 @@
Jakub Jelen f726e5
 #ifdef WITH_OPENSSL
Jakub Jelen f726e5
 #include <openssl/crypto.h>
Jakub Jelen f726e5
 #include <openssl/dh.h>
Jakub Jelen f726e5
+# ifdef HAVE_EVP_KDF_CTX_NEW_ID
Jakub Jelen f726e5
+# include <openssl/kdf.h>
Jakub Jelen f726e5
+# endif
Jakub Jelen f726e5
 #endif
Jakub Jelen f726e5
 
Jakub Jelen f726e5
 #include "ssh.h"
Jakub Jelen f726e5
@@ -942,6 +945,95 @@ kex_choose_conf(struct ssh *ssh)
Jakub Jelen f726e5
 	return r;
Jakub Jelen f726e5
 }
Jakub Jelen f726e5
 
Jakub Jelen f726e5
+#ifdef HAVE_EVP_KDF_CTX_NEW_ID
Jakub Jelen f726e5
+static const EVP_MD *
Jakub Jelen f726e5
+digest_to_md(int digest_type)
Jakub Jelen f726e5
+{
Jakub Jelen f726e5
+	switch (digest_type) {
Jakub Jelen f726e5
+	case SSH_DIGEST_SHA1:
Jakub Jelen f726e5
+		return EVP_sha1();
Jakub Jelen f726e5
+	case SSH_DIGEST_SHA256:
Jakub Jelen f726e5
+		return EVP_sha256();
Jakub Jelen f726e5
+	case SSH_DIGEST_SHA384:
Jakub Jelen f726e5
+		return EVP_sha384();
Jakub Jelen f726e5
+	case SSH_DIGEST_SHA512:
Jakub Jelen f726e5
+		return EVP_sha512();
Jakub Jelen f726e5
+	}
Jakub Jelen f726e5
+	return NULL;
Jakub Jelen f726e5
+}
Jakub Jelen f726e5
+
Jakub Jelen f726e5
+static int
Jakub Jelen f726e5
+derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
Jakub Jelen f726e5
+    const struct sshbuf *shared_secret, u_char **keyp)
Jakub Jelen f726e5
+{
Jakub Jelen f726e5
+	struct kex *kex = ssh->kex;
Jakub Jelen f726e5
+	EVP_KDF_CTX *ctx = NULL;
Jakub Jelen f726e5
+	u_char *key = NULL;
Jakub Jelen f726e5
+	int r, key_len;
Jakub Jelen f726e5
+
Jakub Jelen f726e5
+	if ((key_len = ssh_digest_bytes(kex->hash_alg)) == 0)
Jakub Jelen f726e5
+		return SSH_ERR_INVALID_ARGUMENT;
Jakub Jelen f726e5
+	key_len = ROUNDUP(need, key_len);
Jakub Jelen f726e5
+	if ((key = calloc(1, key_len)) == NULL) {
Jakub Jelen f726e5
+		r = SSH_ERR_ALLOC_FAIL;
Jakub Jelen f726e5
+		goto out;
Jakub Jelen f726e5
+	}
Jakub Jelen f726e5
+
Jakub Jelen f726e5
+	ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF);
Jakub Jelen f726e5
+	if (!ctx) {
Jakub Jelen f726e5
+		r = SSH_ERR_LIBCRYPTO_ERROR;
Jakub Jelen f726e5
+		goto out;
Jakub Jelen f726e5
+	}
Jakub Jelen f726e5
+
Jakub Jelen f726e5
+	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest_to_md(kex->hash_alg));
Jakub Jelen f726e5
+	if (r != 1) {
Jakub Jelen f726e5
+		r = SSH_ERR_LIBCRYPTO_ERROR;
Jakub Jelen f726e5
+		goto out;
Jakub Jelen f726e5
+	}
Jakub Jelen f726e5
+	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY,
Jakub Jelen f726e5
+	    sshbuf_ptr(shared_secret), sshbuf_len(shared_secret));
Jakub Jelen f726e5
+	if (r != 1) {
Jakub Jelen f726e5
+		r = SSH_ERR_LIBCRYPTO_ERROR;
Jakub Jelen f726e5
+		goto out;
Jakub Jelen f726e5
+	}
Jakub Jelen f726e5
+	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, hash, hashlen);
Jakub Jelen f726e5
+	if (r != 1) {
Jakub Jelen f726e5
+		r = SSH_ERR_LIBCRYPTO_ERROR;
Jakub Jelen f726e5
+		goto out;
Jakub Jelen f726e5
+	}
Jakub Jelen f726e5
+	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, id);
Jakub Jelen f726e5
+	if (r != 1) {
Jakub Jelen f726e5
+		r = SSH_ERR_LIBCRYPTO_ERROR;
Jakub Jelen f726e5
+		goto out;
Jakub Jelen f726e5
+	}
Jakub Jelen f726e5
+	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID,
Jakub Jelen 25c16c
+	    sshbuf_ptr(kex->session_id), sshbuf_len(kex->session_id));
Jakub Jelen f726e5
+	if (r != 1) {
Jakub Jelen f726e5
+		r = SSH_ERR_LIBCRYPTO_ERROR;
Jakub Jelen f726e5
+		goto out;
Jakub Jelen f726e5
+	}
Jakub Jelen f726e5
+	r = EVP_KDF_derive(ctx, key, key_len);
Jakub Jelen f726e5
+	if (r != 1) {
Jakub Jelen f726e5
+		r = SSH_ERR_LIBCRYPTO_ERROR;
Jakub Jelen f726e5
+		goto out;
Jakub Jelen f726e5
+	}
Jakub Jelen f726e5
+#ifdef DEBUG_KEX
Jakub Jelen f726e5
+	fprintf(stderr, "key '%c'== ", id);
Jakub Jelen f726e5
+	dump_digest("key", key, key_len);
Jakub Jelen f726e5
+#endif
Jakub Jelen f726e5
+	*keyp = key;
Jakub Jelen f726e5
+	key = NULL;
Jakub Jelen f726e5
+	r = 0;
Jakub Jelen f726e5
+
Jakub Jelen f726e5
+out:
Jakub Jelen f726e5
+	free (key);
Jakub Jelen f726e5
+	EVP_KDF_CTX_free(ctx);
Jakub Jelen f726e5
+	if (r < 0) {
Jakub Jelen f726e5
+		return r;
Jakub Jelen f726e5
+	}
Jakub Jelen f726e5
+	return 0;
Jakub Jelen f726e5
+}
Jakub Jelen f726e5
+#else
Jakub Jelen f726e5
 static int
Jakub Jelen f726e5
 derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
Jakub Jelen f726e5
     const struct sshbuf *shared_secret, u_char **keyp)
Jakub Jelen f726e5
@@ -1004,6 +1096,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
Jakub Jelen f726e5
 	ssh_digest_free(hashctx);
Jakub Jelen f726e5
 	return r;
Jakub Jelen f726e5
 }
Jakub Jelen f726e5
+#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID */
Jakub Jelen f726e5
 
Jakub Jelen f726e5
 #define NKEYS	6
Jakub Jelen f726e5
 int
Jakub Jelen f726e5