Simplify MDC verification
This commit is contained in:
parent
3f1734ae7a
commit
31931c9b0d
|
@ -36,45 +36,6 @@ const nodeCrypto = util.getNodeCrypto();
|
||||||
const Buffer = util.getNodeBuffer();
|
const Buffer = util.getNodeBuffer();
|
||||||
|
|
||||||
export default {
|
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) {
|
encrypt: function(algo, key, plaintext, iv) {
|
||||||
if (algo.substr(0, 3) === 'aes') {
|
if (algo.substr(0, 3) === 'aes') {
|
||||||
return aesEncrypt(algo, key, plaintext, iv);
|
return aesEncrypt(algo, key, plaintext, iv);
|
||||||
|
|
|
@ -111,19 +111,14 @@ SymEncryptedIntegrityProtected.prototype.encrypt = async function (sessionKeyAlg
|
||||||
SymEncryptedIntegrityProtected.prototype.decrypt = async function (sessionKeyAlgorithm, key, streaming) {
|
SymEncryptedIntegrityProtected.prototype.decrypt = async function (sessionKeyAlgorithm, key, streaming) {
|
||||||
if (!streaming) this.encrypted = await stream.readToEnd(this.encrypted);
|
if (!streaming) this.encrypted = await stream.readToEnd(this.encrypted);
|
||||||
const encrypted = stream.clone(this.encrypted);
|
const encrypted = stream.clone(this.encrypted);
|
||||||
const encryptedClone = stream.passiveClone(encrypted);
|
const decrypted = await crypto.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(crypto.cipher[sessionKeyAlgorithm].blockSize));
|
||||||
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
|
|
||||||
|
|
||||||
// there must be a modification detection code packet as the
|
// there must be a modification detection code packet as the
|
||||||
// last packet and everything gets hashed except the hash itself
|
// 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 realHash = stream.slice(stream.passiveClone(decrypted), -20);
|
||||||
const bytes = stream.slice(decrypted, 0, -20);
|
const tohash = stream.slice(decrypted, 0, -20);
|
||||||
const tohash = util.concat([prefix, stream.passiveClone(bytes)]);
|
|
||||||
const verifyHash = Promise.all([
|
const verifyHash = Promise.all([
|
||||||
stream.readToEnd(await crypto.hash.sha1(tohash)),
|
stream.readToEnd(await crypto.hash.sha1(stream.passiveClone(tohash))),
|
||||||
stream.readToEnd(realHash)
|
stream.readToEnd(realHash)
|
||||||
]).then(([hash, mdc]) => {
|
]).then(([hash, mdc]) => {
|
||||||
if (!util.equalsUint8Array(hash, mdc)) {
|
if (!util.equalsUint8Array(hash, mdc)) {
|
||||||
|
@ -131,7 +126,8 @@ SymEncryptedIntegrityProtected.prototype.decrypt = async function (sessionKeyAlg
|
||||||
}
|
}
|
||||||
return new Uint8Array();
|
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)]);
|
packetbytes = stream.concat([packetbytes, stream.fromAsync(() => verifyHash)]);
|
||||||
if (!util.isStream(encrypted) || !config.allow_unauthenticated_stream) {
|
if (!util.isStream(encrypted) || !config.allow_unauthenticated_stream) {
|
||||||
packetbytes = await stream.readToEnd(packetbytes);
|
packetbytes = await stream.readToEnd(packetbytes);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user