mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2025-07-03 00:06:02 +00:00
Compatibility fix for OpenSSL 1.1 (#25)
* Compatibility fix for OpenSSL 1.1 * Don't allocate new cipher context for every input packet * Readd support for OpenSSL 1.0
This commit is contained in:
parent
8d2dccf4ca
commit
dbb7cee399
@ -9,7 +9,7 @@
|
|||||||
static SOCKET inputSock = INVALID_SOCKET;
|
static SOCKET inputSock = INVALID_SOCKET;
|
||||||
static unsigned char currentAesIv[16];
|
static unsigned char currentAesIv[16];
|
||||||
static int initialized;
|
static int initialized;
|
||||||
static EVP_CIPHER_CTX cipherContext;
|
static EVP_CIPHER_CTX* cipherContext;
|
||||||
static int cipherInitialized;
|
static int cipherInitialized;
|
||||||
|
|
||||||
static LINKED_BLOCKING_QUEUE packetQueue;
|
static LINKED_BLOCKING_QUEUE packetQueue;
|
||||||
@ -34,6 +34,18 @@ typedef struct _PACKET_HOLDER {
|
|||||||
LINKED_BLOCKING_QUEUE_ENTRY entry;
|
LINKED_BLOCKING_QUEUE_ENTRY entry;
|
||||||
} PACKET_HOLDER, *PPACKET_HOLDER;
|
} PACKET_HOLDER, *PPACKET_HOLDER;
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
|
#define EVP_CIPHER_CTX_reset(x) EVP_CIPHER_CTX_cleanup(x); EVP_CIPHER_CTX_init(x)
|
||||||
|
#define EVP_CIPHER_CTX_free(x) EVP_CIPHER_CTX_cleanup(x)
|
||||||
|
|
||||||
|
static EVP_CIPHER_CTX preallocatedCipherContext;
|
||||||
|
|
||||||
|
EVP_CIPHER_CTX* EVP_CIPHER_CTX_new() {
|
||||||
|
EVP_CIPHER_CTX_init(&preallocatedCipherContext);
|
||||||
|
return &preallocatedCipherContext;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Initializes the input stream
|
// Initializes the input stream
|
||||||
int initializeInputStream(void) {
|
int initializeInputStream(void) {
|
||||||
memcpy(currentAesIv, StreamConfig.remoteInputAesIv, sizeof(currentAesIv));
|
memcpy(currentAesIv, StreamConfig.remoteInputAesIv, sizeof(currentAesIv));
|
||||||
@ -52,7 +64,7 @@ void destroyInputStream(void) {
|
|||||||
PLINKED_BLOCKING_QUEUE_ENTRY entry, nextEntry;
|
PLINKED_BLOCKING_QUEUE_ENTRY entry, nextEntry;
|
||||||
|
|
||||||
if (cipherInitialized) {
|
if (cipherInitialized) {
|
||||||
EVP_CIPHER_CTX_cleanup(&cipherContext);
|
EVP_CIPHER_CTX_free(cipherContext);
|
||||||
cipherInitialized = 0;
|
cipherInitialized = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,42 +129,47 @@ static int encryptData(const unsigned char* plaintext, int plaintextLen,
|
|||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (AppVersionQuad[0] >= 7) {
|
if (AppVersionQuad[0] >= 7) {
|
||||||
EVP_CIPHER_CTX_init(&cipherContext);
|
if (!cipherInitialized) {
|
||||||
|
if ((cipherContext = EVP_CIPHER_CTX_new()) == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cipherInitialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Gen 7 servers use 128-bit AES GCM
|
// Gen 7 servers use 128-bit AES GCM
|
||||||
if (EVP_EncryptInit_ex(&cipherContext, EVP_aes_128_gcm(), NULL, NULL, NULL) != 1) {
|
if (EVP_EncryptInit_ex(cipherContext, EVP_aes_128_gcm(), NULL, NULL, NULL) != 1) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto gcm_cleanup;
|
goto gcm_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gen 7 servers uses 16 byte IVs
|
// Gen 7 servers uses 16 byte IVs
|
||||||
if (EVP_CIPHER_CTX_ctrl(&cipherContext, EVP_CTRL_GCM_SET_IVLEN, 16, NULL) != 1) {
|
if (EVP_CIPHER_CTX_ctrl(cipherContext, EVP_CTRL_GCM_SET_IVLEN, 16, NULL) != 1) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto gcm_cleanup;
|
goto gcm_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize again but now provide our key and current IV
|
// Initialize again but now provide our key and current IV
|
||||||
if (EVP_EncryptInit_ex(&cipherContext, NULL, NULL,
|
if (EVP_EncryptInit_ex(cipherContext, NULL, NULL,
|
||||||
(const unsigned char*)StreamConfig.remoteInputAesKey, currentAesIv) != 1) {
|
(const unsigned char*)StreamConfig.remoteInputAesKey, currentAesIv) != 1) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto gcm_cleanup;
|
goto gcm_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt into the caller's buffer, leaving room for the auth tag to be prepended
|
// Encrypt into the caller's buffer, leaving room for the auth tag to be prepended
|
||||||
if (EVP_EncryptUpdate(&cipherContext, &ciphertext[16], ciphertextLen, plaintext, plaintextLen) != 1) {
|
if (EVP_EncryptUpdate(cipherContext, &ciphertext[16], ciphertextLen, plaintext, plaintextLen) != 1) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto gcm_cleanup;
|
goto gcm_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GCM encryption won't ever fill ciphertext here but we have to call it anyway
|
// GCM encryption won't ever fill ciphertext here but we have to call it anyway
|
||||||
if (EVP_EncryptFinal_ex(&cipherContext, ciphertext, &len) != 1) {
|
if (EVP_EncryptFinal_ex(cipherContext, ciphertext, &len) != 1) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto gcm_cleanup;
|
goto gcm_cleanup;
|
||||||
}
|
}
|
||||||
LC_ASSERT(len == 0);
|
LC_ASSERT(len == 0);
|
||||||
|
|
||||||
// Read the tag into the caller's buffer
|
// Read the tag into the caller's buffer
|
||||||
if (EVP_CIPHER_CTX_ctrl(&cipherContext, EVP_CTRL_GCM_GET_TAG, 16, ciphertext) != 1) {
|
if (EVP_CIPHER_CTX_ctrl(cipherContext, EVP_CTRL_GCM_GET_TAG, 16, ciphertext) != 1) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto gcm_cleanup;
|
goto gcm_cleanup;
|
||||||
}
|
}
|
||||||
@ -163,18 +180,21 @@ static int encryptData(const unsigned char* plaintext, int plaintextLen,
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
gcm_cleanup:
|
gcm_cleanup:
|
||||||
EVP_CIPHER_CTX_cleanup(&cipherContext);
|
EVP_CIPHER_CTX_reset(cipherContext);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unsigned char paddedData[MAX_INPUT_PACKET_SIZE];
|
unsigned char paddedData[MAX_INPUT_PACKET_SIZE];
|
||||||
int paddedLength;
|
int paddedLength;
|
||||||
|
|
||||||
if (!cipherInitialized) {
|
if (!cipherInitialized) {
|
||||||
EVP_CIPHER_CTX_init(&cipherContext);
|
if ((cipherContext = EVP_CIPHER_CTX_new()) == NULL) {
|
||||||
|
ret = -1;
|
||||||
|
goto cbc_cleanup;
|
||||||
|
}
|
||||||
cipherInitialized = 1;
|
cipherInitialized = 1;
|
||||||
|
|
||||||
// Prior to Gen 7, 128-bit AES CBC is used for encryption
|
// Prior to Gen 7, 128-bit AES CBC is used for encryption
|
||||||
if (EVP_EncryptInit_ex(&cipherContext, EVP_aes_128_cbc(), NULL,
|
if (EVP_EncryptInit_ex(cipherContext, EVP_aes_128_cbc(), NULL,
|
||||||
(const unsigned char*)StreamConfig.remoteInputAesKey, currentAesIv) != 1) {
|
(const unsigned char*)StreamConfig.remoteInputAesKey, currentAesIv) != 1) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cbc_cleanup;
|
goto cbc_cleanup;
|
||||||
@ -185,7 +205,7 @@ static int encryptData(const unsigned char* plaintext, int plaintextLen,
|
|||||||
memcpy(paddedData, plaintext, plaintextLen);
|
memcpy(paddedData, plaintext, plaintextLen);
|
||||||
paddedLength = addPkcs7PaddingInPlace(paddedData, plaintextLen);
|
paddedLength = addPkcs7PaddingInPlace(paddedData, plaintextLen);
|
||||||
|
|
||||||
if (EVP_EncryptUpdate(&cipherContext, ciphertext, ciphertextLen, paddedData, paddedLength) != 1) {
|
if (EVP_EncryptUpdate(cipherContext, ciphertext, ciphertextLen, paddedData, paddedLength) != 1) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cbc_cleanup;
|
goto cbc_cleanup;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user