Drop asmcrypto.js for AES_KW in favor of noble-ciphers

This commit is contained in:
larabr 2024-08-09 14:50:24 +02:00
parent e8de7d76db
commit 1377644fb4

View File

@ -21,7 +21,7 @@
* @module crypto/aes_kw * @module crypto/aes_kw
*/ */
import { AES_CBC } from '@openpgp/asmcrypto.js/aes/cbc.js'; import { aeskw as nobleAesKW } from '@noble/ciphers/aes';
import { getCipherParams } from './cipher'; import { getCipherParams } from './cipher';
import util from '../util'; import util from '../util';
@ -55,7 +55,7 @@ export async function wrap(algo, key, dataToWrap) {
util.printDebugError('Browser did not support operation: ' + err.message); util.printDebugError('Browser did not support operation: ' + err.message);
} }
return asmcryptoWrap(algo, key, dataToWrap); return nobleAesKW(key).encrypt(dataToWrap);
} }
/** /**
@ -82,7 +82,7 @@ export async function unwrap(algo, key, wrappedData) {
throw err; throw err;
} }
util.printDebugError('Browser did not support operation: ' + err.message); util.printDebugError('Browser did not support operation: ' + err.message);
return asmcryptoUnwrap(algo, key, wrappedData); return nobleAesKW(key).decrypt(wrappedData);
} }
try { try {
@ -95,95 +95,3 @@ export async function unwrap(algo, key, wrappedData) {
throw err; throw err;
} }
} }
function asmcryptoWrap(aesAlgo, key, data) {
const aesInstance = new AES_CBC(key, new Uint8Array(16), false);
const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]);
const P = unpack(data);
let A = IV;
const R = P;
const n = P.length / 2;
const t = new Uint32Array([0, 0]);
let B = new Uint32Array(4);
for (let j = 0; j <= 5; ++j) {
for (let i = 0; i < n; ++i) {
t[1] = n * j + (1 + i);
// B = A
B[0] = A[0];
B[1] = A[1];
// B = A || R[i]
B[2] = R[2 * i];
B[3] = R[2 * i + 1];
// B = AES(K, B)
B = unpack(aesInstance.encrypt(pack(B)));
// A = MSB(64, B) ^ t
A = B.subarray(0, 2);
A[0] ^= t[0];
A[1] ^= t[1];
// R[i] = LSB(64, B)
R[2 * i] = B[2];
R[2 * i + 1] = B[3];
}
}
return pack(A, R);
}
function asmcryptoUnwrap(aesAlgo, key, data) {
const aesInstance = new AES_CBC(key, new Uint8Array(16), false);
const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]);
const C = unpack(data);
let A = C.subarray(0, 2);
const R = C.subarray(2);
const n = C.length / 2 - 1;
const t = new Uint32Array([0, 0]);
let B = new Uint32Array(4);
for (let j = 5; j >= 0; --j) {
for (let i = n - 1; i >= 0; --i) {
t[1] = n * j + (i + 1);
// B = A ^ t
B[0] = A[0] ^ t[0];
B[1] = A[1] ^ t[1];
// B = (A ^ t) || R[i]
B[2] = R[2 * i];
B[3] = R[2 * i + 1];
// B = AES-1(B)
B = unpack(aesInstance.decrypt(pack(B)));
// A = MSB(64, B)
A = B.subarray(0, 2);
// R[i] = LSB(64, B)
R[2 * i] = B[2];
R[2 * i + 1] = B[3];
}
}
if (A[0] === IV[0] && A[1] === IV[1]) {
return pack(R);
}
throw new Error('Key Data Integrity failed');
}
function unpack(data) {
const buffer = data.buffer;
const view = new DataView(buffer);
const arr = new Uint32Array(data.length / 4);
for (let i = 0; i < data.length / 4; ++i) {
arr[i] = view.getUint32(4 * i);
}
return arr;
}
function pack() {
let length = 0;
for (let k = 0; k < arguments.length; ++k) {
length += 4 * arguments[k].length;
}
const buffer = new ArrayBuffer(length);
const view = new DataView(buffer);
let offset = 0;
for (let i = 0; i < arguments.length; ++i) {
for (let j = 0; j < arguments[i].length; ++j) {
view.setUint32(offset + 4 * j, arguments[i][j]);
}
offset += 4 * arguments[i].length;
}
return new Uint8Array(buffer);
}