Every RSA key in testvectors_v1 has a modulus whose bit length is a multiple of 8. I checked all 83 rsa_*.json files at the current head (dac1dd4), 629 keyed groups. Bit lengths are exactly 2048, 3072, 4096, or 8192, and the top byte is always at least 0x80.
RFC 8017 permits any modulus bit length, and for a verifier the modulus is attacker-supplied input. It arrives in certificates and presented keys, so a verifier does not get to assume alignment. PSS treats the bit length asymmetrically (emBits = modBits − 1), and misalignment exercises two paths that byte-aligned keys never touch:
- modBits ≢ 1 (mod 8), for example 2047:
emLen still equals the key size, but the zero-bits window in EMSA-PSS-VERIFY steps 6 and 9 widens beyond one bit. Each unchecked top bit doubles a forger's freedom in maskedDB. This is the failure family BERserk-style bugs live in.
- modBits ≡ 1 (mod 8), for example 2041:
emBits is byte-aligned, so emLen = k − 1. The encoded message is one octet shorter than the signature, the leftmost-octet-must-be-zero path in RSASSA-PSS-VERIFY runs, and the step-6 window is zero bits.
A verifier that hardcodes either assumption, top bit set or emLen == k, passes the entire current corpus, and can get one of these cases right while failing the other.
I'd like to contribute two new files, rsa_pss_2047_sha256_mgf1_32_test.json and rsa_pss_2041_sha256_mgf1_32_test.json (SHA-256, MGF1-SHA256, salt length 32, one key each), with the same case set as the existing PSS files: valid signatures, modified-signature and wrong-salt cases, and boundary cases aimed at the alignment logic, meaning encodings with the window bits set and signatures equal to and just above the modulus. Generated with the vectorgen workflow from doc/vectorgen.md, source name github/c4milo/non-byte-aligned-modulus.
Does this fit as new files, or would you rather have the groups added to an existing file instead?
Every RSA key in
testvectors_v1has a modulus whose bit length is a multiple of 8. I checked all 83rsa_*.jsonfiles at the current head (dac1dd4), 629 keyed groups. Bit lengths are exactly 2048, 3072, 4096, or 8192, and the top byte is always at least 0x80.RFC 8017 permits any modulus bit length, and for a verifier the modulus is attacker-supplied input. It arrives in certificates and presented keys, so a verifier does not get to assume alignment. PSS treats the bit length asymmetrically (
emBits = modBits − 1), and misalignment exercises two paths that byte-aligned keys never touch:emLenstill equals the key size, but the zero-bits window in EMSA-PSS-VERIFY steps 6 and 9 widens beyond one bit. Each unchecked top bit doubles a forger's freedom inmaskedDB. This is the failure family BERserk-style bugs live in.emBitsis byte-aligned, soemLen = k − 1. The encoded message is one octet shorter than the signature, the leftmost-octet-must-be-zero path in RSASSA-PSS-VERIFY runs, and the step-6 window is zero bits.A verifier that hardcodes either assumption, top bit set or
emLen == k, passes the entire current corpus, and can get one of these cases right while failing the other.I'd like to contribute two new files,
rsa_pss_2047_sha256_mgf1_32_test.jsonandrsa_pss_2041_sha256_mgf1_32_test.json(SHA-256, MGF1-SHA256, salt length 32, one key each), with the same case set as the existing PSS files: valid signatures, modified-signature and wrong-salt cases, and boundary cases aimed at the alignment logic, meaning encodings with the window bits set and signatures equal to and just above the modulus. Generated with thevectorgenworkflow from doc/vectorgen.md, source namegithub/c4milo/non-byte-aligned-modulus.Does this fit as new files, or would you rather have the groups added to an existing file instead?