xref: /xnu-10063.141.1/EXTERNAL_HEADERS/image4/trust.h (revision d8b80295118ef25ac3a784134bcf95cd8e88109f)
1 /*!
2  * @header
3  * Encapsulation which describes an Image4 trust object. This object can perform
4  * an evaluation in the context of a given environment, record properties that
5  * were encountered during evaluation, and deliver the evaluation result to the
6  * caller according to the type of evaluation being performed.
7  */
8 #ifndef __IMAGE4_API_TRUST_H
9 #define __IMAGE4_API_TRUST_H
10 
11 #include <image4/image4.h>
12 #include <image4/types.h>
13 #include <stdint.h>
14 #include <stdbool.h>
15 
16 #if __has_include(<sys/types.h>)
17 #include <sys/types.h>
18 #else
19 typedef int errno_t;
20 #endif
21 
22 __BEGIN_DECLS
23 OS_ASSUME_NONNULL_BEGIN
24 OS_ASSUME_PTR_ABI_SINGLE_BEGIN
25 
26 #pragma mark Supporting Types
27 /*!
28  * @typedef image4_trust_flags_t
29  * Flags that may be provided to influence the behavior of an
30  * {@link image4_trust_t} object.
31  *
32  * @const IMAGE4_TRUST_FLAG_INIT
33  * No flags set. This value is suitable for initialization purposes.
34  *
35  * @const IMAGE4_TRUST_FLAG_VIOLATION_PANIC
36  * Upon encountering a violation during trust evaluation, the implementation
37  * should abort the current context.
38  */
39 OS_CLOSED_OPTIONS(image4_trust_flags, uint64_t,
40 	IMAGE4_TRUST_FLAG_INIT = 0,
41 	IMAGE4_TRUST_FLAG_VIOLATION_PANIC = (1 << 0),
42 );
43 
44 /*!
45  * @typedef image4_trust_section_t
46  * An enumeration of property sections in an Image4 manifest or object. Note
47  * that this is not strictly aligned with the concept of a "section" as defined
48  * in the Image4 specification.
49  *
50  * @const IMAGE4_TRUST_SECTION_CERTIFICATE
51  * The certificate properties within the manifest section.
52  *
53  * @const IMAGE4_TRUST_SECTION_MANIFEST
54  * The top-level properties in the manifest section.
55  *
56  * @const IMAGE4_TRUST_SECTION_OBJECT
57  * The properties associated with a particular object in the manifest section.
58  *
59  * @const IMAGE4_TRUST_SECTION_RESTORE_INFO
60  * The top-level properties in the RestoreInfo section. The RestoreInfo section
61  * is only recognized by the implementation when the trust object has been
62  * initialized with an IMG4 object that contains an IM4R section.
63  *
64  * This constant first became available in API version 20231103.
65  *
66  * @const IMAGE4_TRUST_SECTION_PAYLOAD_PROPERTIES
67  * The properties associated with the payload that is associated with the trust
68  * object, either by initializing the object with an IMG4 object, or by setting
69  * a payload with {@link image4_trust_set_payload}.
70  *
71  * This constant first became available in API version 20231103.
72  */
73 OS_CLOSED_ENUM(image4_trust_section, uint64_t,
74 	IMAGE4_TRUST_SECTION_CERTIFICATE,
75 	IMAGE4_TRUST_SECTION_MANIFEST,
76 	IMAGE4_TRUST_SECTION_OBJECT,
77 	IMAGE4_TRUST_SECTION_RESTORE_INFO,
78 	IMAGE4_TRUST_SECTION_PAYLOAD_PROPERTIES,
79 	_IMAGE4_TRUST_SECTION_CNT,
80 );
81 
82 /*!
83  * @typedef image4_trust_evaluation_result_t
84  * A callback for the result of a trust evaluation.
85  *
86  * @param trst
87  * The trust object.
88  *
89  * @param result
90  * Upon success, the prescribed payload resulting from the type of trust
91  * evaluation. If the trust evaluation type does not deliver a payload, or the
92  * trust evaluation failed, NULL will be passed.
93  *
94  * @param result_len
95  * The length of the buffer referenced by {@link payload}. If {@link payload} is
96  * NULL, zero will be passed.
97  *
98  * @param error
99  * A POSIX error code describing the result of the trust evaluation. Upon
100  * success, zero will be passed.
101  *
102  * @param context
103  * The caller-provided context pointer. If no context pointer was set, NULL will
104  * be passed.
105  */
106 typedef void (*image4_trust_evaluation_result_t)(
107 	const image4_trust_t *trst,
108 	const void *_Nullable result,
109 	size_t result_len,
110 	errno_t error,
111 	void *_Nullable context
112 );
113 
114 /*!
115  * @const IMAGE4_TRUST_STRUCT_VERSION
116  * The version of the {@link image4_trust_t} structure supported by the
117  * implementation.
118  */
119 #define IMAGE4_TRUST_STRUCT_VERSION (0u)
120 
121 /*!
122  * @header image4_trust_storage_t
123  * An opaque structure which is guaranteed to be large enough to accommodate an
124  * {@link image4_trust_t}.
125  *
126  * @field __opaque
127  * The opaque storage.
128  *
129  * @discussion
130  * The size of this object was set in API version 20231103.
131  */
132 typedef struct _image4_trust_storage {
133 	uint8_t __opaque[1920];
134 } image4_trust_storage_t;
135 
136 /*!
137  * @const IMAGE4_TRUST_STORAGE_INIT
138  * Initializer for a {@link image4_trust_storage_t} object.
139  */
140 #define IMAGE4_TRUST_STORAGE_INIT (image4_trust_storage_t){ \
141 	.__opaque = { 0x00 }, \
142 }
143 
144 #pragma mark API
145 /*!
146  * @function image4_trust_init
147  * Convert a {@link image4_trust_storage_t} to an initialized
148  * {@link image4_trust_t} object.
149  *
150  * @param storage
151  * The storage structure.
152  *
153  * @param environment
154  * The environment in which the trust evaluation should be performed.
155  *
156  * @param evaluation
157  * The trust evaluation type that should be performed.
158  *
159  * @param manifest
160  * A pointer to the Image4 manifest bytes. This buffer may refer to a stitched
161  * manifest and payload object, in which case the implementation will extract
162  * the manifest portion.
163  *
164  * These bytes are not copied into any implementation storage, and the caller is
165  * responsible for ensuring that this memory remains valid for the duration of
166  * the trust object's use.
167  *
168  * @param manifest_len
169  * The length of the buffer referenced by {@link manifest}.
170  *
171  * @param flags
172  * Flags to influence the behavior of the resulting trust object.
173  *
174  * @result
175  * An initialized {@link image4_trust_t} object.
176  */
177 IMAGE4_API_AVAILABLE_SPRING_2024
178 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3 OS_NONNULL4
179 image4_trust_t *
180 _image4_trust_init(
181 	image4_trust_storage_t *storage,
182 	const image4_environment_t *environment,
183 	const image4_trust_evaluation_t *evaluation,
184 	const void *__sized_by(manifest_len) manifest,
185 	size_t manifest_len,
186 	image4_trust_flags_t flags,
187 	image4_struct_version_t v);
188 #define image4_trust_init(_storage, _environment, _evaluation, \
189 		_manifest, _manifest_len, _flags) \
190 	_image4_trust_init( \
191 		(_storage), \
192 		(_environment), \
193 		(_evaluation), \
194 		(_manifest), \
195 		(_manifest_len), \
196 		(_flags), \
197 		IMAGE4_TRUST_STRUCT_VERSION)
198 IMAGE4_XNU_AVAILABLE_INDIRECT(_image4_trust_init);
199 
200 /*!
201  * @function image4_trust_new
202  * Allocates a trust object.
203  *
204  * @param nv
205  * The environment in which the trust evaluation should be performed.
206  *
207  * @param eval
208  * The trust evaluation type that should be performed.
209  *
210  * @param manifest
211  * A pointer to the Image4 manifest bytes. This buffer may refer to a stitched
212  * manifest and payload object, in which case the implementation will extract
213  * the manifest portion.
214  *
215  * These bytes are not copied into any implementation storage, and the caller is
216  * responsible for ensuring that this memory remains valid for the duration of
217  * the trust object's use.
218  *
219  * @param manifest_len
220  * The length of the buffer referenced by {@link manifest}.
221  *
222  * @param flags
223  * Flags to influence the behavior of the resulting trust object.
224  *
225  * @result
226  * A newly-allocated and initialized {@link image4_trust_t} object. The caller
227  * is responsible for disposing of this object with {@link image4_trust_destroy}
228  * when it is no longer needed.
229  *
230  * If insufficient resources were available to allocate the object, or if the
231  * host runtime does not have an allocator, NULL is returned.
232  */
233 IMAGE4_API_AVAILABLE_SPRING_2024
234 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3
235 image4_trust_t *_Nullable
236 image4_trust_new(
237 	const image4_environment_t *nv,
238 	const image4_trust_evaluation_t *eval,
239 	const void *__sized_by(manifest_len) manifest,
240 	size_t manifest_len,
241 	image4_trust_flags_t flags);
242 IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_new);
243 
244 /*!
245  * @function image4_trust_set_payload
246  * Sets the payload to be used during the trust evaluation.
247  *
248  * @param trst
249  * The trust object.
250  *
251  * @param type
252  * The four-character code of the payload.
253  *
254  * @param bytes
255  * A pointer to the payload bytes to authenticate during trust evaluation. This
256  * buffer may refer to a stitched manifest and payload object, in which case the
257  * implementation will extract the payload portion.
258  *
259  * If the buffer does not refer to either a valid Image4 manifest or payload,
260  * the implementation will conclude that it is a bare Image4 payload -- that is,
261  * a payload which is not Image4-wrapped.
262  *
263  * These bytes are not copied into any implementation storage, and the caller is
264  * responsible for ensuring that this memory remains valid for the duration of
265  * the trust object's use.
266  *
267  * @param len
268  * The length of the buffer referenced by {@link bytes}.
269  */
270 IMAGE4_API_AVAILABLE_SPRING_2024
271 OS_EXPORT OS_NONNULL1 OS_NONNULL3
272 void
273 image4_trust_set_payload(
274 	image4_trust_t *trst,
275 	uint32_t type,
276 	const void *__sized_by(len) bytes,
277 	size_t len);
278 IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_set_payload);
279 
280 /*!
281  * @function image4_trust_set_booter
282  * Establish a link between the trust object and another trust object
283  * representing a previous stage of boot, securing it to that stage of boot.
284  * This may be called multiple times. Successive calls secure the previously-
285  * specified booter stage to the newly-specified booter stage, establishing a
286  * chain of trust from the last stage to the first stage.
287  *
288  * @param trst
289  * The trust object. This object must have been created with one of the
290  * following trust evaluation types:
291  *
292  *     - {@link IMAGE4_TRUST_EVALUATION_PREFLIGHT}
293  *     - {@link IMAGE4_TRUST_EVALUATION_SIGN}
294  *
295  * @param booter
296  * The trust object representing the previous stage of boot for {@link trst}.
297  * This object must have been created with the
298  * {@link IMAGE4_TRUST_EVALUATION_BOOT} trust evaluation type.
299  *
300  * This object is not copied into any implementation storage, and the caller is
301  * responsible for ensuring that it remains valid for the duration of the trust
302  * object's use.
303  *
304  * @discussion
305  * Trust objects with booter stages cannot be used to execute firmware because
306  * they are only intended to simulate a boot by replicating side effects of
307  * previous evaluations into the ultimate environment used by the trust object.
308  *
309  * In order to execute firmware, the environment must be consistent with the
310  * requirements of the manifest without modifications being required.
311  */
312 IMAGE4_API_AVAILABLE_SPRING_2024
313 OS_EXPORT OS_NONNULL1 OS_NONNULL2
314 void
315 image4_trust_set_booter(
316 	image4_trust_t *trst,
317 	const image4_trust_t *booter);
318 IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_set_booter);
319 
320 /*!
321  * @function image4_trust_record_property_bool
322  * Records the specified Boolean value into caller-provided storage.
323  *
324  * @param trst
325  * The trust object.
326  *
327  * @param type
328  * The type of property to be recorded (currently either manifest or object).
329  *
330  * @param tag
331  * The four character code of the property to capture.
332  *
333  * @param vp
334  * A pointer to the storage where the value should be written.
335  *
336  * @param vpp
337  * A pointer to storage where a pointer to the value should be written. This
338  * allows the caller to know whether the property was encountered during the
339  * trust evaluation at all. If the property was encountered, the storage
340  * referred to by this pointer will hold the same pointer given in the
341  * {@link vp} parameter.
342  *
343  * If the property was not encountered during trust evaluation, the contents of
344  * this storage are undefined. The caller should initialize the storage to a
345  * reasonable default.
346  *
347  * This may be NULL.
348  *
349  * @discussion
350  * If the property represented a constraint which was not satisfied, the
351  * implementation will not record its value.
352  *
353  * If the property associated with the given tag is present, but is not a
354  * Boolean, the implementation will not record its value.
355  */
356 IMAGE4_API_AVAILABLE_SPRING_2024
357 OS_EXPORT OS_NONNULL1 OS_NONNULL4
358 void
359 image4_trust_record_property_bool(
360 	image4_trust_t *trst,
361 	image4_trust_section_t type,
362 	uint32_t tag,
363 	bool *vp,
364 	const bool *_Nullable *_Nullable vpp);
365 IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_record_property_bool);
366 
367 /*!
368  * @function image4_trust_record_property_integer
369  * Records the specified unsigned integer value into caller-provided storage.
370  *
371  * @param trst
372  * The trust object.
373  *
374  * @param type
375  * The type of property to be recorded (currently either manifest or object).
376  *
377  * @param tag
378  * The four character code of the property to capture.
379  *
380  * @param vp
381  * A pointer to the storage where the value should be written.
382  *
383  * @param vpp
384  * A pointer to storage where a pointer to the value should be written. This
385  * allows the caller to know whether the property was encountered during the
386  * trust evaluation at all. If the property was encountered, the storage
387  * referred to by this pointer will hold the same pointer given in the
388  * {@link vp} parameter.
389  *
390  * If the property was not encountered during trust evaluation, the contents of
391  * this storage are undefined. The caller should initialize the storage to a
392  * reasonable default.
393  *
394  * This may be NULL.
395  *
396  * @discussion
397  * For boring implementation reasons, all integer properties are expressed as
398  * 64-bit unsigned integers. The caller is responsible for enforcing boundaries
399  * on the value recorded.
400  *
401  * If the property represented a constraint which was not satisfied, the
402  * implementation will not record its value.
403  *
404  * If the property associated with the given tag is present, but is not an
405  * integer, the implementation will not record its value.
406  */
407 IMAGE4_API_AVAILABLE_SPRING_2024
408 OS_EXPORT OS_NONNULL1 OS_NONNULL4
409 void
410 image4_trust_record_property_integer(
411 	image4_trust_t *trst,
412 	image4_trust_section_t type,
413 	uint32_t tag,
414 	uint64_t *vp,
415 	const uint64_t *_Nullable *_Nullable vpp);
416 IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_record_property_integer);
417 
418 /*!
419  * @function image4_trust_record_property_data
420  * Records a pointer to the specified octet string value into caller-provided
421  * storage.
422  *
423  * @param trst
424  * The trust object.
425  *
426  * @param type
427  * The type of property to be recorded (currently either manifest or object).
428  *
429  * @param tag
430  * The four character code of the property to capture.
431  *
432  * @param vp
433  * A pointer to the storage where the value should be written. The storage
434  * referenced by this pointer ultimately refers to the caller-provided memory
435  * which contains the Image4 manifest, and therefore its lifetime is tied to the
436  * caller's management of that storage.
437  *
438  * If the property was not encountered during trust evaluation, the contents of
439  * this storage are undefined. The caller should initialize the storage to a
440  * reasonable default.
441  *
442  * @param vp_len
443  * A pointer to the storage where the length of the octet string should be
444  * written.
445  *
446  * @discussion
447  * If the property represented a constraint which was not satisfied, the
448  * implementation will not record its value.
449  *
450  * If the property associated with the given tag is present, but is not an octet
451  * string, the implementation will not record its value.
452  *
453  * Properties which are intended to be used as C strings are represented in the
454  * manifest as simple octet strings which may or may not be null-terminated. The
455  * caller should take care to ensure null termination when the data is used,
456  * e.g. by copying the data into a local buffer using strlcpy(3).
457  */
458 IMAGE4_API_AVAILABLE_SPRING_2024
459 OS_EXPORT OS_NONNULL1 OS_NONNULL4 OS_NONNULL5
460 void
461 image4_trust_record_property_data(
462 	image4_trust_t *trst,
463 	image4_trust_section_t type,
464 	uint32_t tag,
465 	const void *_Nullable *_Nonnull vp,
466 	size_t *vp_len);
467 IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_record_property_data);
468 
469 /*!
470  * @function image4_trust_evaluate
471  * Perform the trust evaluation.
472  *
473  * @param trst
474  * The trust object.
475  *
476  * @param _ctx
477  * A context parameter to be delivered to the result callback.
478  *
479  * @param result
480  * The callback to invoke with the result of the trust evaluation. This callback
481  * is called directly inline from the implementation and must not re-enter the
482  * calling scope.
483  */
484 IMAGE4_API_AVAILABLE_SPRING_2024
485 OS_EXPORT OS_NONNULL1 OS_NONNULL3
486 void
487 image4_trust_evaluate(
488 	const image4_trust_t *trst,
489 	void *_Nullable _ctx,
490 	image4_trust_evaluation_result_t result);
491 IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_evaluate);
492 
493 /*!
494  * @function image4_trust_destroy
495  * Disposes a trust object which was created via {@link image4_trust_new}.
496  *
497  * @param nv
498  * A pointer to the trust object. Upon return, this storage will be set to NULL.
499  * If the object pointed to by this parameter is NULL, this is a no-op.
500  *
501  * @discussion
502  * If this routine is called on an environment object which was not allocated,
503  * it is a no-op.
504  */
505 IMAGE4_API_AVAILABLE_SPRING_2024
506 OS_EXPORT OS_NONNULL1
507 void
508 image4_trust_destroy(
509 	image4_trust_t *_Nonnull *_Nullable trst);
510 IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_destroy);
511 
512 OS_ASSUME_PTR_ABI_SINGLE_END
513 OS_ASSUME_NONNULL_END
514 __END_DECLS
515 
516 #endif // __IMAGE4_API_TRUST_H
517