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 | |