mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-06-18 14:51:30 +00:00
Add native MbedTLS crypto backend
This commit is contained in:
+1
-1
@@ -247,7 +247,7 @@ static void inputSendThreadProc(void* context) {
|
|||||||
else {
|
else {
|
||||||
// Encrypt the message into the output buffer while leaving room for the length
|
// Encrypt the message into the output buffer while leaving room for the length
|
||||||
encryptedSize = sizeof(encryptedBuffer) - 4;
|
encryptedSize = sizeof(encryptedBuffer) - 4;
|
||||||
err = encryptData((const unsigned char*)&holder->packet, holder->packetLength,
|
err = encryptData((unsigned char*)&holder->packet, holder->packetLength,
|
||||||
(unsigned char*)&encryptedBuffer[4], (int*)&encryptedSize);
|
(unsigned char*)&encryptedBuffer[4], (int*)&encryptedSize);
|
||||||
free(holder);
|
free(holder);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
|
|||||||
+138
-1
@@ -1,5 +1,13 @@
|
|||||||
#include "Limelight-internal.h"
|
#include "Limelight-internal.h"
|
||||||
|
|
||||||
|
#ifdef USE_MBEDTLS
|
||||||
|
#include <mbedtls/entropy.h>
|
||||||
|
#include <mbedtls/ctr_drbg.h>
|
||||||
|
|
||||||
|
mbedtls_entropy_context EntropyContext;
|
||||||
|
mbedtls_ctr_drbg_context CtrDrbgContext;
|
||||||
|
bool RandomStateInitialized = false;
|
||||||
|
#else
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
@@ -11,6 +19,7 @@ static int addPkcs7PaddingInPlace(unsigned char* plaintext, int plaintextLen) {
|
|||||||
|
|
||||||
return paddedLength;
|
return paddedLength;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// For CBC modes, inputData buffer must be allocated with length rounded up to next multiple of 16 and inputData buffer may be modified!
|
// For CBC modes, inputData buffer must be allocated with length rounded up to next multiple of 16 and inputData buffer may be modified!
|
||||||
bool PltEncryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
bool PltEncryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||||
@@ -19,6 +28,56 @@ bool PltEncryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
|||||||
unsigned char* tag, int tagLength,
|
unsigned char* tag, int tagLength,
|
||||||
unsigned char* inputData, int inputDataLength,
|
unsigned char* inputData, int inputDataLength,
|
||||||
unsigned char* outputData, int* outputDataLength) {
|
unsigned char* outputData, int* outputDataLength) {
|
||||||
|
#ifdef USE_MBEDTLS
|
||||||
|
mbedtls_cipher_mode_t cipherMode;
|
||||||
|
size_t outLength;
|
||||||
|
|
||||||
|
switch (algorithm) {
|
||||||
|
case ALGORITHM_AES_CBC:
|
||||||
|
LC_ASSERT(keyLength == 16);
|
||||||
|
LC_ASSERT(tag == NULL);
|
||||||
|
LC_ASSERT(tagLength == 0);
|
||||||
|
cipherMode = MBEDTLS_MODE_CBC;
|
||||||
|
break;
|
||||||
|
case ALGORITHM_AES_GCM:
|
||||||
|
LC_ASSERT(keyLength == 16);
|
||||||
|
LC_ASSERT(tag != NULL);
|
||||||
|
LC_ASSERT(tagLength > 0);
|
||||||
|
cipherMode = MBEDTLS_MODE_GCM;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LC_ASSERT(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctx->initialized) {
|
||||||
|
if (mbedtls_cipher_setup(&ctx->ctx, mbedtls_cipher_info_from_values(MBEDTLS_CIPHER_ID_AES, keyLength * 8, cipherMode)) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_cipher_setkey(&ctx->ctx, key, keyLength * 8, MBEDTLS_ENCRYPT) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
outLength = *outputDataLength;
|
||||||
|
|
||||||
|
if (tag != NULL) {
|
||||||
|
if (mbedtls_cipher_auth_encrypt(&ctx->ctx, iv, ivLength, NULL, 0, inputData, inputDataLength, outputData, &outLength, tag, tagLength) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (mbedtls_cipher_crypt(&ctx->ctx, iv, ivLength, inputData, inputDataLength, outputData, &outLength) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*outputDataLength = outLength;
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
const EVP_CIPHER* cipher;
|
const EVP_CIPHER* cipher;
|
||||||
|
|
||||||
@@ -90,6 +149,7 @@ cleanup:
|
|||||||
EVP_CIPHER_CTX_reset(ctx->ctx);
|
EVP_CIPHER_CTX_reset(ctx->ctx);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PltDecryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
bool PltDecryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||||
@@ -98,6 +158,56 @@ bool PltDecryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
|||||||
unsigned char* tag, int tagLength,
|
unsigned char* tag, int tagLength,
|
||||||
unsigned char* inputData, int inputDataLength,
|
unsigned char* inputData, int inputDataLength,
|
||||||
unsigned char* outputData, int* outputDataLength) {
|
unsigned char* outputData, int* outputDataLength) {
|
||||||
|
#ifdef USE_MBEDTLS
|
||||||
|
mbedtls_cipher_mode_t cipherMode;
|
||||||
|
size_t outLength;
|
||||||
|
|
||||||
|
switch (algorithm) {
|
||||||
|
case ALGORITHM_AES_CBC:
|
||||||
|
LC_ASSERT(keyLength == 16);
|
||||||
|
LC_ASSERT(tag == NULL);
|
||||||
|
LC_ASSERT(tagLength == 0);
|
||||||
|
cipherMode = MBEDTLS_MODE_CBC;
|
||||||
|
break;
|
||||||
|
case ALGORITHM_AES_GCM:
|
||||||
|
LC_ASSERT(keyLength == 16);
|
||||||
|
LC_ASSERT(tag != NULL);
|
||||||
|
LC_ASSERT(tagLength > 0);
|
||||||
|
cipherMode = MBEDTLS_MODE_GCM;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LC_ASSERT(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctx->initialized) {
|
||||||
|
if (mbedtls_cipher_setup(&ctx->ctx, mbedtls_cipher_info_from_values(MBEDTLS_CIPHER_ID_AES, keyLength * 8, cipherMode)) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbedtls_cipher_setkey(&ctx->ctx, key, keyLength * 8, MBEDTLS_DECRYPT) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
outLength = *outputDataLength;
|
||||||
|
|
||||||
|
if (tag != NULL) {
|
||||||
|
if (mbedtls_cipher_auth_decrypt(&ctx->ctx, iv, ivLength, NULL, 0, inputData, inputDataLength, outputData, &outLength, tag, tagLength) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (mbedtls_cipher_crypt(&ctx->ctx, iv, ivLength, inputData, inputDataLength, outputData, &outLength) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*outputDataLength = outLength;
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
const EVP_CIPHER* cipher;
|
const EVP_CIPHER* cipher;
|
||||||
|
|
||||||
@@ -169,6 +279,7 @@ cleanup:
|
|||||||
EVP_CIPHER_CTX_reset(ctx->ctx);
|
EVP_CIPHER_CTX_reset(ctx->ctx);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
PPLT_CRYPTO_CONTEXT PltCreateCryptoContext(void) {
|
PPLT_CRYPTO_CONTEXT PltCreateCryptoContext(void) {
|
||||||
@@ -178,20 +289,46 @@ PPLT_CRYPTO_CONTEXT PltCreateCryptoContext(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx->initialized = false;
|
ctx->initialized = false;
|
||||||
|
|
||||||
|
#ifdef USE_MBEDTLS
|
||||||
|
mbedtls_cipher_init(&ctx->ctx);
|
||||||
|
#else
|
||||||
ctx->ctx = EVP_CIPHER_CTX_new();
|
ctx->ctx = EVP_CIPHER_CTX_new();
|
||||||
if (!ctx->ctx) {
|
if (!ctx->ctx) {
|
||||||
free(ctx);
|
free(ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PltDestroyCryptoContext(PPLT_CRYPTO_CONTEXT ctx) {
|
void PltDestroyCryptoContext(PPLT_CRYPTO_CONTEXT ctx) {
|
||||||
|
#ifdef USE_MBEDTLS
|
||||||
|
mbedtls_cipher_free(&ctx->ctx);
|
||||||
|
#else
|
||||||
EVP_CIPHER_CTX_free(ctx->ctx);
|
EVP_CIPHER_CTX_free(ctx->ctx);
|
||||||
|
#endif
|
||||||
free(ctx);
|
free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PltGenerateRandomData(unsigned char* data, int length) {
|
void PltGenerateRandomData(unsigned char* data, int length) {
|
||||||
RAND_bytes(data, length);
|
#ifdef USE_MBEDTLS
|
||||||
|
if (!RandomStateInitialized) {
|
||||||
|
mbedtls_entropy_init(&EntropyContext);
|
||||||
|
mbedtls_ctr_drbg_init(&CtrDrbgContext);
|
||||||
|
if (mbedtls_ctr_drbg_seed(&CtrDrbgContext, mbedtls_entropy_func, &EntropyContext, NULL, 0) != 0) {
|
||||||
|
// Nothing we can really do here...
|
||||||
|
Limelog("Seeding MbedTLS random number generator failed!\n");
|
||||||
|
LC_ASSERT(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RandomStateInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_ctr_drbg_random(&CtrDrbgContext, data, length);
|
||||||
|
#else
|
||||||
|
RAND_bytes(data, length);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,21 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef USE_MBEDTLS
|
||||||
|
#include <mbedtls/cipher.h>
|
||||||
|
#else
|
||||||
// Hide the real OpenSSL definition from other code
|
// Hide the real OpenSSL definition from other code
|
||||||
typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
|
typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct _PLT_CRYPTO_CONTEXT {
|
typedef struct _PLT_CRYPTO_CONTEXT {
|
||||||
|
#ifdef USE_MBEDTLS
|
||||||
|
bool initialized;
|
||||||
|
mbedtls_cipher_context_t ctx;
|
||||||
|
#else
|
||||||
bool initialized; // Used for CBC only
|
bool initialized; // Used for CBC only
|
||||||
EVP_CIPHER_CTX* ctx;
|
EVP_CIPHER_CTX* ctx;
|
||||||
|
#endif
|
||||||
} PLT_CRYPTO_CONTEXT, *PPLT_CRYPTO_CONTEXT;
|
} PLT_CRYPTO_CONTEXT, *PPLT_CRYPTO_CONTEXT;
|
||||||
|
|
||||||
#define ROUND_TO_PKCS7_PADDED_LEN(x) ((((x) + 15) / 16) * 16)
|
#define ROUND_TO_PKCS7_PADDED_LEN(x) ((((x) + 15) / 16) * 16)
|
||||||
|
|||||||
Reference in New Issue
Block a user