[Pkg-javascript-commits] [node-browserify-aes] 27/92: works!

Bastien Roucariès rouca at moszumanska.debian.org
Sun Jun 4 09:35:17 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 62326fb7b195553833ade8773f1423b04e6cdac8
Author: Calvin Metcalf <cmetcalf at appgeo.com>
Date:   Tue Nov 11 12:42:10 2014 -0500

    works!
---
 .travis.yml        |   5 ++-
 authCipher.js      | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 decrypter.js       |   6 +++-
 encrypter.js       |   6 +++-
 ghash.js           |  98 +++++++++++++++++++++++++++++++++++++++++++++++++++
 modes.js           |  21 +++++++++++
 test/fixtures.json |  77 +++++++++++++++++++++++++++++++++++++----
 test/index.js      |  92 +++++++++++++++++++++++++++++++++++++++++-------
 8 files changed, 383 insertions(+), 22 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index d2f3209..18ae2d8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1 +1,4 @@
-language: node_js
\ No newline at end of file
+language: node_js
+node_js:
+  - "0.11"
+  - "0.10"
diff --git a/authCipher.js b/authCipher.js
new file mode 100644
index 0000000..3265a01
--- /dev/null
+++ b/authCipher.js
@@ -0,0 +1,100 @@
+var aes = require('./aes');
+var Transform = require('./cipherBase');
+var inherits = require('inherits');
+var GHASH = require('./ghash');
+var xor = require('./xor');
+inherits(StreamCipher, Transform);
+module.exports = StreamCipher;
+
+function StreamCipher(mode, key, iv, decrypt) {
+  if (!(this instanceof StreamCipher)) {
+    return new StreamCipher(mode, key, iv);
+  }
+  Transform.call(this);
+  this._finID = Buffer.concat([iv, new Buffer([0, 0, 0, 1])]);
+  iv = Buffer.concat([iv, new Buffer([0, 0, 0, 2])]);
+  this._cipher = new aes.AES(key);
+  this._prev = new Buffer(iv.length);
+  this._cache = new Buffer('');
+  this._secCache = new Buffer('');
+  this._decrypt = decrypt;
+  this._alen = 0;
+  this._len = 0;
+  iv.copy(this._prev);
+  this._mode = mode;
+  var h = new Buffer(4);
+  h.fill(0);
+  this._ghash = new GHASH(this._cipher.encryptBlock(h));
+  this._authTag = null;
+  this._called = false;
+}
+StreamCipher.prototype._transform = function (chunk, _, next) {
+  if (!this._called && this._alen) {
+    var rump = 16 - (this._alen % 16);
+    if (rump <16) {
+      rump = new Buffer(rump);
+      rump.fill(0);
+      this._ghash.update(rump);
+    }
+  }
+  this._called = true;
+  var out = this._mode.encrypt(this, chunk);
+  if (this._decrypt) {
+    this._ghash.update(chunk);
+  } else {
+    this._ghash.update(out);
+  }
+  this._len += chunk.length;
+  next(null, out);
+};
+StreamCipher.prototype._flush = function (next) {
+  if (this._decrypt && !this._authTag) {
+    throw new Error('Unsupported state or unable to authenticate data');
+  }
+  var tag = xor(this._ghash.final(this._alen * 8, this._len * 8), this._cipher.encryptBlock(this._finID));
+  if (this._decrypt) {
+    if (xorTest(tag, this._authTag)) {
+      throw new Error('Unsupported state or unable to authenticate data');
+    }
+  } else {
+    this._authTag = tag;
+  }
+  this._cipher.scrub();
+  next();
+};
+StreamCipher.prototype.getAuthTag = function getAuthTag () {
+  if (!this._decrypt && Buffer.isBuffer(this._authTag)) {
+    return this._authTag;
+  } else {
+    throw new Error('Attempting to get auth tag in unsupported state');
+  }
+};
+StreamCipher.prototype.setAuthTag = function setAuthTag (tag) {
+  if (this._decrypt) {
+    this._authTag = tag;
+  } else {
+    throw new Error('Attempting to set auth tag in unsupported state');
+  }
+};
+StreamCipher.prototype.setAAD = function setAAD (buf) {
+  if (!this._called) {
+    this._ghash.update(buf);
+    this._alen += buf.length;
+  } else {
+    throw new Error('Attempting to set AAD in unsupported state');
+  }
+};
+function xorTest(a, b) {
+  var out = 0;
+  if (a.length !== b.length) {
+    out++;
+  }
+  var len = Math.min(a.length, b.length);
+  var i = -1;
+  while (++i < len) {
+    out += (a[i] ^ b[i]);
+  }
+  return out;
+}
+
+
diff --git a/decrypter.js b/decrypter.js
index cbcefee..2cf5dd9 100644
--- a/decrypter.js
+++ b/decrypter.js
@@ -3,6 +3,7 @@ var Transform = require('./cipherBase');
 var inherits = require('inherits');
 var modes = require('./modes');
 var StreamCipher = require('./streamCipher');
