Throw intelligible error on GCM authentication failure, fix/refactor test for modification detection on decryption

Also, address race condition in error handling as part of AEAD message decryption,
which would cause non-uniform errors during testing.
This commit is contained in:
larabr
2023-04-05 00:53:04 +02:00
parent 0e08abb3e2
commit 33af3debc4
3 changed files with 96 additions and 56 deletions

View File

@@ -84,8 +84,14 @@ async function GCM(cipher, key) {
if (webcryptoEmptyMessagesUnsupported && ct.length === tagLength) {
return AES_GCM.decrypt(ct, key, iv, adata);
}
const pt = await webCrypto.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength * 8 }, _key, ct);
return new Uint8Array(pt);
try {
const pt = await webCrypto.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength * 8 }, _key, ct);
return new Uint8Array(pt);
} catch (e) {
if (e.name === 'OperationError') {
throw new Error('Authentication tag mismatch');
}
}
}
};
} catch (err) {

View File

@@ -260,6 +260,7 @@ export async function runAEAD(packet, fn, key, data) {
if (!chunkIndex || chunk.length) {
reader.unshift(finalChunk);
cryptedPromise = modeInstance[fn](chunk, nonce, adataArray);
cryptedPromise.catch(() => {});
queuedBytes += chunk.length - tagLengthIfDecrypting + tagLengthIfEncrypting;
} else {
// After the last chunk, we either encrypt a final, empty
@@ -267,6 +268,7 @@ export async function runAEAD(packet, fn, key, data) {
// validate that final authentication tag.
adataView.setInt32(5 + chunkIndexSizeIfAEADEP + 4, cryptedBytes); // Should be setInt64(5 + chunkIndexSizeIfAEADEP, ...)
cryptedPromise = modeInstance[fn](finalChunk, nonce, adataTagArray);
cryptedPromise.catch(() => {});
queuedBytes += tagLengthIfEncrypting;
done = true;
}