Import legacy ciphers (CAST5, TwoFish, BlowFish, DES) only on demand (#1723)

This primarily affects the lightweight build, which will not include these
(fairly large) modules in the main bundle file.
This commit is contained in:
larabr 2024-02-26 15:37:50 +01:00 committed by GitHub
parent b413a113f9
commit db15f6d6a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 158 additions and 149 deletions

View File

@ -21,7 +21,7 @@
* @module crypto/aes_kw
*/
import * as cipher from './cipher';
import { getCipher } from './cipher';
import util from '../util';
/**
@ -31,8 +31,9 @@ import util from '../util';
* @param {Uint8Array} data
* @returns {Uint8Array}
*/
export function wrap(key, data) {
const aes = new cipher['aes' + (key.length * 8)](key);
export async function wrap(algo, key, data) {
const Cipher = await getCipher(algo);
const aes = new Cipher(key);
const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]);
const P = unpack(data);
let A = IV;
@ -71,8 +72,9 @@ export function wrap(key, data) {
* @returns {Uint8Array}
* @throws {Error}
*/
export function unwrap(key, data) {
const aes = new cipher['aes' + (key.length * 8)](key);
export async function unwrap(algo, key, data) {
const Cipher = await getCipher(algo);
const aes = new Cipher(key);
const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]);
const C = unpack(data);
let A = C.subarray(0, 2);

View File

@ -1,13 +0,0 @@
import * as cipher from '.';
import enums from '../../enums';
/**
* Get implementation of the given cipher
* @param {enums.symmetric} algo
* @returns {Object}
* @throws {Error} on invalid algo
*/
export default function getCipher(algo) {
const algoName = enums.read(enums.symmetric, algo);
return cipher[algoName];
}

View File

@ -1,80 +1,73 @@
/**
* @fileoverview Symmetric cryptography functions
* @module crypto/cipher
*/
import aes from './aes'; // can be imported dynamically once Web Crypto is used for AES-KW too
import enums from '../../enums';
import aes from './aes';
import { DES, TripleDES } from './des';
import CAST5 from './cast5';
import TF from './twofish';
import BF from './blowfish';
export async function getCipher(algo) {
switch (algo) {
case enums.symmetric.aes128:
case enums.symmetric.aes192:
case enums.symmetric.aes256:
return aes(getCipherKeySize(algo));
case enums.symmetric.cast5:
case enums.symmetric.blowfish:
case enums.symmetric.twofish:
case enums.symmetric.tripledes: {
const { legacyCiphers } = await import('./legacy_ciphers');
const cipher = legacyCiphers.get(algo);
if (!cipher) {
throw new Error('Unsupported cipher algorithm');
}
return cipher;
}
default:
throw new Error('Unsupported cipher algorithm');
}
}
/**
* AES-128 encryption and decryption (ID 7)
* @function
* @param {String} key - 128-bit key
* @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto}
* @see {@link https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf|NIST FIPS-197}
* @returns {Object}
* Get block size for given cipher algo
* @param {module:enums.symmetric} algo - alrogithm identifier
*/
export const aes128 = aes(128);
function getCipherBlockSize(algo) {
switch (algo) {
case enums.symmetric.aes128:
case enums.symmetric.aes192:
case enums.symmetric.aes256:
case enums.symmetric.twofish:
return 16;
case enums.symmetric.blowfish:
case enums.symmetric.cast5:
case enums.symmetric.tripledes:
return 8;
default:
throw new Error('Unsupported cipher');
}
}
/**
* AES-128 Block Cipher (ID 8)
* @function
* @param {String} key - 192-bit key
* @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto}
* @see {@link https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf|NIST FIPS-197}
* @returns {Object}
* Get key size for given cipher algo
* @param {module:enums.symmetric} algo - alrogithm identifier
*/
export const aes192 = aes(192);
function getCipherKeySize(algo) {
switch (algo) {
case enums.symmetric.aes128:
case enums.symmetric.blowfish:
case enums.symmetric.cast5:
return 16;
case enums.symmetric.aes192:
case enums.symmetric.tripledes:
return 24;
case enums.symmetric.aes256:
case enums.symmetric.twofish:
return 32;
default:
throw new Error('Unsupported cipher');
}
}
/**
* AES-128 Block Cipher (ID 9)
* @function
* @param {String} key - 256-bit key
* @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto}
* @see {@link https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf|NIST FIPS-197}
* @returns {Object}
* Get block and key size for given cipher algo
* @param {module:enums.symmetric} algo - alrogithm identifier
*/
export const aes256 = aes(256);
// Not in OpenPGP specifications
export const des = DES;
/**
* Triple DES Block Cipher (ID 2)
* @function
* @param {String} key - 192-bit key
* @see {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-67r2.pdf|NIST SP 800-67}
* @returns {Object}
*/
export const tripledes = TripleDES;
/**
* CAST-128 Block Cipher (ID 3)
* @function
* @param {String} key - 128-bit key
* @see {@link https://tools.ietf.org/html/rfc2144|The CAST-128 Encryption Algorithm}
* @returns {Object}
*/
export const cast5 = CAST5;
/**
* Twofish Block Cipher (ID 10)
* @function
* @param {String} key - 256-bit key
* @see {@link https://tools.ietf.org/html/rfc4880#ref-TWOFISH|TWOFISH}
* @returns {Object}
*/
export const twofish = TF;
/**
* Blowfish Block Cipher (ID 4)
* @function
* @param {String} key - 128-bit key
* @see {@link https://tools.ietf.org/html/rfc4880#ref-BLOWFISH|BLOWFISH}
* @returns {Object}
*/
export const blowfish = BF;
/**
* Not implemented
* @function
* @throws {Error}
*/
export const idea = function() {
throw new Error('IDEA symmetric-key algorithm not implemented');
};
export function getCipherParams(algo) {
return { keySize: getCipherKeySize(algo), blockSize: getCipherBlockSize(algo) };
}

View File

@ -0,0 +1,17 @@
/**
* This file is needed to dynamic import the legacy ciphers.
* Separate dynamic imports are not convenient as they result in multiple chunks.
*/
import { TripleDES } from './des';
import CAST5 from './cast5';
import TwoFish from './twofish';
import BlowFish from './blowfish';
import enums from '../../enums';
export const legacyCiphers = new Map([
[enums.symmetric.tripledes, TripleDES],
[enums.symmetric.cast5, CAST5],
[enums.symmetric.blowfish, BlowFish],
[enums.symmetric.twofish, TwoFish]
]);

View File

@ -26,7 +26,7 @@
import publicKey from './public_key';
import mode from './mode';
import { getRandomBytes } from './random';
import getCipher from './cipher/getCipher';
import { getCipher, getCipherParams } from './cipher';
import ECDHSymkey from '../type/ecdh_symkey';
import KDFParams from '../type/kdf_params';
import enums from '../enums';
@ -442,7 +442,7 @@ export async function validateParams(algo, publicParams, privateParams) {
* @async
*/
export async function getPrefixRandom(algo) {
const { blockSize } = getCipher(algo);
const { blockSize } = getCipherParams(algo);
const prefixrandom = await getRandomBytes(blockSize);
const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]);
return util.concat([prefixrandom, repeat]);
@ -455,7 +455,7 @@ export async function getPrefixRandom(algo) {
* @returns {Uint8Array} Random bytes as a string to be used as a key.
*/
export function generateSessionKey(algo) {
const { keySize } = getCipher(algo);
const { keySize } = getCipherParams(algo);
return getRandomBytes(keySize);
}
@ -470,8 +470,6 @@ export function getAEADMode(algo) {
return mode[algoName];
}
export { getCipher };
/**
* Check whether the given curve OID is supported
* @param {module:type/oid} oid - EC object identifier
@ -524,3 +522,6 @@ export function getPreferredCurveHashAlgo(algo, oid) {
throw new Error('Unknown elliptic signing algo');
}
}
export { getCipher, getCipherParams };

View File

@ -23,9 +23,9 @@
import { AES_CFB } from '@openpgp/asmcrypto.js/aes/cfb.js';
import * as stream from '@openpgp/web-stream-tools';
import getCipher from '../cipher/getCipher';
import util from '../../util';
import enums from '../../enums';
import { getCipher, getCipherParams } from '../cipher';
const webCrypto = util.getWebCrypto();
const nodeCrypto = util.getNodeCrypto();
@ -60,7 +60,7 @@ export async function encrypt(algo, key, plaintext, iv, config) {
return aesEncrypt(algo, key, plaintext, iv, config);
}
const Cipher = getCipher(algo);
const Cipher = await getCipher(algo);
const cipherfn = new Cipher(key);
const block_size = cipherfn.blockSize;
@ -103,7 +103,7 @@ export async function decrypt(algo, key, ciphertext, iv) {
return aesDecrypt(algo, key, ciphertext, iv);
}
const Cipher = getCipher(algo);
const Cipher = await getCipher(algo);
const cipherfn = new Cipher(key);
const block_size = cipherfn.blockSize;
@ -131,7 +131,7 @@ export async function decrypt(algo, key, ciphertext, iv) {
class WebCryptoEncryptor {
constructor(algo, key, iv) {
const { blockSize } = getCipher(algo);
const { blockSize } = getCipherParams(algo);
this.key = key;
this.prevBlock = iv;
this.nextBlock = new Uint8Array(blockSize);
@ -141,7 +141,7 @@ class WebCryptoEncryptor {
}
static async isSupported(algo) {
const { keySize } = getCipher(algo);
const { keySize } = getCipherParams(algo);
return webCrypto.importKey('raw', new Uint8Array(keySize), 'aes-cbc', false, ['encrypt'])
.then(() => true, () => false);
}

View File

@ -20,9 +20,8 @@
* @module crypto/mode/ocb
*/
import * as ciphers from '../cipher';
import { getCipher } from '../cipher';
import util from '../../util';
import enums from '../../enums';
const blockLength = 16;
const ivLength = 15;
@ -68,11 +67,11 @@ async function OCB(cipher, key) {
let decipher;
let mask;
constructKeyVariables(cipher, key);
await constructKeyVariables(cipher, key);
function constructKeyVariables(cipher, key) {
const cipherName = enums.read(enums.symmetric, cipher);
const aes = new ciphers[cipherName](key);
async function constructKeyVariables(cipher, key) {
const Cipher = await getCipher(cipher);
const aes = new Cipher(key);
encipher = aes.encrypt.bind(aes);
decipher = aes.decrypt.bind(aes);

View File

@ -29,7 +29,7 @@ import enums from '../../../enums';
import util from '../../../util';
import { b64ToUint8Array } from '../../../encoding/base64';
import * as pkcs5 from '../../pkcs5';
import getCipher from '../../cipher/getCipher';
import { getCipherParams } from '../../cipher';
const webCrypto = util.getWebCrypto();
const nodeCrypto = util.getNodeCrypto();
@ -133,9 +133,9 @@ export async function encrypt(oid, kdfParams, data, Q, fingerprint) {
const curve = new CurveWithOID(oid);
const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q);
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
const { keySize } = getCipher(kdfParams.cipher);
const { keySize } = getCipherParams(kdfParams.cipher);
const Z = await kdf(kdfParams.hash, sharedKey, keySize, param);
const wrappedKey = aesKW.wrap(Z, m);
const wrappedKey = await aesKW.wrap(kdfParams.cipher, Z, m);
return { publicKey, wrappedKey };
}
@ -195,13 +195,13 @@ export async function decrypt(oid, kdfParams, V, C, Q, d, fingerprint) {
const curve = new CurveWithOID(oid);
const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d);
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
const { keySize } = getCipher(kdfParams.cipher);
const { keySize } = getCipherParams(kdfParams.cipher);
let err;
for (let i = 0; i < 3; i++) {
try {
// Work around old go crypto bug and old OpenPGP.js bug, respectively.
const Z = await kdf(kdfParams.hash, sharedKey, keySize, param, i === 1, i === 2);
return pkcs5.decode(aesKW.unwrap(Z, C));
return pkcs5.decode(await aesKW.unwrap(kdfParams.cipher, Z, C));
} catch (e) {
err = e;
}

View File

@ -9,8 +9,8 @@ import { getRandomBytes } from '../../random';
import enums from '../../../enums';
import util from '../../../util';
import getCipher from '../../cipher/getCipher';
import computeHKDF from '../../hkdf';
import { getCipherParams } from '../../cipher';
const HKDF_INFO = {
x25519: util.encodeUTF8('OpenPGP X25519'),
@ -97,9 +97,10 @@ export async function encrypt(algo, data, recipientA) {
recipientA,
sharedSecret
]);
const { keySize } = getCipher(enums.symmetric.aes128);
const cipherAlgo = enums.symmetric.aes128;
const { keySize } = getCipherParams(cipherAlgo);
const encryptionKey = await computeHKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize);
const wrappedKey = aesKW.wrap(encryptionKey, data);
const wrappedKey = await aesKW.wrap(cipherAlgo, encryptionKey, data);
return { ephemeralPublicKey, wrappedKey };
}
case enums.publicKey.x448: {
@ -112,9 +113,10 @@ export async function encrypt(algo, data, recipientA) {
recipientA,
sharedSecret
]);
const { keySize } = getCipher(enums.symmetric.aes256);
const cipherAlgo = enums.symmetric.aes256;
const { keySize } = getCipherParams(enums.symmetric.aes256);
const encryptionKey = await computeHKDF(enums.hash.sha512, hkdfInput, new Uint8Array(), HKDF_INFO.x448, keySize);
const wrappedKey = aesKW.wrap(encryptionKey, data);
const wrappedKey = await aesKW.wrap(cipherAlgo, encryptionKey, data);
return { ephemeralPublicKey, wrappedKey };
}
@ -143,9 +145,10 @@ export async function decrypt(algo, ephemeralPublicKey, wrappedKey, A, k) {
A,
sharedSecret
]);
const { keySize } = getCipher(enums.symmetric.aes128);
const cipherAlgo = enums.symmetric.aes128;
const { keySize } = getCipherParams(cipherAlgo);
const encryptionKey = await computeHKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize);
return aesKW.unwrap(encryptionKey, wrappedKey);
return aesKW.unwrap(cipherAlgo, encryptionKey, wrappedKey);
}
case enums.publicKey.x448: {
const x448 = await util.getNobleCurve(enums.publicKey.x448);
@ -155,9 +158,10 @@ export async function decrypt(algo, ephemeralPublicKey, wrappedKey, A, k) {
A,
sharedSecret
]);
const { keySize } = getCipher(enums.symmetric.aes256);
const cipherAlgo = enums.symmetric.aes256;
const { keySize } = getCipherParams(enums.symmetric.aes256);
const encryptionKey = await computeHKDF(enums.hash.sha512, hkdfInput, new Uint8Array(), HKDF_INFO.x448, keySize);
return aesKW.unwrap(encryptionKey, wrappedKey);
return aesKW.unwrap(cipherAlgo, encryptionKey, wrappedKey);
}
default:
throw new Error('Unsupported ECDH algorithm');

