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
11typedef uint8_t TCType_t;
12enum {
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
226typedef 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
241typedef uint8_t TCQueryType_t;
242enum {
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
255typedef uint64_t TCCapabilities_t;
256enum {
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
270typedef 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 */
294typedef 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 */
300typedef 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