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