1 /* 2 * Copyright (c) 2021 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 23 #ifndef _VM_PMAP_CS_H_ 24 #define _VM_PMAP_CS_H_ 25 26 #ifdef KERNEL_PRIVATE 27 /* 28 * All of PMAP_CS definitions are private and should remain accessible only within XNU 29 * and Apple internal kernel extensions. 30 */ 31 32 #include <mach/kern_return.h> 33 #include <mach/vm_param.h> 34 #include <mach/vm_types.h> 35 #include <mach/boolean.h> 36 #include <img4/firmware.h> 37 #include <img4/nonce.h> 38 39 __BEGIN_DECLS 40 41 #if XNU_KERNEL_PRIVATE 42 /* 43 * Any declarations for types or functions which don't need to be exported to kernel 44 * extensions should go here. Naturally, this means this section can also include 45 * headers which may not be available to kernel extensions. 46 */ 47 48 #if defined(__arm64__) 49 #include <pexpert/arm64/board_config.h> 50 #endif 51 52 #include <kern/lock_rw.h> 53 #include <TrustCache/API.h> 54 55 56 #if PMAP_CS 57 #define PMAP_CS_INCLUDE_CODE_SIGNING 1 58 #endif 59 60 #if XNU_MONITOR 61 #define PMAP_CS_PPL_MONITOR 1 62 #else 63 #define PMAP_CS_PPL_MONITOR 0 64 #endif 65 66 #if PMAP_CS_PPL_MONITOR 67 68 /* 69 * XNU_MONITOR and PMAP_CS are both defined for the same targets in board_config.h. 70 * As a result, whenever XNU_MONITOR is defined, so is PMAP_CS. In an ideal world, we 71 * can remove the use of PMAP_CS macro and simply use XNU_MONITOR, but that would 72 * require a lot of changes throughout the codebase. 73 * 74 * PMAP_CS_PPL_MONITOR is defined when we have XNU_MONITOR _and_ we explicitly don't 75 * have . This effectively means that whenever we have PMAP_CS_PPL_MONITOR, 76 * we should also always have PMAP_CS_INCLUDE_CODE_SIGNING. Lets enforce this with a 77 * build check. 78 */ 79 #if !PMAP_CS_INCLUDE_CODE_SIGNING 80 #error "PMAP_CS_INCLUDE_CODE_SIGNING not defined when under PMAP_CS_PPL_MONITOR" 81 #endif 82 83 /* Immutable part of the trust cache runtime */ 84 extern TrustCacheRuntime_t ppl_trust_cache_rt; 85 86 /* Mutable part of the trust cache runtime */ 87 extern TrustCacheMutableRuntime_t ppl_trust_cache_mut_rt; 88 89 /* Lock for the trust cache runtime */ 90 extern lck_rw_t ppl_trust_cache_rt_lock; 91 92 typedef struct _pmap_img4_payload { 93 /* The trust cache data structure which wraps the payload */ 94 TrustCache_t trust_cache; 95 96 /* The actual image4 trust cache payload */ 97 uint8_t img4_payload[0]; 98 } pmap_img4_payload_t; 99 100 /* State for whether developer mode has been set or not */ 101 extern bool ppl_developer_mode_set; 102 103 /* State of developer mode on the system */ 104 extern bool ppl_developer_mode_storage; 105 106 /** 107 * Load an image4 trust cache of a particular type into the PPL. If validation succeeds, 108 * the payload will remain locked, but the other artifacts will be unlocked. If validation 109 * fails, all artifacts will be unlocked. 110 * 111 * All the lengths passed in will first be rounded up to page-size, so it is expected that 112 * the caller allocates page-aligned data. 113 * 114 * Upon successful validation, the trust cache is added to the runtime maintained by the 115 * PPL. 116 */ 117 kern_return_t 118 pmap_load_trust_cache_with_type( 119 TCType_t type, 120 const vm_address_t pmap_img4_payload, const vm_size_t pmap_img4_payload_len, 121 const vm_address_t img4_manifest, const vm_size_t img4_manifest_len, 122 const vm_address_t img4_aux_manifest, const vm_size_t img4_aux_manifest_len); 123 124 /* 125 * Query a trust cache from within the PPL. This function can only be called when within 126 * the PPL and does not pin the query_token passed in. 127 */ 128 kern_return_t 129 pmap_query_trust_cache_safe( 130 TCQueryType_t query_type, 131 const uint8_t cdhash[kTCEntryHashSize], 132 TrustCacheQueryToken_t *query_token); 133 134 /** 135 * Query a trust cache of a particular type from the PPL. The query_token passed in will 136 * be pinned by the PPL runtime when the PPL is attempting to write to it. This is an API 137 * which can be used for callers external to the PPL. 138 */ 139 kern_return_t 140 pmap_query_trust_cache( 141 TCQueryType_t query_type, 142 const uint8_t cdhash[kTCEntryHashSize], 143 TrustCacheQueryToken_t *query_token); 144 145 /** 146 * Toggle the state of developer mode on the system. This function can only be called with 147 * a true value once in the lifecycle of a boot. 148 * 149 * Until this function is called once to set the state, the PPL will block non-platform 150 * code and JIT on the system. 151 */ 152 void 153 pmap_toggle_developer_mode( 154 bool state); 155 156 #endif /* PMAP_CS_PPL_MONITOR */ 157 158 #if PMAP_CS_INCLUDE_CODE_SIGNING 159 160 #define CORE_ENTITLEMENTS_I_KNOW_WHAT_IM_DOING 161 162 #include <CoreEntitlements/CoreEntitlementsPriv.h> 163 #include <kern/cs_blobs.h> 164 #include <libkern/tree.h> 165 #include <libkern/crypto/sha1.h> 166 #include <libkern/crypto/sha2.h> 167 #include <libkern/coretrust/coretrust.h> 168 169 /* Validation data for a provisioning profile */ 170 typedef struct _pmap_cs_profile { 171 /* 172 * The PPL uses the physical aperture mapping to write to this structure. But 173 * we need to save a pointer to the original mapping for when we are going to 174 * unregister this profile from the PPL. 175 */ 176 void *original_payload; 177 178 /* A CoreEntitlements context for querying the profile */ 179 der_vm_context_t profile_ctx_storage; 180 const der_vm_context_t *profile_ctx; 181 182 /* 183 * Critical information regarding the profile. If a profile has not been verified, 184 * it cannot be associated with a code signature. Development profiles are only 185 * allowed under certain circumstances. 186 */ 187 bool profile_validated; 188 bool development_profile; 189 190 /* 191 * Reference count for the number of code signatures which are currently using 192 * this provisioning profile for their constraint validation. 193 */ 194 uint32_t reference_count; 195 196 /* 197 * The list of entitlements which are provisioned by this provisioning profile. 198 * If this list allows the debuggee entitlements, then this profile is considered 199 * a development profile. 200 */ 201 struct CEQueryContext entitlements_ctx_storage; 202 struct CEQueryContext *entitlements_ctx; 203 204 /* Red-black tree linkage */ 205 RB_ENTRY(_pmap_cs_profile) link; 206 } pmap_cs_profile_t; 207 208 /* This is how we expect the kernel to hand us provisioning profiles */ 209 typedef struct _pmap_profile_payload { 210 /* Storage for the provisioning profile */ 211 pmap_cs_profile_t profile_obj_storage; 212 213 /* Size of the signed profile blob */ 214 vm_size_t profile_blob_size; 215 216 /* The signed profile blob itself */ 217 uint8_t profile_blob[0]; 218 } pmap_profile_payload_t; 219 220 /* Trust levels are ordered, i.e. higher is more trust */ 221 typedef enum { 222 PMAP_CS_UNTRUSTED = 0, 223 224 /* 225 * Trust level given to code directory entries which have been retired and are 226 * no longer valid to be used for any purpose. These code directores are freed 227 * when their reference count touches 0. 228 */ 229 PMAP_CS_RETIRED, 230 231 /* 232 * This trust level signifies that an application has been verified through the 233 * profile based certificate chain, but the profile in question itself has not 234 * been verified. Code directories with this trust aren't allowed to be run 235 * or mapped. 236 */ 237 PMAP_CS_PROFILE_PREFLIGHT, 238 239 /* 240 * Signatures provided through the compilation service. These signatures are meant 241 * to only apply to loadable libraries, and therefore have the lowest acceptable trust. 242 */ 243 PMAP_CS_COMPILATION_SERVICE, 244 245 /* 246 * Signature for out-of-process JIT. These can only be loaded by an entitled process 247 * and have a special library validation policy for being mapped within other processes. 248 * These represent a safer version of JIT. 249 */ 250 PMAP_CS_OOP_JIT, 251 252 /* 253 * These signatures are those which are trusted because they have been signed by the 254 * device local signing key. 255 */ 256 PMAP_CS_LOCAL_SIGNING, 257 258 /* 259 * These signatures belong to applications which are profile validated, and for those 260 * whose profiles have also been verified. 261 */ 262 PMAP_CS_PROFILE_VALIDATED, 263 264 /* 265 * These signatures are those belonging to the app store. 266 */ 267 PMAP_CS_APP_STORE, 268 269 #if PMAP_CS_INCLUDE_INTERNAL_CODE 270 /* 271 * Engineering roots which are still Apple signed. These don't need to be platform 272 * because they are backed by a CMS signature and therefore would've never been 273 * platform anyways. 274 */ 275 PMAP_CS_ENGINEERING_SIGNED_WITH_CMS, 276 #endif 277 278 /* 279 * These signatures represent platform binaries which have the highest trust level. 280 */ 281 PMAP_CS_IN_LOADED_TRUST_CACHE, 282 PMAP_CS_IN_STATIC_TRUST_CACHE, 283 284 #if PMAP_CS_INCLUDE_INTERNAL_CODE 285 /* 286 * Engineering roots installed by engineers for development. These are given the 287 * highest trust level. 288 */ 289 PMAP_CS_ENGINEERING_SIGNED, 290 #endif 291 } pmap_cs_trust_t; 292 293 /* Everything with greater or equal trust is a platform binary */ 294 #define PMAP_CS_LOWEST_PLATFORM_BINARY_TRUST PMAP_CS_IN_LOADED_TRUST_CACHE 295 296 /* Minimum trust level of a code signature to be run/mapped */ 297 #define PMAP_CS_LOWEST_ACCEPTABLE_TRUST PMAP_CS_COMPILATION_SERVICE 298 299 typedef struct pmap_cs_code_directory { 300 union { 301 struct { 302 /* red-black tree linkage */ 303 RB_ENTRY(pmap_cs_code_directory) link; 304 305 /* 306 * Blobs which are small enough are allocated and managed by the PPL. This field 307 * is NULL for large blobs. 308 */ 309 struct pmap_cs_blob *managed_blob; 310 bool managed; 311 312 /* 313 * The superblob of the code signature. The length we store here is the length of the 314 * memory allocated by the kernel itself, which may be greater than the actual length 315 * of the code signature. 316 */ 317 CS_SuperBlob *superblob; 318 vm_size_t superblob_size; 319 bool superblob_validated; 320 321 /* 322 * Code directories can be arbitrarily large, and hashing them can take a long time. We 323 * usually hash code directories in a continuable way, yielding our execution context 324 * after hashing some amount of the bytes. 325 */ 326 union { 327 SHA384_CTX sha384_ctx; 328 SHA256_CTX sha256_ctx; 329 SHA1_CTX sha1_ctx; 330 }; 331 uint32_t cd_length_hashed; 332 333 /* 334 * The best code directory is just an offset away from the superblob. This code directory 335 * is extensively validated for all of its fields. 336 */ 337 const CS_CodeDirectory *cd; 338 bool cd_offset_matched; 339 340 /* 341 * The first code directory is used when validating the CMS blob attached to a code signature 342 * and is often not the best code directory. 343 */ 344 bool first_cd_initialized; 345 bool first_cd_hashed; 346 uint8_t first_cdhash[CS_HASH_MAX_SIZE]; 347 const uint8_t *first_cd; 348 size_t first_cd_length; 349 const uint8_t *cms_blob; 350 size_t cms_blob_length; 351 CoreTrustDigestType ct_digest_type; 352 353 /* 354 * Frequently accessed information from the code directory kept here as a cache. 355 */ 356 const char *identifier; 357 const char *teamid; 358 bool main_binary; 359 360 /* 361 * The DER entitlements blob and CoreEntitlements context for querying this code 362 * signature for entitlements. 363 */ 364 struct CEQueryContext core_entitlements_ctx; 365 struct CEQueryContext *ce_ctx; 366 const CS_GenericBlob *der_entitlements; 367 uint32_t der_entitlements_size; 368 369 /* 370 * This is parhaps the most important field in this structure. It signifies what 371 * level of confidence we have in this code directory and this trust level 372 * defines execution/mapping policies for this code directory. 373 */ 374 pmap_cs_trust_t trust; 375 376 /* 377 * Reference count of how many regions this code directory is associated with through 378 * pmap_cs_associate. 379 */ 380 uint32_t reference_count; 381 382 /* 383 * We maintain this field as it allows us to quickly index into a bucket of supported 384 * hash types, and choose the correct hashing algorithm for this code directory. 385 */ 386 unsigned int hash_type; 387 388 /* Lock on this code directory */ 389 decl_lck_rw_data(, rwlock); 390 391 /* 392 * The PPL may transform the code directory (e.g. for multilevel hashing), 393 * which changes its cdhash. We retain the cdhash of the original, canonical 394 * code directory here. 395 */ 396 uint8_t cdhash[CS_CDHASH_LEN]; 397 398 /* 399 * For performing provisioning profile validation in the PPL, we store the profile as 400 * PPL owned data so it cannot be changed during the validation time period. 401 * 402 * This interface for profile validation is deprecated. 403 */ 404 struct { 405 /* The provisioning profile and its size */ 406 const uint8_t *profile; 407 vm_size_t profile_size; 408 409 /* Size of memory allocated to hold the profile */ 410 vm_size_t allocation_size; 411 } profile_data; 412 413 /* 414 * The provisioning profile object used for validating constrainst for profile validates 415 * signatures. This is the newer interface the PPL uses. 416 */ 417 pmap_cs_profile_t *profile_obj; 418 419 /* 420 * The leaf certificate for CMS blobs as returned to us by CoreTrust. This is used when 421 * verifying a signature against a provisioning profile. 422 */ 423 const uint8_t *cms_leaf; 424 vm_size_t cms_leaf_size; 425 426 /* 427 * The UBC layer may request the PPL to unlock the unneeded part of the code signature. 428 * We hold this boolean to track whether we have unlocked those unneeded bits already or 429 * not. 430 */ 431 bool unneeded_code_signature_unlocked; 432 }; 433 434 /* Free list linkage */ 435 struct pmap_cs_code_directory *pmap_cs_code_directory_next; 436 }; 437 } pmap_cs_code_directory_t; 438 439 /** 440 * Initialize the red-black tree and the locks for managing provisioning profiles within 441 * the PPL. 442 * 443 * This function doesn't trap into the PPL but writes to PPL protected data. Hence, this 444 * function needs to be called before the PPL is locked down, asn otherwise it will cause 445 * a system panic. 446 */ 447 void 448 pmap_initialize_provisioning_profiles(void); 449 450 /** 451 * Register a provisioning profile with the PPL. The payload address and size are both 452 * expected to be page aligned. The PPL will attempt to lockdown the address range before 453 * the profile validation. 454 * 455 * After validation, the profile will be added to an internal red-black tree, allowing 456 * the PPL to safely enumerate all registered profiles. 457 */ 458 kern_return_t 459 pmap_register_provisioning_profile( 460 const vm_address_t payload_addr, 461 const vm_size_t payload_size); 462 463 /** 464 * Unregister a provisioning profile from the PPL. The payload which was registered is 465 * unlocked, and the caller is free to do whatever they want with it. Unregistration is 466 * only successful when there are no reference counts on the profile object. 467 */ 468 kern_return_t 469 pmap_unregister_provisioning_profile( 470 pmap_cs_profile_t *profile_obj); 471 472 /** 473 * Associate a PPL profile object with a PPL code signature object. A code signature 474 * object can only have a single profile associated with it, and a successful association 475 * increments the reference count on the profile object. 476 */ 477 kern_return_t 478 pmap_associate_provisioning_profile( 479 pmap_cs_code_directory_t *cd_entry, 480 pmap_cs_profile_t *profile_obj); 481 482 /** 483 * Disassociate a PPL profile object from a PPL code signature object. Disassociation 484 * through this code path is only successful when the code signature object has been 485 * verified. 486 * 487 * This decrements the reference count on the profile object, potentially allowing it 488 * to be unregistered if the reference count hits zero. 489 */ 490 kern_return_t 491 pmap_disassociate_provisioning_profile( 492 pmap_cs_code_directory_t *cd_entry); 493 494 #endif /* PMAP_CS_INCLUDE_CODE_SIGNING */ 495 496 #endif /* XNU_KERNEL_PRIVATE */ 497 498 /* Availability macros for AppleImage4 */ 499 #if defined(__arm__) || defined(__arm64__) 500 #define PMAP_SUPPORTS_IMAGE4_NONCE 1 501 #define PMAP_SUPPORTS_IMAGE4_OBJECT_EXECUTION 1 502 #endif 503 504 /* Availability macros for developer mode */ 505 #define PMAP_SUPPORTS_DEVELOPER_MODE 1 506 507 /** 508 * The PPl allocates some space for AppleImage4 to store some of its data. It needs to 509 * allocate this space since this region needs to be PPL protected, and the macro which 510 * makes a region PPL protected isn't available to kernel extensions. 511 * 512 * This function can be used to acquire the memory region which is PPL protected. 513 */ 514 void* 515 pmap_image4_pmap_data( 516 size_t *allocated_size); 517 518 /** 519 * Use the AppleImage4 API to set a nonce value based on a particular nonce index. 520 * AppleImage4 ensures that a particular nonce domain value can only be set once 521 * during the boot of the system. 522 */ 523 void 524 pmap_image4_set_nonce( 525 const img4_nonce_domain_index_t ndi, 526 const img4_nonce_t *nonce); 527 528 /** 529 * Use the AppleImage4 API to roll the nonce associated with a particular domain to 530 * make the nonce invalid. 531 */ 532 void 533 pmap_image4_roll_nonce( 534 const img4_nonce_domain_index_t ndi); 535 536 /** 537 * Use the AppleImage4 API to copy the nonce value associated with a particular domain. 538 * 539 * The PPL will attempt to "pin" the nonce_out parameter before writing to it. 540 */ 541 errno_t 542 pmap_image4_copy_nonce( 543 const img4_nonce_domain_index_t ndi, 544 img4_nonce_t *nonce_out); 545 546 /** 547 * Use the AppleImage4 API to perform object execution of a particular known object type. 548 * 549 * These are the supported object types: 550 * - IMG4_RUNTIME_OBJECT_SPEC_INDEX_SUPPLEMENTAL_ROOT 551 */ 552 errno_t 553 pmap_image4_execute_object( 554 img4_runtime_object_spec_index_t obj_spec_index, 555 const img4_buff_t *payload, 556 const img4_buff_t *manifest); 557 558 /** 559 * Use the AppleImage4 API to copy an executed objects contents into provided memroy. 560 * 561 * The PPL will attempt to "pin" the object_out parameter before writing to it. 562 */ 563 errno_t 564 pmap_image4_copy_object( 565 img4_runtime_object_spec_index_t obj_spec_index, 566 vm_address_t object_out, 567 size_t *object_length); 568 569 __END_DECLS 570 571 #endif /* KERNEL_PRIVATE */ 572 #endif /* _VM_PMAP_CS_H_ */ 573