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