Skip to content

Validate siglen against modulus_len in PSS decode - #807

Open
afonsojanu wants to merge 1 commit into
libtom:developfrom
afonsojanu:fix/pss-decode-siglen-check
Open

Validate siglen against modulus_len in PSS decode#807
afonsojanu wants to merge 1 commit into
libtom:developfrom
afonsojanu:fix/pss-decode-siglen-check

Conversation

@afonsojanu

Copy link
Copy Markdown

Fixes #802.

ltc_pkcs_1_pss_decode_mgf1 checks saltlen and modulus_len but never checks that siglen actually matches modulus_len. Later on it does:

XMEMCPY(DB, sig + x, modulus_len - hLen - 1);
x += modulus_len - hLen - 1;
XMEMCPY(hash, sig + x, hLen);

which copies modulus_len - 1 bytes total out of sig, based purely on modulus_len. If siglen < modulus_len, this reads past the end of the caller's buffer.

rsa_verify_hash_v2 happens to avoid triggering this today, because it always passes a buffer of exactly modulus_len (or modulus_len - 1 when modulus_bitlen % 8 == 1, handled via its own x - 1 adjustment) into the decode call. But ltc_pkcs_1_pss_decode_mgf1 is also reachable directly through the public (deprecated) pkcs_1_pss_decode() API, which forwards whatever siglen the caller passes with no validation at all — so a caller of that API supplying a genuinely truncated signature buffer hits the out-of-bounds read.

Fix: add siglen != modulus_len to the existing size-check if, matching the suggested fix in the issue.

Added a regression test in tests/pkcs_1_pss_test.c that calls pkcs_1_pss_decode() directly with a signature one byte shorter than the modulus and asserts it's rejected with CRYPT_PK_INVALID_SIZE rather than being processed. Verified with git-stash: reverting only the fix in pkcs_1_pss_decode.c makes the new assertion fail (on the very first PSS test vector) while everything else still passes; with the fix restored, the full suite passes (SUCCESS: passed=30 failed=0 nop=1).

Built and tested locally against LibTomMath (USE_LTM/LTM_DESC) on macOS/arm64.

ltc_pkcs_1_pss_decode_mgf1 checked saltlen and modulus_len but never
checked that siglen actually matched modulus_len. It then copies
modulus_len - 1 bytes out of sig based on modulus_len alone, so a
caller passing a shorter buffer (as pkcs_1_pss_decode does, unlike
rsa_verify_hash_v2 which happens to validate this indirectly) reads
past the end of it.

Fixes libtom#802
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.

Issue: Missing Signature Length Validation in ltc_pkcs_1_pss_decode_mgf1

1 participant