mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2025-08-17 17:05:50 +00:00
Improve AES-CBC code in preparation for audio encryption
This commit is contained in:
parent
3abd3af4b2
commit
625ec431eb
@ -426,7 +426,7 @@ static bool encryptControlMessage(PNVCTL_ENCRYPTED_PACKET_HEADER encPacket, PNVC
|
||||
memset(iv, 0, sizeof(iv));
|
||||
iv[0] = (unsigned char)encPacket->seq;
|
||||
|
||||
return PltEncryptMessage(encryptionCtx, ALGORITHM_AES_GCM,
|
||||
return PltEncryptMessage(encryptionCtx, ALGORITHM_AES_GCM, 0,
|
||||
(unsigned char*)StreamConfig.remoteInputAesKey, sizeof(StreamConfig.remoteInputAesKey),
|
||||
iv, sizeof(iv),
|
||||
(unsigned char*)(encPacket + 1), AES_GCM_TAG_LENGTH, // Write tag into the space after the encrypted header
|
||||
@ -459,7 +459,7 @@ static bool decryptControlMessageToV1(PNVCTL_ENCRYPTED_PACKET_HEADER encPacket,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!PltDecryptMessage(decryptionCtx, ALGORITHM_AES_GCM,
|
||||
if (!PltDecryptMessage(decryptionCtx, ALGORITHM_AES_GCM, 0,
|
||||
(unsigned char*)StreamConfig.remoteInputAesKey, sizeof(StreamConfig.remoteInputAesKey),
|
||||
iv, sizeof(iv),
|
||||
(unsigned char*)(encPacket + 1), AES_GCM_TAG_LENGTH, // The tag is located right after the header
|
||||
|
@ -63,7 +63,7 @@ static int encryptData(unsigned char* plaintext, int plaintextLen,
|
||||
unsigned char* ciphertext, int* ciphertextLen) {
|
||||
// Starting in Gen 7, AES GCM is used for encryption
|
||||
if (AppVersionQuad[0] >= 7) {
|
||||
if (!PltEncryptMessage(cryptoContext, ALGORITHM_AES_GCM,
|
||||
if (!PltEncryptMessage(cryptoContext, ALGORITHM_AES_GCM, 0,
|
||||
(unsigned char*)StreamConfig.remoteInputAesKey, sizeof(StreamConfig.remoteInputAesKey),
|
||||
currentAesIv, sizeof(currentAesIv),
|
||||
ciphertext, 16,
|
||||
@ -84,7 +84,7 @@ static int encryptData(unsigned char* plaintext, int plaintextLen,
|
||||
memcpy(paddedData, plaintext, plaintextLen);
|
||||
|
||||
// Prior to Gen 7, 128-bit AES CBC is used for encryption
|
||||
return PltEncryptMessage(cryptoContext, ALGORITHM_AES_CBC,
|
||||
return PltEncryptMessage(cryptoContext, ALGORITHM_AES_CBC, 0,
|
||||
(unsigned char*)StreamConfig.remoteInputAesKey, sizeof(StreamConfig.remoteInputAesKey),
|
||||
currentAesIv, sizeof(currentAesIv),
|
||||
NULL, 0,
|
||||
|
@ -26,7 +26,7 @@ static int addPkcs7PaddingInPlace(unsigned char* plaintext, int plaintextLen) {
|
||||
#endif
|
||||
|
||||
// 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, int flags,
|
||||
unsigned char* key, int keyLength,
|
||||
unsigned char* iv, int ivLength,
|
||||
unsigned char* tag, int tagLength,
|
||||
@ -38,6 +38,8 @@ bool PltEncryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||
|
||||
switch (algorithm) {
|
||||
case ALGORITHM_AES_CBC:
|
||||
LC_ASSERT(flags & CIPHER_FLAG_RESET_IV);
|
||||
LC_ASSERT(flags & CIPHER_FLAG_FINISH);
|
||||
LC_ASSERT(tag == NULL);
|
||||
LC_ASSERT(tagLength == 0);
|
||||
cipherMode = MBEDTLS_MODE_CBC;
|
||||
@ -80,7 +82,6 @@ bool PltEncryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||
*outputDataLength = outLength;
|
||||
return true;
|
||||
#else
|
||||
bool ret = false;
|
||||
const EVP_CIPHER* cipher;
|
||||
|
||||
switch (algorithm) {
|
||||
@ -102,22 +103,26 @@ bool PltEncryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||
}
|
||||
|
||||
if (algorithm == ALGORITHM_AES_GCM) {
|
||||
EVP_CIPHER_CTX_reset(ctx->ctx);
|
||||
|
||||
if (EVP_EncryptInit_ex(ctx->ctx, cipher, NULL, NULL, NULL) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx->ctx, EVP_CTRL_GCM_SET_IVLEN, ivLength, NULL) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (EVP_EncryptInit_ex(ctx->ctx, NULL, NULL, key, iv) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!ctx->initialized) {
|
||||
if (!ctx->initialized || (flags & CIPHER_FLAG_RESET_IV)) {
|
||||
EVP_CIPHER_CTX_reset(ctx->ctx);
|
||||
|
||||
if (EVP_EncryptInit_ex(ctx->ctx, cipher, NULL, key, iv) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
|
||||
ctx->initialized = true;
|
||||
@ -127,7 +132,7 @@ bool PltEncryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||
}
|
||||
|
||||
if (EVP_EncryptUpdate(ctx->ctx, outputData, outputDataLength, inputData, inputDataLength) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (algorithm == ALGORITHM_AES_GCM) {
|
||||
@ -135,26 +140,30 @@ bool PltEncryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||
|
||||
// GCM encryption won't ever fill ciphertext here but we have to call it anyway
|
||||
if (EVP_EncryptFinal_ex(ctx->ctx, outputData, &len) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
LC_ASSERT(len == 0);
|
||||
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx->ctx, EVP_CTRL_GCM_GET_TAG, tagLength, tag) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (flags & CIPHER_FLAG_FINISH) {
|
||||
int len;
|
||||
|
||||
ret = true;
|
||||
if (EVP_EncryptFinal_ex(ctx->ctx, &outputData[*outputDataLength], &len) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (algorithm == ALGORITHM_AES_GCM) {
|
||||
EVP_CIPHER_CTX_reset(ctx->ctx);
|
||||
*outputDataLength += len;
|
||||
}
|
||||
return ret;
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool PltDecryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||
// For CBC modes, outputData buffer must be allocated with length rounded up to next multiple of 16!
|
||||
bool PltDecryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm, int flags,
|
||||
unsigned char* key, int keyLength,
|
||||
unsigned char* iv, int ivLength,
|
||||
unsigned char* tag, int tagLength,
|
||||
@ -166,6 +175,8 @@ bool PltDecryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||
|
||||
switch (algorithm) {
|
||||
case ALGORITHM_AES_CBC:
|
||||
LC_ASSERT(flags & CIPHER_FLAG_RESET_IV);
|
||||
LC_ASSERT(flags & CIPHER_FLAG_FINISH);
|
||||
LC_ASSERT(tag == NULL);
|
||||
LC_ASSERT(tagLength == 0);
|
||||
cipherMode = MBEDTLS_MODE_CBC;
|
||||
@ -208,7 +219,6 @@ bool PltDecryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||
*outputDataLength = outLength;
|
||||
return true;
|
||||
#else
|
||||
bool ret = false;
|
||||
const EVP_CIPHER* cipher;
|
||||
|
||||
switch (algorithm) {
|
||||
@ -230,22 +240,26 @@ bool PltDecryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||
}
|
||||
|
||||
if (algorithm == ALGORITHM_AES_GCM) {
|
||||
EVP_CIPHER_CTX_reset(ctx->ctx);
|
||||
|
||||
if (EVP_DecryptInit_ex(ctx->ctx, cipher, NULL, NULL, NULL) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx->ctx, EVP_CTRL_GCM_SET_IVLEN, ivLength, NULL) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (EVP_DecryptInit_ex(ctx->ctx, NULL, NULL, key, iv) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!ctx->initialized) {
|
||||
if (!ctx->initialized || (flags & CIPHER_FLAG_RESET_IV)) {
|
||||
EVP_CIPHER_CTX_reset(ctx->ctx);
|
||||
|
||||
if (EVP_DecryptInit_ex(ctx->ctx, cipher, NULL, key, iv) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
|
||||
ctx->initialized = true;
|
||||
@ -253,7 +267,7 @@ bool PltDecryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||
}
|
||||
|
||||
if (EVP_DecryptUpdate(ctx->ctx, outputData, outputDataLength, inputData, inputDataLength) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (algorithm == ALGORITHM_AES_GCM) {
|
||||
@ -261,24 +275,27 @@ bool PltDecryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||
|
||||
// Set the GCM tag before calling EVP_DecryptFinal_ex()
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx->ctx, EVP_CTRL_GCM_SET_TAG, tagLength, tag) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
|
||||
// GCM will never have additional plaintext here, but we need to call it to
|
||||
// ensure that the GCM authentication tag is correct for this data.
|
||||
if (EVP_DecryptFinal_ex(ctx->ctx, outputData, &len) != 1) {
|
||||
goto cleanup;
|
||||
return false;
|
||||
}
|
||||
LC_ASSERT(len == 0);
|
||||
}
|
||||
else if (flags & CIPHER_FLAG_FINISH) {
|
||||
int len;
|
||||
|
||||
ret = true;
|
||||
if (EVP_DecryptFinal_ex(ctx->ctx, &outputData[*outputDataLength], &len) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (algorithm == ALGORITHM_AES_GCM) {
|
||||
EVP_CIPHER_CTX_reset(ctx->ctx);
|
||||
*outputDataLength += len;
|
||||
}
|
||||
return ret;
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -27,14 +27,17 @@ void PltDestroyCryptoContext(PPLT_CRYPTO_CONTEXT ctx);
|
||||
#define ALGORITHM_AES_CBC 1
|
||||
#define ALGORITHM_AES_GCM 2
|
||||
|
||||
bool PltEncryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||
#define CIPHER_FLAG_RESET_IV 0x01
|
||||
#define CIPHER_FLAG_FINISH 0x02
|
||||
|
||||
bool PltEncryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm, int flags,
|
||||
unsigned char* key, int keyLength,
|
||||
unsigned char* iv, int ivLength,
|
||||
unsigned char* tag, int tagLength,
|
||||
unsigned char* inputData, int inputDataLength,
|
||||
unsigned char* outputData, int* outputDataLength);
|
||||
|
||||
bool PltDecryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm,
|
||||
bool PltDecryptMessage(PPLT_CRYPTO_CONTEXT ctx, int algorithm, int flags,
|
||||
unsigned char* key, int keyLength,
|
||||
unsigned char* iv, int ivLength,
|
||||
unsigned char* tag, int tagLength,
|
||||
|
Loading…
x
Reference in New Issue
Block a user