3 * Image4 runtime interfaces.
5 #ifndef __IMG4_RUNTIME_H
6 #define __IMG4_RUNTIME_H
8 #ifndef __IMG4_INDIRECT
9 #error "Please #include <img4/firmware.h> instead of this file directly"
10 #endif // __IMG4_INDIRECT
16 OS_ASSUME_NONNULL_BEGIN
19 * @typedef img4_identifier_t
20 * An enumeration describing identifiers in the Image4 specification.
22 * @const IMG4_IDENTIFIER_CEPO
23 * The chip epoch as documented in 2.1.1. Authoritative manifests will specify a
24 * certificate epoch which is greater than or equal to that of the chip.
26 * Unsigned 32-bit integer.
28 * @const IMG4_IDENTIFIER_BORD
29 * The board identifier as documented in 2.1.3. Authoritative manifests will
30 * specify a board identifier which is equal to that of the chip.
32 * Unsigned 32-bit integer.
34 * @const IMG4_IDENTIFIER_CHIP
35 * The chip identifier as documented in 2.1.2. Authoritative manifests will
36 * specify a chip identifier which is equal to that of the chip.
38 * Unsigned 32-bit integer.
40 * @const IMG4_IDENTIFIER_SDOM
41 * The security domain as documented in 2.1.5. Authoritative manifests will
42 * specify a security domain which is equal to that that of the chip.
44 * Unsigned 32-bit integer.
46 * @const IMG4_IDENTIFIER_ECID
47 * The unique chip identifier as documented in 2.1.4. Authoritative manifests
48 * will specify a unique chip identifier which is equal to that of the chip.
50 * Unsigned 64-bit integer.
52 * @const IMG4_IDENTIFIER_CPRO
53 * The certificate production status as documented in 2.1.6. Authoritative
54 * manifests will specify a certificate production status which is equal to that
59 * @const IMG4_IDENTIFIER_CSEC
60 * The certificate security mode as documented in 2.1.7. Authoritative manifests
61 * will specify a certificate security mode which is equal to that of the chip.
65 * @const IMG4_IDENTIFIER_EPRO
66 * The effective production status as documented in 2.1.23. Unless the chip
67 * environment supports demotion, this will always be the same as
68 * {@link IMG4_IDENTIFIER_CPRO}. An executable firmware in an authoritative
69 * manifest will specify an EPRO object property which is equal to that of the
74 * @const IMG4_IDENTIFIER_ESEC
75 * The effective security mode as documented in 2.1.25. Unless the chip
76 * environment supports demotion, this will always be the same as
77 * {@link IMG4_IDENTIFIER_CSEC}. An executable firmware in an authoritative
78 * manifest will specify an ESEC object property which is equal to that of the
83 * @const IMG4_IDENTIFIER_IUOU
84 * The "internal use only unit" property. Indicates whether the chip is present
85 * on a server-side authlist which permits installing builds which are otherwise
86 * restricted to parts whose CPRO is 0. This property is only published by macOS
87 * devices whose root of trust is in an arm coprocessor (e.g. T2).
89 * Authoritative manifests will specify an internal-use-only-build property
90 * which, if true, is equal to the internal-use-only-unit property of the chip.
91 * If the internal-use-only-build property is false, then there is no constraint
92 * on the chip's internal-use-only-unit property.
96 * @const IMG4_IDENTIFIER_RSCH
97 * The research fusing status. Indicates whether the chip is intended for
98 * security research to be performed by external parties. Authoritative
99 * manifests will specify a research fusing state which is equal to that of the
104 * @const IMG4_IDENTIFIER_CHMH
105 * The chained manifest hash from the previous stage of secure boot as described
106 * in 2.2.11. An authoritative manifest will either
108 * - specify a manifest hash which is equal to that of the previous secure
109 * boot stage's manifest
110 * - itself have a manifest hash which is equal to that of the previous
111 * secure boot stage's manifest
113 * If the previous stage of secure boot enabled mix-n-match, there is no
114 * constraint on the previous stage's manifest hash.
116 * Manifests which specify this property cannot be used to create new trust
117 * chains -- they may only extend existing ones.
121 * @const IMG4_IDENTIFIER_AMNM
122 * The allow-mix-n-match status of the chip. If mix-n-match is enabled, secure
123 * boot will permit different manifests to be used at each stage of boot. If the
124 * chip environment allows mix-n-match, evaluation will not require an anti-
125 * replay token to be specified, and any chained manifest hash constraints are
130 * @const IMG4_IDENTIFIER_EUOU
131 * The engineering-use-only-unit status of the chip. This is in effect an alias
132 * for the {@link IMG4_IDENTIFIER_IUOU} property. Either property being present
133 * in the environment will satisfy a manifest's iuob constraint.
137 * @const _IMG4_IDENTIFIER_CNT
138 * A convenience value representing the number of known identifiers.
140 IMG4_API_AVAILABLE_20200508
141 OS_CLOSED_ENUM(img4_identifier
, uint64_t,
142 IMG4_IDENTIFIER_CEPO
,
143 IMG4_IDENTIFIER_BORD
,
144 IMG4_IDENTIFIER_CHIP
,
145 IMG4_IDENTIFIER_SDOM
,
146 IMG4_IDENTIFIER_ECID
,
147 IMG4_IDENTIFIER_CPRO
,
148 IMG4_IDENTIFIER_CSEC
,
149 IMG4_IDENTIFIER_EPRO
,
150 IMG4_IDENTIFIER_ESEC
,
151 IMG4_IDENTIFIER_IUOU
,
152 IMG4_IDENTIFIER_RSCH
,
153 IMG4_IDENTIFIER_CHMH
,
154 IMG4_IDENTIFIER_AMNM
,
155 IMG4_IDENTIFIER_EUOU
,
156 _IMG4_IDENTIFIER_CNT
,
160 * @const IMG4_DGST_STRUCT_VERSION
161 * The version of the {@link img4_dgst_t} structure supported by the
164 #define IMG4_DGST_STRUCT_VERSION (0u)
167 * @const IMG4_DGST_MAX_LEN
168 * The maximum length of a digest representable by an {@link img4_dgst_t}.
170 #define IMG4_DGST_MAX_LEN (48u)
173 * @typedef img4_dgst_t
174 * A structure representing an Image4 digest.
177 * The version of the structure. Initialize to {@link IMG4_DGST_STRUCT_VERSION}.
180 * The length of the digest.
185 IMG4_API_AVAILABLE_20200508
186 typedef struct _img4_dgst
{
187 img4_struct_version_t i4d_version
;
189 uint8_t i4d_bytes
[IMG4_DGST_MAX_LEN
];
193 * @const IMG4_DGST_INIT
194 * A convenience initializer for an {@link img4_dgst_t} structure.
196 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
197 #define IMG4_DGST_INIT (img4_dgst_t){ \
198 .i4d_version = IMG4_DGST_STRUCT_VERSION, \
202 #elif defined(__cplusplus) && __cplusplus >= 201103L
203 #define IMG4_DGST_INIT (img4_nonce_t{ \
204 IMG4_DGST_STRUCT_VERSION, \
208 #elif defined(__cplusplus)
209 #define IMG4_DGST_INIT (img4_nonce_t((img4_nonce_t){ \
210 IMG4_DGST_STRUCT_VERSION, \
215 #define IMG4_DGST_INIT {IMG4_DGST_STRUCT_VERSION}
219 * @typedef img4_runtime_init_t
220 * A function which initializes the runtime.
223 * The runtime for which the function is being invoked.
226 * This function is called by the implementation prior to any other runtime
227 * function being called. The implementation will ensure that it is called only
228 * once. Any runtime with an initialization function must be registered with the
229 * {@link IMG4_RUNTIME_REGISTER} macro.
231 IMG4_API_AVAILABLE_20200508
232 typedef void (*img4_runtime_init_t
)(
233 const img4_runtime_t
*rt
237 * @typedef img4_runtime_alloc_t
238 * An allocation function.
241 * The runtime for which the function is being invoked.
244 * The number of bytes to allocate.
247 * A pointer to the new allocation, or NULL if there was an allocation failure.
249 IMG4_API_AVAILABLE_20200508
250 typedef void *_Nullable (*img4_runtime_alloc_t
)(
251 const img4_runtime_t
*rt
,
256 * @typedef img4_runtime_dealloc_t
257 * A deallocation function.
260 * The runtime for which the function is being invoked.
263 * A pointer to the allocation to free. The callee is expected to return
264 * immediately if NULL is passed.
267 * The size of the allocation. Not all implementation may require this
268 * information to be specified.
270 IMG4_API_AVAILABLE_20200508
271 typedef void (*img4_runtime_dealloc_t
)(
272 const img4_runtime_t
*rt
,
278 * @typedef img4_log_level_t
279 * An enumeration describing the importance/severity of a log message.
281 * @const IMG4_LOG_LEVEL_ERROR
282 * A fatal condition which will cause the implementation to abort its current
285 * @const IMG4_LOG_LEVEL_INFO
286 * Information that may be of interest to the system operator.
288 * @const IMG4_LOG_LEVEL_DEBUG
289 * Information that may be of interest to the maintainer.
291 * @const _IMG4_LOG_LEVEL_CNT
292 * A convenience constant indicating the number of log levels.
294 IMG4_API_AVAILABLE_20200508
295 OS_CLOSED_ENUM(img4_log_level
, uint64_t,
296 IMG4_LOG_LEVEL_ERROR
,
298 IMG4_LOG_LEVEL_DEBUG
,
303 * @typedef img4_runtime_log_t
304 * A function which writes log messages.
307 * The runtime for which the function is being invoked.
310 * An implementation-specific handle for the log message.
313 * The message of the log level. The implementation is free to determine whether
314 * a given message is worthy of record.
317 * A printf(3)-style format string.
320 * Arguments to be interpreted by the format string according to the
321 * specifications in printf(3).
323 OS_FORMAT_PRINTF(4, 5)
324 IMG4_API_AVAILABLE_20200508
325 typedef void (*img4_runtime_log_t
)(
326 const img4_runtime_t
*rt
,
327 void *_Nullable handle
,
328 img4_log_level_t level
,
334 * @typedef img4_runtime_log_handle_t
335 * A function which returns a log handle.
338 * The runtime for which the function is being invoked.
341 * A runtime-specific log handle that will be passed to the logging function.
343 IMG4_API_AVAILABLE_20200508
344 typedef void *_Nullable (*img4_runtime_log_handle_t
)(
345 const img4_runtime_t
*rt
349 * @typedef img4_runtime_get_identifier_bool_t
350 * A function which retrieves a Boolean Image4 identifier.
353 * The runtime for which the function is being invoked.
356 * The chip for which to retrieve the identifier.
359 * The identifier to retrieve.
362 * Upon successful return, storage which is populated with the retrieved value.
365 * Upon success, the callee is expected to return zero. Otherwise, the callee
366 * may return one of the following error codes:
368 * [ENOTSUP] The identifier cannot be queried in the runtime
369 * [ENOENT] The identifier was not found in the runtime's identity
371 * [ENODEV] There was an error querying the runtime's identity oracle
373 IMG4_API_AVAILABLE_20200508
374 typedef errno_t (*img4_runtime_get_identifier_bool_t
)(
375 const img4_runtime_t
*rt
,
376 const img4_chip_t
*chip
,
377 img4_identifier_t identifier
,
382 * @typedef img4_runtime_get_identifier_uint32_t
383 * A function which retrieves an unsigned 32-bit integer Image4 identifier.
386 * The runtime for which the function is being invoked.
389 * The chip for which to retrieve the identifier.
392 * The identifier to retrieve.
395 * Upon successful return, storage which is populated with the retrieved value.
398 * Upon success, the callee is expected to return zero. Otherwise, the callee
399 * may return one of the following error codes:
401 * [ENOTSUP] The identifier cannot be queried in the runtime
402 * [ENOENT] The identifier was not found in the runtime's identity
404 * [ENODEV] There was an error querying the runtime's identity oracle
406 IMG4_API_AVAILABLE_20200508
407 typedef errno_t (*img4_runtime_get_identifier_uint32_t
)(
408 const img4_runtime_t
*rt
,
409 const img4_chip_t
*chip
,
410 img4_identifier_t identifier
,
415 * @typedef img4_runtime_get_identifier_uint64_t
416 * A function which retrieves an unsigned 64-bit integer Image4 identifier.
419 * The runtime for which the function is being invoked.
422 * The chip for which to retrieve the identifier.
425 * The identifier to retrieve.
428 * Upon successful return, storage which is populated with the retrieved value.
431 * Upon success, the callee is expected to return zero. Otherwise, the callee
432 * may return one of the following error codes:
434 * [ENOTSUP] The identifier cannot be queried in the runtime
435 * [ENOENT] The identifier was not found in the runtime's identity
437 * [ENODEV] There was an error querying the runtime's identity oracle
439 IMG4_API_AVAILABLE_20200508
440 typedef errno_t (*img4_runtime_get_identifier_uint64_t
)(
441 const img4_runtime_t
*rt
,
442 const img4_chip_t
*chip
,
443 img4_identifier_t identifier
,
448 * @typedef img4_runtime_get_identifier_digest_t
449 * A function which retrieves a digest Image4 identifier.
452 * The runtime for which the function is being invoked.
455 * The chip for which to retrieve the identifier.
458 * The identifier to retrieve.
461 * Upon successful return, storage which is populated with the retrieved value.
464 * Upon success, the callee is expected to return zero. Otherwise, the callee
465 * may return one of the following error codes:
467 * [ENOTSUP] The identifier cannot be queried in the runtime
468 * [ENOENT] The identifier was not found in the runtime's identity
470 * [ENODEV] There was an error querying the runtime's identity oracle
472 IMG4_API_AVAILABLE_20200508
473 typedef errno_t (*img4_runtime_get_identifier_digest_t
)(
474 const img4_runtime_t
*rt
,
475 const img4_chip_t
*chip
,
476 img4_identifier_t identifier
,
481 * @define IMG4_BUFF_STRUCT_VERSION
482 * The version of the {@link img4_buff_t} structure supported by the
485 #define IMG4_BUFF_STRUCT_VERSION (0u)
489 * A structure describing a buffer.
492 * The version of the structure. Initialize to {@link IMG4_BUFF_STRUCT_VERSION}.
495 * A pointer to the buffer.
498 * The length of the buffer.
501 * The deallocation function for the buffer. May be NULL if the underlying
502 * memory does not require cleanup. When the implementation invokes this
503 * function, it will always pass {@link IMG4_RUNTIME_DEFAULT}, and the callee
504 * should not consult this parameter for any reason.
507 img4_struct_version_t i4b_version
;
510 img4_runtime_dealloc_t _Nullable i4b_dealloc
;
511 } IMG4_API_AVAILABLE_20200508
;
514 * @const IMG4_BUFF_INIT
515 * A convenience initializer for the {@link img4_buff_t} structure.
517 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
518 #define IMG4_BUFF_INIT (img4_buff_t){ \
519 .i4b_version = IMG4_BUFF_STRUCT_VERSION, \
522 .i4b_dealloc = NULL, \
524 #elif defined(__cplusplus) && __cplusplus >= 201103L
525 #define IMG4_BUFF_INIT (img4_buff_t{ \
526 IMG4_BUFF_STRUCT_VERSION, \
531 #elif defined(__cplusplus)
532 #define IMG4_BUFF_INIT (img4_buff_t((img4_buff_t){ \
533 IMG4_BUFF_STRUCT_VERSION, \
539 #define IMG4_BUFF_INIT {IMG4_BUFF_STRUCT_VERSION}
543 * @define IMG4_RUNTIME_STRUCT_VERSION
544 * The version of the {@link img4_runtime_t} structure supported by the
547 #define IMG4_RUNTIME_STRUCT_VERSION (1u)
550 * @struct _img4_runtime
551 * A structure describing required primitives in the operating environment's
554 * @field i4rt_version
555 * The version of the structure supported by the implementation. In a custom
556 * execution context, initialize to {@link IMG4_RUNTIME_STRUCT_VERSION}.
559 * A string describing the environment.
562 * The runtime initialization function. See discussion in
563 * {@link img4_runtime_init_t}.
566 * The allocation function for the environment (e.g. in Darwin userspace, this
567 * would be a pointer to malloc(3)).
569 * @field i4rt_dealloc
570 * The deallocation function for the environment (e.g. in Darwin userspace, this
571 * would be a pointer to free(3)).
574 * The function which logs messages from the implementation.
576 * @field i4rt_log_handle
577 * The function which returns the handle to be passed to the logging function.
579 * @field i4rt_get_identifier_bool
580 * The function which returns Boolean identifiers.
582 * @field i4rt_get_identifier_uint32
583 * The function which returns unsigned 32-bit integer identifiers.
585 * @field i4rt_get_identifier_uint64
586 * The function which returns unsigned 64-bit integer identifiers.
588 * @field i4rt_get_identifier_digest
589 * The function which returns digest identifiers.
591 * @field i4rt_context
592 * A user-defined context pointer.
594 struct _img4_runtime
{
595 img4_struct_version_t i4rt_version
;
596 const char *i4rt_name
;
597 img4_runtime_init_t _Nullable i4rt_init
;
598 img4_runtime_alloc_t i4rt_alloc
;
599 img4_runtime_dealloc_t i4rt_dealloc
;
600 img4_runtime_log_t i4rt_log
;
601 img4_runtime_log_handle_t i4rt_log_handle
;
602 img4_runtime_get_identifier_bool_t i4rt_get_identifier_bool
;
603 img4_runtime_get_identifier_uint32_t i4rt_get_identifier_uint32
;
604 img4_runtime_get_identifier_uint64_t i4rt_get_identifier_uint64
;
605 img4_runtime_get_identifier_digest_t i4rt_get_identifier_digest
;
606 void *_Nullable i4rt_context
;
607 } IMG4_API_AVAILABLE_20200508
;
610 * @function IMG4_RUNTIME_REGISTER
611 * Registers a runtime with the module implementation such that its
612 * initialization function can be called. In environments which support dynamic
613 * library linkage, only runtimes registered from the main executable image can
614 * be discovered by the implementation.
617 * The img4_runtime_t structure to register.
619 #define IMG4_RUNTIME_REGISTER(_rt) LINKER_SET_ENTRY(__img4_rt, _rt);
622 * @const IMG4_RUNTIME_DEFAULT
623 * The default runtime for the current operating environment.
625 #if !XNU_KERNEL_PRIVATE
626 IMG4_API_AVAILABLE_20200508
628 const img4_runtime_t _img4_runtime_default
;
629 #define IMG4_RUNTIME_DEFAULT (&_img4_runtime_default)
631 #define IMG4_RUNTIME_DEFAULT (img4if->i4if_v7.runtime_default)
635 * @const IMG4_RUNTIME_PMAP_CS
636 * The runtime for the xnu pmap monitor. This runtime is not available outside
637 * the kernel-proper. On architectures which do not have an xnu monitor, this
638 * is merely an alias for the default kernel runtime.
640 #if XNU_KERNEL_PRIVATE
641 #define IMG4_RUNTIME_PMAP_CS (img4if->i4if_v7.runtime_pmap_cs)
645 * @const IMG4_RUNTIME_RESTORE
646 * The runtime for the restore ramdisk. This runtime is not available outside
647 * of the Darwin userspace library.
650 IMG4_API_AVAILABLE_20200508
652 const img4_runtime_t _img4_runtime_restore
;
653 #define IMG4_RUNTIME_RESTORE (&_img4_runtime_restore)
657 * @function img4_buff_dealloc
658 * Deallocates a buffer according to its deallocation function.
661 * A pointer to the a pointer to the buffer. This parameter may be NULL, in
662 * which case the implementation will return immediately.
665 * This interface will always invoke the deallocation callback with
666 * {@link IMG4_RUNTIME_DEFAULT}. The callee should not consult this parameter
669 #if !XNU_KERNEL_PRIVATE
670 IMG4_API_AVAILABLE_20200508
673 img4_buff_dealloc(img4_buff_t
*_Nullable buff
);
675 #define img4_buff_dealloc(...) (img4if->i4if_v7.buff_dealloc(__VA_ARGS__))
678 OS_ASSUME_NONNULL_END
680 #endif // __IMG4_RUNTIME_H