+var AuthCipher = require('./authCipher');
 var ebtk = require('./EVP_BytesToKey');
 
 inherits(Decipher, Transform);
@@ -75,7 +76,8 @@ var modelist = {
   CBC: require('./modes/cbc'),
   CFB: require('./modes/cfb'),
   OFB: require('./modes/ofb'),
-  CTR: require('./modes/ctr')
+  CTR: require('./modes/ctr'),
+  GCM: require('./modes/ctr')
 };
 
 module.exports = function (crypto) {
@@ -98,6 +100,8 @@ module.exports = function (crypto) {
     }
     if (config.type === 'stream') {
       return new StreamCipher(modelist[config.mode], password, iv, true);
+    } else if (config.type === 'auth') {
+      return new AuthCipher(modelist[config.mode], password, iv, true);
     }
     return new Decipher(modelist[config.mode], password, iv);
   }
diff --git a/encrypter.js b/encrypter.js
index d981190..78dd9eb 100644
--- a/encrypter.js
+++ b/encrypter.js
@@ -4,6 +4,7 @@ var inherits = require('inherits');
 var modes = require('./modes');
 var ebtk = require('./EVP_BytesToKey');
 var StreamCipher = require('./streamCipher');
+var AuthCipher = require('./authCipher');
 inherits(Cipher, Transform);
 function Cipher(mode, key, iv) {
   if (!(this instanceof Cipher)) {
@@ -68,7 +69,8 @@ var modelist = {
   CBC: require('./modes/cbc'),
   CFB: require('./modes/cfb'),
   OFB: require('./modes/ofb'),
-  CTR: require('./modes/ctr')
+  CTR: require('./modes/ctr'),
+  GCM: require('./modes/ctr')
 };
 module.exports = function (crypto) {
   function createCipheriv(suite, password, iv) {
@@ -90,6 +92,8 @@ module.exports = function (crypto) {
     }
     if (config.type === 'stream') {
       return new StreamCipher(modelist[config.mode], password, iv);
+    } else if (config.type === 'auth') {
+      return new AuthCipher(modelist[config.mode], password, iv);
     }
     return new Cipher(modelist[config.mode], password, iv);
   }
diff --git a/ghash.js b/ghash.js
new file mode 100644
index 0000000..f2fdade
--- /dev/null
+++ b/ghash.js
@@ -0,0 +1,98 @@
+var zeros = new Buffer(16);
+zeros.fill(0);
+module.exports = GHASH;
+function GHASH(key){
+  this.h = key;
+  this.state = new Buffer(16);
+  this.state.fill(0);
+  this.cache = new Buffer('');
+}
+// from http://bitwiseshiftleft.github.io/sjcl/doc/symbols/src/core_gcm.js.html
+// by Juho Vähä-Herttua
+GHASH.prototype.ghash = function (block) {
+  var i = -1;
+  while (++i < block.length) {
+   this.state[i] ^= 0xff & block[i];
+  }
+  this._multiply();
+};
+
+GHASH.prototype._multiply = function () {
+  var Vi = toArray(this.h);
+  var Zi = [0, 0, 0, 0];
+  var j, xi, lsb_Vi;
+  var i = -1;
+  while (++i < 128) {
+    xi = (this.state[~~(i/8)] & (1 << (7-i%8))) !== 0;
+    if (xi) {
+      // Z_i+1 = Z_i ^ V_i
+      Zi = xor(Zi, Vi);
+    }
+
+    // Store the value of LSB(V_i)
+    lsb_Vi = (Vi[3] & 1) !== 0;
+
+    // V_i+1 = V_i >> 1
+    for (j=3; j>0; j--) {
+      Vi[j] = (Vi[j] >>> 1) | ((Vi[j-1]&1) << 31);
+    }
+    Vi[0] = Vi[0] >>> 1;
+
+    // If LSB(V_i) is 1, V_i+1 = (V_i >> 1) ^ R
+    if (lsb_Vi) {
+      Vi[0] = Vi[0] ^ (0xe1 << 24);
+    }
+  }
+  this.state = fromArray(Zi);
+};
+GHASH.prototype.update = function (buf) {
+  this.cache = Buffer.concat([this.cache, buf]);
+  var chunk;
+  while (this.cache.length >= 16) {
+    chunk = this.cache.slice(0, 16);
+    this.cache = this.cache.slice(16);
+    this.ghash(chunk);
+  }
+};
+GHASH.prototype.final = function (abl, bl) {
+  if (this.cache.length) {
+    this.ghash(Buffer.concat([this.cache, zeros], 16));
+  }
+  this.ghash(fromArray([
+     0, abl,
+     0, bl
+   ]));
+  return this.state;
+};
+
+function toArray(buf) {
+  return [
+    buf.readUInt32BE(0),
+    buf.readUInt32BE(4),
+    buf.readUInt32BE(8),
+    buf.readUInt32BE(12)
+  ];
+}
+function fromArray(out) {
+  out = out.map(fixup_uint32);
+  var buf = new Buffer(16);
+  buf.writeUInt32BE(out[0], 0);
+  buf.writeUInt32BE(out[1], 4);
+  buf.writeUInt32BE(out[2], 8);
+  buf.writeUInt32BE(out[3], 12);
+  return buf;
+}
+var uint_max = Math.pow(2, 32);
+function fixup_uint32(x) {
+    var ret, x_pos;
+    ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x;
+    return ret;
+}
+function xor(a, b) {
+  return [
+    a[0] ^ b[0],
+    a[1] ^ b[1],
+    a[2] ^ b[2],
+    a[3] ^ b[3],
+  ];
+}
\ No newline at end of file
diff --git a/modes.js b/modes.js
index 78e62fd..d9d3052 100644
--- a/modes.js
+++ b/modes.js
@@ -105,4 +105,25 @@ exports['aes-256-ctr'] = {
   iv: 16,
   mode: 'CTR',
   type: 'stream'
+};
+exports['aes-128-gcm'] = {
+  cipher: 'AES',
+  key: 128,
+  iv: 12,
+  mode: 'GCM',
+  type: 'auth'
+};
+exports['aes-192-gcm'] = {
+  cipher: 'AES',
+  key: 192,
+  iv: 12,
+  mode: 'GCM',
+  type: 'auth'
+};
+exports['aes-256-gcm'] = {
+  cipher: 'AES',
+  key: 256,
+  iv: 12,
+  mode: 'GCM',
+  type: 'auth'
 };
\ No newline at end of file
diff --git a/test/fixtures.json b/test/fixtures.json
index 2ef1f26..83a194b 100644
--- a/test/fixtures.json
+++ b/test/fixtures.json
@@ -39,8 +39,17 @@
                 "aes-256-ofb": "9e495087",
                 "aes-128-ctr": "e914ee82",
                 "aes-192-ctr": "3620077c",
-                "aes-256-ctr": "9e495087"
+                "aes-256-ctr": "9e495087",
+                "aes-128-gcm": "265acbb0",
+                "aes-192-gcm": "39c211e5",
+                "aes-256-gcm": "ffc91d0e"
             }
+        },
+        "aad": "calvin",
+        "authtag": {
+            "aes-128-gcm": "cd9752d7719746f5aecdb2086421a890",
+            "aes-192-gcm": "5f12847627262e0503eed9b26ec31d7e",
+            "aes-256-gcm": "1405b12c87d1a694e742c97f0e1336bb"
         }
     },
     {
@@ -83,8 +92,17 @@
                 "aes-256-ofb": "831ec789aecaa6fd45e28074bea498ffd18388fa47fa74443b375df6b84ae7893e68769ea5f345a1f2607ae0e107580a7ad9845baa4d58f2c88ba8c2d704c66c33e6ba13979d4131b0ae2700a379d3f8d1c58c485ab3198a5946374fcff536d3a4c8f84207609c3e7dd4f0feec180dcc34e1c4691f52dba052800f64dc30c2263c57487cbe2233ea09f3c52668e3eef132113655c5a27eab3a7a93916cf8f430066fe3f2fd206dc8475868994deec10497023cc2b91411325447ccaf676df858a8b25c0384ee75579546bdac462a80f953129be4cf211cd330c5c22cf583aed1ea50cb3c184f [...]
                 "aes-128-ctr": "0304a8ae497c46305a87df178b39538b09256d77a2ab6ce7b73a1a9336c9eaf03f7c70d3528161c3ce37f321cdd41f9622f56b49ac805f8d9421544ff33d25813308932adbdb4bdd94fa466600fc494f4c13e09427e8fedbe26b68f60234ab6abafd384ed3de1e05a8f95775b6016d35d7787130313917cac6de8ddac5ec58fc5d42cd51499c6805bc3a7156d4afa998e9e48c4b40f00920d3a75fef6d6dc2750f400c27de06316e2de7b6e97d2e5bfc0f523a6b5d77504f547a7ed82947e0a490336d8256801eb71fac82bc57a6fa709fa5c3070ce5f4be2e8a0367ce65e4c870fea15793d8 [...]
                 "aes-192-ctr": "35f1e120808e87537835e1cce77e657378c5b5b41bfaf9cb2ca1bb7e3af77dc34c145f5cae8038baca491a3b679c8d842f1db36b9acd457b7add1641948406a04f6002008c123829b3768fab2ae2699d717c43ac5bdf751585520835639a38f41f7e63c9de078a8e0f7459c18a7186154a6150a766dd4d94cb96505a62529d23d0ab69529c59496b8192175c69974c9902f48fc9837209541c7a41e74120ab55f53278db8f2d70473472af150a078e0ee39bf5b3f24d2e403984243ccf308ed2a4c542adb5d4d280a2b39680c53775bebdb47fc78fa4363d8c5d6ef329c3da20923ba8ff5ba3 [...]
-                "aes-256-ctr": "831ec789aecaa6fd45e28074bea498ffb909b2072fbfdd7985423e2d70c395a4224e7bcc3745f25c4bc4829bc8ec677c218deb67517c9d089abed424a9da9fe67c61ef8b2502b95b4e74b99f73eded3e7601edd78e37092520ffefcc7d365bbfb3c2e03a0b846453242f26a420800ca22e7712afeff63782578bc053b17305e8dbc4eb2374f53bab365b25f24f7d147179a10b04cae992bd55304f449e91b131351ffd46007c3d94292ff94b3a4f6e254f7ea202fe15353ad4af36a7c8ef873332733435e847a8c95405fb80da8e63b6552de521c63e00eb090931f5661f28a487de228d0592 [...]
+                "aes-256-ctr": "831ec789aecaa6fd45e28074bea498ffb909b2072fbfdd7985423e2d70c395a4224e7bcc3745f25c4bc4829bc8ec677c218deb67517c9d089abed424a9da9fe67c61ef8b2502b95b4e74b99f73eded3e7601edd78e37092520ffefcc7d365bbfb3c2e03a0b846453242f26a420800ca22e7712afeff63782578bc053b17305e8dbc4eb2374f53bab365b25f24f7d147179a10b04cae992bd55304f449e91b131351ffd46007c3d94292ff94b3a4f6e254f7ea202fe15353ad4af36a7c8ef873332733435e847a8c95405fb80da8e63b6552de521c63e00eb090931f5661f28a487de228d0592 [...]
+                "aes-128-gcm": "5b40dbf68e41f9ad5f866d091add301b568f36d2f8af4255d006226e1a1fb11c753aa8b598552211f893f0ebb689bf3f90529f03ad708ba50c4a8bde434358cfcb31f0cd3e6d420309f02b75d5e9c428eac5dda9301b64fdc2fcbe7aee0bc6ccc004a38695e321c0cf1a349d7c3778b146a14ea414486b2cd8e484d85ff368a49bd353b07eef54843501c5da15d903430e9832809f605a6f4f746f3152f247352eb4eedd64da7f4d92db15c064b2c7f8934e1aef2650f8a88af205fd9504e2c331a042eab4ff3e6652b0011eb5d3841a6426cfdc788fd496591eda050231b3523da964cce147 [...]
+                "aes-192-gcm": "9dfc5fc3fe3d57a282e6b29ab01563cf220c2fd944625a6bdf0c99f6fc4321cc7b41fb526e039cee334077cb54622b088bae12f4e7ad1b7780efc2b3ebcb31414cefcf2a1af75758ef013c6cfb2d3449afe85171e66399b45317fece10f15a92a9bd5c9aee943150de761c7ada89e69a0e88cef44b93b5282d982571d7a71d10192364a2b341b3eda6b202b2c24eff456138899c49e8c7f31354d2991bb99024957af80678bb48d9caeaea47cb2730fa2d4c35734700fb31d40a4ab7b89668bfa877e914ebdea7794f15d117f923d22cdd8857bd66af2cdeab4c5a0e13568447453294d66289 [...]
+                "aes-256-gcm": "743610df0ee25bc4fad4ff3786491472d0bb1f2440f5b213ee3b161d238edb1f83ff7302b3a24a7b60aab549ca17b7015372886b7047cbc559a12b7a752ed7269579440a0d9f426e03f7c06a4b8877a190bdc0a89379ebf8a0dde7b3f05d0e2c1f03ce40507a522458b9a8a4a8f3bea206d66e68ce2e09316018ad81de8971cc56e0e5d76842406bc31bd8c7e599c48d14d80508192b1a916c575c4591da778f09d4066cb4d0c760e1959040cdc57b9e144ced2ebc0407b69eade13c31fcfb7fe80b55c3a86bd0212e71d3d3fae3f460de5b5bbea32901c4f75f9b536bfb3fc2f0911da1ec4a [...]
             }
