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