UNPKG

k9crypt

Version:

A special encryption algorithm created for K9Crypt.

83 lines (71 loc) 3.08 kB
const { PAYLOAD_MAGIC, PAYLOAD_VERSION_V2, PAYLOAD_VERSION_V3, PAYLOAD_VERSION_V4, PAYLOAD_VERSION_V5, PAYLOAD_HEADER_SIZE, PAYLOAD_HEADER_SIZE_V5, SALT_SIZE, IV_SIZE, IV_SIZE_V5, TAG_SIZE, ARGON2_SALT_SIZE, ARGON2_HASH_LENGTH, MIN_PAYLOAD_SIZE, MIN_V2_PAYLOAD_SIZE, MIN_V5_PAYLOAD_SIZE } = require('../../constants'); const { parseHeader } = require('./header'); exports.parsePayload = (data) => { if (!Buffer.isBuffer(data)) throw new TypeError('payload data must be a Buffer'); const vb = data.length >= 5 ? data[4] : 0; const hasMagic = data.length >= 4 && data.subarray(0, 4).equals(PAYLOAD_MAGIC); // V5 if (hasMagic && vb === PAYLOAD_VERSION_V5) { if (data.length < MIN_V5_PAYLOAD_SIZE) throw new Error('Payload too small'); const hdr = data.subarray(0, PAYLOAD_HEADER_SIZE_V5); const tm = parseHeader(hdr); const to = data.length - 80; // ARGON2_HASH_LENGTH + ARGON2_SALT_SIZE const to2 = to - TAG_SIZE; const so = PAYLOAD_HEADER_SIZE_V5; const io = so + SALT_SIZE; const co = io + IV_SIZE_V5; return { version: PAYLOAD_VERSION_V5, header: hdr, timeMetadata: tm, body: data.subarray(0, to), salt: data.subarray(so, io), iv: data.subarray(io, co), ciphertext: data.subarray(co, to2), tag: data.subarray(to2, to), integritySalt: data.subarray(to, to + 16), dataHash: data.subarray(to + 16) }; } // V2-V4 if (hasMagic && (vb === PAYLOAD_VERSION_V2 || vb === PAYLOAD_VERSION_V3 || vb === PAYLOAD_VERSION_V4)) { if (data.length < MIN_V2_PAYLOAD_SIZE) throw new Error('Payload too small'); const hdr = data.subarray(0, PAYLOAD_HEADER_SIZE); const tm = parseHeader(hdr); const to = data.length - 80; const to2 = to - TAG_SIZE; const so = PAYLOAD_HEADER_SIZE; const io = so + SALT_SIZE; const eo = io + 5 * IV_SIZE; return { version: tm.version, header: hdr, timeMetadata: tm, body: data.subarray(0, to), salt: data.subarray(so, io), iv1: data.subarray(io, io + 16), iv2: data.subarray(io + 16, io + 32), iv3: data.subarray(io + 32, io + 48), iv4: data.subarray(io + 48, io + 64), iv5: data.subarray(io + 64, io + 80), encrypted: data.subarray(eo, to2), tag1: data.subarray(to2, to), argon2Salt: data.subarray(to, to + 16), dataHash: data.subarray(to + 16) }; } // V1 legacy (no header) if (data.length < MIN_PAYLOAD_SIZE) throw new Error('Payload too small'); const to = data.length - 80; const to2 = to - TAG_SIZE; const io = SALT_SIZE; const eo = io + 5 * IV_SIZE; return { version: 1, header: null, timeMetadata: null, body: data.subarray(0, to), salt: data.subarray(0, SALT_SIZE), iv1: data.subarray(io, io + 16), iv2: data.subarray(io + 16, io + 32), iv3: data.subarray(io + 32, io + 48), iv4: data.subarray(io + 48, io + 64), iv5: data.subarray(io + 64, io + 80), encrypted: data.subarray(eo, to2), tag1: data.subarray(to2, to), argon2Salt: data.subarray(to, to + 16), dataHash: data.subarray(to + 16) }; };