+        },
+        "aad": "fdfe32b59b3d2d2b85dfbb680babe590ec162058988561b0a869e58505df",
+        "authtag": {
+            "aes-128-gcm": "f856f31f89b1330659c23002e06d73e7",
+            "aes-192-gcm": "a149e211df65731305f61762107d9c1c",
+            "aes-256-gcm": "69bb4d3b34632ec108e0f6d41e010aa5"
         }
     },
     {
@@ -127,8 +145,17 @@
                 "aes-256-ofb": "9205f2d6c23b",
                 "aes-128-ctr": "5b5d3c47f2ac",
                 "aes-192-ctr": "64809bc44b10",
-                "aes-256-ctr": "9205f2d6c23b"
+                "aes-256-ctr": "9205f2d6c23b",
+                "aes-128-gcm": "649c5507cde1",
+                "aes-192-gcm": "5239ea645cb6",
+                "aes-256-gcm": "a1702685be71"
             }
+        },
+        "aad": "48221a601f6da68625580fa7d56fb44f",
+        "authtag": {
+            "aes-128-gcm": "4b733a96b107050c93acdcbb4df4315a",
+            "aes-192-gcm": "14eed33237b36219c66cfcba504da0a5",
+            "aes-256-gcm": "f29edfbedf6fd640075b091c6eddd774"
         }
     },
     {
@@ -171,8 +198,17 @@
                 "aes-256-ofb": "7ce64552d7320552347e2d3af0830ca0",
                 "aes-128-ctr": "34adb0e5b44d764af0808eff9745d704",
                 "aes-192-ctr": "957ea1bcb6d9a139d5153623813db192",
-                "aes-256-ctr": "7ce64552d7320552347e2d3af0830ca0"
+                "aes-256-ctr": "7ce64552d7320552347e2d3af0830ca0",
+                "aes-128-gcm": "805adfa669bfc28f7a70cb4c182f88a4",
+                "aes-192-gcm": "85c67323b51b771db6e6dc6f94e071c3",
+                "aes-256-gcm": "60ab90ab11fc38539c4882d1ce04748b"
             }
