Improve AES-CBC code in preparation for audio encryption

This commit is contained in:
Cameron Gutman committed 2021-04-21 23:59:14 -05:00
1 parent 3abd3af4b2
commit 625ec431eb
4 files changed
+56 -36

No files matched your search

+47 -30
View File
@@ -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
}