#ifndef libTrustCache_Types_h #define libTrustCache_Types_h #include __BEGIN_DECLS #include #include #include typedef uint8_t TCType_t; enum { /* * These types of trust caches are always loaded as modules. Their validation * is done externally by upper-level software. * * Static trust caches are bundled with the operating system and are the primary * method of denoting platform trust. Engineering trust caches are similar to * static trust caches except that they can be created by engineers at their * desk as a root for a static trust cache. Legacy trust caches are image3 signed * modules. This library does not support validating image3 signatures, so it * accepts the trust caches only as direct modules. These are still considered * loadable trust caches. */ kTCTypeStatic = 0x00, kTCTypeEngineering = 0x01, kTCTypeLegacy = 0x02, /* * Do NOT change the order of the types listed here. This header is shared across * a variety of projects and they update at different cadences. Adding a new type * requires appending to the end of the enumeration, instead of insertion in the * middle somewhere. */ /* * Type: Personalized * These are engineering roots which are only ever valid for development devices. * These can be created by engineers at their desks for testing software. */ kTCTypeDTRS = 0x03, /* * Type: Personalized * These are loadable trust caches which are viable for all kinds of devices and * can be used for testing, but also for shipping code in production devices. */ kTCTypeLTRS = 0x04, /* * Type: Personalized * Used by disk images which are used to supply platform code for a number of use * cases, including the multidude of disk images supplied for engineering use-cases * such as the factoey disk image. */ kTCTypePersonalizedDiskImage = 0x05, /* * Type: Categorized * Developer disk images which are personalized per device. These have a different * tag than standard loadable trust caches and helps differentiate them. However, * these were never productionized and are for all purposes, retired. */ kTCTypeDeveloperDiskImage = 0x06, /* * Type: Personalized * These trust caches are similar to a personalized LTRS trust cache type except * they are personalized against a long lived nonce, allowing these to remain * useable across reboots of the system. */ kTCTypeLTRSWithDDINonce = 0x07, /* * Type: Personalized * These trust cache types are used to authenticate code shipped in Cryptexes for * security research devices. Outside of the SRD, these are also used in some data * center use cases which deploy code through Cryptexes. */ kTCTypeCryptex = 0x08, /* * Type: Personalized (against supplemental root) * These are special trust caches which validate against a supplemental root beyond * Tatsu. These are only meant for special deployments within some data centers. */ kTCTypeEphemeralCryptex = 0x09, /* * Type: Global * OTA updates ship an update brain to assist with the OS update. The brain is some * code with platform privileges which can do whatever the current OS needs it to do * in order to update the system. */ kTCTypeUpdateBrain = 0x0A, /* * Type: Global * Trust caches which are loaded by the Install Assistant on macOS in order to help * with installing macOS. */ kTCTypeInstallAssistant = 0x0B, /* * Type: Global * These are used by macOS systems to ship a bootability brain. The bootability brain * is a piece of code which helps determine if macOS systems of a different version * are bootable or not. The brain is useful because the logic for determining that a * system is bootable or not differs with each release. */ kTCTypeBootabilityBrain = 0x0C, /* * Type: Personalized (against Cryptex 1 Boot/Preboot environments) * These trust cache types are used by SPLAT at different stages of the boot pipeline * for loading code responsible for system boot up, such as the shared cache. */ kTCTypeCryptex1BootOS = 0x0D, kTCTypeCryptex1BootApp = 0x0E, kTCTypeCryptex1PreBootApp = 0x0F, /* * Type: Global * These are disk images which are globally signed against the FF00 chip environment. * They are used when disk images want to supply code for devices across the fleet * without requiring individual personalization for each. * * The developer disk image is supplied through this mechanism as well, as of January * 5th, 2022. */ kTCTypeGlobalDiskImage = 0x10, /* * Type: Personalized (Cryptex1 mobile asset brain) * The mobile asset brain contains the core logic for mobileassetd, which is a system * daemon responsible for downloading and maintaining assets on the device. The brain * is meant to be back-deployable, which is what the trust cache helps with. */ kTCTypeMobileAssetBrain = 0x11, /* * Type: Personalized (Cryptex1 boot reduced) * Safari is backported to older builds. Since Safari is now moving to a SPLAT based * mount volume, we need to support loading a trust cache which is used to mount and * run Safari from the future. */ kTCTypeSafariDownlevel = 0x12, /* * Type: Personalized (Cryptex 1 Preboot) * This trust cache type is used for the semi-SPLAT use-case for loading the new dyld * shared cache onto the platform, along with some other system libraries. This is * only required for macOS. */ kTCTypeCryptex1PreBootOS = 0x13, kTCTypeTotal, /* Invalid type */ kTCTypeInvalid = 0xFF, }; /* Availability macros for different trust cache types */ #define kLibTrustCacheHasCryptex1BootOS 1 #define kLibTrustCacheHasCryptex1BootApp 1 #define kLibTrustCacheHasCryptex1PreBootApp 1 #define kLibTrustCacheHasMobileAssetBrain 1 #define kLibTrustCacheHasSafariDownlevel 1 #define kLibTrustCacheHasCryptex1PreBootOS 1 typedef struct _TrustCache { /* Linked list linkage for the trust cache */ struct _TrustCache *next; struct _TrustCache *prev; /* The type of this trust cache */ TCType_t type; /* TODO: Add reference counts when we support unloading */ /* The trust cache module itself */ uint64_t moduleSize; TrustCacheModuleBase_t *module; } TrustCache_t; typedef uint8_t TCQueryType_t; enum { /* Query all types of trust caches in the runtime */ kTCQueryTypeAll = 0x00, /* Static query type includes engineering trust caches */ kTCQueryTypeStatic = 0x01, /* Most first party trust cache types are loadable ones */ kTCQueryTypeLoadable = 0x02, kTCQueryTypeTotal, }; typedef uint64_t TCCapabilities_t; enum { /* Supports no capabilities */ kTCCapabilityNone = 0, /* Supports the hash type field */ kTCCapabilityHashType = (1 << 0), /* Supports the flags field */ kTCCapabilityFlags = (1 << 1), /* Supports the constraints category field */ kTCCapabilityConstraintsCategory = (1 << 2), }; typedef struct _TrustCacheQueryToken { /* Trust cache where query was found */ const TrustCache_t *trustCache; /* Entry within the trust cache where query was found */ const void *trustCacheEntry; } TrustCacheQueryToken_t; /* * The runtime data structure is setup in a very special way. To make use of HW mitigations * offered by the silicon, the runtime can be placed in a region which is locked down by the * HW at some commit point. This theoretically allows the static and the engineering trust * caches to be locked down and immutable if the storage for the trust cache data structure * is also allocated within this same immutable memory segment. * * At the same time, we need to be able to support dynamically loaded trust caches on the * system. We can't keep a list head within the runtime for these trust caches, since that * head will be locked down when the runtime is locked, preventing us from adding a new link * in the chain. To solve this, the runtime instead stores a pointer to a wrapped data structure. * This pointer itself is locked down and can't be changed, but the contents of the wrapped * structure are mutable, making it a good place to store the linked list head. */ /* Data structure expected to be stored within mutable memory */ typedef struct _TrustCacheMutableRuntime { /* Loadable trust caches on the system */ TrustCache_t *loadableTCHead; } TrustCacheMutableRuntime_t; /* Data structure expected to be stored within immutable memory */ typedef struct _TrustCacheRuntime { /* Runtime to use for image 4 object verification */ const img4_runtime_t *image4RT; /* Configuration for trust cache types */ bool allowSecondStaticTC; bool allowEngineeringTC; bool allowLegacyTC; /* Static trust cache for the system */ TrustCache_t *staticTCHead; /* Engineering trust caches for the system */ TrustCache_t *engineeringTCHead; /* Mutable runtime instance */ TrustCacheMutableRuntime_t *mutableRT; } TrustCacheRuntime_t; __END_DECLS #endif /* libTrustCache_Types_h */