Page MenuHomePhabricator

D7061.diff
No OneTemporary

D7061.diff

diff --git a/lib/utils/pkcs7-padding.js b/lib/utils/pkcs7-padding.js
--- a/lib/utils/pkcs7-padding.js
+++ b/lib/utils/pkcs7-padding.js
@@ -16,6 +16,56 @@
import invariant from 'invariant';
+export type PaddingConfiguration = {
+ +blockSizeBytes: number,
+ +superblockSizeBlocks: number,
+};
+
+/**
+ * The padding configuration for 10KB superblocks.
+ * The block size is 250 bytes, and the superblock size is 40 blocks.
+ */
+const PKCS7_10KB: PaddingConfiguration = {
+ blockSizeBytes: 250,
+ superblockSizeBlocks: 40,
+};
+
+/**
+ * Pads the input using the extended PKCS#7 padding (superblock padding).
+ * The input is first padded using the standard PKCS#7 padding, and then
+ * padded to the nearest multiple of superblocks (blocks of blocks).
+ *
+ * @param {Uint8Array} data - The input to be padded.
+ * @param {PaddingConfiguration} paddingConfiguration - The padding
+ * configuration. Defaults to multiple of 10KB. See {@link PKCS7_10KB}.
+ * @returns {Uint8Array} The padded input.
+ */
+function pad(
+ data: Uint8Array,
+ { blockSizeBytes, superblockSizeBlocks }: PaddingConfiguration = PKCS7_10KB,
+): Uint8Array {
+ const pkcs7Padded = pkcs7pad(data, blockSizeBytes);
+ return superblockPad(pkcs7Padded, blockSizeBytes, superblockSizeBlocks);
+}
+
+/**
+ * Unpads the input using the extended PKCS#7 padding (superblock padding).
+ * The input is first unpadded on the block basis, and then unpadded using
+ * the standard PKCS#7 padding.
+ *
+ * @param {Uint8Array} data - The input to be unpadded.
+ * @param {PaddingConfiguration} paddingConfiguration - The padding
+ * configuration. Defaults to multiple of 10KB. See {@link PKCS7_10KB}.
+ * @returns {Uint8Array} The unpadded input.
+ */
+function unpad(
+ data: Uint8Array,
+ { blockSizeBytes }: PaddingConfiguration = PKCS7_10KB,
+): Uint8Array {
+ const blockUnpadded = superblockUnpad(data, blockSizeBytes);
+ return pkcs7unpad(blockUnpadded);
+}
+
/**
* PKCS#7 padding function for `Uint8Array` data.
*
@@ -119,4 +169,12 @@
return unpaddedData;
}
-export { pkcs7pad, pkcs7unpad, superblockPad, superblockUnpad };
+export { PKCS7_10KB, pad, unpad };
+
+// exported for testing purposes only
+export const testing = {
+ pkcs7pad,
+ pkcs7unpad,
+ superblockPad,
+ superblockUnpad,
+};
diff --git a/lib/utils/pkcs7-padding.test.js b/lib/utils/pkcs7-padding.test.js
--- a/lib/utils/pkcs7-padding.test.js
+++ b/lib/utils/pkcs7-padding.test.js
@@ -1,11 +1,9 @@
// @flow
-import {
- pkcs7pad,
- pkcs7unpad,
- superblockPad,
- superblockUnpad,
-} from './pkcs7-padding.js';
+import type { PaddingConfiguration } from './pkcs7-padding';
+import { pad, unpad, testing } from './pkcs7-padding.js';
+
+const { pkcs7pad, pkcs7unpad, superblockPad, superblockUnpad } = testing;
describe('PKCS#7 Padding', () => {
it('should pad data to a multiple of blockSize bytes', () => {
@@ -155,6 +153,66 @@
});
});
+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 {
const data = new Uint8Array(length);
for (let i = 0; i < length; i++) {

File Metadata

Mime Type
text/plain
Expires
Wed, Dec 4, 12:06 PM (39 m, 10 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2614216
Default Alt Text
D7061.diff (5 KB)

Event Timeline