fix(crypto): harden keybag, ASN.1 and key derivation code paths - #219
Open
BuenGenio wants to merge 3 commits into
Open
fix(crypto): harden keybag, ASN.1 and key derivation code paths#219BuenGenio wants to merge 3 commits into
BuenGenio wants to merge 3 commits into
Conversation
Audit and harden the existing software-encryption code. All changes are on the read path; behaviour is unchanged for a well-formed encrypted volume. Keybag parsing (ApfsLib/KeyMgmt.cpp): - Validate kl_nbytes against the buffer that was actually read so a corrupt value can no longer drive an out-of-bounds heap read in Keybag::Init. - Bounds-check the variable-length entry walk in Keybag::GetKey and reuse it from FindKey, so a malformed keybag cannot walk past m_data. - Verify each keybag block individually instead of verifying the whole buffer blockcnt times with identical arguments. - Check the ReadBlocks return value, cap the keybag block count to reject an absurd allocation, and only let the container keybag set m_is_unencrypted. ASN.1/DER parser (Crypto/Asn1Der.cpp): - Avoid undefined behaviour from out-of-bounds pointer arithmetic and a possible null-pointer dereference in der_decode_len/der_decode_tl by comparing sizes instead of pointers. Key derivation (Crypto/Crypto.cpp, Crypto/Crypto.h): - Change the PBKDF2 iteration count from int to uint32_t; the keybag value is uint64_t and a large count truncated to a negative int, silently producing the wrong key. Drop dead variables. Volume key handling (ApfsLib/KeyMgmt.cpp, ApfsLib/ApfsVolume.cpp): - Treat a null password as empty in GetVolumeKey to avoid a strlen() null dereference. - Zero derived key material (dk, kek, vek) from the stack after use. - Extract the duplicated volume-encryption setup into ApfsVolume::InitVolumeKey() so Init and MountSnapshot behave consistently. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PList.h uses uint8_t and uint32_t but relied on them being pulled in transitively by another standard header. libstdc++ 15 (GCC 15) no longer does so, which broke the build with errors such as "'uint8_t' does not name a type". Include <cstdint> explicitly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fix(crypto): harden keybag, ASN.1 and key derivation code paths
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Audit and hardening of the existing software-encryption code path (keybag parsing, ASN.1/DER decoding, PBKDF2, volume key handling). All changes are on the read path — behaviour is unchanged for a well-formed encrypted volume; the goal is to make corrupt or hostile input fail safely instead of reading out of bounds or crashing.
##Bugs fixed
Hardening / cleanup
Build fix (second commit)
fix(build): add missing include to PList.h — pre-existing and unrelated to crypto, but required for the project to build at all on GCC 15 / libstdc++ 15, which no longer leaks transitively.
Testing
Built with cmake + make (GCC 15, Release):