xref: /xnu-8796.141.3/EXTERNAL_HEADERS/TrustCache/Types.h (revision 1b191cb58250d0705d8a51287127505aa4bc0789)
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     /*
209      * Type: Personalized (Cryptex1 mobile asset brain)
210      * This is exactly the same as the kTCTypeMobileAssetBrain type, except this using
211      * the PDI nonce. The PDI nonce rolls every boot, and having a trust cache type
212      * here helps create an asset brain personalization which works on the current
213      * boot, but becomes invalid after a reboot, thus ensuring the brain which was
214      * personalized will only remain valid for the current OS (this type is used by
215      * the update brain which performs an OTA).
216      */
217     kTCTypeMobileAssetBrainEphemeral = 0x18,
218 
219     kTCTypeTotal,
220 
221     /* Invalid type */
222     kTCTypeInvalid = 0xFF,
223 };
224 
225 /* Availability macros for different trust cache types */
226 #define kLibTrustCacheHasCryptex1BootOS 1
227 #define kLibTrustCacheHasCryptex1BootApp 1
228 #define kLibTrustCacheHasCryptex1PreBootApp 1
229 #define kLibTrustCacheHasMobileAssetBrain 1
230 #define kLibTrustCacheHasSafariDownlevel 1
231 #define kLibTrustCacheHasCryptex1PreBootOS 1
232 #define kLibTrustCacheHasSupplementalPersistent 1
233 #define kLibTrustCacheHasSupplementalEphemeral 1
234 #define kLibTrustCacheHasCryptex1Generic 1
235 #define kLibTrustCacheHasCryptex1GenericSupplemental 1
236 #define kLibTrustCacheHasMobileAssetBrainEphemeral 1
237 
238 typedef struct _TrustCache {
239     /* Linked list linkage for the trust cache */
240     struct _TrustCache *next;
241     struct _TrustCache *prev;
242 
243     /* The type of this trust cache */
244     TCType_t type;
245 
246     /* TODO: Add reference counts when we support unloading */
247 
248     /* The trust cache module itself */
249     size_t moduleSize;
250     const TrustCacheModuleBase_t *module;
251 } TrustCache_t;
252 
253 typedef uint8_t TCQueryType_t;
254 enum {
255     /* Query all types of trust caches in the runtime */
256     kTCQueryTypeAll = 0x00,
257 
258     /* Static query type includes engineering trust caches */
259     kTCQueryTypeStatic = 0x01,
260 
261     /* Most first party trust cache types are loadable ones */
262     kTCQueryTypeLoadable = 0x02,
263 
264     kTCQueryTypeTotal,
265 };
266 
267 typedef uint64_t TCCapabilities_t;
268 enum {
269     /* Supports no capabilities */
270     kTCCapabilityNone = 0,
271 
272     /* Supports the hash type field */
273     kTCCapabilityHashType = (1 << 0),
274 
275     /* Supports the flags field */
276     kTCCapabilityFlags = (1 << 1),
277 
278     /* Supports the constraints category field */
279     kTCCapabilityConstraintsCategory = (1 << 2),
280 };
281 
282 typedef struct _TrustCacheQueryToken {
283     /* Trust cache where query was found */
284     const TrustCache_t *trustCache;
285 
286     /* Entry within the trust cache where query was found */
287     const void *trustCacheEntry;
288 } TrustCacheQueryToken_t;
289 
290 /*
291  * The runtime data structure is setup in a very special way. To make use of HW mitigations
292  * offered by the silicon, the runtime can be placed in a region which is locked down by the
293  * HW at some commit point. This theoretically allows the static and the engineering trust
294  * caches to be locked down and immutable if the storage for the trust cache data structure
295  * is also allocated within this same immutable memory segment.
296  *
297  * At the same time, we need to be able to support dynamically loaded trust caches on the
298  * system. We can't keep a list head within the runtime for these trust caches, since that
299  * head will be locked down when the runtime is locked, preventing us from adding a new link
300  * in the chain. To solve this, the runtime instead stores a pointer to a wrapped data structure.
301  * This pointer itself is locked down and can't be changed, but the contents of the wrapped
302  * structure are mutable, making it a good place to store the linked list head.
303  */
304 
305 /* Data structure expected to be stored within mutable memory */
306 typedef struct _TrustCacheMutableRuntime {
307     /* Loadable trust caches on the system */
308     TrustCache_t *loadableTCHead;
309 } TrustCacheMutableRuntime_t;
310 
311 /* Data structure expected to be stored within immutable memory */
312 typedef struct _TrustCacheRuntime {
313     /* Runtime to use for image 4 object verification */
314     const img4_runtime_t *image4RT;
315 
316     /* Configuration for trust cache types */
317     bool allowSecondStaticTC;
318     bool allowEngineeringTC;
319     bool allowLegacyTC;
320 
321     /* Static trust cache for the system */
322     TrustCache_t *staticTCHead;
323 
324     /* Engineering trust caches for the system */
325     TrustCache_t *engineeringTCHead;
326 
327     /* Mutable runtime instance */
328     TrustCacheMutableRuntime_t *mutableRT;
329 } TrustCacheRuntime_t;
330 
331 __END_DECLS
332 #endif /* libTrustCache_Types_h */
333