dotnet3.1/corefx-openssl-0008-Work-around-OpenSSL-3.0-ciphers-not-restoring-origin.patch
2021-08-24 11:54:01 -04:00

80 lines
3.8 KiB
Diff

From 30e2e4cbb11a4fbdb7102133b19bfc990a2ba939 Mon Sep 17 00:00:00 2001
From: Jeremy Barton <jbarton@microsoft.com>
Date: Fri, 16 Apr 2021 09:38:47 -0700
Subject: [PATCH 08/11] Work around OpenSSL 3.0 ciphers not restoring original
IV on reset.
---
.../opensslshim.h | 2 ++
.../osslcompat_30.h | 1 +
.../pal_evp_cipher.c | 20 ++++++++++++++++++-
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
index 957860cae4..c5052c1ba5 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
@@ -271,6 +271,7 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
LEGACY_FUNCTION(EVP_CIPHER_CTX_cleanup) \
REQUIRED_FUNCTION(EVP_CIPHER_CTX_ctrl) \
FALLBACK_FUNCTION(EVP_CIPHER_CTX_free) \
+ LIGHTUP_FUNCTION(EVP_CIPHER_CTX_get_original_iv) \
LEGACY_FUNCTION(EVP_CIPHER_CTX_init) \
FALLBACK_FUNCTION(EVP_CIPHER_CTX_new) \
FALLBACK_FUNCTION(EVP_CIPHER_CTX_reset) \
@@ -676,6 +677,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define EVP_CIPHER_CTX_cleanup EVP_CIPHER_CTX_cleanup_ptr
#define EVP_CIPHER_CTX_ctrl EVP_CIPHER_CTX_ctrl_ptr
#define EVP_CIPHER_CTX_free EVP_CIPHER_CTX_free_ptr
+#define EVP_CIPHER_CTX_get_original_iv EVP_CIPHER_CTX_get_original_iv_ptr
#define EVP_CIPHER_CTX_init EVP_CIPHER_CTX_init_ptr
#define EVP_CIPHER_CTX_new EVP_CIPHER_CTX_new_ptr
#define EVP_CIPHER_CTX_reset EVP_CIPHER_CTX_reset_ptr
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h b/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h
index b87b4e7250..bb529df51e 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h
@@ -18,6 +18,7 @@ typedef struct ossl_lib_ctx_st OSSL_LIB_CTX;
void ERR_new(void);
void ERR_set_debug(const char *file, int line, const char *func);
void ERR_set_error(int lib, int reason, const char *fmt, ...);
+int EVP_CIPHER_CTX_get_original_iv(EVP_CIPHER_CTX *ctx, void *buf, size_t len);
int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX* ctx, int bits);
int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX* ctx, const EVP_MD* md);
int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX* ctx, int pad_mode);
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.c b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.c
index af2483fa0c..4d21294fa1 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.c
@@ -127,8 +127,26 @@ int32_t CryptoNative_EvpCipherReset(EVP_CIPHER_CTX* ctx)
//
// But since we have a different object returned for CreateEncryptor
// and CreateDecryptor we don't need to worry about that.
+ uint8_t* iv = NULL;
- return EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, KEEP_CURRENT_DIRECTION);
+#ifdef NEED_OPENSSL_3_0
+ // OpenSSL 3.0 alpha 13 does not properly reset the IV. Work around that by
+ // asking for the original IV, and giving it back.
+ uint8_t tmpIV[EVP_MAX_IV_LENGTH];
+
+ // If we're direct against 3.0, or we're portable and found 3.0
+ if (API_EXISTS(EVP_CIPHER_CTX_get_original_iv))
+ {
+ if (EVP_CIPHER_CTX_get_original_iv(ctx, tmpIV, sizeof(tmpIV)) != 1)
+ {
+ return 0;
+ }
+
+ iv = tmpIV;
+ }
+#endif
+
+ return EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, KEEP_CURRENT_DIRECTION);
}
int32_t CryptoNative_EvpCipherCtxSetPadding(EVP_CIPHER_CTX* x, int32_t padding)
--
2.31.1