+        },
+        "aad": "f6bf5b6bb5ee1b",
+        "authtag": {
+            "aes-128-gcm": "a1b6a1eb59fa46b25b29be41ea2ccee8",
+            "aes-192-gcm": "f7151ce9217f96f6472caa08677eaa8c",
+            "aes-256-gcm": "94765e8761e86f826fce4202a96103a9"
         }
     },
     {
@@ -215,8 +251,17 @@
                 "aes-256-ofb": "6892cdc900665063523fb9b4940b2c11b0",
                 "aes-128-ctr": "7af8f9e6715c1a95f27021ca5e43fe7e05",
                 "aes-192-ctr": "4c3a98af7e03e16563c1636a26d3508e46",
-                "aes-256-ctr": "6892cdc900665063523fb9b4940b2c11e6"
+                "aes-256-ctr": "6892cdc900665063523fb9b4940b2c11e6",
+                "aes-128-gcm": "5b37aa3bb8fcba7dd9d8f3525d06455d5c",
+                "aes-192-gcm": "5a184c0d697e3147ce5dea377670b38f4d",
+                "aes-256-gcm": "d13327c3a244fb8a2f349f1505811adfa8"
             }
+        },
+        "aad": "950d79f5d8481ba511069b6444cb4f85faebe54c84a3dd89b0b1aa9e78ca0a7824309d423af773893084482db47ee132ade0981ca1e3a46868ada087fab5f60d87",
+        "authtag": {
+            "aes-128-gcm": "2fc30ffae7130b2d90d9ae83c5e1c50b",
+            "aes-192-gcm": "c33b5960ba9a6d0078f3fa52089d88eb",
+            "aes-256-gcm": "fbc18b1cdb10be8eb28bf4d4a76b1991"
         }
     },
     {
@@ -259,8 +304,17 @@
                 "aes-256-ofb": "24fcfa77fd9ab62df106f9ad36d62b",
                 "aes-128-ctr": "a0f218d4ca8260b99c321ce17cee51",
                 "aes-192-ctr": "59206a4c437279d2bb397f55d23236",
-                "aes-256-ctr": "24fcfa77fd9ab62df106f9ad36d62b"
+                "aes-256-ctr": "24fcfa77fd9ab62df106f9ad36d62b",
+                "aes-128-gcm": "b3298f7197b41a83d50b3dc95b9eb7",
+                "aes-192-gcm": "6137327d7d1d90df5118547f234741",
+                "aes-256-gcm": "e18b9b20b654f0430ed291cd0374be"
             }
