[PATCH] cipher: fix dhgex for non-GCM ciphers for OpenSSL 3.0

Marc Kleine-Budde mkl at pengutronix.de
Fri Dec 4 01:49:32 AEDT 2020


From: Thomas Dwyer III <tomiii at tomiii.com>

During OpenSSL 3.0 development since OpenSSL commits:

| 718b133a5328 Implement AES CBC ciphers in the default provider
| 819a7ae9fc77 Implement AES CTR ciphers in the default provider

the dhgex tests (make t-exec LTESTS="dhgex") are failing.

The issue is that openssh needs the "current" IV state (which the
now-deprecated EVP_CIPHER_CTX_iv() used to return), but it's calling the wrong
openssl function to obtain it. See openssl PR #12233 for additional discussion.

The latest changes in OpenSSL 3.0 in combination with this patch fixes the
non-GCM ciphers. All but the chacha20-poly1305 test are not working again:

| dhgex bits 3072 diffie-hellman-group-exchange-sha1 3des-cbc
| dhgex bits 3072 diffie-hellman-group-exchange-sha256 3des-cbc
| dhgex bits 3072 diffie-hellman-group-exchange-sha1 aes128-cbc
| dhgex bits 3072 diffie-hellman-group-exchange-sha256 aes128-cbc
| dhgex bits 3072 diffie-hellman-group-exchange-sha1 aes128-ctr
| dhgex bits 3072 diffie-hellman-group-exchange-sha256 aes128-ctr
| dhgex bits 3072 diffie-hellman-group-exchange-sha1 aes128-gcm at openssh.com
| dhgex bits 3072 diffie-hellman-group-exchange-sha256 aes128-gcm at openssh.com
| dhgex bits 7680 diffie-hellman-group-exchange-sha1 aes192-cbc
| dhgex bits 7680 diffie-hellman-group-exchange-sha256 aes192-cbc
| dhgex bits 7680 diffie-hellman-group-exchange-sha1 aes192-ctr
| dhgex bits 7680 diffie-hellman-group-exchange-sha256 aes192-ctr
| dhgex bits 8192 diffie-hellman-group-exchange-sha1 aes256-cbc
| dhgex bits 8192 diffie-hellman-group-exchange-sha256 aes256-cbc
| dhgex bits 8192 diffie-hellman-group-exchange-sha1 aes256-ctr
| dhgex bits 8192 diffie-hellman-group-exchange-sha256 aes256-ctr
| dhgex bits 8192 diffie-hellman-group-exchange-sha1 aes256-gcm at openssh.com
| dhgex bits 8192 diffie-hellman-group-exchange-sha256 aes256-gcm at openssh.com
| dhgex bits 8192 diffie-hellman-group-exchange-sha1 rijndael-cbc at lysator.liu.se
| dhgex bits 8192 diffie-hellman-group-exchange-sha256 rijndael-cbc at lysator.liu.se
| dhgex bits 8192 diffie-hellman-group-exchange-sha1 chacha20-poly1305 at openssh.com
| ssh failed ()
| dhgex bits 8192 diffie-hellman-group-exchange-sha256 chacha20-poly1305 at openssh.com
| ssh failed ()

Link: https://www.spinics.net/lists/openssh-unix-dev/msg06860.html
Link: https://github.com/openssl/openssl/pull/12233
---
 cipher.c                             | 2 +-
 configure.ac                         | 5 +++++
 openbsd-compat/libressl-api-compat.c | 8 ++++++++
 openbsd-compat/openssl-compat.h      | 5 +++++
 4 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/cipher.c b/cipher.c
index 8195199b32a2..5fac23d938e1 100644
--- a/cipher.c
+++ b/cipher.c
@@ -498,7 +498,7 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, size_t len)
 		if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
 		   len, iv))
 		       return SSH_ERR_LIBCRYPTO_ERROR;
-	} else if (!EVP_CIPHER_CTX_get_iv(cc->evp, iv, len))
+	} else if (!EVP_CIPHER_CTX_get_iv_state(cc->evp, iv, len))
 	       return SSH_ERR_LIBCRYPTO_ERROR;
 #endif
 	return 0;
diff --git a/configure.ac b/configure.ac
index 35d1aca9fc90..2b14c8de1ad3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2875,6 +2875,11 @@ if test "x$openssl" = "xyes" ; then
 		EVP_chacha20 \
 	])
 
+	# LibreSSL/OpenSSL 3.x API
+	AC_CHECK_FUNCS([ \
+		EVP_CIPHER_CTX_get_iv_state \
+	])
+
 	if test "x$openssl_engine" = "xyes" ; then
 		AC_MSG_CHECKING([for OpenSSL ENGINE support])
 		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
diff --git a/openbsd-compat/libressl-api-compat.c b/openbsd-compat/libressl-api-compat.c
index ae00ff593b7e..a04938fa8260 100644
--- a/openbsd-compat/libressl-api-compat.c
+++ b/openbsd-compat/libressl-api-compat.c
@@ -363,6 +363,14 @@ EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx, unsigned char *iv, size_t len)
 }
 #endif /* HAVE_EVP_CIPHER_CTX_GET_IV */
 
+#ifndef HAVE_EVP_CIPHER_CTX_GET_IV_STATE
+int
+EVP_CIPHER_CTX_get_iv_state(const EVP_CIPHER_CTX *ctx, unsigned char *iv, size_t len)
+{
+	return EVP_CIPHER_CTX_get_iv(ctx, iv, len);
+}
+#endif /* HAVE_EVP_CIPHER_CTX_GET_IV_STATE */
+
 #ifndef HAVE_EVP_CIPHER_CTX_SET_IV
 int
 EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, const unsigned char *iv, size_t len)
diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h
index 388ae8aa0077..c7ff5f0a1f0f 100644
--- a/openbsd-compat/openssl-compat.h
+++ b/openbsd-compat/openssl-compat.h
@@ -117,6 +117,11 @@ int EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx,
     unsigned char *iv, size_t len);
 #endif /* HAVE_EVP_CIPHER_CTX_GET_IV */
 
+#ifndef HAVE_EVP_CIPHER_CTX_GET_IV_STATE
+int EVP_CIPHER_CTX_get_iv_state(const EVP_CIPHER_CTX *ctx,
+    unsigned char *iv, size_t len);
+#endif /* HAVE_EVP_CIPHER_CTX_GET_IV_STATE */
+
 #ifndef HAVE_EVP_CIPHER_CTX_SET_IV
 int EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx,
     const unsigned char *iv, size_t len);
-- 
2.20.1



More information about the openssh-unix-dev mailing list