xref: /xnu-8796.121.2/EXTERNAL_HEADERS/TrustCache/Types.h (revision c54f35ca767986246321eb901baf8f5ff7923f6a)
1 #ifndef libTrustCache_Types_h
2 #define libTrustCache_Types_h
3 
4 #include <sys/cdefs.h>
5 __BEGIN_DECLS
6 
7 #include <stdint.h>
8 #include <img4/firmware.h>
9 #include <TrustCache/RawTypes.h>
10 
11 typedef uint8_t TCType_t;
12 enum {
13     /*
14      * These types of trust caches are always loaded as modules. Their validation
15      * is done externally by upper-level software.
16      *
17      * Static trust caches are bundled with the operating system and are the primary
18      * method of denoting platform trust. Engineering trust caches are similar to
19      * static trust caches except that they can be created by engineers at their
20      * desk as a root for a static trust cache. Legacy trust caches are image3 signed
21      * modules. This library does not support validating image3 signatures, so it
22      * accepts the trust caches only as direct modules. These are still considered
23      * loadable trust caches.
24      */
25     kTCTypeStatic = 0x00,
26     kTCTypeEngineering = 0x01,
27     kTCTypeLegacy = 0x02,
28 
29     /*
30      * Do NOT change the order of the types listed here. This header is shared across
31      * a variety of projects and they update at different cadences. Adding a new type
32      * requires appending to the end of the enumeration, instead of insertion in the
33      * middle somewhere.
34      */
35 
36     /*
37      * Type: Personalized
38      * These are engineering roots which are only ever valid for development devices.
39      * These can be created by engineers at their desks for testing software.
40      */
41     kTCTypeDTRS = 0x03,
42 
43     /*
44      * Type: Personalized
45      * These are loadable trust caches which are viable for all kinds of devices and
46      * can be used for testing, but also for shipping code in production devices.
47      */
48     kTCTypeLTRS = 0x04,
49 
50     /*
51      * Type: Personalized
52      * Used by disk images which are used to supply platform code for a number of use
53      * cases, including the multidude of disk images supplied for engineering use-cases
54      * such as the factoey disk image.
55      */
56     kTCTypePersonalizedDiskImage = 0x05,
57 
58     /*
59      * Type: Categorized
60      * Developer disk images which are personalized per device. These have a different
61      * tag than standard loadable trust caches and helps differentiate them. However,
62      * these were never productionized and are for all purposes, retired.
63      */
64     kTCTypeDeveloperDiskImage = 0x06,
65 
66     /*
67      * Type: Personalized
68      * These trust caches are similar to a personalized LTRS trust cache type except
69      * they are personalized against a long lived nonce, allowing these to remain
70      * useable across reboots of the system.
71      */
72     kTCTypeLTRSWithDDINonce = 0x07,
73 
74     /*
75      * Type: Personalized
76      * These trust cache types are used to authenticate code shipped in Cryptexes for
77      * security research devices. Outside of the SRD, these are also used in some data
78      * center use cases which deploy code through Cryptexes.
79      */
80     kTCTypeCryptex = 0x08,
81 
82     /*
83      * Type: Personalized (against supplemental root)
84      * These are special trust caches which validate against a supplemental root beyond
85      * Tatsu. These are only meant for special deployments within some data centers.
86      *
87      * NOTE: This type is deprecated in favor of the newer Supplemental Persistent
88      * and Supplemental Ephemeral types.
89      */
90     kTCTypeEphemeralCryptex = 0x09,
91 
92     /*
93      * Type: Global
94      * OTA updates ship an update brain to assist with the OS update. The brain is some
95      * code with platform privileges which can do whatever the current OS needs it to do
96      * in order to update the system.
97      */
98     kTCTypeUpdateBrain = 0x0A,
99 
100     /*
101      * Type: Global
102      * Trust caches which are loaded by the Install Assistant on macOS in order to help
103      * with installing macOS.
104      */
105     kTCTypeInstallAssistant = 0x0B,
106 
107     /*
108      * Type: Global
109      * These are used by macOS systems to ship a bootability brain. The bootability brain
110      * is a piece of code which helps determine if macOS systems of a different version
111      * are bootable or not. The brain is useful because the logic for determining that a
112      * system is bootable or not differs with each release.
113      */
114     kTCTypeBootabilityBrain = 0x0C,
115 
116     /*
117      * Type: Personalized (against Cryptex 1 Boot/Preboot environments)
118      * These trust cache types are used by SPLAT at different stages of the boot pipeline
119      * for loading code responsible for system boot up, such as the shared cache.
120      *
121      * The personalization uses a Cryptex1 nonce domain, which is embedded within the
122      * manifest itself.
123      */
124     kTCTypeCryptex1BootOS = 0x0D,
125     kTCTypeCryptex1BootApp = 0x0E,
126     kTCTypeCryptex1PreBootApp = 0x0F,
127 
128     /*
129      * Type: Global
130      * These are disk images which are globally signed against the FF00 chip environment.
131      * They are used when disk images want to supply code for devices across the fleet
132      * without requiring individual personalization for each.
133      *
134      * The developer disk image is supplied through this mechanism as well, as of January
135      * 5th, 2022.
136      */
137     kTCTypeGlobalDiskImage = 0x10,
138 
139     /*
140      * Type: Personalized (Cryptex1 mobile asset brain)
141      * The mobile asset brain contains the core logic for mobileassetd, which is a system
142      * daemon responsible for downloading and maintaining assets on the device. The brain
143      * is meant to be back-deployable, which is what the trust cache helps with.
144      *
145      * The personalization uses a Cryptex1 nonce domain, which is embedded within the
146      * manifest itself.
147      */
148     kTCTypeMobileAssetBrain = 0x11,
149 
150     /*
151      * Type: Personalized (Cryptex1 boot reduced)
152      * Safari is backported to older builds. Since Safari is now moving to a SPLAT based
153      * mount volume, we need to support loading a trust cache which is used to mount and
154      * run Safari from the future.
155      *
156      * The personalization uses a Cryptex1 nonce domain, which is embedded within the
157      * manifest itself.
158      */
159     kTCTypeSafariDownlevel = 0x12,
160 
161     /*
162      * Type: Personalized (Cryptex 1 Preboot)
163      * This trust cache type is used for the semi-SPLAT use-case for loading the new dyld
164      * shared cache onto the platform, along with some other system libraries. This is
165      * only required for macOS.
166      *
167      * The personalization uses a Cryptex1 nonce domain, which is embedded within the
168      * manifest itself.
169      */
170     kTCTypeCryptex1PreBootOS = 0x13,
171 
172     /*
173      * Type: Personalized (Supplemental Root)
174      * Persistent trust caches which are signed by an authority different from Tatsu.
175      * These are only required for deployment on darwinOS platforms.
176      */
177     kTCTypeSupplementalPersistent = 0x14,
178 
179     /*
180      * Type: Personalized (Supplemental Root)
181      * Ephemeral trust caches which are signed by an authority different from Tatsu.
182      * These are only required for deployment on darwinOS platforms.
183      */
184     kTCTypeSupplementalEphemeral = 0x15,
185 
186     /*
187      * Type: Personalized (Cryptex1 Generic)
188      * This type can be used by the assortment of PDIs we ship. Each PDI train can opt
189      * into allocating a Cryptex1 sub-type for itself, and then ship on the OS being
190      * signed by the Cryptex1 generic environment. This allows the PDI to adopt Cryptex1
191      * personalization without requiring a new bespoke trust cache type.
192      *
193      * The personalization uses a Cryptex1 nonce domain, which is embedded within the
194      * manifest itself.
195      */
196     kTCTypeCryptex1Generic = 0x16,
197 
198     /*
199      * Type: Personalized (Cryptex1 Generic Supplemental)
200      * Similar to the kTCTypeCryptex1Generic type except the manifest is signed by the
201      * supplemental root of trust. Only viable for some data center use-cases.
202      *
203      * The personalization uses a Cryptex1 nonce domain, which is embedded within the
204      * manifest itself.
205      */
206     kTCTypeCryptex1GenericSupplemental = 0x17,
207 
208     kTCTypeTotal,
209 
210     /* Invalid type */
211     kTCTypeInvalid = 0xFF,
212 };
213 
214 /* Availability macros for different trust cache types */
215 #define kLibTrustCacheHasCryptex1BootOS 1
216 #define kLibTrustCacheHasCryptex1BootApp 1
217 #define kLibTrustCacheHasCryptex1PreBootApp 1
218 #define kLibTrustCacheHasMobileAssetBrain 1
219 #define kLibTrustCacheHasSafariDownlevel 1
220 #define kLibTrustCacheHasCryptex1PreBootOS 1
221 #define kLibTrustCacheHasSupplementalPersistent 1
222 #define kLibTrustCacheHasSupplementalEphemeral 1
223 #define kLibTrustCacheHasCryptex1Generic 1
224 #define kLibTrustCacheHasCryptex1GenericSupplemental 1
225 
226 typedef struct _TrustCache {
227     /* Linked list linkage for the trust cache */
228     struct _TrustCache *next;
229     struct _TrustCache *prev;
230 
231     /* The type of this trust cache */
232     TCType_t type;
233 
234     /* TODO: Add reference counts when we support unloading */
235 
236     /* The trust cache module itself */
237     size_t moduleSize;
238     const TrustCacheModuleBase_t *module;
239 } TrustCache_t;
240 
241 typedef uint8_t TCQueryType_t;
242 enum {
243     /* Query all types of trust caches in the runtime */
244     kTCQueryTypeAll = 0x00,
245 
246     /* Static query type includes engineering trust caches */
247     kTCQueryTypeStatic = 0x01,
248 
249     /* Most first party trust cache types are loadable ones */
250     kTCQueryTypeLoadable = 0x02,
251 
252     kTCQueryTypeTotal,
253 };
254 
255 typedef uint64_t TCCapabilities_t;
256 enum {
257     /* Supports no capabilities */
258     kTCCapabilityNone = 0,
259 
260     /* Supports the hash type field */
261     kTCCapabilityHashType = (1 << 0),
262 
263     /* Supports the flags field */
264     kTCCapabilityFlags = (1 << 1),
265 
266     /* Supports the constraints category field */
267     kTCCapabilityConstraintsCategory = (1 << 2),
268 };
269 
270 typedef struct _TrustCacheQueryToken {
271     /* Trust cache where query was found */
272     const TrustCache_t *trustCache;
273 
274     /* Entry within the trust cache where query was found */
275     const void *trustCacheEntry;
276 } TrustCacheQueryToken_t;
277 
278 /*
279  * The runtime data structure is setup in a very special way. To make use of HW mitigations
280  * offered by the silicon, the runtime can be placed in a region which is locked down by the
281  * HW at some commit point. This theoretically allows the static and the engineering trust
282  * caches to be locked down and immutable if the storage for the trust cache data structure
283  * is also allocated within this same immutable memory segment.
284  *
285  * At the same time, we need to be able to support dynamically loaded trust caches on the
286  * system. We can't keep a list head within the runtime for these trust caches, since that
287  * head will be locked down when the runtime is locked, preventing us from adding a new link
288  * in the chain. To solve this, the runtime instead stores a pointer to a wrapped data structure.
289  * This pointer itself is locked down and can't be changed, but the contents of the wrapped
290  * structure are mutable, making it a good place to store the linked list head.
291  */
292 
293 /* Data structure expected to be stored within mutable memory */
294 typedef struct _TrustCacheMutableRuntime {
295     /* Loadable trust caches on the system */
296     TrustCache_t *loadableTCHead;
297 } TrustCacheMutableRuntime_t;
298 
299 /* Data structure expected to be stored within immutable memory */
300 typedef struct _TrustCacheRuntime {
301     /* Runtime to use for image 4 object verification */
302     const img4_runtime_t *image4RT;
303 
304     /* Configuration for trust cache types */
305     bool allowSecondStaticTC;
306     bool allowEngineeringTC;
307     bool allowLegacyTC;
308 
309     /* Static trust cache for the system */
310     TrustCache_t *staticTCHead;
311 
312     /* Engineering trust caches for the system */
313     TrustCache_t *engineeringTCHead;
314 
315     /* Mutable runtime instance */
316     TrustCacheMutableRuntime_t *mutableRT;
317 } TrustCacheRuntime_t;
318 
319 __END_DECLS
320 #endif /* libTrustCache_Types_h */
321