+        },
+        "aad": "25f5dec376996cd7bea422bb",
+        "authtag": {
+            "aes-128-gcm": "9b39a1c53e5ec8b327a353375bd2daf6",
+            "aes-192-gcm": "f073f0a06ca07c0409ed09b43abe77a6",
+            "aes-256-gcm": "acd7ced603ce6be2ff7020587dbad6cb"
         }
     },
     {
@@ -303,8 +357,17 @@
                 "aes-256-ofb": "ada22f724d28d74dc5591a3ea915b9b429cab5d0ec68588ba26102d97820a217169fb7cd9abe5213930d17c4d3d6ebcd44479fb15e3b54137c7bd484162c3041a597d91e6c28a21316798a0e4a2ce5e634285152cc88f0f62305e029ab06ed5c9f608698d50e203e925ac44c9ed25fb68d847a6cae8f41dcd41aca86bd9776f53958c7d4120c149388fc9010fd38cc21b7975168c0d9f7b4c2107892c633b6a93122817ebe56e63f264e229465577348d65634cd9bdaa5c3d8f1d4a37d4bfac89a8461d8cf657707b85c96a568bf097775d5de1d2e5db538e425a13aa8075dfb34f0e304a45d [...]
                 "aes-128-ctr": "8ecc1cc287e5e021fa0bc138f6163fd5606452082ffdf1b9f4c656de8575a9281c92a5b8d8fb4200390dcc2ee19f4ece0f8641f9db68d83511e8e440498637d666149502774db005b743908accbd33c6bf8ed0bb62d902d34bc4effed598dd09f0439866c875b0cb5344bb6969362f33de483ca0d6f495566c7430657307686e4d3d7d7e0ab257c4dc3a194b393c73ee51fe4345fd2b7be06bff5387fa0bb5b920e4fc40530fb166523c7db6b306ed420bf5b8bfd0e7e98ba24785e14591c0caaea8b681290988d85597a842720c9b5e1cb4648760c684c4dbbebe69d80e71849c9b41abbfb3 [...]
                 "aes-192-ctr": "20ba2943ba5830131d093d81a860ac1820f2ee46ecef5baa6284c04a02099ccfafdbd607ce0479183297ba30bfb1e72b2bd8d28cce7a4f6b37c8eeccaa284b4c1211d4b5f20801e51fce83f44e8f84a6665e4692def15bbaf7bb05e9ed8c99f6f9f8c36c353fb394b845bfd33d560a5f63a0f341bbab72302fceb983956fcece8de41f3473618584301cc723a412127a84dabdf07e6b32822beae5f7b0eb6d4615870e38c00bea22f094532fd5828f6609e087e45090482d4c75864495269a66c750bc0c6d9c0cb438792645b2ebfa457b4fb4e2e3f7138f33fc1f2939d1e13b60c3770a9b69 [...]
-                "aes-256-ctr": "ada22f724d28d74dc5591a3ea915b9b45a3efa301064ce54819adb110fe0a05a796ea18881cadcd4f4dc86800ee8813919f23a2f496773b310c7932443a7fbb1b864736ee637c6e3d6d735d7120b5524b216bca5566a06bd113903106cc58ca4d02348089a82aaa8b1436ee8604bcad05993b77bef85a62d0482687416d331c213550c1a922323014440b1d98e3409cdda6dc14e576e0d4733d36ee9ca3423c12ea7ea14d27b169be73a7f20f20601537fff42fb9028280cf50512fe0fec0cd27e95bcfe55dff70f68d8c07f2a9fada664b1b2b4d0050ad2d6695d4b11154e2a1426a7bac2ce [...]
+                "aes-256-ctr": "ada22f724d28d74dc5591a3ea915b9b45a3efa301064ce54819adb110fe0a05a796ea18881cadcd4f4dc86800ee8813919f23a2f496773b310c7932443a7fbb1b864736ee637c6e3d6d735d7120b5524b216bca5566a06bd113903106cc58ca4d02348089a82aaa8b1436ee8604bcad05993b77bef85a62d0482687416d331c213550c1a922323014440b1d98e3409cdda6dc14e576e0d4733d36ee9ca3423c12ea7ea14d27b169be73a7f20f20601537fff42fb9028280cf50512fe0fec0cd27e95bcfe55dff70f68d8c07f2a9fada664b1b2b4d0050ad2d6695d4b11154e2a1426a7bac2ce [...]
+                "aes-128-gcm": "7900570231a4e405c8910d3ba09a2e93b7740eb90b12a833b14337e9801abea379ce7a75cf9ce1be79738734ffd4bcc3e1080f51ba6caa97a47a72df907820efa4054956c487dc1ae1bd1693e81499680077d51205a084306d70e680a40a7655895277c23ebc77fc7f7a4314802e4509d5cf483752bb9b7404cb8bdf3972ab11a0cc48803220a9ae8cd178cb1bd33311153394f08a338e32f4cf3f68763c73ed1883b0f25052af73ddb94333772688c51737f48ad12318648600743cbac1690c91af7392cd0adc2cb8e09d41ee1cea02f25157edaaddb4ae4bcd3c060bc6d905e2ebadb6a1b0 [...]
+                "aes-192-gcm": "71877f4afe1808b64822bc063291574ceec04a95882b8039541bd4742936a46c469c8241d2aff5fbc3833b134ce6b5933fc2cf8c2a4302b2ba3927dddff30ed497914769d653e9cb2470f178311bda074cee9dfa94fb2003b3612b533ca25783ab9567f122629462c431d9453d3b4fff769565019becc7228dbc8f97e23618715f121b547cd1b17a5128640c06b7e9b015be5019bbd33533d0b8e02fb6afa1c9ac319b649bd483ff434d1ec60a86aa8f21ebc7a9003a7eb76723740b1b54b199b36870fd6facd69356b6757d868ecfa646918507b5ac2f27c646f27db0b994cd76da3c1c72cb [...]
+                "aes-256-gcm": "76a318375e0ed9359c519be2e811f77dca42a04a0ac7f101448ecb8f3a036d639bdc50dbbc038c2fddcef450c70963db62adc1dc7b0b62de6d2899a84b2842b469881653bd48de8b57fbaa7730ef163883ce92ee426a6cd719f8dfe2e2debdae71caab6bedc937431a2aaa9209a7833312c57efddbead66f3c373b8dedd3a6a98e86b8e90f99743fd02eddc5c56d605bf13c4c7339cc62048862a8dab23c78eb6b47b1753b620e709a838ab6144ac091ac5d9aef33e9b69dca0f22d4b44bf2b4b0eff4f3d4dfebd825921ab4340042486c55e553714d72c41d723da56667178fe46ad341f5c4 [...]
             }
