commit:     10bdd9eb10ccaecab63972168b3802e6e2f00127
Author:     Kenton Groombridge <concord <AT> gentoo <DOT> org>
AuthorDate: Sun Jul  3 02:43:00 2022 +0000
Commit:     Kenton Groombridge <concord <AT> gentoo <DOT> org>
CommitDate: Sun Jul  3 02:49:19 2022 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=10bdd9eb

net-voip/mumble: backport crypto thread patch for 1.4.230

The backported patch to migrate to the OpenSSL 3.0-compatible API
introduces a sporadic crash. Backport the upstream patch at commit
f8d47db318f302f5a7d343f15c9936c7030c49c4 to fix this issue.

Signed-off-by: Kenton Groombridge <concord <AT> gentoo.org>

 .../mumble/files/mumble-1.4-crypto-threads.patch   | 131 +++++++++++++++++++++
 ...-1.4.230-r1.ebuild => mumble-1.4.230-r2.ebuild} |   1 +
 2 files changed, 132 insertions(+)

diff --git a/net-voip/mumble/files/mumble-1.4-crypto-threads.patch 
b/net-voip/mumble/files/mumble-1.4-crypto-threads.patch
new file mode 100644
index 000000000000..0ad371cd6c63
--- /dev/null
+++ b/net-voip/mumble/files/mumble-1.4-crypto-threads.patch
@@ -0,0 +1,131 @@
+commit f8d47db318f302f5a7d343f15c9936c7030c49c4
+Author: Terry Geng <te...@terriex.com>
+Date:   Sun Dec 12 22:39:38 2021 -0500
+
+    FIX(crypto): Sharing EVP context between threads crushes Mumble
+    
+    Functions ocb_encrypt and ocb_decrypt share the same set
+    of encrypt and decrypt contexts. However, they are invoked
+    in different threads (audio input thread and server
+    handler thread).
+    This may lead to conflicts that would crash Mumble.
+    This patch separates contexts used in these two functions
+    to avoid such conflicts.
+    
+    Fixes #5361
+
+diff --git a/src/crypto/CryptStateOCB2.cpp b/src/crypto/CryptStateOCB2.cpp
+index 640fdedac..3b3473ffe 100644
+--- a/src/crypto/CryptStateOCB2.cpp
++++ b/src/crypto/CryptStateOCB2.cpp
+@@ -30,7 +30,9 @@
+ #include <cstring>
+ #include <openssl/rand.h>
+ 
+-CryptStateOCB2::CryptStateOCB2() : CryptState(), 
enc_ctx(EVP_CIPHER_CTX_new()), dec_ctx(EVP_CIPHER_CTX_new()) {
++CryptStateOCB2::CryptStateOCB2()
++      : CryptState(), enc_ctx_ocb_enc(EVP_CIPHER_CTX_new()), 
dec_ctx_ocb_enc(EVP_CIPHER_CTX_new()),
++        enc_ctx_ocb_dec(EVP_CIPHER_CTX_new()), 
dec_ctx_ocb_dec(EVP_CIPHER_CTX_new()) {
+       for (int i = 0; i < 0x100; i++)
+               decrypt_history[i] = 0;
+       memset(raw_key, 0, AES_KEY_SIZE_BYTES);
+@@ -39,8 +41,10 @@ CryptStateOCB2::CryptStateOCB2() : CryptState(), 
enc_ctx(EVP_CIPHER_CTX_new()),
+ }
+ 
+ CryptStateOCB2::~CryptStateOCB2() noexcept {
+-      EVP_CIPHER_CTX_free(enc_ctx);
+-      EVP_CIPHER_CTX_free(dec_ctx);
++      EVP_CIPHER_CTX_free(enc_ctx_ocb_enc);
++      EVP_CIPHER_CTX_free(dec_ctx_ocb_enc);
++      EVP_CIPHER_CTX_free(enc_ctx_ocb_dec);
++      EVP_CIPHER_CTX_free(dec_ctx_ocb_dec);
+ }
+ 
+ bool CryptStateOCB2::isValid() const {
+@@ -257,25 +261,28 @@ static void inline ZERO(keyblock &block) {
+               block[i] = 0;
+ }
+ 
+-#define AESencrypt(src, dst, key)                                             
                    \
+-      {                                                                       
                      \
+-              int outlen = 0;                                                 
                          \
+-              EVP_EncryptInit_ex(enc_ctx, EVP_aes_128_ecb(), NULL, key, 
NULL);                          \
+-              EVP_CIPHER_CTX_set_padding(enc_ctx, 0);                         
                          \
+-              EVP_EncryptUpdate(enc_ctx, reinterpret_cast< unsigned char * 
>(dst), &outlen,             \
+-                                                reinterpret_cast< const 
unsigned char * >(src), AES_BLOCK_SIZE);        \
+-              EVP_EncryptFinal_ex(enc_ctx, reinterpret_cast< unsigned char * 
>(dst + outlen), &outlen); \
++#define AESencrypt_ctx(src, dst, key, enc_ctx)                                
                      \
++      {                                                                       
                        \
++              int outlen = 0;                                                 
                            \
++              EVP_EncryptInit_ex(enc_ctx, EVP_aes_128_ecb(), NULL, key, 
NULL);                            \
++              EVP_CIPHER_CTX_set_padding(enc_ctx, 0);                         
                            \
++              EVP_EncryptUpdate(enc_ctx, reinterpret_cast< unsigned char * 
>(dst), &outlen,               \
++                                                reinterpret_cast< const 
unsigned char * >(src), AES_BLOCK_SIZE);          \
++              EVP_EncryptFinal_ex(enc_ctx, reinterpret_cast< unsigned char * 
>((dst) + outlen), &outlen); \
+       }
+-#define AESdecrypt(src, dst, key)                                             
                    \
+-      {                                                                       
                      \
+-              int outlen = 0;                                                 
                          \
+-              EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_ecb(), NULL, key, 
NULL);                          \
+-              EVP_CIPHER_CTX_set_padding(dec_ctx, 0);                         
                          \
+-              EVP_DecryptUpdate(dec_ctx, reinterpret_cast< unsigned char * 
>(dst), &outlen,             \
+-                                                reinterpret_cast< const 
unsigned char * >(src), AES_BLOCK_SIZE);        \
+-              EVP_DecryptFinal_ex(dec_ctx, reinterpret_cast< unsigned char * 
>(dst + outlen), &outlen); \
++#define AESdecrypt_ctx(src, dst, key, dec_ctx)                                
                      \
++      {                                                                       
                        \
++              int outlen = 0;                                                 
                            \
++              EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_ecb(), NULL, key, 
NULL);                            \
++              EVP_CIPHER_CTX_set_padding(dec_ctx, 0);                         
                            \
++              EVP_DecryptUpdate(dec_ctx, reinterpret_cast< unsigned char * 
>(dst), &outlen,               \
++                                                reinterpret_cast< const 
unsigned char * >(src), AES_BLOCK_SIZE);          \
++              EVP_DecryptFinal_ex(dec_ctx, reinterpret_cast< unsigned char * 
>((dst) + outlen), &outlen); \
+       }
+ 
++#define AESencrypt(src, dst, key) AESencrypt_ctx(src, dst, key, 
enc_ctx_ocb_enc)
++#define AESdecrypt(src, dst, key) AESdecrypt_ctx(src, dst, key, 
dec_ctx_ocb_enc)
++
+ bool CryptStateOCB2::ocb_encrypt(const unsigned char *plain, unsigned char 
*encrypted, unsigned int len,
+                                                                const unsigned 
char *nonce, unsigned char *tag, bool modifyPlainOnXEXStarAttack) {
+       keyblock checksum, delta, tmp, pad;
+@@ -345,6 +352,12 @@ bool CryptStateOCB2::ocb_encrypt(const unsigned char 
*plain, unsigned char *encr
+       return success;
+ }
+ 
++#undef AESencrypt
++#undef AESdecrypt
++
++#define AESencrypt(src, dst, key) AESencrypt_ctx(src, dst, key, 
enc_ctx_ocb_dec)
++#define AESdecrypt(src, dst, key) AESdecrypt_ctx(src, dst, key, 
dec_ctx_ocb_dec)
++
+ bool CryptStateOCB2::ocb_decrypt(const unsigned char *encrypted, unsigned 
char *plain, unsigned int len,
+                                                                const unsigned 
char *nonce, unsigned char *tag) {
+       keyblock checksum, delta, tmp, pad;
+@@ -392,9 +405,9 @@ bool CryptStateOCB2::ocb_decrypt(const unsigned char 
*encrypted, unsigned char *
+       return success;
+ }
+ 
++#undef AESencrypt
++#undef AESdecrypt
+ #undef BLOCKSIZE
+ #undef SHIFTBITS
+ #undef SWAPPED
+ #undef HIGHBIT
+-#undef AESencrypt
+-#undef AESdecrypt
+diff --git a/src/crypto/CryptStateOCB2.h b/src/crypto/CryptStateOCB2.h
+index cc3f1c0bc..0fd3000ad 100644
+--- a/src/crypto/CryptStateOCB2.h
++++ b/src/crypto/CryptStateOCB2.h
+@@ -44,8 +44,10 @@ private:
+       unsigned char decrypt_iv[AES_BLOCK_SIZE];
+       unsigned char decrypt_history[0x100];
+ 
+-      EVP_CIPHER_CTX *enc_ctx;
+-      EVP_CIPHER_CTX *dec_ctx;
++      EVP_CIPHER_CTX *enc_ctx_ocb_enc;
++      EVP_CIPHER_CTX *dec_ctx_ocb_enc;
++      EVP_CIPHER_CTX *enc_ctx_ocb_dec;
++      EVP_CIPHER_CTX *dec_ctx_ocb_dec;
+ };
+ 
+ 

diff --git a/net-voip/mumble/mumble-1.4.230-r1.ebuild 
b/net-voip/mumble/mumble-1.4.230-r2.ebuild
similarity index 98%
rename from net-voip/mumble/mumble-1.4.230-r1.ebuild
rename to net-voip/mumble/mumble-1.4.230-r2.ebuild
index 690186d97251..1eb64420e4ac 100644
--- a/net-voip/mumble/mumble-1.4.230-r1.ebuild
+++ b/net-voip/mumble/mumble-1.4.230-r2.ebuild
@@ -71,6 +71,7 @@ BDEPEND="
 
 PATCHES=(
        "${WORKDIR}/${PN}-1.4-openssl3.patch"
+       "${FILESDIR}/${PN}-1.4-crypto-threads.patch"
        "${FILESDIR}/${PN}-1.4.230-gcc12-include-memory.patch"
        "${FILESDIR}/${PN}-1.4.230-poco-link-cmake.patch"
 )

Reply via email to