From 31931c9b0d997ee7068182bcd41db593a2c06b09 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Fri, 21 Dec 2018 11:08:10 -0500 Subject: [PATCH] Simplify MDC verification --- src/crypto/cfb.js | 39 ------------------- .../sym_encrypted_integrity_protected.js | 14 +++---- 2 files changed, 5 insertions(+), 48 deletions(-) diff --git a/src/crypto/cfb.js b/src/crypto/cfb.js index 4b805db5..1a83972e 100644 --- a/src/crypto/cfb.js +++ b/src/crypto/cfb.js @@ -36,45 +36,6 @@ const nodeCrypto = util.getNodeCrypto(); const Buffer = util.getNodeBuffer(); export default { - - /** - * Decrypts the prefixed data for the Modification Detection Code (MDC) computation - * @param {String} cipherfn.encrypt Cipher function to use, - * @see module:crypto/cipher. - * @param {Uint8Array} key Uint8Array representation of key to be used to check the mdc - * This will be passed to the cipherfn - * @param {Uint8Array} ciphertext The encrypted data - * @returns {Uint8Array} plaintext Data of D(ciphertext) with blocksize length +2 - */ - mdc: function(cipherfn, key, ciphertext) { - cipherfn = new cipher[cipherfn](key); - const block_size = cipherfn.blockSize; - - let iblock = new Uint8Array(block_size); - let ablock = new Uint8Array(block_size); - let i; - - - // initialisation vector - for (i = 0; i < block_size; i++) { - iblock[i] = 0; - } - - iblock = cipherfn.encrypt(iblock); - for (i = 0; i < block_size; i++) { - ablock[i] = ciphertext[i]; - iblock[i] ^= ablock[i]; - } - - ablock = cipherfn.encrypt(ablock); - - const result = new Uint8Array(iblock.length + 2); - result.set(iblock); - result[iblock.length] = ablock[0] ^ ciphertext[block_size]; - result[iblock.length + 1] = ablock[1] ^ ciphertext[block_size + 1]; - return result; - }, - encrypt: function(algo, key, plaintext, iv) { if (algo.substr(0, 3) === 'aes') { return aesEncrypt(algo, key, plaintext, iv); diff --git a/src/packet/sym_encrypted_integrity_protected.js b/src/packet/sym_encrypted_integrity_protected.js index 018cbeda..a2c4e66b 100644 --- a/src/packet/sym_encrypted_integrity_protected.js +++ b/src/packet/sym_encrypted_integrity_protected.js @@ -111,19 +111,14 @@ SymEncryptedIntegrityProtected.prototype.encrypt = async function (sessionKeyAlg SymEncryptedIntegrityProtected.prototype.decrypt = async function (sessionKeyAlgorithm, key, streaming) { if (!streaming) this.encrypted = await stream.readToEnd(this.encrypted); const encrypted = stream.clone(this.encrypted); - const encryptedClone = stream.passiveClone(encrypted); - let decrypted = await crypto.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(crypto.cipher[sessionKeyAlgorithm].blockSize)); - decrypted = stream.slice(decrypted, crypto.cipher[sessionKeyAlgorithm].blockSize + 2); // Remove random prefix + const decrypted = await crypto.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(crypto.cipher[sessionKeyAlgorithm].blockSize)); // there must be a modification detection code packet as the // last packet and everything gets hashed except the hash itself - const encryptedPrefix = await stream.readToEnd(stream.slice(encryptedClone, 0, crypto.cipher[sessionKeyAlgorithm].blockSize + 2)); - const prefix = crypto.cfb.mdc(sessionKeyAlgorithm, key, encryptedPrefix); const realHash = stream.slice(stream.passiveClone(decrypted), -20); - const bytes = stream.slice(decrypted, 0, -20); - const tohash = util.concat([prefix, stream.passiveClone(bytes)]); + const tohash = stream.slice(decrypted, 0, -20); const verifyHash = Promise.all([ - stream.readToEnd(await crypto.hash.sha1(tohash)), + stream.readToEnd(await crypto.hash.sha1(stream.passiveClone(tohash))), stream.readToEnd(realHash) ]).then(([hash, mdc]) => { if (!util.equalsUint8Array(hash, mdc)) { @@ -131,7 +126,8 @@ SymEncryptedIntegrityProtected.prototype.decrypt = async function (sessionKeyAlg } return new Uint8Array(); }); - let packetbytes = stream.slice(bytes, 0, -2); + const bytes = stream.slice(tohash, crypto.cipher[sessionKeyAlgorithm].blockSize + 2); // Remove random prefix + let packetbytes = stream.slice(bytes, 0, -2); // Remove MDC packet packetbytes = stream.concat([packetbytes, stream.fromAsync(() => verifyHash)]); if (!util.isStream(encrypted) || !config.allow_unauthenticated_stream) { packetbytes = await stream.readToEnd(packetbytes);