[Pkg-javascript-commits] [node-browserify-aes] 01/10: fix variable length iv issue in gcm
Bastien Roucariès
rouca at moszumanska.debian.org
Thu Nov 9 12:42:42 UTC 2017
This is an automated email from the git hooks/post-receive script.
rouca pushed a commit to branch master
in repository node-browserify-aes.
commit a5680e9c464771b086ed8b44b11f26993cdc66ea
Author: Calvin Metcalf <cmetcalf at appgeo.com>
Date: Tue Oct 10 13:32:55 2017 -0400
fix variable length iv issue in gcm
---
authCipher.js | 33 +++++++++++++++++++++++++++++----
decrypter.js | 2 +-
encrypter.js | 2 +-
incr32.js | 15 +++++++++++++++
modes/ctr.js | 15 +--------------
test/index.js | 43 +++++++++++++++++++++++++++++++++++++++++++
6 files changed, 90 insertions(+), 20 deletions(-)
diff --git a/authCipher.js b/authCipher.js
index 2a7affc..c6e8a76 100644
--- a/authCipher.js
+++ b/authCipher.js
@@ -4,6 +4,7 @@ var Transform = require('cipher-base')
var inherits = require('inherits')
var GHASH = require('./ghash')
var xor = require('buffer-xor')
+var incr32 = require('./incr32')
function xorTest (a, b) {
var out = 0
@@ -17,13 +18,39 @@ function xorTest (a, b) {
return out
}
+function calcIv (self, iv, ck) {
+ if (iv.length === 12) {
+ self._finID = Buffer.concat([iv, Buffer.from([0, 0, 0, 1])])
+ return Buffer.concat([iv, Buffer.from([0, 0, 0, 2])])
+ }
+ var ghash = new GHASH(ck)
+ var len = iv.length
+ var toPad = len % 16
+ ghash.update(iv)
+ if (toPad) {
+ toPad = 16 - toPad
+ ghash.update(Buffer.alloc(toPad, 0))
+ }
+ ghash.update(Buffer.alloc(8, 0))
+ var ivBits = len * 8
+ var tail = Buffer.alloc(8)
+ tail.writeUIntBE(ivBits, 0, 8)
+ ghash.update(tail)
+ self._finID = ghash.state
+ var out = Buffer.from(self._finID)
+ incr32(out)
+ return out
+}
function StreamCipher (mode, key, iv, decrypt) {
Transform.call(this)
- this._finID = Buffer.concat([iv, Buffer.from([0, 0, 0, 1])])
- iv = Buffer.concat([iv, Buffer.from([0, 0, 0, 2])])
+ var h = Buffer.alloc(4, 0)
this._cipher = new aes.AES(key)
+ var ck = this._cipher.encryptBlock(h)
+ this._ghash = new GHASH(ck)
+ iv = calcIv(this, iv, ck)
+
this._prev = Buffer.from(iv)
this._cache = Buffer.allocUnsafe(0)
this._secCache = Buffer.allocUnsafe(0)
@@ -32,8 +59,6 @@ function StreamCipher (mode, key, iv, decrypt) {
this._len = 0
this._mode = mode
- var h = Buffer.alloc(4, 0)
- this._ghash = new GHASH(this._cipher.encryptBlock(h))
this._authTag = null
this._called = false
}
diff --git a/decrypter.js b/decrypter.js
index a2f596b..d752033 100644
--- a/decrypter.js
+++ b/decrypter.js
@@ -95,7 +95,7 @@ function createDecipheriv (suite, password, iv) {
if (!config) throw new TypeError('invalid suite type')
if (typeof iv === 'string') iv = Buffer.from(iv)
- if (iv.length !== config.iv) throw new TypeError('invalid iv length ' + iv.length)
+ if (config.mode !== 'GCM' && iv.length !== config.iv) throw new TypeError('invalid iv length ' + iv.length)
if (typeof password === 'string') password = Buffer.from(password)
if (password.length !== config.key / 8) throw new TypeError('invalid key length ' + password.length)
diff --git a/encrypter.js b/encrypter.js
index df2eab8..0c4c58b 100644
--- a/encrypter.js
+++ b/encrypter.js
@@ -91,7 +91,7 @@ function createCipheriv (suite, password, iv) {
if (password.length !== config.key / 8) throw new TypeError('invalid key length ' + password.length)
if (typeof iv === 'string') iv = Buffer.from(iv)
- if (iv.length !== config.iv) throw new TypeError('invalid iv length ' + iv.length)
+ if (config.mode !== 'GCM' && iv.length !== config.iv) throw new TypeError('invalid iv length ' + iv.length)
if (config.type === 'stream') {
return new StreamCipher(config.module, password, iv)
diff --git a/incr32.js b/incr32.js
new file mode 100644
index 0000000..c1a9089
--- /dev/null
+++ b/incr32.js
@@ -0,0 +1,15 @@
+function incr32 (iv) {
+ var len = iv.length
+ var item
+ while (len--) {
+ item = iv.readUInt8(len)
+ if (item === 255) {
+ iv.writeUInt8(0, len)
+ } else {
+ item++
+ iv.writeUInt8(item, len)
+ break
+ }
+ }
+}
+module.exports = incr32
diff --git a/modes/ctr.js b/modes/ctr.js
index ca282fb..4a84e1b 100644
--- a/modes/ctr.js
+++ b/modes/ctr.js
@@ -1,19 +1,6 @@
var xor = require('buffer-xor')
-function incr32 (iv) {
- var len = iv.length
- var item
- while (len--) {
- item = iv.readUInt8(len)
- if (item === 255) {
- iv.writeUInt8(0, len)
- } else {
- item++
- iv.writeUInt8(item, len)
- break
- }
- }
-}
+var incr32 = require('../incr32')
function getBlock (self) {
var out = self._cipher.encryptBlockRaw(self._prev)
diff --git a/test/index.js b/test/index.js
index edf4dfa..a356477 100644
--- a/test/index.js
+++ b/test/index.js
@@ -431,6 +431,49 @@ test('correctly handle incremental base64 output', function (t) {
t.equals(data, decrypted, 'round trips')
})
+var gcmTest = [
+ {
+ length: 8,
+ answer: 'f0714f44',
+ tag: 'a5814f7c3d8e7eee899d260fb91784bf'
+ },
+ {
+ length: 16,
+ answer: 'b93caf62',
+ tag: '58fd9623495ac556f0d26cbc9fa4384c'
+ },
+ {
+ length: 21,
+ answer: '4534b74d',
+ tag: '5299c9c1011f32b17db796745239298a'
+ },
+ {
+ length: 43,
+ answer: 'b16a634b',
+ tag: 'd9274cb14b01e8e6a8fe3866b0e17f65'
+ }
+]
+function testIV (t, length, answer, tag) {
+ t.test('key length ' + length, function (t) {
+ t.plan(3)
+ var key = Buffer.alloc(32, 0)
+ var iv = Buffer.alloc(length, 0)
+ var cipher = crypto.createCipheriv('aes-256-gcm', key, iv)
+ var out = cipher.update('fooo').toString('hex')
+ t.equals(out, answer)
+ cipher.final()
+ t.equals(tag, cipher.getAuthTag().toString('hex'))
+ var decipher = crypto.createDecipheriv('aes-256-gcm', key, iv)
+ decipher.setAuthTag(Buffer.from(tag, 'hex'))
+ var decrypted = decipher.update(Buffer.from(answer, 'hex'))
+ t.equals(decrypted.toString(), 'fooo')
+ })
+}
+test('different IV lengths work for GCM', function (t) {
+ gcmTest.forEach(function (item) {
+ testIV(t, item.length, item.answer, item.tag)
+ })
+})
test('handle long uft8 plaintexts', function (t) {
t.plan(1)
var salt = Buffer.alloc(32, 0)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-browserify-aes.git
More information about the Pkg-javascript-commits
mailing list