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