From 33303b212692b2e4fe3db8fa9f0a4f9e0303d05c Mon Sep 17 00:00:00 2001 From: Tom Swindell Date: Thu, 24 May 2018 16:14:31 +0100 Subject: [PATCH 1/4] Added aes128cbc mode. Signed-off-by: Tom Swindell --- index.js | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index 8d5fcf5..75cca70 100644 --- a/index.js +++ b/index.js @@ -27,12 +27,33 @@ function assert(condition, message) { } } +function sha256(msg) { + return crypto.createHash("sha256").update(msg).digest(); +} + function sha512(msg) { return crypto.createHash("sha512").update(msg).digest(); } +function aes128CbcEncrypt(iv, key, plaintext) { + var cipher = crypto.createCipheriv("aes-128-cbc", key, iv); + cipher.setAutoPadding(false) + var firstChunk = cipher.update(plaintext); + var secondChunk = cipher.final(); + return Buffer.concat([firstChunk, secondChunk]); +} + +function aes128CbcDecrypt(iv, key, ciphertext) { + var cipher = crypto.createDecipheriv("aes-128-cbc", key, iv); + cipher.setAutoPadding(false) + var firstChunk = cipher.update(ciphertext); + var secondChunk = cipher.final(); + return Buffer.concat([firstChunk, secondChunk]); +} + function aes256CbcEncrypt(iv, key, plaintext) { var cipher = crypto.createCipheriv("aes-256-cbc", key, iv); + cipher.setAutoPadding(false) var firstChunk = cipher.update(plaintext); var secondChunk = cipher.final(); return Buffer.concat([firstChunk, secondChunk]); @@ -166,11 +187,11 @@ exports.encrypt = function(publicKeyTo, msg, opts) { ephemPublicKey = getPublic(ephemPrivateKey); resolve(derive(ephemPrivateKey, publicKeyTo)); }).then(function(Px) { - var hash = sha512(Px); + var hash = ('aes128cbc' in opts) ? sha256(Px) : sha512(Px); var iv = opts.iv || crypto.randomBytes(16); - var encryptionKey = hash.slice(0, 32); - var macKey = hash.slice(32); - var ciphertext = aes256CbcEncrypt(iv, encryptionKey, msg); + var encryptionKey = ('aes128cbc' in opts) ? hash.slice(0, 16) : hash.slice(0, 32); + var macKey = ('aes128cbc' in opts) ? hash.slice(16) : hash.slice(0, 32); + var ciphertext = ('aes128cbc' in opts) ? aes128CbcEncrypt(iv, encryptionKey, msg) : aes256CbcEncrypt(iv, encryptionKey, msg); var dataToMac = Buffer.concat([iv, ephemPublicKey, ciphertext]); var mac = hmacSha256(macKey, dataToMac); return { @@ -192,9 +213,9 @@ exports.encrypt = function(publicKeyTo, msg, opts) { */ exports.decrypt = function(privateKey, opts) { return derive(privateKey, opts.ephemPublicKey).then(function(Px) { - var hash = sha512(Px); - var encryptionKey = hash.slice(0, 32); - var macKey = hash.slice(32); + var hash = ('aes128cbc' in opts) ? sha256(Px) : sha512(Px); + var encryptionKey = ('aes128cbc' in opts) ? hash.slice(0, 16) : hash.slice(0, 32); + var macKey = ('aes128cbc' in opts) ? hash.slice(16) : hash.slice(32); var dataToMac = Buffer.concat([ opts.iv, opts.ephemPublicKey, @@ -202,6 +223,6 @@ exports.decrypt = function(privateKey, opts) { ]); var realMac = hmacSha256(macKey, dataToMac); assert(equalConstTime(opts.mac, realMac), "Bad MAC"); - return aes256CbcDecrypt(opts.iv, encryptionKey, opts.ciphertext); + return ('aes128cbc' in opts) ? aes128CbcDecrypt(opts.iv, encryptionKey, opts.ciphertext) : aes256CbcDecrypt(opts.iv, encryptionKey, opts.ciphertext); }); }; From ff24af7c54a658e0cc7e8bbee472d6a3777eea88 Mon Sep 17 00:00:00 2001 From: Tom Swindell Date: Mon, 19 Nov 2018 09:23:34 +0000 Subject: [PATCH 2/4] Added aes128cbc browser mode. Signed-off-by: Tom Swindell --- browser.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/browser.js b/browser.js index 66806d5..239b804 100644 --- a/browser.js +++ b/browser.js @@ -22,6 +22,12 @@ function randomBytes(size) { return new Buffer(arr); } +function sha256(msg) { + return subtle.digest({name: "SHA-256"}, msg).then(function(hash) { + return new Buffer(new Uint8Array(hash)); + }); +} + function sha512(msg) { return subtle.digest({name: "SHA-512"}, msg).then(function(hash) { return new Buffer(new Uint8Array(hash)); @@ -122,11 +128,11 @@ exports.encrypt = function(publicKeyTo, msg, opts) { ephemPublicKey = getPublic(ephemPrivateKey); resolve(derive(ephemPrivateKey, publicKeyTo)); }).then(function(Px) { - return sha512(Px); + return ('aes128cbc' in opts) ? sha256(Px) : sha512(Px); }).then(function(hash) { iv = opts.iv || randomBytes(16); - var encryptionKey = hash.slice(0, 32); - macKey = hash.slice(32); + var encryptionKey = ('aes128cbc' in opts) ? hash.slice(0, 16) : hash.slice(0, 32); + macKey = ('aes128cbc' in opts) ? hash.slice(16) : hash.slice(32); return aesCbcEncrypt(iv, encryptionKey, msg); }).then(function(data) { ciphertext = data; From f5e99832aacc26549c64383a514758acde3fd125 Mon Sep 17 00:00:00 2001 From: Tom Swindell Date: Thu, 24 May 2018 16:14:31 +0100 Subject: [PATCH 3/4] Added aes128cbc mode. Signed-off-by: Tom Swindell --- index.js | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index a63218b..9254f32 100644 --- a/index.js +++ b/index.js @@ -44,12 +44,33 @@ function assert(condition, message) { } } +function sha256(msg) { + return crypto.createHash("sha256").update(msg).digest(); +} + function sha512(msg) { return crypto.createHash("sha512").update(msg).digest(); } +function aes128CbcEncrypt(iv, key, plaintext) { + var cipher = crypto.createCipheriv("aes-128-cbc", key, iv); + cipher.setAutoPadding(false) + var firstChunk = cipher.update(plaintext); + var secondChunk = cipher.final(); + return Buffer.concat([firstChunk, secondChunk]); +} + +function aes128CbcDecrypt(iv, key, ciphertext) { + var cipher = crypto.createDecipheriv("aes-128-cbc", key, iv); + cipher.setAutoPadding(false) + var firstChunk = cipher.update(ciphertext); + var secondChunk = cipher.final(); + return Buffer.concat([firstChunk, secondChunk]); +} + function aes256CbcEncrypt(iv, key, plaintext) { var cipher = crypto.createCipheriv("aes-256-cbc", key, iv); + cipher.setAutoPadding(false) var firstChunk = cipher.update(plaintext); var secondChunk = cipher.final(); return Buffer.concat([firstChunk, secondChunk]); @@ -216,11 +237,11 @@ exports.encrypt = function(publicKeyTo, msg, opts) { ephemPublicKey = getPublic(ephemPrivateKey); resolve(derive(ephemPrivateKey, publicKeyTo)); }).then(function(Px) { - var hash = sha512(Px); + var hash = ('aes128cbc' in opts) ? sha256(Px) : sha512(Px); var iv = opts.iv || crypto.randomBytes(16); - var encryptionKey = hash.slice(0, 32); - var macKey = hash.slice(32); - var ciphertext = aes256CbcEncrypt(iv, encryptionKey, msg); + var encryptionKey = ('aes128cbc' in opts) ? hash.slice(0, 16) : hash.slice(0, 32); + var macKey = ('aes128cbc' in opts) ? hash.slice(16) : hash.slice(0, 32); + var ciphertext = ('aes128cbc' in opts) ? aes128CbcEncrypt(iv, encryptionKey, msg) : aes256CbcEncrypt(iv, encryptionKey, msg); var dataToMac = Buffer.concat([iv, ephemPublicKey, ciphertext]); var mac = Buffer.from(hmacSha256(macKey, dataToMac)); return { @@ -244,15 +265,16 @@ exports.decrypt = function(privateKey, opts) { return derive(privateKey, opts.ephemPublicKey).then(function(Px) { assert(privateKey.length === 32, "Bad private key"); assert(isValidPrivateKey(privateKey), "Bad private key"); - var hash = sha512(Px); - var encryptionKey = hash.slice(0, 32); - var macKey = hash.slice(32); + var hash = ('aes128cbc' in opts) ? sha256(Px) : sha512(Px); + var encryptionKey = ('aes128cbc' in opts) ? hash.slice(0, 16) : hash.slice(0, 32); + var macKey = ('aes128cbc' in opts) ? hash.slice(16) : hash.slice(32); var dataToMac = Buffer.concat([ opts.iv, opts.ephemPublicKey, opts.ciphertext ]); var realMac = hmacSha256(macKey, dataToMac); - assert(equalConstTime(opts.mac, realMac), "Bad MAC"); return aes256CbcDecrypt(opts.iv, encryptionKey, opts.ciphertext); + assert(equalConstTime(opts.mac, realMac), "Bad MAC"); + return ('aes128cbc' in opts) ? aes128CbcDecrypt(opts.iv, encryptionKey, opts.ciphertext) : aes256CbcDecrypt(opts.iv, encryptionKey, opts.ciphertext); }); }; From 7cfe5a11bae81faa1a8c3170460c460bc13d57da Mon Sep 17 00:00:00 2001 From: Tom Swindell Date: Mon, 19 Nov 2018 09:23:34 +0000 Subject: [PATCH 4/4] Added aes128cbc browser mode. Signed-off-by: Tom Swindell --- browser.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/browser.js b/browser.js index 11cb609..3637ce5 100644 --- a/browser.js +++ b/browser.js @@ -55,6 +55,12 @@ function randomBytes(size) { return Buffer.from(arr); } +function sha256(msg) { + return subtle.digest({name: "SHA-256"}, msg).then(function(hash) { + return new Buffer(new Uint8Array(hash)); + }); +} + function sha512(msg) { return new Promise(function(resolve) { var hash = nodeCrypto.createHash('sha512'); @@ -218,11 +224,11 @@ exports.encrypt = function(publicKeyTo, msg, opts) { ephemPublicKey = getPublic(ephemPrivateKey); resolve(derive(ephemPrivateKey, publicKeyTo)); }).then(function(Px) { - return sha512(Px); + return ('aes128cbc' in opts) ? sha256(Px) : sha512(Px); }).then(function(hash) { iv = opts.iv || randomBytes(16); - var encryptionKey = hash.slice(0, 32); - macKey = hash.slice(32); + var encryptionKey = ('aes128cbc' in opts) ? hash.slice(0, 16) : hash.slice(0, 32); + macKey = ('aes128cbc' in opts) ? hash.slice(16) : hash.slice(32); return aesCbcEncrypt(iv, encryptionKey, msg); }).then(function(data) { ciphertext = data;