xref: /xnu-8019.80.24/EXTERNAL_HEADERS/img4/runtime.h (revision a325d9c4a84054e40bbe985afedcb50ab80993ea)
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