From 26de17150cdf239a98e647beb49c4331dc053035 Mon Sep 17 00:00:00 2001 From: Sanjana Rajan Date: Sat, 29 Jul 2017 18:34:18 +0200 Subject: [PATCH] use internal aes encrypt in key wrap, start refactoring aes to do decryption as well --- src/crypto/aes_kw.js | 18 +- src/crypto/cipher/aes.js | 370 +++++++++++++++++++++++++++++++++++++-- test/general/key.js | 1 - 3 files changed, 365 insertions(+), 24 deletions(-) diff --git a/src/crypto/aes_kw.js b/src/crypto/aes_kw.js index 93f3143f..265cd053 100644 --- a/src/crypto/aes_kw.js +++ b/src/crypto/aes_kw.js @@ -15,8 +15,9 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// Implementation of RFC 3394 Key Wrap & Key Unwrap funcions +// Implementation of RFC 3394 AES Key Wrap & Key Unwrap funcions +import cipher from './cipher'; import AES from 'aes'; function createArrayBuffer(data) { @@ -60,7 +61,7 @@ function pack() { return new Uint8Array(buffer); } -function createCipher(key) { +function formatKey(key) { var length = key.length; var buffer = createArrayBuffer(key); var view = new DataView(buffer); @@ -68,12 +69,13 @@ function createCipher(key) { for (var i=0; i> 24) & 255); } -function F1(x0, x1, x2, x3) { - return B1(T1[x0 & 255]) | (B1(T1[(x1 >> 8) & 255]) << 8) | (B1(T1[(x2 >> 16) & 255]) << 16) | (B1(T1[x3 >>> 24]) << 24); +function F1_enc(x0, x1, x2, x3) { + return B1(T1_enc[x0 & 255]) | (B1(T1_enc[(x1 >> 8) & 255]) << 8) | (B1(T1_enc[(x2 >> 16) & 255]) << 16) | (B1(T1_enc[x3 >>> 24]) << 24); +} + +function F1_dec(x0, x1, x2, x3) { + return B1(T1_dec[x0 & 255]) | (B1(T1_dec[(x1 >> 8) & 255]) << 8) | (B1(T1_dec[(x2 >> 16) & 255]) << 16) | (B1(T1_dec[x3 >>> 24]) << 24); } function packBytes(octets) { @@ -370,7 +664,7 @@ function unpackBytes(packed) { var maxkc = 8; var maxrk = 14; -function keyExpansion(key) { +function scheduleEncKey(key) { var kc, i, j, r, t; var rounds; var keySched = new Array(maxrk + 1); @@ -456,6 +750,8 @@ function keyExpansion(key) { }; } + + function AESencrypt(block, ctx, t) { var r, rounds, b; @@ -468,10 +764,10 @@ function AESencrypt(block, ctx, t) { t[2] = b[2] ^ ctx.rk[r][2]; t[3] = b[3] ^ ctx.rk[r][3]; - b[0] = T1[t[0] & 255] ^ T2[(t[1] >> 8) & 255] ^ T3[(t[2] >> 16) & 255] ^ T4[t[3] >>> 24]; - b[1] = T1[t[1] & 255] ^ T2[(t[2] >> 8) & 255] ^ T3[(t[3] >> 16) & 255] ^ T4[t[0] >>> 24]; - b[2] = T1[t[2] & 255] ^ T2[(t[3] >> 8) & 255] ^ T3[(t[0] >> 16) & 255] ^ T4[t[1] >>> 24]; - b[3] = T1[t[3] & 255] ^ T2[(t[0] >> 8) & 255] ^ T3[(t[1] >> 16) & 255] ^ T4[t[2] >>> 24]; + b[0] = T1_enc[t[0] & 255] ^ T2_enc[(t[1] >> 8) & 255] ^ T3_enc[(t[2] >> 16) & 255] ^ T4_enc[t[3] >>> 24]; + b[1] = T1_enc[t[1] & 255] ^ T2_enc[(t[2] >> 8) & 255] ^ T3_enc[(t[3] >> 16) & 255] ^ T4_enc[t[0] >>> 24]; + b[2] = T1_enc[t[2] & 255] ^ T2_enc[(t[3] >> 8) & 255] ^ T3_enc[(t[0] >> 16) & 255] ^ T4_enc[t[1] >>> 24]; + b[3] = T1_enc[t[3] & 255] ^ T2_enc[(t[0] >> 8) & 255] ^ T3_enc[(t[1] >> 16) & 255] ^ T4_enc[t[2] >>> 24]; } // last round is special @@ -482,10 +778,44 @@ function AESencrypt(block, ctx, t) { t[2] = b[2] ^ ctx.rk[r][2]; t[3] = b[3] ^ ctx.rk[r][3]; - b[0] = F1(t[0], t[1], t[2], t[3]) ^ ctx.rk[rounds][0]; - b[1] = F1(t[1], t[2], t[3], t[0]) ^ ctx.rk[rounds][1]; - b[2] = F1(t[2], t[3], t[0], t[1]) ^ ctx.rk[rounds][2]; - b[3] = F1(t[3], t[0], t[1], t[2]) ^ ctx.rk[rounds][3]; + b[0] = F1_enc(t[0], t[1], t[2], t[3]) ^ ctx.rk[rounds][0]; + b[1] = F1_enc(t[1], t[2], t[3], t[0]) ^ ctx.rk[rounds][1]; + b[2] = F1_enc(t[2], t[3], t[0], t[1]) ^ ctx.rk[rounds][2]; + b[3] = F1_enc(t[3], t[0], t[1], t[2]) ^ ctx.rk[rounds][3]; + + return unpackBytes(b); +} + +function AESdecrypt(block, ctx, t) { + var r, rounds, b; + + b = packBytes(block); + rounds = ctx.rounds; + + for (r = 0; r < rounds - 1; r++) { + t[0] = b[0] ^ ctx.rk[r][0]; + t[1] = b[3] ^ ctx.rk[r][1]; + t[2] = b[2] ^ ctx.rk[r][2]; + t[3] = b[1] ^ ctx.rk[r][3]; + + b[0] = T1_dec[t[0] & 255] ^ T2_dec[(t[1] >> 8) & 255] ^ T3_dec[(t[2] >> 16) & 255] ^ T4_dec[t[3] >>> 24]; + b[1] = T1_dec[t[1] & 255] ^ T2_dec[(t[2] >> 8) & 255] ^ T3_dec[(t[3] >> 16) & 255] ^ T4_dec[t[0] >>> 24]; + b[2] = T1_dec[t[2] & 255] ^ T2_dec[(t[3] >> 8) & 255] ^ T3_dec[(t[0] >> 16) & 255] ^ T4_dec[t[1] >>> 24]; + b[3] = T1_dec[t[3] & 255] ^ T2_dec[(t[0] >> 8) & 255] ^ T3_dec[(t[1] >> 16) & 255] ^ T4_dec[t[2] >>> 24]; + } + + // last round is special + r = rounds - 1; + + t[0] = b[0] ^ ctx.rk[r][0]; + t[1] = b[3] ^ ctx.rk[r][1]; + t[2] = b[2] ^ ctx.rk[r][2]; + t[3] = b[1] ^ ctx.rk[r][3]; + + b[0] = F1_dec(t[0], t[1], t[2], t[3]) ^ ctx.rk[rounds][0]; + b[3] = F1_dec(t[1], t[2], t[3], t[0]) ^ ctx.rk[rounds][1]; + b[2] = F1_dec(t[2], t[3], t[0], t[1]) ^ ctx.rk[rounds][2]; + b[1] = F1_dec(t[3], t[0], t[1], t[2]) ^ ctx.rk[rounds][3]; return unpackBytes(b); } @@ -493,11 +823,15 @@ function AESencrypt(block, ctx, t) { function makeClass(length) { var c = function(key) { - this.key = keyExpansion(key); - this._temp = new Uint32Array(this.blockSize / 4); + this.enc_key = scheduleEncKey(key); + //this.dec_key = scheduleDecKey(this.enc_key); this.encrypt = function(block) { - return AESencrypt(block, this.key, this._temp); + return AESencrypt(block, this.enc_key, new Uint32Array(this.blockSize / 4)); + }; + + this.decrypt = function(block) { + return AESdecrypt(block, this.enc_key, new Uint32Array(this.blockSize / 4)); }; }; diff --git a/test/general/key.js b/test/general/key.js index 8a790a5f..4ab27a69 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -527,7 +527,6 @@ describe('Key', function() { '=Q/kB', '-----END PGP PUBLIC KEY BLOCK-----'].join('\n'); -<<<<<<< HEAD var valid_binding_sig_among_many_expired_sigs_pub = [ '-----BEGIN PGP PUBLIC KEY BLOCK-----', '',