From a06bf91f35833a7a45a3ff7a02a45c88893332a3 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 16 Oct 2019 13:47:56 +0200 Subject: [PATCH] Fix queued bytes calculation for AEAD concurrency --- src/packet/sym_encrypted_aead_protected.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/packet/sym_encrypted_aead_protected.js b/src/packet/sym_encrypted_aead_protected.js index bf88113f..521bd0e9 100644 --- a/src/packet/sym_encrypted_aead_protected.js +++ b/src/packet/sym_encrypted_aead_protected.js @@ -124,6 +124,7 @@ SymEncryptedAEADProtected.prototype.crypt = async function (fn, key, data, strea const mode = crypto[enums.read(enums.aead, this.aeadAlgo)]; const modeInstance = await mode(cipher, key); const tagLengthIfDecrypting = fn === 'decrypt' ? mode.tagLength : 0; + const tagLengthIfEncrypting = fn === 'encrypt' ? mode.tagLength : 0; const chunkSize = 2 ** (this.chunkSizeByte + 6) + tagLengthIfDecrypting; // ((uint64_t)1 << (c + 6)) const adataBuffer = new ArrayBuffer(21); const adataArray = new Uint8Array(adataBuffer, 0, 13); @@ -154,21 +155,22 @@ SymEncryptedAEADProtected.prototype.crypt = async function (fn, key, data, strea if (!chunkIndex || chunk.length) { reader.unshift(finalChunk); cryptedPromise = modeInstance[fn](chunk, mode.getNonce(iv, chunkIndexArray), adataArray); + queuedBytes += chunk.length - tagLengthIfDecrypting + tagLengthIfEncrypting; } else { // After the last chunk, we either encrypt a final, empty // data chunk to get the final authentication tag or // validate that final authentication tag. adataView.setInt32(13 + 4, cryptedBytes); // Should be setInt64(13, ...) cryptedPromise = modeInstance[fn](finalChunk, mode.getNonce(iv, chunkIndexArray), adataTagArray); + queuedBytes += tagLengthIfEncrypting; done = true; } cryptedBytes += chunk.length - tagLengthIfDecrypting; - queuedBytes += chunk.length - tagLengthIfDecrypting; // eslint-disable-next-line no-loop-func latestPromise = latestPromise.then(() => cryptedPromise).then(async crypted => { await writer.ready; await writer.write(crypted); - queuedBytes -= chunk.length; + queuedBytes -= crypted.length; }).catch(err => writer.abort(err)); if (done || queuedBytes > writer.desiredSize) { await latestPromise; // Respect backpressure