Changeset View
Changeset View
Standalone View
Standalone View
lib/utils/pkcs7-padding.test.js
// @flow | // @flow | ||||
import { | import type { PaddingConfiguration } from './pkcs7-padding'; | ||||
pkcs7pad, | import { pad, unpad, testing } from './pkcs7-padding.js'; | ||||
pkcs7unpad, | |||||
superblockPad, | const { pkcs7pad, pkcs7unpad, superblockPad, superblockUnpad } = testing; | ||||
superblockUnpad, | |||||
} from './pkcs7-padding.js'; | |||||
describe('PKCS#7 Padding', () => { | describe('PKCS#7 Padding', () => { | ||||
it('should pad data to a multiple of blockSize bytes', () => { | it('should pad data to a multiple of blockSize bytes', () => { | ||||
const blockSize = 16; | const blockSize = 16; | ||||
const data = generateRandomData(100); | const data = generateRandomData(100); | ||||
const expectedPadding = 16 - (data.length % blockSize); | const expectedPadding = 16 - (data.length % blockSize); | ||||
const padded = pkcs7pad(data, blockSize); | const padded = pkcs7pad(data, blockSize); | ||||
▲ Show 20 Lines • Show All 133 Lines • ▼ Show 20 Lines | const padded = new Uint8Array([ | ||||
...generateRandomArray(2 * 16), | ...generateRandomArray(2 * 16), | ||||
...generateRandomArray(2 * 15), | ...generateRandomArray(2 * 15), | ||||
...[1], | ...[1], | ||||
]); | ]); | ||||
expect(() => superblockUnpad(padded, blockSizeBytes)).toThrow(); | expect(() => superblockUnpad(padded, blockSizeBytes)).toThrow(); | ||||
}); | }); | ||||
}); | }); | ||||
describe('padding integration tests (pad and unpad)', () => { | |||||
it('should pad data to a multiple of superblockSize blocks', () => { | |||||
const config: PaddingConfiguration = { | |||||
blockSizeBytes: 16, | |||||
superblockSizeBlocks: 4, | |||||
}; | |||||
// 20 bytes of data - expected 4 blocks total (1 superblock): | |||||
// - block 1 (16 bytes) = 16 bytes of data | |||||
// - block 2 (16 bytes) = 4 bytes of data (remaining 12 bytes of padding) | |||||
// - block 3 (16 bytes) = full padding (filled with 2s) | |||||
// - block 4 (16 bytes) = full padding (filled with 2s) | |||||
const dataLengthBytes = 20; | |||||
const expectedPkcs7Padding = 12; | |||||
const expectedBlockPadding = 2; | |||||
const expectedPaddedLength = 4 * 16; | |||||
const data = generateRandomData(dataLengthBytes); | |||||
const padded = pad(data, config); | |||||
expect(padded.length % expectedPaddedLength).toBe(0); | |||||
expect(padded[padded.length - 1]).toBe(expectedBlockPadding); | |||||
expect(padded[2 * 16 - 1]).toBe(expectedPkcs7Padding); | |||||
}); | |||||
it('pad should add a full superblock if pkcs7-padded input is a multiple of superblockSize blocks', () => { | |||||
const config: PaddingConfiguration = { | |||||
blockSizeBytes: 16, | |||||
superblockSizeBlocks: 4, | |||||
}; | |||||
// 5 bytes less so pkcs7 padding is 5 bytes and pads equally to superblock | |||||
// size | |||||
const pkcs7paddingLength = 5; | |||||
const dataLengthBytes = 4 * 16 - pkcs7paddingLength; | |||||
const expectedPaddedLength = 8 * 16; | |||||
const expectedBlockPadding = 4; | |||||
const data = generateRandomData(dataLengthBytes); | |||||
const padded = pad(data, config); | |||||
expect(padded.length % expectedPaddedLength).toBe(0); | |||||
expect(padded[padded.length - 1]).toBe(expectedBlockPadding); | |||||
}); | |||||
it('pad and unpad should be inverses', () => { | |||||
const config: PaddingConfiguration = { | |||||
blockSizeBytes: 16, | |||||
superblockSizeBlocks: 4, | |||||
}; | |||||
const data = generateRandomData(100); | |||||
const padded = pad(data, config); | |||||
const unpadded = unpad(padded, config); | |||||
expect(unpadded.length).toBe(data.length); | |||||
expect(unpadded).toEqual(data); | |||||
}); | |||||
}); | |||||
function generateRandomData(length: number): Uint8Array { | function generateRandomData(length: number): Uint8Array { | ||||
const data = new Uint8Array(length); | const data = new Uint8Array(length); | ||||
for (let i = 0; i < length; i++) { | for (let i = 0; i < length; i++) { | ||||
data[i] = Math.floor(Math.random() * 256); | data[i] = Math.floor(Math.random() * 256); | ||||
} | } | ||||
return data; | return data; | ||||
} | } | ||||
function generateRandomArray(length: number): Array<number> { | function generateRandomArray(length: number): Array<number> { | ||||
return new Array(length).map(() => Math.floor(Math.random() * 256)); | return new Array(length).map(() => Math.floor(Math.random() * 256)); | ||||
} | } |