Add Argon2S2K.reloadWasmModule() for manually triggering memory deallocation (#14)

Also, make `ARGON2_WASM_MEMORY_THRESHOLD_RELOAD`
a static class property, to be able to change its value.
This commit is contained in:
larabr 2024-04-12 10:13:36 +02:00 committed by larabr
parent bec09a16fa
commit 55f8ab2629
3 changed files with 36 additions and 5 deletions

2
openpgp.d.ts vendored
View File

@ -942,6 +942,8 @@ export namespace enums {
}
export declare class Argon2S2K {
static reloadWasmModule(): void;
static ARGON2_WASM_MEMORY_THRESHOLD_RELOAD: number;
constructor(config: Config);
salt: Uint8Array;
/** @throws Argon2OutOfMemoryError */

View File

@ -23,9 +23,26 @@ export class Argon2OutOfMemoryError extends Error {
let loadArgonWasmModule;
let argon2Promise;
// reload wasm module above this treshold, to deallocated used memory
const ARGON2_WASM_MEMORY_THRESHOLD_RELOAD = 2 << 19;
// (cannot be declared as a simple `static` field as its not supported by Safari 14)
let ARGON2_WASM_MEMORY_THRESHOLD_RELOAD = 2 << 19;
class Argon2S2K {
static get ARGON2_WASM_MEMORY_THRESHOLD_RELOAD() {
return ARGON2_WASM_MEMORY_THRESHOLD_RELOAD;
}
static set ARGON2_WASM_MEMORY_THRESHOLD_RELOAD(memoryThreshold) {
ARGON2_WASM_MEMORY_THRESHOLD_RELOAD = memoryThreshold;
}
static reloadWasmModule() {
if (!loadArgonWasmModule) return;
// it will be awaited if needed at the next `produceKey` invocation
argon2Promise = loadArgonWasmModule();
argon2Promise.catch(() => {});
}
/**
* @param {Object} [config] - Full configuration, defaults to openpgp.config
*/
@ -125,10 +142,8 @@ class Argon2S2K {
});
// a lot of memory was used, reload to deallocate
if (decodedM > ARGON2_WASM_MEMORY_THRESHOLD_RELOAD) {
// it will be awaited if needed at the next `produceKey` invocation
argon2Promise = loadArgonWasmModule();
argon2Promise.catch(() => {});
if (decodedM > Argon2S2K.ARGON2_WASM_MEMORY_THRESHOLD_RELOAD) {
Argon2S2K.reloadWasmModule();
}
return hash;
} catch (e) {

View File

@ -335,6 +335,20 @@ class MemoryBenchamrkSuite {
await decryptedData.pipeTo(sink);
});
suite.add('openpgp.encrypt/decryptSessionKeys (argon2)', async () => {
const config = { s2kType: openpgp.enums.s2k.argon2 };
const passwords = 'password';
const sessionKey = {
algorithm: 'aes128',
data: require('crypto').getRandomValues(new Uint8Array(16))
};
const encrypted = await openpgp.encryptSessionKey({ ...sessionKey, passwords, config, format: 'object' });
assert(encrypted.packets.length === 1);
const skesk = encrypted.packets[0];
assert(skesk.s2k.type === 'argon2');
await openpgp.decryptSessionKeys({ message: encrypted, passwords });
});
const stats = await suite.run();
// Print JSON stats to stdout
console.log(JSON.stringify(stats, null, 4));