Appendix: Apple Silicon Trust Cache Format
The internal structure of a trust cache.
Overview
An Image4 manifest brings user-space code into the measured set through two objects: the trust cache object and the restore trust cache object. Each object carries a digest of a trust cache, and the trust cache holds the CDHash of every binary it covers.
A trust cache has a relatively simple structure, with a minimal header followed by an array of fixed-length entries:
TrustCacheEntryFlags ::= ENUMERATION {
amfid(1),
remLoBit(64),
remHiBit(128),
}
TrustCacheEntry ::= SEQUENCE {
cdHash UInt8 [20],
hashType UInt8,
TrustCacheEntryFlags UInt8,
constraintCategory UInt8,
reserved UInt8,
}
TrustCache ::= SEQUENCE {
version UInt32,
uuid UInt8 [16],
entryCount UInt32,
entries TrustCacheEntry [...],
}The header is 24 bytes: a 32-bit version, the UUID, and a 32-bit entry count. The entry above is the version 2 entry. A node’s parser also accepts earlier versions, and the entry shrinks with each earlier version: a version 1 entry ends after the flags byte, and a version 0 entry is a bare 20-byte CDHash.
The cryptexctl dump-trust-cache command also dumps this structure. The CDHashes can be compared to a binary by using codesign to extract its CDHash.