diff --git a/lib/expmt/cbc.js b/lib/expmt/cbc.js index e507da4..eb24603 100644 --- a/lib/expmt/cbc.js +++ b/lib/expmt/cbc.js @@ -1,5 +1,6 @@ var Random = require('../random'); +// Cipher Block Chaining // http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29 var CBC = function CBC(blockcipher, cipherkeybuf, ivbuf) { if (!(this instanceof CBC)) @@ -40,6 +41,12 @@ CBC.encryptblock = function(blockbuf, ivbuf, blockcipher, cipherkeybuf) { return encbuf; }; +CBC.decryptblock = function(encbuf, ivbuf, blockcipher, cipherkeybuf) { + var xorbuf = blockcipher.decrypt(encbuf, cipherkeybuf); + var blockbuf = CBC.xorbufs(xorbuf, ivbuf); + return blockbuf; +}; + CBC.encryptblocks = function(blockbufs, ivbuf, blockcipher, cipherkeybuf) { var encbufs = []; @@ -55,6 +62,21 @@ CBC.encryptblocks = function(blockbufs, ivbuf, blockcipher, cipherkeybuf) { return encbufs; }; +CBC.decryptblocks = function(encbufs, ivbuf, blockcipher, cipherkeybuf) { + var blockbufs = []; + + for (var i = 0; i < encbufs.length; i++) { + var encbuf = encbufs[i]; + var blockbuf = CBC.decryptblock(encbuf, ivbuf, blockcipher, cipherkeybuf); + + blockbufs.push(blockbuf); + + ivbuf = encbuf; + } + + return encbufs; +}; + CBC.pkcs7pad = function(buf, blocksize) { var bytesize = blocksize / 8; var padbytesize = bytesize - buf.length; diff --git a/test/test.cbc.js b/test/test.cbc.js index 2c4bb41..0f56d57 100644 --- a/test/test.cbc.js +++ b/test/test.cbc.js @@ -90,6 +90,29 @@ describe('CBC', function() { }); + describe('@decryptblock', function() { + + it('should decrypt an encrypted block', function() { + var messagebuf = new Buffer(128 / 8); + messagebuf.fill(0); + var ivbuf = new Buffer(128 / 8); + ivbuf.fill(0x10); + var cipherkeybuf = new Buffer(128 / 8); + cipherkeybuf.fill(0); + var blockcipher = {}; + blockcipher.encrypt = function(messagebuf, cipherkeybuf) { + return messagebuf; + }; + blockcipher.decrypt = function(messagebuf, cipherkeybuf) { + return messagebuf; + }; + var encbuf = CBC.encryptblock(messagebuf, ivbuf, blockcipher, cipherkeybuf); + var buf = CBC.decryptblock(encbuf, ivbuf, blockcipher, cipherkeybuf); + buf.toString('hex').should.equal(messagebuf.toString('hex')); + }); + + }); + describe('@encryptblocks', function() { it('should return this known value', function() {