Skip to content

Fix ISO10126 and PKCS7 unpad#32

Open
Simn wants to merge 2 commits into
masterfrom
unpad-fixes
Open

Fix ISO10126 and PKCS7 unpad#32
Simn wants to merge 2 commits into
masterfrom
unpad-fixes

Conversation

@Simn
Copy link
Copy Markdown
Member

@Simn Simn commented Mar 11, 2026

(Full disclosure: I know nothing about this and simply asked Claude.)

We received a report about potential security problems in these functions. The ISO10126 one looks like an obvious fix, so that should be good. The other one is more involved and this should definitely not be merged before it has been reviewed by a human being.

Comment thread src/haxe/crypto/padding/PKCS7.hx Outdated
Comment on lines +30 to +33
// Arithmetic-right-shift trick: for a 32-bit signed int x,
// (x >> 31) is -1 (all bits set) when x < 0, and 0 otherwise.
bad |= (padding - 1) >> 31; // non-zero if padding < 1
bad |= (len - padding) >> 31; // non-zero if padding > len
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine but assumes 32-bit integers. At least Python and JS are failing some of the tests because the shift here does not produce the expected bit pattern. haxe.Int32 would probably fix this?

Comment thread tests/src/unit/crypto/PaddingTest.hx Outdated
Comment on lines +129 to +131
// one corrupted byte in the middle of an otherwise valid padding region
// "0001040404040404": last byte = 4, bytes at positions 4-7 are 00,04,04,04
exc(() -> PKCS7.unpad(Bytes.ofHex("0001040404040404")));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here it is straight up lying about the test case: the bytes should be (for example) AAAAAA00040404 (so the 4 padding bytes are actually 00 04 04 04 as it wands).

Comment thread tests/src/unit/crypto/PaddingTest.hx Outdated
Comment on lines +133 to +139
// only the first padding byte is wrong — catches a non-constant-time loop
// "0808080808080801": last byte = 1, byte at position 7 = 0x01 — that's fine,
// but the declared padding value is 1, so only position 7 is checked and it
// equals 1 → actually valid. Use a case where the first mismatch is early:
// "0102030404040404": last byte = 4, bytes at positions 4-7: 04,04,04,04 → valid
// "0102030400040404": last byte = 4, byte at position 4 = 0x00 ≠ 4 → invalid
exc(() -> PKCS7.unpad(Bytes.ofHex("0102030400040404")));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LLMism of generating an invalid test case, realising it's fine, then trying again. This is also the same test case in the end as the previous one, remove.

@Simn
Copy link
Copy Markdown
Member Author

Simn commented Mar 11, 2026

Oh hey, glad to see you're still around and thanks for the review!

@flashultra
Copy link
Copy Markdown
Collaborator

With the recent changes, everything seems correct to me.

@Simn Simn marked this pull request as ready for review May 6, 2026 17:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants