Cleanup and unit test gcm.js
This commit is contained in:
parent
49faca83c5
commit
8aa15b66a9
|
@ -23,12 +23,14 @@
|
|||
'use strict';
|
||||
|
||||
import util from '../util.js';
|
||||
import config from '../config';
|
||||
import asmCrypto from 'asmcrypto-lite';
|
||||
const webCrypto = util.getWebCrypto();
|
||||
const nodeCrypto = util.getNodeCrypto();
|
||||
const Buffer = util.getNodeBuffer();
|
||||
|
||||
export const ivLength = 12;
|
||||
const ALGO = 'AES-GCM';
|
||||
|
||||
/**
|
||||
* Encrypt plaintext input.
|
||||
|
@ -40,26 +42,18 @@ export const ivLength = 12;
|
|||
*/
|
||||
export function encrypt(cipher, plaintext, key, iv) {
|
||||
if (cipher.substr(0,3) !== 'aes') {
|
||||
return Promise.reject(new Error('Invalid cipher for GCM mode'));
|
||||
return Promise.reject(new Error('GCM mode supports only AES cipher'));
|
||||
}
|
||||
|
||||
if (webCrypto) { // native WebCrypto api
|
||||
const keyOptions = {
|
||||
name: 'AES-GCM'
|
||||
},
|
||||
encryptOptions = {
|
||||
name: 'AES-GCM',
|
||||
iv: iv
|
||||
};
|
||||
return webCrypto.importKey('raw', key, keyOptions, false, ['encrypt']).then(keyObj => {
|
||||
return webCrypto.encrypt(encryptOptions, keyObj, plaintext);
|
||||
}).then(ciphertext => {
|
||||
return new Uint8Array(ciphertext);
|
||||
});
|
||||
const keySize = cipher.substr(3,3);
|
||||
if (webCrypto && config.useNative && keySize !== '192') { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
|
||||
return webCrypto.importKey('raw', key, { name: ALGO }, false, ['encrypt'])
|
||||
.then(keyObj => webCrypto.encrypt({ name: ALGO, iv }, keyObj, plaintext))
|
||||
.then(ciphertext => new Uint8Array(ciphertext));
|
||||
|
||||
} else if(nodeCrypto) { // native node crypto library
|
||||
let cipherObj = new nodeCrypto.createCipheriv('aes-' + cipher.substr(3,3) + '-gcm', new Buffer(key), new Buffer(iv));
|
||||
let encrypted = Buffer.concat([cipherObj.update(new Buffer(plaintext)), cipherObj.final()]);
|
||||
} else if (nodeCrypto && config.useNative) { // Node crypto library
|
||||
const en = new nodeCrypto.createCipheriv('aes-' + keySize + '-gcm', new Buffer(key), new Buffer(iv));
|
||||
const encrypted = Buffer.concat([en.update(new Buffer(plaintext)), en.final()]);
|
||||
return Promise.resolve(new Uint8Array(encrypted));
|
||||
|
||||
} else { // asm.js fallback
|
||||
|
@ -77,26 +71,18 @@ export function encrypt(cipher, plaintext, key, iv) {
|
|||
*/
|
||||
export function decrypt(cipher, ciphertext, key, iv) {
|
||||
if (cipher.substr(0,3) !== 'aes') {
|
||||
return Promise.reject(new Error('Invalid cipher for GCM mode'));
|
||||
return Promise.reject(new Error('GCM mode supports only AES cipher'));
|
||||
}
|
||||
|
||||
if (webCrypto) { // native WebCrypto api
|
||||
const keyOptions = {
|
||||
name: 'AES-GCM'
|
||||
},
|
||||
decryptOptions = {
|
||||
name: 'AES-GCM',
|
||||
iv: iv
|
||||
};
|
||||
return webCrypto.importKey('raw', key, keyOptions, false, ['decrypt']).then(keyObj => {
|
||||
return webCrypto.decrypt(decryptOptions, keyObj, ciphertext);
|
||||
}).then(plaintext => {
|
||||
return new Uint8Array(plaintext);
|
||||
});
|
||||
const keySize = cipher.substr(3,3);
|
||||
if (webCrypto && config.useNative && keySize !== '192') { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
|
||||
return webCrypto.importKey('raw', key, { name: ALGO }, false, ['decrypt'])
|
||||
.then(keyObj => webCrypto.decrypt({ name: ALGO, iv }, keyObj, ciphertext))
|
||||
.then(plaintext => new Uint8Array(plaintext));
|
||||
|
||||
} else if(nodeCrypto) { // native node crypto library
|
||||
let decipherObj = new nodeCrypto.createDecipheriv('aes-' + cipher.substr(3,3) + '-gcm', new Buffer(key), new Buffer(iv));
|
||||
let decrypted = Buffer.concat([decipherObj.update(new Buffer(ciphertext)), decipherObj.final()]);
|
||||
} else if (nodeCrypto && config.useNative) { // Node crypto library
|
||||
let de = new nodeCrypto.createDecipheriv('aes-' + keySize + '-gcm', new Buffer(key), new Buffer(iv));
|
||||
let decrypted = Buffer.concat([de.update(new Buffer(ciphertext)), de.final()]);
|
||||
return Promise.resolve(new Uint8Array(decrypted));
|
||||
|
||||
} else { // asm.js fallback
|
||||
|
|
|
@ -80,7 +80,7 @@ describe('API functional testing', function() {
|
|||
0x51,0xe0,0x22,0xf0,0xff,0xa7,0x42,0xd4,0xde,0x0b,0x47,0x8f,0x2b,
|
||||
0xf5,0x4d,0x04,0x32,0x91,0x89,0x4b,0x0e,0x05,0x8d,0x70,0xf9,0xbb,
|
||||
0xe7,0xd6,0x76,0xea,0x0e,0x1a,0x90,0x30,0xf5,0x98,0x01,0xc5,0x73])];
|
||||
|
||||
|
||||
var DSApubMPIstrs = [
|
||||
new Uint8Array([0x08,0x00,0xa8,0x85,0x5c,0x28,0x05,0x94,0x03,0xbe,0x07,0x6c,0x13,0x3e,0x65,
|
||||
0xfb,0xb5,0xe1,0x99,0x7c,0xfa,0x84,0xe3,0xac,0x47,0xa5,0xc4,0x46,0xd8,0x5f,
|
||||
|
@ -143,7 +143,7 @@ describe('API functional testing', function() {
|
|||
new Uint8Array([0x01,0x00,0x9b,0x58,0xa8,0xf4,0x04,0xb1,0xd5,0x14,0x09,0xe1,0xe1,0xa1,0x8a,
|
||||
0x0b,0xa3,0xc3,0xa3,0x66,0xaa,0x27,0x99,0x50,0x1c,0x4d,0xba,0x24,0xee,0xdf,
|
||||
0xdf,0xb8,0x8e,0x8e])];
|
||||
|
||||
|
||||
var ElgamalpubMPIstrs = [
|
||||
new Uint8Array([0x08,0x00,0xea,0xcc,0xbe,0xe2,0xe4,0x5a,0x51,0x18,0x93,0xa1,0x12,0x2f,0x00,
|
||||
0x99,0x42,0xd8,0x5c,0x1c,0x2f,0xb6,0x3c,0xd9,0x94,0x61,0xb4,0x55,0x8d,0x4e,
|
||||
|
@ -200,13 +200,13 @@ describe('API functional testing', function() {
|
|||
RSAsecMPIs[i] = new openpgp.MPI();
|
||||
RSAsecMPIs[i].read(RSAsecMPIstrs[i]);
|
||||
}
|
||||
|
||||
|
||||
var DSAsecMPIs = [];
|
||||
for (i = 0; i < 1; i++) {
|
||||
DSAsecMPIs[i] = new openpgp.MPI();
|
||||
DSAsecMPIs[i].read(DSAsecMPIstrs[i]);
|
||||
}
|
||||
|
||||
|
||||
var DSApubMPIs = [];
|
||||
for (i = 0; i < 4; i++) {
|
||||
DSApubMPIs[i] = new openpgp.MPI();
|
||||
|
@ -217,7 +217,7 @@ describe('API functional testing', function() {
|
|||
ElgamalsecMPIs[i] = new openpgp.MPI();
|
||||
ElgamalsecMPIs[i].read(ElgamalsecMPIstrs[i]);
|
||||
}
|
||||
|
||||
|
||||
var ElgamalpubMPIs = [];
|
||||
for (i = 0; i < 3; i++) {
|
||||
ElgamalpubMPIs[i] = new openpgp.MPI();
|
||||
|
@ -287,6 +287,25 @@ describe('API functional testing', function() {
|
|||
});
|
||||
}
|
||||
|
||||
function testAESGCM(plaintext) {
|
||||
symmAlgos.forEach(function(algo) {
|
||||
if(algo.substr(0,3) === 'aes') {
|
||||
it(algo, function(done) {
|
||||
var key = openpgp.crypto.generateSessionKey(algo);
|
||||
var iv = openpgp.crypto.random.getRandomValues(new Uint8Array(openpgp.crypto.gcm.ivLength));
|
||||
|
||||
openpgp.crypto.gcm.encrypt(algo, util.str2Uint8Array(plaintext), key, iv).then(function(ciphertext) {
|
||||
return openpgp.crypto.gcm.decrypt(algo, ciphertext, key, iv);
|
||||
}).then(function(decrypted) {
|
||||
var decryptedStr = util.Uint8Array2str(decrypted);
|
||||
expect(decryptedStr).to.equal(plaintext);
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
it("Symmetric with OpenPGP CFB resync", function () {
|
||||
testCFB("hello", true);
|
||||
testCFB("1234567", true);
|
||||
|
@ -301,11 +320,37 @@ describe('API functional testing', function() {
|
|||
testCFB("12345678901234567890123456789012345678901234567890", false);
|
||||
});
|
||||
|
||||
it("asmCrypto AES without OpenPGP CFB resync", function () {
|
||||
testCFB("hello");
|
||||
testCFB("1234567");
|
||||
testCFB("foobarfoobar1234567890");
|
||||
testCFB("12345678901234567890123456789012345678901234567890");
|
||||
it.skip("asmCrypto AES without OpenPGP CFB resync", function () {
|
||||
testAESCFB("hello");
|
||||
testAESCFB("1234567");
|
||||
testAESCFB("foobarfoobar1234567890");
|
||||
testAESCFB("12345678901234567890123456789012345678901234567890");
|
||||
});
|
||||
|
||||
describe('Symmetric AES-GCM (native)', function() {
|
||||
var useNativeVal;
|
||||
beforeEach(function() {
|
||||
useNativeVal = openpgp.config.useNative;
|
||||
openpgp.config.useNative = true;
|
||||
});
|
||||
afterEach(function() {
|
||||
openpgp.config.useNative = useNativeVal;
|
||||
});
|
||||
|
||||
testAESGCM("12345678901234567890123456789012345678901234567890");
|
||||
});
|
||||
|
||||
describe('Symmetric AES-GCM (asm.js fallback)', function() {
|
||||
var useNativeVal;
|
||||
beforeEach(function() {
|
||||
useNativeVal = openpgp.config.useNative;
|
||||
openpgp.config.useNative = false;
|
||||
});
|
||||
afterEach(function() {
|
||||
openpgp.config.useNative = useNativeVal;
|
||||
});
|
||||
|
||||
testAESGCM("12345678901234567890123456789012345678901234567890");
|
||||
});
|
||||
|
||||
it('Asymmetric using RSA with eme_pkcs1 padding', function (done) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user