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