From 4568d080d5e2cada2771afce978d1dff80ce5a8c Mon Sep 17 00:00:00 2001 From: Daniel Huigens <d.huigens@protonmail.com> Date: Fri, 20 Apr 2018 17:28:15 +0200 Subject: [PATCH] Fix decryption with multiple chunks --- src/packet/sym_encrypted_aead_protected.js | 4 ++-- test/general/openpgp.js | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/packet/sym_encrypted_aead_protected.js b/src/packet/sym_encrypted_aead_protected.js index ede69d62..43836977 100644 --- a/src/packet/sym_encrypted_aead_protected.js +++ b/src/packet/sym_encrypted_aead_protected.js @@ -137,14 +137,14 @@ SymEncryptedAEADProtected.prototype.crypt = async function (fn, key, data, final const modeInstance = await mode(cipher, key); if (config.aead_protect_version === 4) { const tagLengthIfDecrypting = fn === 'decrypt' ? mode.tagLength : 0; - const chunkSize = 2 ** (this.chunkSizeByte + 6); // ((uint64_t)1 << (c + 6)) + const chunkSize = 2 ** (this.chunkSizeByte + 6) + tagLengthIfDecrypting; // ((uint64_t)1 << (c + 6)) const adataBuffer = new ArrayBuffer(21); const adataArray = new Uint8Array(adataBuffer, 0, 13); const adataTagArray = new Uint8Array(adataBuffer); const adataView = new DataView(adataBuffer); const chunkIndexArray = new Uint8Array(adataBuffer, 5, 8); adataArray.set([0xC0 | this.tag, this.version, this.cipherAlgo, this.aeadAlgo, this.chunkSizeByte], 0); - adataView.setInt32(13 + 4, data.length - tagLengthIfDecrypting); // Should be setInt64(13, ...) + adataView.setInt32(13 + 4, data.length - tagLengthIfDecrypting * Math.ceil(data.length / chunkSize)); // Should be setInt64(13, ...) const cryptedPromises = []; for (let chunkIndex = 0; chunkIndex === 0 || data.length;) { cryptedPromises.push( diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 32a7cf72..d202a42c 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -599,6 +599,7 @@ describe('OpenPGP.js public api tests', function() { let aead_protectVal; let aead_protect_versionVal; let aead_modeVal; + let aead_chunk_size_byteVal; beforeEach(function(done) { publicKey = openpgp.key.readArmored(pub_key); @@ -625,6 +626,7 @@ describe('OpenPGP.js public api tests', function() { aead_protectVal = openpgp.config.aead_protect; aead_protect_versionVal = openpgp.config.aead_protect_version; aead_modeVal = openpgp.config.aead_mode; + aead_chunk_size_byteVal = openpgp.config.aead_chunk_size_byte; done(); }); @@ -634,6 +636,7 @@ describe('OpenPGP.js public api tests', function() { openpgp.config.aead_protect = aead_protectVal; openpgp.config.aead_protect_version = aead_protect_versionVal; openpgp.config.aead_mode = aead_modeVal; + openpgp.config.aead_chunk_size_byte = aead_chunk_size_byteVal; }); it('Decrypting key with wrong passphrase rejected', async function () { @@ -732,6 +735,21 @@ describe('OpenPGP.js public api tests', function() { } }); + tryTests('EAX mode (small chunk size)', tests, { + if: openpgp.util.getWebCryptoAll() || openpgp.util.getNodeCrypto(), + beforeEach: function() { + openpgp.config.use_native = true; + openpgp.config.aead_protect = true; + openpgp.config.aead_protect_version = 4; + openpgp.config.aead_chunk_size_byte = 0; + + // Monkey-patch AEAD feature flag + publicKey.keys[0].users[0].selfCertifications[0].features = [7]; + publicKey_2000_2008.keys[0].users[0].selfCertifications[0].features = [7]; + publicKey_2038_2045.keys[0].users[0].selfCertifications[0].features = [7]; + } + }); + tryTests('OCB mode', tests, { if: true, beforeEach: function() {