View File

@ -174,7 +174,7 @@ class SecretKeyPacket extends PublicKeyPacket {
if (this.s2kUsage !== 253 || this.isLegacyAEAD) {
this.iv = bytes.subarray(
i,
i + crypto.getCipher(this.symmetric).blockSize
i + crypto.getCipherParams(this.symmetric).blockSize
);
this.usedModernAEAD = false;
} else {
@ -388,7 +388,7 @@ class SecretKeyPacket extends PublicKeyPacket {
const cleartext = crypto.serializeParams(this.algorithm, this.privateParams);
this.symmetric = enums.symmetric.aes256;
const { blockSize } = crypto.getCipher(this.symmetric);
const { blockSize } = crypto.getCipherParams(this.symmetric);
if (config.aeadProtect) {
this.s2kUsage = 253;
@ -568,7 +568,7 @@ class SecretKeyPacket extends PublicKeyPacket {
* @returns encryption key
*/
async function produceEncryptionKey(keyVersion, s2k, passphrase, cipherAlgo, aeadMode, serializedPacketTag, isLegacyAEAD) {
const { keySize } = crypto.getCipher(cipherAlgo);
const { keySize } = crypto.getCipherParams(cipherAlgo);
const derivedKey = await s2k.produceKey(passphrase, keySize);
if (!aeadMode || keyVersion === 5 || isLegacyAEAD) {
return derivedKey;

View File

@ -138,7 +138,7 @@ class SymEncryptedIntegrityProtectedDataPacket {
this.chunkSizeByte = config.aeadChunkSizeByte;
this.encrypted = await runAEAD(this, 'encrypt', key, bytes);
} else {
const { blockSize } = crypto.getCipher(sessionKeyAlgorithm);
const { blockSize } = crypto.getCipherParams(sessionKeyAlgorithm);
const prefix = await crypto.getPrefixRandom(sessionKeyAlgorithm);
const mdc = new Uint8Array([0xD3, 0x14]); // modification detection code packet
@ -169,7 +169,7 @@ class SymEncryptedIntegrityProtectedDataPacket {
if (this.version === 2) {
packetbytes = await runAEAD(this, 'decrypt', key, encrypted);
} else {
const { blockSize } = crypto.getCipher(sessionKeyAlgorithm);
const { blockSize } = crypto.getCipherParams(sessionKeyAlgorithm);
const decrypted = await crypto.mode.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(blockSize));
// there must be a modification detection code packet as the
@ -231,7 +231,7 @@ export async function runAEAD(packet, fn, key, data) {
let iv;
let ivView;
if (isSEIPDv2) {
const { keySize } = crypto.getCipher(packet.cipherAlgorithm);
const { keySize } = crypto.getCipherParams(packet.cipherAlgorithm);
const { ivLength } = mode;
const info = new Uint8Array(adataBuffer, 0, 5);
const derived = await computeHKDF(enums.hash.sha256, key, packet.salt, info, keySize + ivLength);

View File

@ -163,7 +163,7 @@ class SymEncryptedSessionKeyPacket {
this.sessionKeyEncryptionAlgorithm :
this.sessionKeyAlgorithm;
const { blockSize, keySize } = crypto.getCipher(algo);
const { blockSize, keySize } = crypto.getCipherParams(algo);
const key = await this.s2k.produceKey(passphrase, keySize);
if (this.version >= 5) {
@ -199,7 +199,7 @@ class SymEncryptedSessionKeyPacket {
this.s2k = newS2KFromConfig(config);
this.s2k.generateSalt();
const { blockSize, keySize } = crypto.getCipher(algo);
const { blockSize, keySize } = crypto.getCipherParams(algo);
const key = await this.s2k.produceKey(passphrase, keySize);
if (this.sessionKey === null) {

View File

@ -86,7 +86,7 @@ class SymmetricallyEncryptedDataPacket {
throw new Error('Message is not authenticated.');
}
const { blockSize } = crypto.getCipher(sessionKeyAlgorithm);
const { blockSize } = crypto.getCipherParams(sessionKeyAlgorithm);
const encrypted = await stream.readToEnd(stream.clone(this.encrypted));
const decrypted = await crypto.mode.cfb.decrypt(sessionKeyAlgorithm, key,
encrypted.subarray(blockSize + 2),
@ -107,7 +107,7 @@ class SymmetricallyEncryptedDataPacket {
*/
async encrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
const data = this.packets.write();
const { blockSize } = crypto.getCipher(sessionKeyAlgorithm);
const { blockSize } = crypto.getCipherParams(sessionKeyAlgorithm);
const prefix = await crypto.getPrefixRandom(sessionKeyAlgorithm);
const FRE = await crypto.mode.cfb.encrypt(sessionKeyAlgorithm, key, prefix, new Uint8Array(blockSize), config);

View File

@ -2,41 +2,48 @@ import { expect } from 'chai';
import * as aesKW from '../../src/crypto/aes_kw.js';
import util from '../../src/util.js';
import enums from '../../src/enums.js';
export default () => describe('AES Key Wrap and Unwrap', function () {
const test_vectors = [
[
'128 bits of Key Data with a 128-bit KEK',
enums.symmetric.aes128,
'000102030405060708090A0B0C0D0E0F',
'00112233445566778899AABBCCDDEEFF',
'1FA68B0A8112B447 AEF34BD8FB5A7B82 9D3E862371D2CFE5'
],
[
'128 bits of Key Data with a 192-bit KEK',
enums.symmetric.aes192,
'000102030405060708090A0B0C0D0E0F1011121314151617',
'00112233445566778899AABBCCDDEEFF',
'96778B25AE6CA435 F92B5B97C050AED2 468AB8A17AD84E5D'
],
[
'128 bits of Key Data with a 256-bit KEK',
enums.symmetric.aes256,
'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F',
'00112233445566778899AABBCCDDEEFF',
'64E8C3F9CE0F5BA2 63E9777905818A2A 93C8191E7D6E8AE7'
],
[
'192 bits of Key Data with a 192-bit KEK',
enums.symmetric.aes192,
'000102030405060708090A0B0C0D0E0F1011121314151617',
'00112233445566778899AABBCCDDEEFF0001020304050607',
'031D33264E15D332 68F24EC260743EDC E1C6C7DDEE725A93 6BA814915C6762D2'
],
[
'192 bits of Key Data with a 256-bit KEK',
enums.symmetric.aes256,
'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F',
'00112233445566778899AABBCCDDEEFF0001020304050607',
'A8F9BC1612C68B3F F6E6F4FBE30E71E4 769C8B80A32CB895 8CD5D17D6B254DA1'
],
[
'256 bits of Key Data with a 256-bit KEK',
enums.symmetric.aes256,
'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F',
'00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F',
'28C9F404C4B810F4 CBCCB35CFB87F826 3F5786E2D80ED326 CBC7F0E71A99F43B FB988B9B7A02DD21'
@ -44,15 +51,15 @@ export default () => describe('AES Key Wrap and Unwrap', function () {
];
test_vectors.forEach(function(test) {
it(test[0], function(done) {
const kek = util.hexToUint8Array(test[1]);
const input = test[2].replace(/\s/g, '');
it(test[0], async function() {
const algo = test[1];
const kek = util.hexToUint8Array(test[2]);
const input = test[3].replace(/\s/g, '');
const input_bin = util.uint8ArrayToString(util.hexToUint8Array(input));
const output = test[3].replace(/\s/g, '');
const output = test[4].replace(/\s/g, '');
const output_bin = util.uint8ArrayToString(util.hexToUint8Array(output));
expect(util.uint8ArrayToHex(aesKW.wrap(kek, input_bin)).toUpperCase()).to.equal(output);
expect(util.uint8ArrayToHex(aesKW.unwrap(kek, output_bin)).toUpperCase()).to.equal(input);
done();
expect(util.uint8ArrayToHex(await aesKW.wrap(algo, kek, input_bin)).toUpperCase()).to.equal(output);
expect(util.uint8ArrayToHex(await aesKW.unwrap(algo, kek, output_bin)).toUpperCase()).to.equal(input);
});
});
});

View File

@ -1,9 +1,11 @@
import { expect } from 'chai';
import { aes128 as AES128 } from '../../../src/crypto/cipher';
import enums from '../../../src/enums';
import { getCipher } from '../../../src/crypto/cipher';
export default () => describe('AES Rijndael cipher test with test vectors from ecb_tbl.txt', function() {
function test_aes(input, key, output) {
async function test_aes(input, key, output) {
const AES128 = await getCipher(enums.symmetric.aes128);
const aes = new AES128(new Uint8Array(key));
const encrypted = aes.encrypt(new Uint8Array(input));
@ -61,24 +63,21 @@ export default () => describe('AES Rijndael cipher test with test vectors from e
[[0x08,0x09,0x0A,0x0B,0x0D,0x0E,0x0F,0x10,0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1A,0x1C,0x1D,0x1E,0x1F,0x21,0x22,0x23,0x24,0x26,0x27,0x28,0x29,0x2B,0x2C,0x2D,0x2E],[0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21],[0x08,0x0E,0x95,0x17,0xEB,0x16,0x77,0x71,0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3]],
[[0x30,0x31,0x32,0x33,0x35,0x36,0x37,0x38,0x3A,0x3B,0x3C,0x3D,0x3F,0x40,0x41,0x42,0x44,0x45,0x46,0x47,0x49,0x4A,0x4B,0x4C,0x4E,0x4F,0x50,0x51,0x53,0x54,0x55,0x56],[0x72,0x61,0x65,0xC1,0x72,0x3F,0xBC,0xF6,0xC0,0x26,0xD7,0xD0,0x0B,0x09,0x10,0x27],[0x7C,0x17,0x00,0x21,0x1A,0x39,0x91,0xFC,0x0E,0xCD,0xED,0x0A,0xB3,0xE5,0x76,0xB0]]];
it('128 bit key', function (done) {
it('128 bit key', async function () {
for (let i = 0; i < testvectors128.length; i++) {
test_aes(testvectors128[i][1],testvectors128[i][0],testvectors128[i][2]);
await test_aes(testvectors128[i][1],testvectors128[i][0],testvectors128[i][2]);
}
done();
});
it('192 bit key', function (done) {
it('192 bit key', async function () {
for (let i = 0; i < testvectors192.length; i++) {
test_aes(testvectors192[i][1],testvectors192[i][0],testvectors192[i][2]);
await test_aes(testvectors192[i][1],testvectors192[i][0],testvectors192[i][2]);
}
done();
});
it('256 bit key', function (done) {
it('256 bit key', async function () {
for (let i = 0; i < testvectors256.length; i++) {
test_aes(testvectors256[i][1],testvectors256[i][0],testvectors256[i][2]);
await test_aes(testvectors256[i][1],testvectors256[i][0],testvectors256[i][2]);
}
done();
});
});

View File

@ -254,7 +254,7 @@ export default () => describe('API functional testing', function() {
async function testCFB(plaintext, config = openpgp.config) {
await Promise.all(symmAlgoNames.map(async function(algoName) {
const algo = openpgp.enums.write(openpgp.enums.symmetric, algoName);
const { blockSize } = crypto.getCipher(algo);
const { blockSize } = crypto.getCipherParams(algo);
const symmKey = crypto.generateSessionKey(algo);
const IV = new Uint8Array(blockSize);
const symmencData = await crypto.mode.cfb.encrypt(algo, symmKey, util.stringToUint8Array(plaintext), IV, config);