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 kTCTypeEphemeralCryptex = 0x09, 88 89 /* 90 * Type: Global 91 * OTA updates ship an update brain to assist with the OS update. The brain is some 92 * code with platform privileges which can do whatever the current OS needs it to do 93 * in order to update the system. 94 */ 95 kTCTypeUpdateBrain = 0x0A, 96 97 /* 98 * Type: Global 99 * Trust caches which are loaded by the Install Assistant on macOS in order to help 100 * with installing macOS. 101 */ 102 kTCTypeInstallAssistant = 0x0B, 103 104 /* 105 * Type: Global 106 * These are used by macOS systems to ship a bootability brain. The bootability brain 107 * is a piece of code which helps determine if macOS systems of a different version 108 * are bootable or not. The brain is useful because the logic for determining that a 109 * system is bootable or not differs with each release. 110 */ 111 kTCTypeBootabilityBrain = 0x0C, 112 113 /* 114 * Type: Personalized (against Cryptex 1 Boot/Preboot environments) 115 * These trust cache types are used by SPLAT at different stages of the boot pipeline 116 * for loading code responsible for system boot up, such as the shared cache. 117 */ 118 kTCTypeCryptex1BootOS = 0x0D, 119 kTCTypeCryptex1BootApp = 0x0E, 120 kTCTypeCryptex1PreBootApp = 0x0F, 121 122 /* 123 * Type: Global 124 * These are disk images which are globally signed against the FF00 chip environment. 125 * They are used when disk images want to supply code for devices across the fleet 126 * without requiring individual personalization for each. 127 * 128 * The developer disk image is supplied through this mechanism as well, as of January 129 * 5th, 2022. 130 */ 131 kTCTypeGlobalDiskImage = 0x10, 132 133 /* 134 * Type: Personalized (Cryptex1 mobile asset brain) 135 * The mobile asset brain contains the core logic for mobileassetd, which is a system 136 * daemon responsible for downloading and maintaining assets on the device. The brain 137 * is meant to be back-deployable, which is what the trust cache helps with. 138 */ 139 kTCTypeMobileAssetBrain = 0x11, 140 141 /* 142 * Type: Personalized (Cryptex1 boot reduced) 143 * Safari is backported to older builds. Since Safari is now moving to a SPLAT based 144 * mount volume, we need to support loading a trust cache which is used to mount and 145 * run Safari from the future. 146 */ 147 kTCTypeSafariDownlevel = 0x12, 148 149 /* 150 * Type: Personalized (Cryptex 1 Preboot) 151 * This trust cache type is used for the semi-SPLAT use-case for loading the new dyld 152 * shared cache onto the platform, along with some other system libraries. This is 153 * only required for macOS. 154 */ 155 kTCTypeCryptex1PreBootOS = 0x13, 156 157 kTCTypeTotal, 158 159 /* Invalid type */ 160 kTCTypeInvalid = 0xFF, 161 }; 162 163 /* Availability macros for different trust cache types */ 164 #define kLibTrustCacheHasCryptex1BootOS 1 165 #define kLibTrustCacheHasCryptex1BootApp 1 166 #define kLibTrustCacheHasCryptex1PreBootApp 1 167 #define kLibTrustCacheHasMobileAssetBrain 1 168 #define kLibTrustCacheHasSafariDownlevel 1 169 #define kLibTrustCacheHasCryptex1PreBootOS 1 170 171 typedef struct _TrustCache { 172 /* Linked list linkage for the trust cache */ 173 struct _TrustCache *next; 174 struct _TrustCache *prev; 175 176 /* The type of this trust cache */ 177 TCType_t type; 178 179 /* TODO: Add reference counts when we support unloading */ 180 181 /* The trust cache module itself */ 182 uint64_t moduleSize; 183 TrustCacheModuleBase_t *module; 184 } TrustCache_t; 185 186 typedef uint8_t TCQueryType_t; 187 enum { 188 /* Query all types of trust caches in the runtime */ 189 kTCQueryTypeAll = 0x00, 190 191 /* Static query type includes engineering trust caches */ 192 kTCQueryTypeStatic = 0x01, 193 194 /* Most first party trust cache types are loadable ones */ 195 kTCQueryTypeLoadable = 0x02, 196 197 kTCQueryTypeTotal, 198 }; 199 200 typedef uint64_t TCCapabilities_t; 201 enum { 202 /* Supports no capabilities */ 203 kTCCapabilityNone = 0, 204 205 /* Supports the hash type field */ 206 kTCCapabilityHashType = (1 << 0), 207 208 /* Supports the flags field */ 209 kTCCapabilityFlags = (1 << 1), 210 211 /* Supports the constraints category field */ 212 kTCCapabilityConstraintsCategory = (1 << 2), 213 }; 214 215 typedef struct _TrustCacheQueryToken { 216 /* Trust cache where query was found */ 217 const TrustCache_t *trustCache; 218 219 /* Entry within the trust cache where query was found */ 220 const void *trustCacheEntry; 221 } TrustCacheQueryToken_t; 222 223 /* 224 * The runtime data structure is setup in a very special way. To make use of HW mitigations 225 * offered by the silicon, the runtime can be placed in a region which is locked down by the 226 * HW at some commit point. This theoretically allows the static and the engineering trust 227 * caches to be locked down and immutable if the storage for the trust cache data structure 228 * is also allocated within this same immutable memory segment. 229 * 230 * At the same time, we need to be able to support dynamically loaded trust caches on the 231 * system. We can't keep a list head within the runtime for these trust caches, since that 232 * head will be locked down when the runtime is locked, preventing us from adding a new link 233 * in the chain. To solve this, the runtime instead stores a pointer to a wrapped data structure. 234 * This pointer itself is locked down and can't be changed, but the contents of the wrapped 235 * structure are mutable, making it a good place to store the linked list head. 236 */ 237 238 /* Data structure expected to be stored within mutable memory */ 239 typedef struct _TrustCacheMutableRuntime { 240 /* Loadable trust caches on the system */ 241 TrustCache_t *loadableTCHead; 242 } TrustCacheMutableRuntime_t; 243 244 /* Data structure expected to be stored within immutable memory */ 245 typedef struct _TrustCacheRuntime { 246 /* Runtime to use for image 4 object verification */ 247 const img4_runtime_t *image4RT; 248 249 /* Configuration for trust cache types */ 250 bool allowSecondStaticTC; 251 bool allowEngineeringTC; 252 bool allowLegacyTC; 253 254 /* Static trust cache for the system */ 255 TrustCache_t *staticTCHead; 256 257 /* Engineering trust caches for the system */ 258 TrustCache_t *engineeringTCHead; 259 260 /* Mutable runtime instance */ 261 TrustCacheMutableRuntime_t *mutableRT; 262 } TrustCacheRuntime_t; 263 264 __END_DECLS 265 #endif /* libTrustCache_Types_h */ 266