Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3404636
D7061.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
D7061.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D7061: [lib] Introduce combined padding interface
Attached
Detach File
Event Timeline
Log In to Comment