1 /* 2 * Copyright © 2017-2024 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 /*! 29 * @header 30 * Encapsulation which describes an Image4 environment. The environment 31 * encompasses chip properties and trust evaluation policies, including digest 32 * algorithm selection and secure boot level enforcement. 33 */ 34 #ifndef __IMAGE4_API_ENVIRONMENT_H 35 #define __IMAGE4_API_ENVIRONMENT_H 36 37 #include <image4/image4.h> 38 #include <image4/types.h> 39 #include <image4/coprocessor.h> 40 #include <stdbool.h> 41 42 __BEGIN_DECLS 43 OS_ASSUME_NONNULL_BEGIN 44 OS_ASSUME_PTR_ABI_SINGLE_BEGIN 45 46 #pragma mark Forward Types 47 /*! 48 * @typedef image4_environment_storage_t 49 * The canonical type for environment storage. 50 */ 51 typedef struct _image4_environment_storage image4_environment_storage_t; 52 53 /*! 54 * @typedef image4_environment_query_boot_nonce_t 55 * A callback to provide the boot nonce for the environment. 56 * 57 * @param nv 58 * The environment for which to retrieve the boot nonce. 59 * 60 * @param n 61 * Storage in which the callee should write the nonce upon successful return. 62 * 63 * @param n_len 64 * Storage in which the callee should write the nonce length upon successful 65 * return. 66 * 67 * On function entry, the content of this parameter is undefined. 68 * 69 * @param _ctx 70 * The context pointer which was provided during the environment's construction. 71 * 72 * @result 73 * The callee is expected to return zero on success. Otherwise, the callee may 74 * return one of the following POSIX error codes: 75 * 76 * [ENOTSUP] Obtaining the boot nonce is not supported; this will cause the 77 * implementation to act as if no callback was specified 78 * [ENOENT] The boot nonce does not exist 79 * [ENXIO] The boot nonce is not yet available for the environment, and 80 * the environment's bootstrap nonce (if any) should be used for 81 * anti-replay instead 82 * 83 * @discussion 84 * This callback is utilized by exec, sign, and boot trust evaluations. 85 */ 86 typedef errno_t (*image4_environment_query_boot_nonce_t)( 87 const image4_environment_t *nv, 88 uint8_t n[__static_size _Nonnull IMAGE4_NONCE_MAX_LEN], 89 size_t *n_len, 90 void *_ctx 91 ); 92 93 /*! 94 * @typedef image4_environment_query_nonce_digest_t 95 * A callback to provide a nonce digest for use during preflight trust 96 * evaluations. 97 * 98 * @param nv 99 * The environment for which to retrieve the boot nonce. 100 * 101 * @param nd 102 * Storage in which the callee should write the nonce digest upon successful 103 * return. 104 * 105 * @param nd_len 106 * Storage in which the callee should write the nonce digest length upon 107 * successful return. 108 * 109 * On function entry, the content of this parameter is undefined. 110 * 111 * @param _ctx 112 * The context pointer which was provided during the environment's construction. 113 * 114 * @result 115 * The callee is expected to return zero on success. Otherwise, the callee may 116 * return one of the following POSIX error codes: 117 * 118 * [ENOTSUP] Obtaining the nonce digest is not supported; this will cause 119 * the implementation to act as if no callback was specified 120 * [ENOENT] The nonce digest does not exist 121 * 122 * @discussion 123 * This callback is utilized by preflight, sign, and boot trust evaluations. In 124 * sign and trust trust evaluations, it is only called if the nonce itself 125 * cannot be obtained from either the environment internally or the boot nonce 126 * callback. 127 */ 128 typedef errno_t (*image4_environment_query_nonce_digest_t)( 129 const image4_environment_t *nv, 130 uint8_t nd[__static_size _Nonnull IMAGE4_DIGEST_MAX_LEN], 131 size_t *nd_len, 132 void *_ctx 133 ); 134 135 /*! 136 * @typedef image4_environment_identifier_bool_t 137 * A callback which conveys the value of a Boolean identifier associated with 138 * the environment during an identification. 139 * 140 * @param nv 141 * The environment which is being identified. 142 * 143 * @param id4 144 * The Boolean identifier. 145 * 146 * @param val 147 * The value of the identifier. 148 * 149 * @param _ctx 150 * The context pointer which was provided during the environment's construction. 151 */ 152 typedef void (*image4_environment_identifier_bool_t)( 153 const image4_environment_t *nv, 154 const image4_identifier_t *id4, 155 bool val, 156 void *_ctx 157 ); 158 159 /*! 160 * @typedef image4_environment_identifier_integer_t 161 * A callback which conveys the value of an unsigned 64-bit integer identifier 162 * associated with the environment during an identification. 163 * 164 * @param nv 165 * The environment which is being identified. 166 * 167 * @param id4 168 * The integer identifier. 169 * 170 * @param val 171 * The value of the identifier. 172 * 173 * @param _ctx 174 * The context pointer which was provided during the environment's construction. 175 */ 176 typedef void (*image4_environment_identifier_integer_t)( 177 const image4_environment_t *nv, 178 const image4_identifier_t *id4, 179 uint64_t val, 180 void *_ctx 181 ); 182 183 /*! 184 * @typedef image4_environment_identifier_data_t 185 * A callback which conveys the value of an octet string identifier associated 186 * with the environment during an identification. 187 * 188 * @param nv 189 * The environment which is being identified. 190 * 191 * @param id4 192 * The octet string identifier. 193 * 194 * @param vp 195 * A pointer to the octet string bytes. 196 * 197 * @param vp_len 198 * The length of the octet string indicated by {@link vp}. 199 * 200 * @param _ctx 201 * The context pointer which was provided during the environment's construction. 202 */ 203 typedef void (*image4_environment_identifier_data_t)( 204 const image4_environment_t *nv, 205 const image4_identifier_t *id4, 206 const void *vp, 207 size_t vp_len, 208 void *_ctx 209 ); 210 211 /*! 212 * @const IMAGE4_ENVIRONMENT_CALLBACKS_STRUCT_VERSION 213 * The version of the {@link image4_environment_callbacks_t} structure supported 214 * by the implementation. 215 */ 216 #define IMAGE4_ENVIRONMENT_CALLBACKS_STRUCT_VERSION (0u) 217 218 /*! 219 * @struct image4_environment_callbacks_t 220 * A callback structure which may be given to influence the behavior of an 221 * {@link image4_environment_t}. 222 * 223 * @field nvcb_version 224 * The version of the structure. Initialize to 225 * {@link IMAGE4_ENVIRONMENT_CALLBACKS_STRUCT_VERSION}. 226 * 227 * @field nvcb_query_boot_nonce 228 * The callback to query the boot nonce. 229 * 230 * @field nvcb_query_nonce_digest 231 * The callback to query a nonce digest. 232 * 233 * @field nvcb_construct_boot 234 * The callback to construct the boot sequence for the environment. 235 * 236 * @field nvcb_identifier_bool 237 * The callback to convey a Boolean identifier in the environment. 238 * 239 * @field nvcb_identifier_integer 240 * The callback to convey an integer identifier in the environment. 241 * 242 * @field nvcb_identifier_data 243 * The callback to convey an octet string identifier in the environment. 244 */ 245 typedef struct _image4_environment_callbacks { 246 image4_struct_version_t nvcb_version; 247 image4_environment_query_boot_nonce_t _Nullable nvcb_query_boot_nonce; 248 image4_environment_query_nonce_digest_t _Nullable nvcb_query_nonce_digest; 249 image4_environment_identifier_bool_t _Nullable nvcb_identifier_bool; 250 image4_environment_identifier_integer_t _Nullable nvcb_identifier_integer; 251 image4_environment_identifier_data_t _Nullable nvcb_identifier_data; 252 } image4_environment_callbacks_t; 253 254 /*! 255 * @const IMAGE4_ENVIRONMENT_STRUCT_VERSION 256 * The version of the {@link image4_environment_t} structure supported by the 257 * implementation. 258 */ 259 #define IMAGE4_ENVIRONMENT_STRUCT_VERSION (0u) 260 261 /*! 262 * @struct image4_environment_storage_t 263 * An opaque structure which is guaranteed to be large enough to accommodate an 264 * {@link image4_environment_t}. 265 * 266 * @field __opaque 267 * The opaque storage. 268 */ 269 struct _image4_environment_storage { 270 uint8_t __opaque[256]; 271 }; 272 273 /*! 274 * @const IMAGE4_TRUST_STORAGE_INIT 275 * Initializer for a {@link image4_environment_storage_t} object. 276 */ 277 #define IMAGE4_ENVIRONMENT_STORAGE_INIT (image4_environment_storage_t){ \ 278 .__opaque = { 0x00 }, \ 279 } 280 281 #pragma mark API 282 /*! 283 * @function image4_environment_init 284 * Initializes an environment in which to perform a trust evaluation. 285 * 286 * @param storage 287 * The storage structure. 288 * 289 * @param coproc 290 * The coprocessor which will perform the evaluation. If NULL, 291 * {@link IMAGE4_COPROCESSOR_HOST} will be assumed. 292 * 293 * @param handle 294 * The specific environment and policy within the coprocessor to use for 295 * performing the evaluation. If {@link IMAGE4_COPROCESSOR_HOST} is used, this 296 * parameter is ignored. 297 * 298 * @result 299 * An initialized {@link image4_environment_t} object. 300 */ 301 IMAGE4_API_AVAILABLE_SPRING_2024 302 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 303 image4_environment_t * 304 _image4_environment_init( 305 image4_environment_storage_t *storage, 306 const image4_coprocessor_t *_Nullable coproc, 307 image4_coprocessor_handle_t handle, 308 image4_struct_version_t v); 309 #define image4_environment_init(_storage, _coproc, _handle) \ 310 _image4_environment_init( \ 311 (_storage), \ 312 (_coproc), \ 313 (_handle), \ 314 IMAGE4_ENVIRONMENT_STRUCT_VERSION) 315 IMAGE4_XNU_AVAILABLE_INDIRECT(_image4_environment_init); 316 317 /*! 318 * @function image4_environment_init_coproc 319 * A less-verbose form of {@link image4_environment_init}. 320 * 321 * @param _storage 322 * The storage structure. 323 * 324 * @param _coproc_short 325 * The shortened form of the coprocessor name, e.g. `AP` for 326 * `IMAGE4_COPROCESSOR_AP`. 327 * 328 * @param _handle_short 329 * The shortened form of the coprocessor handle name, e.g. `FF00` for 330 * `IMAGE4_COPROCESSOR_AP_FF00`. 331 * 332 * @result 333 * An initialized {@link image4_environment_t} object. 334 * 335 * @example 336 * The following two code snippets are equivalent. 337 * 338 * nv = image4_environment_init( 339 * &s, 340 * IMAGE4_COPROCESSOR_CRYPTEX1, 341 * IMAGE4_COPROCESSOR_CRYPTEX1_BOOT); 342 * and 343 * 344 * nv = image4_environment_init_coproc(&s, CRYPTEX1, BOOT); 345 */ 346 #define image4_environment_init_coproc(_storage, _coproc_short, _handle_short) \ 347 image4_environment_init( \ 348 (_storage), \ 349 IMAGE4_COPROCESSOR_ ## _coproc_short, \ 350 IMAGE4_COPROCESSOR_HANDLE_ ## _coproc_short ## _ ## _handle_short) 351 352 /*! 353 * @function image4_environment_new 354 * Allocates an environment in which to perform a trust evaluation. 355 * 356 * @param coproc 357 * The coprocessor which will perform the evaluation. If NULL, 358 * {@link IMAGE4_COPROCESSOR_HOST} will be assumed. 359 * 360 * @param handle 361 * The specific environment and policy within the coprocessor to use for 362 * performing the evaluation. If {@link IMAGE4_COPROCESSOR_HOST} is used, this 363 * parameter is ignored. 364 * 365 * @result 366 * A newly-allocated and initialized {@link image4_environment_t} object. The 367 * caller is responsible for disposing of this object with 368 * {@link image4_environment_destroy} when it is no longer needed. 369 * 370 * If insufficient resources were available to allocate the object, or if the 371 * host runtime does not have an allocator, NULL is returned. 372 */ 373 IMAGE4_API_AVAILABLE_SPRING_2024 374 OS_EXPORT OS_WARN_RESULT 375 image4_environment_t *_Nullable 376 image4_environment_new( 377 const image4_coprocessor_t *_Nullable coproc, 378 image4_coprocessor_handle_t handle); 379 IMAGE4_XNU_AVAILABLE_DIRECT(image4_environment_new); 380 381 /*! 382 * @function image4_environment_new_coproc 383 * A less-verbose form of {@link image4_environment_new}. 384 * 385 * @param _coproc_short 386 * The shortened form of the coprocessor name, e.g. `AP` for 387 * `IMAGE4_COPROCESSOR_AP`. 388 * 389 * @param _handle_short 390 * The shortened form of the coprocessor handle name, e.g. `FF00` for 391 * `IMAGE4_COPROCESSOR_AP_FF00`. 392 * 393 * @result 394 * A newly-allocated and initialized {@link image4_environment_t} object. The 395 * caller is responsible for disposing of this object with 396 * {@link image4_environment_destroy} when it is no longer needed. 397 * 398 * If insufficient resources were available to allocate the object, or if the 399 * host runtime does not have an allocator, NULL is returned. 400 * 401 * @example 402 * The following two code snippets are equivalent. 403 * 404 * nv = image4_environment_new( 405 * IMAGE4_COPROCESSOR_CRYPTEX1, 406 * IMAGE4_COPROCESSOR_CRYPTEX1_BOOT); 407 * and 408 * 409 * nv = image4_environment_new_coproc(CRYPTEX1, BOOT); 410 */ 411 #define image4_environment_new_coproc(_coproc_short, _handle_short) \ 412 image4_environment_new( \ 413 IMAGE4_COPROCESSOR_ ## _coproc_short, \ 414 IMAGE4_COPROCESSOR_HANDLE_ ## _coproc_short ## _ ## _handle_short) 415 416 /*! 417 * @function image4_environment_set_secure_boot 418 * Sets the desired secure boot level of the environment. 419 * 420 * @param nv 421 * The environment to manipulate. 422 * 423 * @param secure_boot 424 * The desired secure boot level. 425 * 426 * @discussion 427 * If the environment designated by the coprocessor and handle does not support 428 * secure boot, this is a no-op. 429 */ 430 IMAGE4_API_AVAILABLE_SPRING_2024 431 OS_EXPORT OS_NONNULL1 432 void 433 image4_environment_set_secure_boot( 434 image4_environment_t *nv, 435 image4_secure_boot_t secure_boot); 436 IMAGE4_XNU_AVAILABLE_DIRECT(image4_environment_set_secure_boot); 437 438 /*! 439 * @function image4_environment_set_nonce_domain 440 * Sets the nonce domain number for the environment. This value will be returned 441 * as the value for the coprocessor's nonce domain property during environment 442 * iteration (e.g. if the environment is a Cryptex1 coprocessor handle, the ndom 443 * property). 444 * 445 * @param nv 446 * The environment to modify. 447 * 448 * @param nonce_domain 449 * The nonce domain number to set. 450 * 451 * @discussion 452 * This operation does not impact trust evaluation, which always defers to the 453 * nonce domain signed into the manifest if one is present. It is intended to 454 * support two workflows: 455 * 456 * 1. Constructing a personalization request using the callbacks associated 457 * with {@link image4_environment_identify} by allowing all the code that 458 * sets the values of the TSS request to reside in the identifier 459 * callbacks 460 * 2. Related to the above, performing nonce management operations on the 461 * nonce slot associated by the given domain (e.g. generating a proposal 462 * nonce with {@link image4_environment_generate_nonce_proposal}) 463 * 464 * Certain coprocessor environments recognize a nonce domain entitlement, but 465 * only one valid value for that entitlement (e.g. 466 * {@link IMAGE4_COPROCESSOR_HANDLE_CRYPTEX1_BOOT}). These environments do not 467 * require the nonce domain to be set; it is automatically recognized based on 468 * the static properties of the coprocessor. 469 */ 470 IMAGE4_API_AVAILABLE_SPRING_2024 471 OS_EXPORT OS_NONNULL1 472 void 473 image4_environment_set_nonce_domain( 474 image4_environment_t *nv, 475 uint32_t nonce_domain); 476 IMAGE4_XNU_AVAILABLE_DIRECT(image4_environment_set_nonce_domain); 477 478 /*! 479 * @function image4_environment_set_callbacks 480 * Sets the callbacks for an environment. 481 * 482 * @param nv 483 * The environment to manipulate. 484 * 485 * @param callbacks 486 * The callback structure. 487 * 488 * @param _ctx 489 * The caller-defined context to be passed to each callback. 490 */ 491 IMAGE4_API_AVAILABLE_SPRING_2024 492 OS_EXPORT OS_NONNULL1 OS_NONNULL2 493 void 494 image4_environment_set_callbacks( 495 image4_environment_t *nv, 496 const image4_environment_callbacks_t *callbacks, 497 void *_Nullable _ctx); 498 IMAGE4_XNU_AVAILABLE_DIRECT(image4_environment_set_callbacks); 499 500 /*! 501 * @function image4_environment_identify 502 * Identifies the environment and provides the identity via the callbacks 503 * specified in the {@link image4_environment_callbacks_t} structure set for 504 * the environment. 505 * 506 * @param nv 507 * The environment to identify. 508 * 509 * @discussion 510 * If no callbacks were provided, or if no identifier callbacks were set in the 511 * callback structure, the implementation's behavior is undefined. 512 */ 513 IMAGE4_API_AVAILABLE_SPRING_2024 514 OS_EXPORT OS_NONNULL1 515 void 516 image4_environment_identify( 517 const image4_environment_t *nv); 518 IMAGE4_XNU_AVAILABLE_DIRECT(image4_environment_identify); 519 520 /*! 521 * @function image4_environment_get_digest_info 522 * Retrieves the CoreCrypto digest info structure which the environment uses to 523 * compute digests. 524 * 525 * @param nv 526 * The environment to query. 527 * 528 * @result 529 * A pointer to the CoreCrypto digest info structure corresponding to the 530 * environment. 531 * 532 * @availability 533 * This function first became available in API version 20231215. 534 */ 535 IMAGE4_API_AVAILABLE_FALL_2024 536 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 537 const struct ccdigest_info * 538 image4_environment_get_digest_info( 539 const image4_environment_t *nv); 540 IMAGE4_XNU_AVAILABLE_DIRECT(image4_environment_get_digest_info); 541 542 /*! 543 * @function image4_environment_copy_nonce_digest 544 * Copies the digest of the specified nonce. 545 * 546 * @param nv 547 * The environment to query. 548 * 549 * @param d 550 * Upon successful return, the digest of the live nonce for the environment. On 551 * failure, the contents of this structure are undefined. 552 * 553 * @param d_len 554 * Upon successful return, the length of the nonce digest. 555 * 556 * @result 557 * Upon success, zero is returned. Otherwise, the implementation may directly 558 * return one of the following POSIX error codes: 559 * 560 * [EPERM] The caller lacks the entitlement required to access the 561 * desired nonce 562 * [ENOTSUP] The environment does not manage a nonce for anti-replay 563 * [ESTALE] The nonce has been invalidated and will not be available until 564 * the next boot 565 */ 566 IMAGE4_API_AVAILABLE_SPRING_2024 567 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3 568 errno_t 569 image4_environment_copy_nonce_digest( 570 const image4_environment_t *nv, 571 uint8_t d[__static_size _Nonnull IMAGE4_DIGEST_MAX_LEN], 572 size_t *d_len); 573 IMAGE4_XNU_AVAILABLE_DIRECT(image4_environment_copy_nonce_digest); 574 575 /*! 576 * @function image4_environment_roll_nonce 577 * Invalidates the live nonce for the environment such that a new nonce will be 578 * generated at the next boot. 579 * 580 * @param nv 581 * The environment to manipulate. 582 * 583 * @result 584 * Upon success, zero is returned. Otherwise, the implementation may directly 585 * return one of the following POSIX error codes: 586 * 587 * [EPERM] The caller lacks the entitlement required to access the 588 * desired nonce 589 * [ENOTSUP] The environment does not manage a nonce for anti-replay 590 */ 591 IMAGE4_API_AVAILABLE_SPRING_2024 592 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 593 errno_t 594 image4_environment_roll_nonce( 595 const image4_environment_t *nv); 596 IMAGE4_XNU_AVAILABLE_DIRECT(image4_environment_roll_nonce); 597 598 /*! 599 * @function image4_environment_generate_nonce_proposal 600 * Generates a nonce proposal for the environment and returns the hash of the 601 * proposal. 602 * 603 * @param nv 604 * The environment to manipulate. 605 * 606 * @param d 607 * Upon successful return, the digest of the proposal nonce which was 608 * generated. On failure, the contents of this structure are undefined. 609 * 610 * @param d_len 611 * Upon successful return, the length of the nonce digest. 612 * 613 * @param n 614 * Upon successful return, the proposal nonce which was generated. 615 * 616 * This parameter may be NULL. If the caller's minimum deployment target is less 617 * than macOS 15 or iOS 17, and the caller is building with -fbounds-checking, 618 * then the caller must pass a non-NULL parameter. 619 * 620 * @param n_len 621 * Upon input, the length of the buffer referred to by {@link n}. Since 622 * {@link n} can be NULL, C does not permit the static qualifier to enforce a 623 * minimum array size, and therefore this parameter communicates the length of 624 * the buffer to the callee. Upon successful return, the this parameter will 625 * be the length of the nonce returned in {@link n}. 626 * 627 * @result 628 * Upon success, zero is returned. Otherwise, the implementation may directly 629 * return one of the following POSIX error codes: 630 * 631 * [EPERM] The caller lacks the entitlement required to manipulate the 632 * desired nonce 633 * [EACCES] The caller requested the proposal nonce in addition to its 634 * digest, and the environment does not support returning the 635 * nonce to the caller's execution context 636 * [ENOTSUP] The environment does not manage a nonce for anti-replay 637 * 638 * @discussion 639 * The {@link n} and {@link n_len} parameters must either both be NULL or non- 640 * NULL. Passing NULL for one but not the other will result in undefined 641 * behavior in the implementation. 642 * 643 * If the caller's minimum deployment target is less than macOS 15 or iOS 17, 644 * and the caller is building with -fbounds-checking, then the caller must pass 645 * non-NULL values for both {@link n} and {@link n_len}. In this case, the value 646 * referred to be {@link n_len} should be 0 to indicate to the implementation 647 * that the proposal nonce itself is not desired. 648 */ 649 IMAGE4_API_AVAILABLE_SPRING_2024 650 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 651 errno_t 652 image4_environment_generate_nonce_proposal( 653 const image4_environment_t *nv, 654 uint8_t d[__static_size _Nonnull IMAGE4_DIGEST_MAX_LEN], 655 size_t *d_len, 656 uint8_t n[__static_array_or_null(IMAGE4_NONCE_MAX_LEN)], 657 size_t *_Nullable n_len); 658 IMAGE4_XNU_AVAILABLE_DIRECT(image4_environment_generate_nonce_proposal); 659 660 /*! 661 * @function image4_environment_commit_nonce_proposal 662 * Commits the nonce proposal corresponding to the digest provided by the caller 663 * such that it will be accepted and live at the next boot. 664 * 665 * @param nv 666 * The environment to manipulate. 667 * 668 * @param d 669 * The digest of the proposal to commit. 670 * 671 * @param d_len 672 * The length of the nonce proposal digest. 673 * 674 * @result 675 * Upon success, zero is returned. Otherwise, the implementation may directly 676 * return one of the following POSIX error codes: 677 * 678 * [EPERM] The caller lacks the entitlement required to manipulate the 679 * desired nonce 680 * [ENOTSUP] The environment does not manage a nonce for anti-replay 681 * [ENODEV] There is no proposal for the given nonce 682 * [EILSEQ] The digest provided by the caller does not correspond to the 683 * active proposal; this may occur if another subsystem 684 * generates a proposal for the environment 685 */ 686 IMAGE4_API_AVAILABLE_SPRING_2024 687 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 688 errno_t 689 image4_environment_commit_nonce_proposal( 690 const image4_environment_t *nv, 691 const uint8_t d[__static_size _Nonnull IMAGE4_DIGEST_MAX_LEN], 692 size_t *d_len); 693 IMAGE4_XNU_AVAILABLE_DIRECT(image4_environment_commit_nonce_proposal); 694 695 /*! 696 * @function image4_environment_flash 697 * Activates an Image4 object with the provided environment. 698 * 699 * @param nv 700 * The environment to manipulate. 701 * 702 * @param object 703 * A pointer to the Image4 object bytes that will be activated. These bytes must 704 * represent a complete Image4 object. If the environment requires personalized 705 * signatures, then the object must also have a RestoreInfo section with the DFU 706 * nonce set in the appropriate property. 707 * 708 * @param object_len 709 * The length of the buffer referenced by {@link object}. 710 * 711 * @param n 712 * Upon successful return, the value of the nonce which was consumed during the 713 * DFU operation. The caller is expected to store this value in a RestoreInfo 714 * section in order to subsequently verify the manifest. 715 * 716 * This parameter may be NULL. 717 * 718 * @param n_len 719 * Upon input, the length of the buffer referred to by {@link n}. Since 720 * {@link n} can be NULL, C does not permit the static qualifier to enforce a 721 * minimum array size, and therefore this parameter communicates the length of 722 * the buffer to the callee. Upon successful return, the this parameter will 723 * be the length of the nonce returned in {@link n}. 724 * 725 * @result 726 * Upon success, zero is returned. Otherwise, the implementation may directly 727 * return one of the following POSIX error codes: 728 * 729 * [EPERM] The caller lacks the entitlement required to DFU the 730 * environment 731 * [ENOTSUP] The environment does not support DFU in this target 732 * 733 * The implementation may also return any error that the 734 * {@link image4_trust_evaluation_result_t} callback may deliver to its callee. 735 * 736 * @availability 737 * This function first became available in API version 20240112. 738 * 739 * @discussion 740 * The {@link n} and {@link n_len} parameters must either both be NULL or non- 741 * NULL. Passing NULL for one but not the other will result in undefined 742 * behavior in the implementation. 743 * 744 * If the caller's minimum deployment target is less than macOS 15 or iOS 17, 745 * and the caller is building with -fbounds-checking, then the caller must pass 746 * non-NULL values for both {@link n} and {@link n_len}. In this case, the value 747 * referred to be {@link n_len} should be 0 to indicate to the implementation 748 * that the proposal nonce itself is not desired. 749 */ 750 IMAGE4_API_AVAILABLE_FALL_2024 751 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 752 errno_t 753 image4_environment_flash( 754 const image4_environment_t *nv, 755 const void *__sized_by(object_len) object, 756 size_t object_len, 757 uint8_t n[__static_array_or_null(IMAGE4_NONCE_MAX_LEN)], 758 size_t *_Nullable n_len); 759 IMAGE4_XNU_AVAILABLE_DIRECT(image4_environment_flash); 760 761 /*! 762 * @function image4_environment_destroy 763 * Disposes an environment object which was created via 764 * {@link image4_environment_new}. 765 * 766 * @param nv 767 * A pointer to the environment object. Upon return, this storage will be set to 768 * NULL. If the object pointed to by this parameter is NULL, this is a no-op. 769 * 770 * @discussion 771 * If this routine is called on an environment object which was not allocated, 772 * it is a no-op. 773 */ 774 IMAGE4_API_AVAILABLE_SPRING_2024 775 OS_EXPORT OS_NONNULL1 776 void 777 image4_environment_destroy( 778 image4_environment_t *_Nonnull *_Nullable nv); 779 IMAGE4_XNU_AVAILABLE_DIRECT(image4_environment_destroy); 780 781 #pragma mark Retired 782 IMAGE4_XNU_RETIRED_DIRECT(image4_environment_get_nonce_handle); 783 784 OS_ASSUME_PTR_ABI_SINGLE_END 785 OS_ASSUME_NONNULL_END 786 __END_DECLS 787 788 #endif // __IMAGE4_API_ENVIRONMENT_H 789