+        },
+        "aad": "6312bc1a31a878b4b2ef1df84c9b1c42",
+        "authtag": {
+            "aes-128-gcm": "18df427e45e9daf7ac9bc6b80fbc9d91",
+            "aes-192-gcm": "f349e362a080131c428cfd623b6d8eb1",
+            "aes-256-gcm": "d3a6450ab9b9d2d7cec85556216c3d81"
         }
     }
 ]
\ No newline at end of file
diff --git a/test/index.js b/test/index.js
index 5f173ed..9e8ccbe 100644
--- a/test/index.js
+++ b/test/index.js
@@ -5,9 +5,15 @@ var crypto = require('../');
 var modes = require('../modes');
 var types = Object.keys(modes);
 var ebtk = require('../EVP_BytesToKey');
+function isGCM(cipher) {
+  return modes[cipher].mode === 'GCM';
+}
 fixtures.forEach(function (fixture, i) {
   //var ciphers = fixture.results.ciphers = {};
   types.forEach(function (cipher) {
+    if (isGCM(cipher)) {
+      return;
+    }
     test('fixture ' + i + ' ' + cipher, function (t) {
       t.plan(1);
       var suite = crypto.createCipher(cipher, new Buffer(fixture.password));
@@ -84,34 +90,67 @@ fixtures.forEach(function (fixture, i) {
       t.equals(buf.toString('utf8'), buf2.toString('utf8'), 'final');
     });
     //var cipherivs = fixture.results.cipherivs = {};
+
     types.forEach(function (cipher) {
       if (modes[cipher].mode === 'ECB') {
         return;
       }
       test('fixture ' + i + ' ' + cipher + '-iv', function (t) {
-        t.plan(1);
-        var suite = crypto.createCipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key, new Buffer(fixture.iv, 'hex'));
+        if (isGCM(cipher)) {
+          t.plan(4);
+        } else {
+          t.plan(2);
+        }
+        var suite = crypto.createCipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key, isGCM(cipher) ? (new Buffer(fixture.iv, 'hex').slice(0, 12)) : (new Buffer(fixture.iv, 'hex')));
+        var suite2 = _crypto.createCipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key, isGCM(cipher) ? (new Buffer(fixture.iv, 'hex').slice(0, 12)) : (new Buffer(fixture.iv, 'hex')));
         var buf = new Buffer('');
+        var buf2 = new Buffer('');
         suite.on('data', function (d) {
           buf = Buffer.concat([buf, d]);
         });
         suite.on('error', function (e) {
           console.log(e);
         });
+        suite2.on('data', function (d) {
+          buf2 = Buffer.concat([buf2, d]);
+        });
+        suite2.on('error', function (e) {
+          console.log(e);
+        });
         suite.on("end", function () {
-          t.equals(buf.toString('hex'), fixture.results.cipherivs[cipher]);
+          t.equals(buf.toString('hex'), fixture.results.cipherivs[cipher], 'vs fixture');
+          t.equals(buf.toString('hex'), buf2.toString('hex'), 'vs node');
+          if (isGCM(cipher)) {
+            t.equals(suite.getAuthTag().toString('hex'), fixture.authtag[cipher], 'authtag vs fixture');
+            t.equals(suite.getAuthTag().toString('hex'), suite2.getAuthTag().toString('hex'), 'authtag vs node');
+          }
         });
+        if (isGCM(cipher)) {
+          suite.setAAD(new Buffer(fixture.aad, 'hex'));
+          suite2.setAAD(new Buffer(fixture.aad, 'hex'));
+        }
+        suite2.write(new Buffer(fixture.text));
+        suite2.end();
         suite.write(new Buffer(fixture.text));
         suite.end();
       });
+      
       test('fixture ' + i + ' ' + cipher + '-legacy-iv', function (t) {
-        t.plan(4);
-        var suite = crypto.createCipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key, new Buffer(fixture.iv, 'hex'));
+        if (isGCM(cipher)) {
+          t.plan(6);
+        } else {
+          t.plan(4);
+        }
+        var suite = crypto.createCipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key, isGCM(cipher) ? (new Buffer(fixture.iv, 'hex').slice(0, 12)) : (new Buffer(fixture.iv, 'hex')));
+        var suite2 = _crypto.createCipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key, isGCM(cipher) ? (new Buffer(fixture.iv, 'hex').slice(0, 12)) : (new Buffer(fixture.iv, 'hex')));
         var buf = new Buffer('');
-        var suite2 = _crypto.createCipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key, new Buffer(fixture.iv, 'hex'));
         var buf2 = new Buffer('');
         var inbuf = new Buffer(fixture.text);
         var mid = ~~(inbuf.length/2);
+        if (isGCM(cipher)) {
+          suite.setAAD(new Buffer(fixture.aad, 'hex'));
+          suite2.setAAD(new Buffer(fixture.aad, 'hex'));
+        }
         buf = Buffer.concat([buf, suite.update(inbuf.slice(0, mid))]);
         buf2 = Buffer.concat([buf2, suite2.update(inbuf.slice(0, mid))]);
         t.equals(buf.toString('hex'), buf2.toString('hex'), 'intermediate');
@@ -122,33 +161,62 @@ fixtures.forEach(function (fixture, i) {
         buf2 = Buffer.concat([buf2, suite2.final()]);
         t.equals(buf.toString('hex'), fixture.results.cipherivs[cipher]);
         t.equals(buf.toString('hex'), buf2.toString('hex'), 'final');
+        if (isGCM(cipher)) {
+          t.equals(suite.getAuthTag().toString('hex'), fixture.authtag[cipher], 'authtag vs fixture');
+          t.equals(suite.getAuthTag().toString('hex'), suite2.getAuthTag().toString('hex'), 'authtag vs node');
+        }
       });
       test('fixture ' + i + ' ' + cipher + '-iv-decrypt', function (t) {
-        t.plan(1);
-        var suite = crypto.createDecipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key, new Buffer(fixture.iv, 'hex'));
+        t.plan(2);
+        var suite = crypto.createDecipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key,  isGCM(cipher) ? (new Buffer(fixture.iv, 'hex').slice(0, 12)) : (new Buffer(fixture.iv, 'hex')));
         var buf = new Buffer('');
+        var suite2 = _crypto.createDecipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key,  isGCM(cipher) ? (new Buffer(fixture.iv, 'hex').slice(0, 12)) : (new Buffer(fixture.iv, 'hex')));
+        var buf2 = new Buffer('');
         suite.on('data', function (d) {
           buf = Buffer.concat([buf, d]);
         });
         suite.on('error', function (e) {
-          console.log(e);
+          t.notOk(e);
+        });
+        suite2.on('data', function (d) {
+          buf2 = Buffer.concat([buf2, d]);
+        });
+        suite2.on('error', function (e) {
+          t.notOk(e);
         });
         suite.on("end", function () {
-            t.equals(buf.toString('utf8'), fixture.text);
+            t.equals(buf.toString('utf8'), fixture.text, 'correct text vs fixture');
+            t.equals(buf.toString('utf8'), buf2.toString('utf8'), 'correct text vs node');
         });
+        if (isGCM(cipher)) {
+          suite.setAuthTag(new Buffer(fixture.authtag[cipher], 'hex'));
+          suite2.setAuthTag(new Buffer(fixture.authtag[cipher], 'hex'));
+          suite.setAAD(new Buffer(fixture.aad, 'hex'));
+          suite2.setAAD(new Buffer(fixture.aad, 'hex'));
+        }
+        
+        suite2.write(new Buffer(fixture.results.cipherivs[cipher], 'hex'));
         suite.write(new Buffer(fixture.results.cipherivs[cipher], 'hex'));
+        suite2.end();
         suite.end();
       });
       test('fixture ' + i + ' ' + cipher + '-decrypt-legacy', function (t) {
         t.plan(4);
-        var suite = crypto.createDecipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key, new Buffer(fixture.iv, 'hex'));
+        var suite = crypto.createDecipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key,  isGCM(cipher) ? (new Buffer(fixture.iv, 'hex').slice(0, 12)) : (new Buffer(fixture.iv, 'hex')));
         var buf = new Buffer('');
