1 /*! 2 * @header 3 * Image4 runtime interfaces. 4 */ 5 #ifndef __IMG4_RUNTIME_H 6 #define __IMG4_RUNTIME_H 7 8 #ifndef __IMG4_INDIRECT 9 #error "Please #include <img4/firmware.h> instead of this file directly" 10 #endif // __IMG4_INDIRECT 11 12 OS_ASSUME_NONNULL_BEGIN 13 14 /*! 15 * @typedef img4_identifier_t 16 * An enumeration describing identifiers in the Image4 specification. 17 * 18 * @const IMG4_IDENTIFIER_CEPO 19 * The chip epoch as documented in 2.1.1. Authoritative manifests will specify a 20 * certificate epoch which is greater than or equal to that of the chip. 21 * 22 * Unsigned 32-bit integer. 23 * 24 * @const IMG4_IDENTIFIER_BORD 25 * The board identifier as documented in 2.1.3. Authoritative manifests will 26 * specify a board identifier which is equal to that of the chip. 27 * 28 * Unsigned 32-bit integer. 29 * 30 * @const IMG4_IDENTIFIER_CHIP 31 * The chip identifier as documented in 2.1.2. Authoritative manifests will 32 * specify a chip identifier which is equal to that of the chip. 33 * 34 * Unsigned 32-bit integer. 35 * 36 * @const IMG4_IDENTIFIER_SDOM 37 * The security domain as documented in 2.1.5. Authoritative manifests will 38 * specify a security domain which is equal to that that of the chip. 39 * 40 * Unsigned 32-bit integer. Valid values are 41 * 42 * 0 Manufacturing 43 * 1 Darwin 44 * 2 Data Center (unsure) 45 * 3 Unused 46 * 47 * @const IMG4_IDENTIFIER_ECID 48 * The unique chip identifier as documented in 2.1.4. Authoritative manifests 49 * will specify a unique chip identifier which is equal to that of the chip. 50 * 51 * Unsigned 64-bit integer. 52 * 53 * @const IMG4_IDENTIFIER_CPRO 54 * The certificate production status as documented in 2.1.6. Authoritative 55 * manifests will specify a certificate production status which is equal to that 56 * of the chip. 57 * 58 * Boolean. 59 * 60 * @const IMG4_IDENTIFIER_CSEC 61 * The certificate security mode as documented in 2.1.7. Authoritative manifests 62 * will specify a certificate security mode which is equal to that of the chip. 63 * 64 * Boolean. 65 * 66 * @const IMG4_IDENTIFIER_EPRO 67 * The effective production status as documented in 2.1.23. Unless the chip 68 * environment supports demotion, this will always be the same as 69 * {@link IMG4_IDENTIFIER_CPRO}. An executable firmware in an authoritative 70 * manifest will specify an EPRO object property which is equal to that of the 71 * chip post-demotion. 72 * 73 * Boolean. 74 * 75 * @const IMG4_IDENTIFIER_ESEC 76 * The effective security mode as documented in 2.1.25. Unless the chip 77 * environment supports demotion, this will always be the same as 78 * {@link IMG4_IDENTIFIER_CSEC}. An executable firmware in an authoritative 79 * manifest will specify an ESEC object property which is equal to that of the 80 * chip post-demotion. 81 * 82 * Boolean. 83 * 84 * @const IMG4_IDENTIFIER_IUOU 85 * The "internal use only unit" property. Indicates whether the chip is present 86 * on a server-side authlist which permits installing builds which are otherwise 87 * restricted to parts whose CPRO is 0. This property is only published by macOS 88 * devices whose root of trust is in an arm coprocessor (e.g. T2). 89 * 90 * Authoritative manifests will specify an internal-use-only-build property 91 * which, if true, is equal to the internal-use-only-unit property of the chip. 92 * If the internal-use-only-build property is false, then there is no constraint 93 * on the chip's internal-use-only-unit property. 94 * 95 * Boolean. 96 * 97 * @const IMG4_IDENTIFIER_RSCH 98 * The research fusing status. Indicates whether the chip is intended for 99 * security research to be performed by external parties. Authoritative 100 * manifests will specify a research fusing state which is equal to that of the 101 * chip. 102 * 103 * Boolean. 104 * 105 * This identifier was never recognized by SecureROM and has been obsoleted by 106 * {@link IMG4_IDENTIFIER_ESDM}. 107 * 108 * @const IMG4_IDENTIFIER_CHMH 109 * The chained manifest hash from the previous stage of secure boot as described 110 * in 2.2.11. An authoritative manifest will either 111 * 112 * - specify a manifest hash which is equal to that of the previous secure 113 * boot stage's manifest 114 * - itself have a manifest hash which is equal to that of the previous 115 * secure boot stage's manifest 116 * 117 * If the previous stage of secure boot enabled mix-n-match, there is no 118 * constraint on the previous stage's manifest hash. 119 * 120 * Manifests which specify this property cannot be used to create new trust 121 * chains -- they may only extend existing ones. 122 * 123 * Digest. 124 * 125 * @const IMG4_IDENTIFIER_AMNM 126 * The allow-mix-n-match status of the chip. If mix-n-match is enabled, secure 127 * boot will permit different manifests to be used at each stage of boot. If the 128 * chip environment allows mix-n-match, evaluation will not require an anti- 129 * replay token to be specified, and any chained manifest hash constraints are 130 * ignored. 131 * 132 * Boolean. 133 * 134 * @const IMG4_IDENTIFIER_EUOU 135 * The engineering-use-only-unit status of the chip. This is in effect an alias 136 * for the {@link IMG4_IDENTIFIER_IUOU} property. Either property being present 137 * in the environment will satisfy a manifest's iuob constraint. 138 * 139 * Boolean. 140 * 141 * @const IMG4_IDENTIFIER_LOVE 142 * The long version of the OS currently booted on the chip (Long Os VErsion). 143 * 144 * Authoritative manifests will specify a version number which is greater than 145 * that of the chip. 146 * 147 * C string. 148 * 149 * @const IMG4_IDENTIFIER_ESDM 150 * The extended security domain of the chip. Authoritative manifests will 151 * specify an extended security domain which is equal to that of the chip. 152 * 153 * Unsigned 32-bit integer. This integer represents 8 fusing bits, and therefore 154 * the maximum valid value is 0xff. 155 * 156 * @const IMG4_IDENTIFIER_FPGT 157 * The factory pre-release global trust status of the chip. This is in effect an 158 * alias for the {@link IMG4_IDENTIFIER_IUOU} property. Either property being 159 * present in the environment will satisfy a manifest's iuob constraint. 160 * 161 * Boolean. 162 * 163 * @const IMG4_IDENTIFIER_UDID 164 * The universal device identifier of the chip. This uniquely identifies the SoC 165 * globally across all SoCs. Authoritative manifests will specify a UDID which 166 * is equal to that of the chip. 167 * 168 * 128-bit octet string. 169 * 170 * @const IMG4_IDENTIFIER_FCHP 171 * The chip identifier of the Cryptex coprocessor associated with the chip. This 172 * distinguishes the software Crytpex coprocessor instances which operate on the 173 * AP. Authoritative manifests will specify a Cryptex chip identifier that is 174 * equal to that of the chip. 175 * 176 * Runtimes are not capable of reporting this value, and queries for it should 177 * return ENOENT. This invariant is defined for convenience to the 178 * implementation. 179 * 180 * Unsigned 32-bit integer. 181 * 182 * @const IMG4_IDENTIFIER_TYPE 183 * The type identifier of the Cryptex coprocessor associated with the chip. This 184 * distinguishes software Cryptex coprocessor instances of the same chip 185 * identifier which operate on the AP. Authoritative manifests will specify a 186 * Cryptex type that is equal to that of the chip. 187 * 188 * Runtimes are not capable of reporting this value, and queries for it should 189 * return ENOENT. This invariant is defined for convenience to the 190 * implementation. 191 * 192 * Unsigned 32-bit integer. 193 * 194 * @const IMG4_IDENTIFIER_STYP 195 * The subtype identifier of the Cryptex coprocessor associated with the chip. 196 * This permits an additional level of granularity to distinguish Cryptex 197 * coprocessor instances from one another. Authoritative manifests will specify 198 * a Cryptex subtype that is equal to that of the chip. 199 * 200 * Runtimes are not capable of reporting this value, and queries for it should 201 * return ENOENT. This invariant is defined for convenience to the 202 * implementation. 203 * 204 * Unsigned 32-bit integer. 205 * 206 * @const IMG4_IDENTIFIER_CLAS 207 * The product class of the Cryptex coprocessor associated with the chip. 208 * Authoritative manifests will specify a product class that is equal to that of 209 * the chip. 210 * 211 * Valid values for this property are: 212 * 213 * 0xf0 - Intel Mac (with or without T2 security chip) 214 * 0xf1 - Apple Silicon Mac 215 * 0xf2 - iPhone/iPad/iPod touch 216 * 0xf3 - watch 217 * 0xf4 - tv/HomePod 218 * 219 * Unsigned 32-bit integer. 220 * 221 * @const IMG4_IDENTIFIER_SPIH 222 * The booted supplemental manifest hash. 223 * 224 * Digest. 225 * 226 * @const IMG4_IDENTIFIER_NSPH 227 * The preboot supplemental manifest hash intended to become active at the next 228 * boot. 229 * 230 * Digest. 231 * 232 * @const IMG4_IDENTIFIER_STNG 233 * The generation number of the last-executed blessed local policy on the AP. 234 * 235 * Unsigned 64-bit integer. 236 * 237 * @const IMG4_IDENTIFIER_VUID 238 * The volume group UUID that the chip is booting from. 239 * 240 * 128-bit octet string. 241 * 242 * @const _IMG4_IDENTIFIER_CNT 243 * A convenience value representing the number of known identifiers. 244 */ 245 IMG4_API_AVAILABLE_20200508 246 OS_CLOSED_ENUM(img4_identifier, uint64_t, 247 IMG4_IDENTIFIER_CEPO, 248 IMG4_IDENTIFIER_BORD, 249 IMG4_IDENTIFIER_CHIP, 250 IMG4_IDENTIFIER_SDOM, 251 IMG4_IDENTIFIER_ECID, 252 IMG4_IDENTIFIER_CPRO, 253 IMG4_IDENTIFIER_CSEC, 254 IMG4_IDENTIFIER_EPRO, 255 IMG4_IDENTIFIER_ESEC, 256 IMG4_IDENTIFIER_IUOU, 257 IMG4_IDENTIFIER_RSCH, 258 IMG4_IDENTIFIER_CHMH, 259 IMG4_IDENTIFIER_AMNM, 260 IMG4_IDENTIFIER_EUOU, 261 IMG4_IDENTIFIER_LOVE, 262 IMG4_IDENTIFIER_ESDM, 263 IMG4_IDENTIFIER_FPGT, 264 IMG4_IDENTIFIER_UDID, 265 IMG4_IDENTIFIER_FCHP, 266 IMG4_IDENTIFIER_TYPE, 267 IMG4_IDENTIFIER_STYP, 268 IMG4_IDENTIFIER_CLAS, 269 IMG4_IDENTIFIER_SPIH, 270 IMG4_IDENTIFIER_NSPH, 271 IMG4_IDENTIFIER_STNG, 272 IMG4_IDENTIFIER_VUID, 273 _IMG4_IDENTIFIER_CNT, 274 ); 275 276 /*! 277 * @typedef img4_pmap_data_t 278 * An opaque type representing state protected by the host's page mapping layer 279 * as it deems appropriate. Do not use directly. 280 */ 281 IMG4_API_AVAILABLE_20210521 282 typedef struct _img4_pmap_data img4_pmap_data_t; 283 284 /*! 285 * @typedef img4_runtime_object_spec_index_t 286 * An enumeration describing the executable objects recognized by runtimes. 287 * 288 * @const IMG4_RUNTIME_OBJECT_SPEC_INDEX_MANIFEST 289 * The enumerated constant which refers to the internal manifest object. 290 * 291 * @const IMG4_RUNTIME_OBJECT_SPEC_INDEX_SUPPLEMENTAL_ROOT 292 * The enumerated constant which refers to the 293 * {@link IMG4_RUNTIME_OBJECT_SPEC_SUPPLEMENTAL_ROOT} object. 294 * 295 * @const IMG4_RUNTIME_OBJECT_SPEC_INDEX_SUPPLEMENTAL_OBJECT 296 * The enumerated constant which refers to the 297 * {@link IMG4_RUNTIME_OBJECT_SPEC_SUPPLEMENTAL_OBJECT} object. 298 * 299 * @const IMG4_RUNTIME_OBJECT_SPEC_INDEX_LOCAL_POLICY 300 * The enumerated constant which refers to the 301 * {@link IMG4_RUNTIME_OBJECT_SPEC_LOCAL_POLICY} object. 302 * 303 * @const _IMG4_RUNTIME_OBJECT_SPEC_INDEX_CNT 304 * A sentinel value representing the total number of executable object 305 * specifications. 306 */ 307 IMG4_API_AVAILABLE_20210521 308 OS_CLOSED_ENUM(img4_runtime_object_spec_index, uint64_t, 309 IMG4_RUNTIME_OBJECT_SPEC_INDEX_MANIFEST, 310 IMG4_RUNTIME_OBJECT_SPEC_INDEX_SUPPLEMENTAL_ROOT, 311 IMG4_RUNTIME_OBJECT_SPEC_INDEX_SUPPLEMENTAL_OBJECT, 312 IMG4_RUNTIME_OBJECT_SPEC_INDEX_LOCAL_POLICY, 313 _IMG4_RUNTIME_OBJECT_SPEC_INDEX_CNT, 314 ); 315 316 /*! 317 * @typedef img4_runtime_object_spec_t 318 * A specification for an object known to and executable by a runtime. 319 */ 320 IMG4_API_AVAILABLE_20210205 321 typedef struct _img4_runtime_object_spec img4_runtime_object_spec_t; 322 323 /*! 324 * @typedef img4_runtime_init_t 325 * A function which initializes the runtime. 326 * 327 * @param rt 328 * The runtime for which the function is being invoked. 329 * 330 * @discussion 331 * This function is called by the implementation prior to any other runtime 332 * function being called. The implementation will ensure that it is called only 333 * once. Any runtime with an initialization function must be registered with the 334 * {@link IMG4_RUNTIME_REGISTER} macro. 335 */ 336 IMG4_API_AVAILABLE_20200508 337 typedef void (*img4_runtime_init_t)( 338 const img4_runtime_t *rt 339 ); 340 341 /*! 342 * @typedef img4_runtime_alloc_t 343 * An allocation function. 344 * 345 * @param rt 346 * The runtime for which the function is being invoked. 347 * 348 * @param n 349 * The number of bytes to allocate. 350 * 351 * @result 352 * A pointer to the new allocation, or NULL if there was an allocation failure. 353 * 354 * The memory returned by this function is expected to be zero-filled. 355 */ 356 IMG4_API_AVAILABLE_20200508 357 typedef void *_Nullable (*img4_runtime_alloc_t)( 358 const img4_runtime_t *rt, 359 size_t n 360 ); 361 362 /*! 363 * @typedef img4_runtime_dealloc_t 364 * A deallocation function. 365 * 366 * @param rt 367 * The runtime for which the function is being invoked. 368 * 369 * @param p 370 * A pointer to the allocation to free. The callee is expected to return 371 * immediately if NULL is passed. 372 * 373 * @param n 374 * The size of the allocation. Not all implementation may require this 375 * information to be specified. 376 */ 377 IMG4_API_AVAILABLE_20200508 378 typedef void (*img4_runtime_dealloc_t)( 379 const img4_runtime_t *rt, 380 void *_Nullable p, 381 size_t n 382 ); 383 384 /*! 385 * @typedef img4_log_level_t 386 * An enumeration describing the importance/severity of a log message. 387 * 388 * @const IMG4_LOG_LEVEL_ERROR 389 * A fatal condition which will cause the implementation to abort its current 390 * operation. 391 * 392 * @const IMG4_LOG_LEVEL_INFO 393 * Information that may be of interest to the system operator. 394 * 395 * @const IMG4_LOG_LEVEL_DEBUG 396 * Information that may be of interest to the maintainer. 397 * 398 * @const _IMG4_LOG_LEVEL_CNT 399 * A convenience constant indicating the number of log levels. 400 */ 401 IMG4_API_AVAILABLE_20200508 402 OS_CLOSED_ENUM(img4_log_level, uint64_t, 403 IMG4_LOG_LEVEL_ERROR, 404 IMG4_LOG_LEVEL_INFO, 405 IMG4_LOG_LEVEL_DEBUG, 406 _IMG4_LOG_LEVEL_CNT, 407 ); 408 409 /*! 410 * @typedef img4_runtime_log_t 411 * A function which writes log messages. 412 * 413 * @param rt 414 * The runtime for which the function is being invoked. 415 * 416 * @param handle 417 * An implementation-specific handle for the log message. 418 * 419 * @param level 420 * The message of the log level. The implementation is free to determine whether 421 * a given message is worthy of record. 422 * 423 * @param fmt 424 * A printf(3)-style format string. 425 * 426 * @param ... 427 * Arguments to be interpreted by the format string according to the 428 * specifications in printf(3). 429 */ 430 OS_FORMAT_PRINTF(4, 5) 431 IMG4_API_AVAILABLE_20200508 432 typedef void (*img4_runtime_log_t)( 433 const img4_runtime_t *rt, 434 void *_Nullable handle, 435 img4_log_level_t level, 436 const char *fmt, 437 ... 438 ); 439 440 /*! 441 * @typedef img4_runtime_log_handle_t 442 * A function which returns a log handle. 443 * 444 * @param rt 445 * The runtime for which the function is being invoked. 446 * 447 * @result 448 * A runtime-specific log handle that will be passed to the logging function. 449 */ 450 IMG4_API_AVAILABLE_20200508 451 typedef void *_Nullable (*img4_runtime_log_handle_t)( 452 const img4_runtime_t *rt 453 ); 454 455 /*! 456 * @typedef img4_runtime_get_identifier_bool_t 457 * A function which retrieves a Boolean Image4 identifier. 458 * 459 * @param rt 460 * The runtime for which the function is being invoked. 461 * 462 * @param chip 463 * The chip for which to retrieve the identifier. 464 * 465 * @param identifier 466 * The identifier to retrieve. 467 * 468 * @param value 469 * Upon successful return, storage which is populated with the retrieved value. 470 * 471 * @result 472 * Upon success, the callee is expected to return zero. Otherwise, the callee 473 * may return one of the following error codes: 474 * 475 * [ENOTSUP] The identifier cannot be queried in the runtime 476 * [ENOENT] The identifier was not found in the runtime's identity 477 * oracle 478 * [ENODEV] There was an error querying the runtime's identity oracle 479 */ 480 IMG4_API_AVAILABLE_20200508 481 typedef errno_t (*img4_runtime_get_identifier_bool_t)( 482 const img4_runtime_t *rt, 483 const img4_chip_t *chip, 484 img4_identifier_t identifier, 485 bool *value 486 ); 487 488 /*! 489 * @typedef img4_runtime_get_identifier_uint32_t 490 * A function which retrieves an unsigned 32-bit integer Image4 identifier. 491 * 492 * @param rt 493 * The runtime for which the function is being invoked. 494 * 495 * @param chip 496 * The chip for which to retrieve the identifier. 497 * 498 * @param identifier 499 * The identifier to retrieve. 500 * 501 * @param value 502 * Upon successful return, storage which is populated with the retrieved value. 503 * 504 * @result 505 * Upon success, the callee is expected to return zero. Otherwise, the callee 506 * may return one of the following error codes: 507 * 508 * [ENOTSUP] The identifier cannot be queried in the runtime 509 * [ENOENT] The identifier was not found in the runtime's identity 510 * oracle 511 * [ENODEV] There was an error querying the runtime's identity oracle 512 */ 513 IMG4_API_AVAILABLE_20200508 514 typedef errno_t (*img4_runtime_get_identifier_uint32_t)( 515 const img4_runtime_t *rt, 516 const img4_chip_t *chip, 517 img4_identifier_t identifier, 518 uint32_t *value 519 ); 520 521 /*! 522 * @typedef img4_runtime_get_identifier_uint64_t 523 * A function which retrieves an unsigned 64-bit integer Image4 identifier. 524 * 525 * @param rt 526 * The runtime for which the function is being invoked. 527 * 528 * @param chip 529 * The chip for which to retrieve the identifier. 530 * 531 * @param identifier 532 * The identifier to retrieve. 533 * 534 * @param value 535 * Upon successful return, storage which is populated with the retrieved value. 536 * 537 * @result 538 * Upon success, the callee is expected to return zero. Otherwise, the callee 539 * may return one of the following error codes: 540 * 541 * [ENOTSUP] The identifier cannot be queried in the runtime 542 * [ENOENT] The identifier was not found in the runtime's identity 543 * oracle 544 * [ENODEV] There was an error querying the runtime's identity oracle 545 */ 546 IMG4_API_AVAILABLE_20200508 547 typedef errno_t (*img4_runtime_get_identifier_uint64_t)( 548 const img4_runtime_t *rt, 549 const img4_chip_t *chip, 550 img4_identifier_t identifier, 551 uint64_t *value 552 ); 553 554 /*! 555 * @typedef img4_runtime_get_identifier_digest_t 556 * A function which retrieves a digest Image4 identifier. 557 * 558 * @param rt 559 * The runtime for which the function is being invoked. 560 * 561 * @param chip 562 * The chip for which to retrieve the identifier. 563 * 564 * @param identifier 565 * The identifier to retrieve. 566 * 567 * @param value 568 * Upon successful return, storage which is populated with the retrieved value. 569 * 570 * @result 571 * Upon success, the callee is expected to return zero. Otherwise, the callee 572 * may return one of the following error codes: 573 * 574 * [ENOTSUP] The identifier cannot be queried in the runtime 575 * [ENOENT] The identifier was not found in the runtime's identity 576 * oracle 577 * [ENODEV] There was an error querying the runtime's identity oracle 578 */ 579 IMG4_API_AVAILABLE_20200508 580 typedef errno_t (*img4_runtime_get_identifier_digest_t)( 581 const img4_runtime_t *rt, 582 const img4_chip_t *chip, 583 img4_identifier_t identifier, 584 img4_dgst_t *value 585 ); 586 587 /*! 588 * @typedef img4_runtime_get_identifier_cstr_t 589 * A function which retrieves a C-string Image4 identifier. 590 * 591 * @param rt 592 * The runtime for which the function is being invoked. 593 * 594 * @param chip 595 * The chip for which to retrieve the identifier. 596 * 597 * @param identifier 598 * The identifier to retrieve. 599 * 600 * @param value 601 * Upon successful return, storage which is populated with the retrieved value. 602 * 603 * @result 604 * Upon success, the callee is expected to return zero. Otherwise, the callee 605 * may return one of the following error codes: 606 * 607 * [ENOTSUP] The identifier cannot be queried in the runtime 608 * [ENOENT] The identifier was not found in the runtime's identity 609 * oracle 610 * [ENODEV] There was an error querying the runtime's identity oracle 611 */ 612 IMG4_API_AVAILABLE_20210113 613 typedef errno_t (*img4_runtime_get_identifier_cstr_t)( 614 const img4_runtime_t *rt, 615 const img4_chip_t *chip, 616 img4_identifier_t identifier, 617 img4_cstr_t *value 618 ); 619 620 /*! 621 * @typedef img4_runtime_execute_object_t 622 * A function which executes an object type known to the runtime. 623 * 624 * @param rt 625 * The runtime for which the function is being invoked. 626 * 627 * @param obj_spec 628 * The object specification for the payload being executed. 629 * 630 * @param payload 631 * The payload bytes to execute. These bytes are delivered in their raw form, 632 * i.e. without any Image4 payload wrapping. 633 * 634 * @param manifest 635 * The manifest which authenticats the payload. If the payload is intended to be 636 * used without authentication (or with alternate means of authentication), this 637 * may be NULL. 638 * 639 * @result 640 * Upon success, the callee is expected to return zero. Otherwise, the callee 641 * may return any appropriate POSIX error code. 642 * 643 * @discussion 644 * This function is only called if the payload has been successfully 645 * authenticated; the callee can consider the bytes as trusted. 646 */ 647 IMG4_API_AVAILABLE_20210205 648 typedef errno_t (*img4_runtime_execute_object_t)( 649 const img4_runtime_t *rt, 650 const img4_runtime_object_spec_t *obj_spec, 651 const img4_buff_t *payload, 652 const img4_buff_t *_Nullable manifest 653 ); 654 655 /*! 656 * @typedef img4_runtime_copy_object_t 657 * A function which obtains the payload of a previously-executed object. 658 * 659 * @param rt 660 * The runtime for which the function is being invoked. 661 * 662 * @param obj_spec 663 * The object specification for the payload being obtained. 664 * 665 * @param payload 666 * A pointer to a buffer object in which to copy the object. 667 * 668 * @param payload_len 669 * Upon successful return, a pointer to the total number of bytes coped into the 670 * buffer referred to by {@link payload}. This parameter may be NULL. 671 * 672 * In the event that buffer referred to be {@link payload} is insufficient to, 673 * accommodate the object, the callee is expected to set this parameter to the 674 * total number of bytes required. 675 * 676 * @result 677 * Upon success, the callee is expected to return zero. Otherwise, the callee 678 * may return one of the following error codes: 679 * 680 * [EOVERFLOW] The provided buffer is not large enough for the payload; 681 * in this case the callee is expected to set the 682 * {@link i4b_len} of the given buffer to the required 683 * length 684 * [ENOENT] The object has not yet been executed 685 */ 686 IMG4_API_AVAILABLE_20210205 687 typedef errno_t (*img4_runtime_copy_object_t)( 688 const img4_runtime_t *rt, 689 const img4_runtime_object_spec_t *obj_spec, 690 img4_buff_t *payload, 691 size_t *_Nullable payload_len 692 ); 693 694 /*! 695 * @typedef img4_runtime_alloc_type_t 696 * A function which allocates a single object of a given type. 697 * 698 * @param rt 699 * The runtime for which the function is being invoked. 700 * 701 * @param handle 702 * The domain-specific handle describing the object and the allocation site. 703 * 704 * @result 705 * A pointer to the new allocation, or NULL if there was an allocation failure. 706 * The memory returned by this function is expected to be zero-filled. 707 */ 708 IMG4_API_AVAILABLE_20210226 709 typedef void *_Nullable (*img4_runtime_alloc_type_t)( 710 const img4_runtime_t *rt, 711 void *_Nullable handle 712 ); 713 714 /*! 715 * @typedef img4_runtime_dealloc_type_t 716 * A function which deallocates a single object of a given type. 717 * 718 * @param rt 719 * The runtime for which the function is being invoked. 720 * 721 * @param handle 722 * The domain-specific handle describing the object and the deallocation site. 723 * 724 * @param p 725 * The address of the object to deallocate. 726 */ 727 IMG4_API_AVAILABLE_20210226 728 typedef void (*img4_runtime_dealloc_type_t)( 729 const img4_runtime_t *rt, 730 void *_Nullable handle, 731 void *p 732 ); 733 734 /*! 735 * @typedef img4_runtime_set_nonce_t 736 * A function which sets the value of a nonce managed by the runtime. 737 * 738 * @param rt 739 * The runtime for which the function is being invoked. 740 * 741 * @param ndi 742 * The index of the nonce domain whose nonce should be set. 743 * 744 * @param n 745 * The value of the nonce indicated by {@link nd}. 746 */ 747 IMG4_API_AVAILABLE_20210521 748 typedef void (*img4_runtime_set_nonce_t)( 749 const img4_runtime_t *rt, 750 img4_nonce_domain_index_t ndi, 751 const img4_nonce_t *n 752 ); 753 754 /*! 755 * @typedef img4_runtime_roll_nonce_t 756 * A function which rolls a nonce managed by the runtime. 757 * 758 * @param rt 759 * The runtime for which the function is being invoked. 760 * 761 * @param ndi 762 * The index of the nonce domain whose nonce should be rolled. 763 */ 764 IMG4_API_AVAILABLE_20210521 765 typedef void (*img4_runtime_roll_nonce_t)( 766 const img4_runtime_t *rt, 767 img4_nonce_domain_index_t ndi 768 ); 769 770 /*! 771 * @typedef img4_runtime_copy_nonce_t 772 * A function which retrieve the value of a nonce managed by the runtime. 773 * 774 * @param rt 775 * The runtime for which the function is being invoked. 776 * 777 * @param ndi 778 * The index of the nonce domain whose nonce should be queried. 779 * 780 * @param n 781 * Upon successful return, the value of the nonce indicated by {@link nd}. If 782 * the caller simply wishes to check if the nonce has been invalidated, this 783 * parameter may be NULL, and the caller can check for ESTALE. 784 * 785 * @result 786 * Upon success, zero is returned. The implementation may also return one of the 787 * following error codes directly: 788 * 789 * [ESTALE] The nonce for the given domain has been invalidated, and the 790 * host must reboot in order to generate a new one 791 */ 792 IMG4_API_AVAILABLE_20210521 793 typedef errno_t (*img4_runtime_copy_nonce_t)( 794 const img4_runtime_t *rt, 795 img4_nonce_domain_index_t ndi, 796 img4_nonce_t *_Nullable n 797 ); 798 799 /*! 800 * @define IMG4_BUFF_STRUCT_VERSION 801 * The version of the {@link img4_buff_t} structure supported by the 802 * implementation. 803 */ 804 #define IMG4_BUFF_STRUCT_VERSION (0u) 805 806 /*! 807 * @struct _img4_buff 808 * A structure describing a buffer. 809 * 810 * @field i4b_version 811 * The version of the structure. Initialize to {@link IMG4_BUFF_STRUCT_VERSION}. 812 * 813 * @field i4b_bytes 814 * A pointer to the buffer. 815 * 816 * @field i4b_len 817 * The length of the buffer. 818 * 819 * @field i4b_dealloc 820 * The deallocation function for the buffer. May be NULL if the underlying 821 * memory does not require cleanup. When the implementation invokes this 822 * function, it will always pass {@link IMG4_RUNTIME_DEFAULT}, and the callee 823 * should not consult this parameter for any reason. 824 */ 825 struct _img4_buff { 826 img4_struct_version_t i4b_version; 827 uint8_t *i4b_bytes; 828 size_t i4b_len; 829 img4_runtime_dealloc_t _Nullable i4b_dealloc; 830 } IMG4_API_AVAILABLE_20200508; 831 832 /*! 833 * @const IMG4_BUFF_INIT 834 * A convenience initializer for the {@link img4_buff_t} structure. 835 */ 836 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 837 #define IMG4_BUFF_INIT (img4_buff_t){ \ 838 .i4b_version = IMG4_BUFF_STRUCT_VERSION, \ 839 .i4b_len = 0, \ 840 .i4b_bytes = NULL, \ 841 .i4b_dealloc = NULL, \ 842 } 843 #elif defined(__cplusplus) && __cplusplus >= 201103L 844 #define IMG4_BUFF_INIT (img4_buff_t{ \ 845 IMG4_BUFF_STRUCT_VERSION, \ 846 NULL, \ 847 0, \ 848 NULL, \ 849 }) 850 #elif defined(__cplusplus) 851 #define IMG4_BUFF_INIT (img4_buff_t((img4_buff_t){ \ 852 IMG4_BUFF_STRUCT_VERSION, \ 853 NULL, \ 854 0, \ 855 NULL, \ 856 })) 857 #else 858 #define IMG4_BUFF_INIT {IMG4_BUFF_STRUCT_VERSION} 859 #endif 860 861 /*! 862 * @define IMG4_RUNTIME_STRUCT_VERSION 863 * The version of the {@link img4_runtime_t} structure supported by the 864 * implementation. 865 */ 866 #define IMG4_RUNTIME_STRUCT_VERSION (5u) 867 868 /*! 869 * @struct _img4_runtime 870 * A structure describing required primitives in the operating environment's 871 * runtime. 872 * 873 * @field i4rt_version 874 * The version of the structure supported by the implementation. In a custom 875 * execution context, initialize to {@link IMG4_RUNTIME_STRUCT_VERSION}. 876 * 877 * @field i4rt_name 878 * A string describing the environment. 879 * 880 * @field i4rt_init 881 * The runtime initialization function. See discussion in 882 * {@link img4_runtime_init_t}. 883 * 884 * @field i4rt_alloc 885 * The allocation function for the environment (e.g. in Darwin userspace, this 886 * would be a pointer to malloc(3)). The memory returned is expected to be zero- 887 * filled. 888 * 889 * @field i4rt_dealloc 890 * The deallocation function for the environment (e.g. in Darwin userspace, this 891 * would be a pointer to free(3)). 892 * 893 * @field i4rt_log 894 * The function which logs messages from the implementation. 895 * 896 * @field i4rt_log_handle 897 * The function which returns the handle to be passed to the logging function. 898 * 899 * @field i4rt_get_identifier_bool 900 * The function which returns Boolean identifiers. 901 * 902 * @field i4rt_get_identifier_uint32 903 * The function which returns unsigned 32-bit integer identifiers. 904 * 905 * @field i4rt_get_identifier_uint64 906 * The function which returns unsigned 64-bit integer identifiers. 907 * 908 * @field i4rt_get_identifier_digest 909 * The function which returns digest identifiers. 910 * 911 * @field i4rt_context 912 * A user-defined context pointer. Introduced in version 1 of the structure. 913 * 914 * @field i4rt_get_identifier_cstr 915 * The function which returns C-string identifiers. Introduced in version 2 of 916 * the structure. 917 * 918 * @field i4rt_execute_object 919 * The function which executes objects. Introduced in version 3 of the 920 * structure. 921 * 922 * @field i4rt_copy_object 923 * The function which copies objects. Introduced in version 3 of the structure. 924 * 925 * @field i4rt_alloc_type 926 * The typed allocation function for the environment. This allocator should be 927 * used for any fixed-size, structured allocation that may contain pointers. 928 * 929 * The memory returned is expected to be zero-filled. Introduced in version 4 of 930 * the structure. 931 * 932 * @field i4rt_dealloc_type 933 * The typed deallocation function for the environment. Introduced in version 4 934 * of the structure. 935 * 936 * @field i4rt_set_nonce 937 * The nonce-set function for the environment. Introduced in version 5 of the 938 * structure. 939 * 940 * @field i4rt_roll_nonce 941 * The nonce-roll function for the environment. Introduced in version 5 of the 942 * structure. 943 * 944 * @field i4rt_roll_nonce 945 * The nonce-copy function for the environment. Introduced in version 5 of the 946 * structure. 947 */ 948 struct _img4_runtime { 949 img4_struct_version_t i4rt_version; 950 const char *i4rt_name; 951 img4_runtime_init_t _Nullable i4rt_init; 952 img4_runtime_alloc_t i4rt_alloc; 953 img4_runtime_dealloc_t i4rt_dealloc; 954 img4_runtime_log_t i4rt_log; 955 img4_runtime_log_handle_t i4rt_log_handle; 956 img4_runtime_get_identifier_bool_t i4rt_get_identifier_bool; 957 img4_runtime_get_identifier_uint32_t i4rt_get_identifier_uint32; 958 img4_runtime_get_identifier_uint64_t i4rt_get_identifier_uint64; 959 img4_runtime_get_identifier_digest_t i4rt_get_identifier_digest; 960 void *_Nullable i4rt_context; 961 img4_runtime_get_identifier_cstr_t i4rt_get_identifier_cstr; 962 img4_runtime_execute_object_t i4rt_execute_object; 963 img4_runtime_copy_object_t i4rt_copy_object; 964 img4_runtime_alloc_type_t i4rt_alloc_type; 965 img4_runtime_dealloc_type_t i4rt_dealloc_type; 966 img4_runtime_set_nonce_t i4rt_set_nonce; 967 img4_runtime_roll_nonce_t i4rt_roll_nonce; 968 img4_runtime_copy_nonce_t i4rt_copy_nonce; 969 } IMG4_API_AVAILABLE_20200508; 970 971 /*! 972 * @function IMG4_RUNTIME_REGISTER 973 * Registers a runtime with the module implementation such that its 974 * initialization function can be called. In environments which support dynamic 975 * library linkage, only runtimes registered from the main executable image can 976 * be discovered by the implementation. 977 * 978 * @param _rt 979 * The img4_runtime_t structure to register. 980 */ 981 #define IMG4_RUNTIME_REGISTER(_rt) LINKER_SET_ENTRY(__img4_rt, _rt); 982 983 /*! 984 * @const IMG4_RUNTIME_DEFAULT 985 * The default runtime for the current operating environment. 986 */ 987 #if !XNU_KERNEL_PRIVATE 988 IMG4_API_AVAILABLE_20200508 989 OS_EXPORT 990 const img4_runtime_t _img4_runtime_default; 991 #define IMG4_RUNTIME_DEFAULT (&_img4_runtime_default) 992 #else 993 #define IMG4_RUNTIME_DEFAULT (img4if->i4if_v7.runtime_default) 994 #endif 995 996 /*! 997 * @const IMG4_RUNTIME_PMAP_CS 998 * The runtime for the xnu pmap layer which is safe to be executed in a 999 * supervisor execution level if supported by hardware. This runtime is not 1000 * available outside the kernel-proper. 1001 */ 1002 #if XNU_KERNEL_PRIVATE 1003 #define IMG4_RUNTIME_PMAP_CS (img4if->i4if_v7.runtime_pmap_cs) 1004 #elif _DARWIN_BUILDING_TARGET_APPLEIMAGE4 1005 #define IMG4_RUNTIME_PMAP_CS (&_img4_runtime_pmap_cs) 1006 #endif 1007 1008 /*! 1009 * @const IMG4_RUNTIME_RESTORE 1010 * The runtime for the restore ramdisk. This runtime is not available outside 1011 * of the Darwin userspace library. 1012 */ 1013 #if !KERNEL 1014 IMG4_API_AVAILABLE_20200508 1015 OS_EXPORT 1016 const img4_runtime_t _img4_runtime_restore; 1017 #define IMG4_RUNTIME_RESTORE (&_img4_runtime_restore) 1018 #endif 1019 1020 /*! 1021 * @function img4_buff_dealloc 1022 * Deallocates a buffer according to its deallocation function. 1023 * 1024 * @param buff 1025 * A pointer to the a pointer to the buffer. This parameter may be NULL, in 1026 * which case the implementation will return immediately. 1027 * 1028 * @discussion 1029 * This interface will always invoke the deallocation callback with 1030 * {@link IMG4_RUNTIME_DEFAULT}. The callee should not consult this parameter 1031 * for any reason. 1032 */ 1033 #if !XNU_KERNEL_PRIVATE 1034 IMG4_API_AVAILABLE_20200508 1035 OS_EXPORT 1036 void 1037 img4_buff_dealloc(img4_buff_t *_Nullable buff); 1038 #else 1039 #define img4_buff_dealloc(...) (img4if->i4if_v7.buff_dealloc(__VA_ARGS__)) 1040 #endif 1041 1042 #pragma mark Object Specifications 1043 /*! 1044 * @const IMG4_RUNTIME_OBJECT_SPEC_SUPPLEMENTAL_ROOT 1045 * The DER representation of the certificate to use as the root of trust for 1046 * evaluating the supplemental software package. This object can only be 1047 * executed once for any given boot session. 1048 */ 1049 #if !XNU_KERNEL_PRIVATE 1050 IMG4_API_AVAILABLE_20210205 1051 OS_EXPORT 1052 const img4_runtime_object_spec_t _img4_runtime_object_spec_supplemental_root; 1053 #define IMG4_RUNTIME_OBJECT_SPEC_SUPPLEMENTAL_ROOT \ 1054 (&_img4_runtime_object_spec_supplemental_root) 1055 #else 1056 #define IMG4_RUNTIME_OBJECT_SPEC_SUPPLEMENTAL_ROOT \ 1057 (img4if->i4if_v11.runtime_object_spec_supplemental_root) 1058 #endif 1059 1060 /*! 1061 * @const IMG4_RUNTIME_OBJECT_SPEC_LOCAL_POLICY 1062 * The local policy object which has been authorized by the user for a 1063 * subsequent boot of the system. This object may be executed multiple times in 1064 * a given boot session. A subsequent local policy must have been authorized by 1065 * the user after the currently-active one in order to successfully execute. 1066 */ 1067 #if !XNU_KERNEL_PRIVATE 1068 IMG4_API_AVAILABLE_20210205 1069 OS_EXPORT 1070 const img4_runtime_object_spec_t _img4_runtime_object_spec_local_policy; 1071 #define IMG4_RUNTIME_OBJECT_SPEC_LOCAL_POLICY \ 1072 (&_img4_runtime_object_spec_local_policy) 1073 #else 1074 #define IMG4_RUNTIME_OBJECT_SPEC_LOCAL_POLICY \ 1075 (img4if->i4if_v18.runtime_object_spec_local_policy) 1076 #endif 1077 1078 #pragma mark API 1079 /*! 1080 * @function img4_runtime_find_object_spec 1081 * Returns the object specification for the given four-character code. 1082 * 1083 * @param _4cc 1084 * The four-character code for which to find the object specification. 1085 * 1086 * @result 1087 * The object specification, or NULL if the four-character code is not an 1088 * executable object known to the implementation. 1089 */ 1090 #if !XNU_KERNEL_PRIVATE 1091 IMG4_API_AVAILABLE_20210205 1092 OS_EXPORT OS_WARN_RESULT 1093 const img4_runtime_object_spec_t *_Nullable 1094 img4_runtime_find_object_spec(img4_4cc_t _4cc); 1095 #else 1096 #define img4_runtime_find_object_spec(...) \ 1097 (img4if->i4if_v11.runtime_find_object_spec(__VA_ARGS__)) 1098 #endif 1099 1100 /*! 1101 * @function img4_runtime_execute_object 1102 * Executes an object within the runtime. 1103 * 1104 * @param rt 1105 * The runtime in which to execute the object. 1106 * 1107 * @param obj_spec 1108 * The specification for the object. 1109 * 1110 * @param obj 1111 * The buffer representing the object. The structure and form of the bytes 1112 * is dictated by the object specification. Usually, these bytes are a wrapped 1113 * Image4 payload. 1114 * 1115 * @param manifest 1116 * The Image4 manifest authenticating the object. If the object has a manifest 1117 * stitched to it, this parameter may be NULL. 1118 * 1119 * @result 1120 * Upon success, zero is returned. Otherwise, one of the following error codes: 1121 * 1122 * [EPERM] The caller does not have permission to set the object 1123 * [EALREADY] The object may only be set once, and it has already been set 1124 * 1125 * Any error code returned by {@link img4_firmware_evaluate} may also be 1126 * returned. 1127 * 1128 * Any error code returned by the runtime's {@link i4rt_execute_object} callback 1129 * will also be returned. 1130 */ 1131 #if !XNU_KERNEL_PRIVATE 1132 IMG4_API_AVAILABLE_20210205 1133 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3 1134 errno_t 1135 img4_runtime_execute_object(const img4_runtime_t *rt, 1136 const img4_runtime_object_spec_t *obj_spec, 1137 const img4_buff_t *obj, 1138 const img4_buff_t *_Nullable manifest); 1139 #else 1140 #define img4_runtime_execute_object(...) \ 1141 (img4if->i4if_v11.runtime_execute_object(__VA_ARGS__)) 1142 #endif 1143 1144 /*! 1145 * @function img4_runtime_copy_object 1146 * Copies the payload of an object executed within the runtime. 1147 * 1148 * @param rt 1149 * The runtime in which to query the object. 1150 * 1151 * @param obj_spec 1152 * The specification for the object. 1153 * 1154 * @param payload 1155 * Upon successful return, a pointer to a buffer object which refers to storage 1156 * that will hold the payload. 1157 * 1158 * @param payload_len 1159 * Upon successful return, a pointer to the total number of bytes coped into the 1160 * buffer referred to by {@link payload}. This parameter may be NULL. 1161 * 1162 * In the event that buffer referred to be {@link payload} is not large enough, 1163 * this parameter will be set to the total number of bytes required. 1164 * 1165 * @result 1166 * Upon success, zero is returned. Otherwise, one of the following error codes: 1167 * 1168 * [EPERM] The caller does not have permission to copy the object 1169 * [ENOENT] The requested object is not present 1170 */ 1171 #if !XNU_KERNEL_PRIVATE 1172 IMG4_API_AVAILABLE_20210205 1173 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3 1174 errno_t 1175 img4_runtime_copy_object(const img4_runtime_t *rt, 1176 const img4_runtime_object_spec_t *obj_spec, 1177 img4_buff_t *payload, 1178 size_t *_Nullable payload_len); 1179 #else 1180 #define img4_runtime_copy_object(...) \ 1181 (img4if->i4if_v11.runtime_copy_object(__VA_ARGS__)) 1182 #endif 1183 1184 OS_ASSUME_NONNULL_END 1185 1186 #endif // __IMG4_RUNTIME_H 1187