Skip to content

pkcs5: return an error instead of panicking on a short DES/3DES IV#2383

Merged
tarcieri merged 1 commit into
RustCrypto:masterfrom
arpitjain099:chore/pkcs5-des-iv-length
Jul 20, 2026
Merged

pkcs5: return an error instead of panicking on a short DES/3DES IV#2383
tarcieri merged 1 commit into
RustCrypto:masterfrom
arpitjain099:chore/pkcs5-des-iv-length

Conversation

@arpitjain099

Copy link
Copy Markdown
Contributor

While reading the PBES2 EncryptionScheme parser I noticed the DES-CBC and 3DES-EDE3-CBC arms can panic on attacker-controlled input.

Both DES arms do iv[0..DES_BLOCK_SIZE].try_into(), so the fixed-size slice happens before the try_into length check. If an AlgorithmIdentifier carries a DES-CBC or 3DES OID with an IV octet string shorter than 8 bytes, that range slice panics (range end index 8 out of range for slice of length N) instead of returning an error. The AES arms already call try_into on the whole slice, which reports a wrong length as an error, so this is just an inconsistency between the branches.

The IV comes straight from the DER parameters, so any code path that decodes an untrusted EncryptionScheme is affected, including pkcs8::EncryptedPrivateKeyInfo::decrypt, where the params are decoded before the password is ever used. A crafted 3DES-encrypted key blob panics regardless of the password.

The fix drops the manual slice and lets try_into on the full slice do the length check, matching the AES arms. DesCbc/DesEde3Cbc both hold [u8; 8], so TryInto<[u8; 8]> enforces exactly 8 bytes.

Added regression tests in pkcs5/tests/pbes2.rs: a short (3-byte) IV for both DES-CBC and 3DES now decodes to Err, and a valid 8-byte 3DES IV still decodes. The 3DES test is behind the 3des feature and the DES-CBC one behind des-insecure; ran with cargo test -p pkcs5 --features 3des,des-insecure. Before the change the short-IV cases panicked at pbes2.rs:546 and :552; after it they pass.

The DES-CBC and 3DES-EDE3-CBC arms of the EncryptionScheme parser slice
iv[0..DES_BLOCK_SIZE] before the try_into length check, so an
AlgorithmIdentifier carrying one of those OIDs with an IV octet string
shorter than 8 bytes panics with a slice range error instead of
returning an error. The AES arms already run try_into on the whole
slice, which length-checks gracefully; mirror that in the DES arms.

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
@tarcieri
tarcieri merged commit 2ceed71 into RustCrypto:master Jul 20, 2026
11 checks passed
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.

2 participants