-        var suite2 = _crypto.createDecipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key, new Buffer(fixture.iv, 'hex'));
+        var suite2 = _crypto.createDecipheriv(cipher, ebtk(_crypto, fixture.password, modes[cipher].key).key,  isGCM(cipher) ? (new Buffer(fixture.iv, 'hex').slice(0, 12)) : (new Buffer(fixture.iv, 'hex')));
         var buf2 = new Buffer('');
         var inbuf = new Buffer(fixture.results.cipherivs[cipher], 'hex');
         var mid = ~~(inbuf.length/2);
+        if (isGCM(cipher)) {
+          suite.setAAD(new Buffer(fixture.aad, 'hex'));
+          suite2.setAAD(new Buffer(fixture.aad, 'hex'));
+          suite.setAuthTag(new Buffer(fixture.authtag[cipher], 'hex'));
+          suite2.setAuthTag(new Buffer(fixture.authtag[cipher], 'hex'));
+        }
         buf = Buffer.concat([buf, suite.update(inbuf.slice(0, mid))]);
         buf2 = Buffer.concat([buf2, suite2.update(inbuf.slice(0, mid))]);
+
         t.equals(buf.toString('utf8'), buf2.toString('utf8'), 'intermediate');
         buf = Buffer.concat([buf, suite.update(inbuf.slice(mid))]);
         buf2 = Buffer.concat([buf2, suite2.update(inbuf.slice(mid))]);

-- 
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