3 * Image4 interfaces. These interfaces encapsulate the basic concepts required
4 * for authenticating and validating Image4 manifests as being authoritative.
8 * An environment is a description of a host comprised of hardware identifiers
9 * and policy configurations. For example, the environment of an iPhone may
10 * include the following hardware identifiers (among others):
13 * A number identifying the chip design.
16 * A number identifying the board.
19 * A number uniquely identifying a specific instance of a chip.
21 * The environment also includes policy information derived by previous stages
22 * of secure boot. Examples of such policy are:
24 * Mix-n-Match Prevention
25 * Whether firmware payloads from multiple, valid secure boot manifests
26 * should be prevented from being executed on the host environment. The
30 * An Image4 manifest is a set of constraints that describe a host environment.
31 * For example, a manifest may have been signed such that it is only valid for a
32 * single host environment. In this case, the manifest may include specific
33 * values for ChipID, BoardID, UniqueChipID, etc. Such a manifest is said to be
34 * personalized for that environment.
36 * If an environment meets the constraints in a manifest, that manifest is said
37 * to be authoritative over the environment.
39 * The manifest also includes one or more objects which may be executed in the
43 * An object is a description of a payload. An object can describe any payload,
44 * not just the payload that is in the Image4. An object describes a payload by
45 * means of its digest. Examples of objects present in a secure boot manifest
46 * are the kernelcache and the static trust cache.
48 * If an authoritative manifest accurately describes an object, then that object
49 * may be executed in the host environment. The mechanics of execution typically
50 * involve mapping its payload into a privileged memory region. For example,
51 * when the kernelcache is executed, its payload bytes are mapped into the range
52 * of memory associated with supervisor mode.
55 * A payload is the raw sequence of bytes that is described by an object. When
56 * described via an Image4 object, payloads are first wrapped in Image4 encoding
57 * to associate a tag with them. The resulting series of bytes is what is
58 * contained in a .im4p file.
60 * An Image4 file may only contain a single payload (even though a manifest may
61 * describe multiple payloads through multiple objects).
64 * A tag is a FourCC which can identify any of the following:
66 * - an object property (e.g. the 'DGST' property)
67 * - a manifest property (e.g. the 'BORD' property)
68 * - a certificate property
69 * - a type of object (e.g. 'krnl')
71 * Tags comprised of all-caps are reserved for the Image4 specification.
73 * @section Secure Boot Policy
74 * Manifests are evaluated with the Secure Boot evaluation policy. Broadly
75 * speaking, this policy:
77 * - enforces that manifest identifiers match the host's silicon
79 * - enforces that the epoch of the certificate which signed the manifest is
80 * greater than or equal to the host silicon's epoch
81 * - enforces that the current manifest is the same one that was used in the
82 * previous stage of Secure Boot unless mix-n-match is allowed
84 * For manifests which lack a CHMH property, mix-n-match policy is enforced as
87 * (1) If the previous stage of Secure Boot disallows mix-n-match and the
88 * manifest does not possess the AMNM entitlement, the hash of the
89 * manifest will be enforced against the hash of the manifest which was
90 * evaluated by the previous stage of Secure Boot.
92 * (2) If the previous stage of Secure Boot allows mix-n-match or the manifest
93 * possesses the AMNM entitlement, the manifest's constraints will be
94 * enforced on the environment, but the manifest will not be expected to
95 * be consistent with the manifest evaluated in the previous stage of
96 * Secure Boot, i.e. the hash of the previous manifest will not be
97 * enforced against the manifest being evaluated.
99 * Enforcement of the manifest's constraints will include the value of the
100 * BNCH tag in the manifest, if any. Therefore the caller should always
101 * provide a nonce value to the implementation via {@link img4_set_nonce}
102 * if this option is used.
104 * For manifests which possess a CHMH property, mix-n-match policy is enforced
107 * (1) If the previous stage of Secure Boot disallows mix-n-match or the
108 * manifest does not possess the AMNM entitlement, the value of the CHMH
109 * property will be enforced against the hash of the manifest which was
110 * evaluated by the previous stage of Secure Boot.
112 * (2) If the previous stage of Secure Boot allows mix-n-match and the
113 * manifest possesses the AMNM entitlement, all of the manifest's
114 * constraints will be enforced on the environment except for the CHMH
115 * constraint, which will be ignored.
117 * Enforcement of the manifest's constraints will include the value of the
118 * BNCH tag in the manifest, if any. Therefore the caller should always
119 * provide a nonce value to the implementation via {@link img4_set_nonce}
120 * if this option is used.
122 * The CHMH policy may be expressed as the following truth table:
124 * AMNM [manifest] Verify Manifest Hash [environment] Enforce CHMH
138 #include <sys/cdefs.h>
140 #define __IMG4_INDIRECT 1
143 * This header is used in the pmap layer in xnu, which is in osfmk, which does
144 * not have access to most of the BSD headers. (But for some reason it does have
145 * access to sys/cdefs.h.) The only thing we need from that header is the
146 * errno_t typedef though, so if we can't get to it, then just typedef it
149 #if MACH_KERNEL_PRIVATE
152 #include <sys/types.h>
155 #if !IMG4_PROJECT_BUILD
156 #include <img4/api.h>
162 * @typedef img4_tag_t
163 * A type describing an Image4 tag.
165 IMG4_API_AVAILABLE_20180112
166 typedef uint32_t img4_tag_t
;
169 * @typedef img4_section_t
170 * A type describing the sections of an Image4 object.
172 * @const IMG4_SECTION_MANIFEST
173 * The manifest section.
175 * @const IMG4_SECTION_OBJECT
176 * The object section.
178 * @const IMG4_SECTION_RESTOREINFO
179 * The restore info section.
181 OS_ENUM(img4_section
, uint8_t,
182 IMG4_SECTION_MANIFEST
,
184 IMG4_SECTION_RESTOREINFO
,
185 ) IMG4_API_AVAILABLE_20180112
;
188 * @typedef img4_destructor_t
189 * A type describing a destructor routine for an Image4 object.
192 * A pointer to the buffer to dispose of.
195 * The length of the buffer.
197 IMG4_API_AVAILABLE_20180112
198 typedef void (*img4_destructor_t
)(
203 * @typedef img4_flags_t
204 * A flagset modifying the behavior of an {@link img4_t}.
207 * No flags set. This value is suitable for initialization purposes.
209 * @const I4F_TRUST_MANIFEST
210 * Causes the implementation to bypass trust evaluation for the manifest, i.e.
211 * it will not verify that a manifest has been signed by Apple before trusting
214 * This option is for testing purposes only and is not respected on the RELEASE
215 * variant of the implementation.
217 * @const I4F_FORCE_MIXNMATCH
218 * Causes the implementation to bypass mix-n-match policy evaluation and always
219 * allow mix-n-match, irrespective of the previous boot stage's conclusion or
220 * manifest policy. This also allows replay of manifests whose personalization
221 * has been invalidated by rolling the nonce.
223 * This option is for testing purposes only and is not respected on the RELEASE
224 * variant of the implementation.
226 * @const I4F_FIRST_STAGE
227 * Indicates that the manifest being evaluated is the first link in the secure
228 * boot chain. This causes the implementation to enforce the manifest directly
229 * on the environment rather than requiring that a previous stage has already
230 * done so by way of checking the previous stage's boot manifest hash. In effect
231 * this disables the mix-n-match enforcement policy.
233 * The critical difference between this flag and {@link I4F_FORCE_MIXNMATCH} is
234 * that this flag will cause the entire manifest to be enforced on the
235 * environment, including the anti-replay token in BNCH.
236 * {@link I4F_FORCE_MIXNMATCH} will ignore the nonce.
238 * It is illegal to use a manifest which possesses a CHMH tag as a first-stage
241 OS_ENUM(img4_flags
, uint64_t,
243 I4F_TRUST_MANIFEST
= (1 << 0),
244 I4F_FORCE_MIXNMATCH
= (1 << 1),
245 I4F_FIRST_STAGE
= (1 << 2),
246 ) IMG4_API_AVAILABLE_20180112
;
248 typedef char _img4_opaque_data_64
[696];
250 typedef char _img4_opaque_data_32
[520];
254 * An opaque structure representing Image4 data. The Image4 data must contain a
255 * manifest and may optionally contain a payload. Neither this type nor the APIs
256 * APIs which manipulate it are thread-safe.
258 IMG4_API_AVAILABLE_20180112
259 typedef struct _img4
{
260 #if __ILP64__ || __LP64__
261 _img4_opaque_data_64 __opaque
;
263 _img4_opaque_data_32 __opaque
;
267 typedef char _img4_payload_opaque_data_64
[496];
269 #if __ARM_ARCH_7S__ || __i386__
270 typedef char _img4_payload_opaque_data_32
[324];
272 typedef char _img4_payload_opaque_data_32
[328];
276 * @typedef img4_payload_t
277 * An opaque structure describing Image4 payload data. Neither this type nor the
278 * APIs which manipulate it are thread-safe.
280 IMG4_API_AVAILABLE_20180112
281 typedef struct _img4_payload
{
282 #if __ILP64__ || __LP64__
283 _img4_payload_opaque_data_64 __opaque
;
285 _img4_payload_opaque_data_32 __opaque
;
289 #if !IMG4_PROJECT_BUILD
290 #include <img4/environment.h>
291 #include <img4/nonce.h>
292 #include <img4/payload.h>
296 #include "environment.h"
302 * @function img4_init
303 * Initializes an Image4.
306 * A pointer to the storage to initialize.
309 * Flags to modify initialization.
312 * The Image4 data from which to initialize. If a destructor is provided,
313 * control of this buffer transfers to the Image4.
316 * The length of the Image4 data.
319 * A destructor for the Image4 data. May be NULL if the buffer does not require
320 * explicit deallocation (e.g. because the buffer is stack data).
323 * Upon success, zero is returned. The implementation may also return one of the
324 * following error codes directly:
326 * [EILSEQ] The data is not valid Image4 data
327 * [EFTYPE] The data does not contain an Image4 manifest
330 * The bytes given to this routine must represent an Image4 manifest. They may
331 * optionally also represent an Image4 payload.
333 #if !MACH_KERNEL_PRIVATE
334 IMG4_API_AVAILABLE_20180112
335 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL3
337 img4_init(img4_t
*i4
, img4_flags_t flags
, const uint8_t *bytes
, size_t len
,
338 img4_destructor_t destructor
);
340 #define img4_init(...) (img4if->i4if_init(__VA_ARGS__))
344 * @function img4_set_nonce
345 * Sets the anti-reply token to be used during manifest enforcement. This value
346 * will be compared against the value of the manifest's BNCH property.
349 * The Image4 to modify.
352 * The bytes which comprise the anti-replay token.
355 * The length of the anti-replay token.
358 * If a nonce is not set prior to a call to either
359 * {@link img4_get_trusted_payload} or
360 * {@link img4_get_trusted_external_payload}, the implementation will act as
361 * though there is no nonce in the environment. Therefore, any manifests which
362 * have a BNCH property constraint will fail to validate.
364 #if !MACH_KERNEL_PRIVATE
365 IMG4_API_AVAILABLE_20180112
366 OS_EXPORT OS_NONNULL1 OS_NONNULL2
368 img4_set_nonce(img4_t
*i4
, const void *bytes
, size_t len
);
370 #define img4_set_nonce(...) (img4if->i4if_set_nonce(__VA_ARGS__))
374 * @function img4_set_nonce_domain
375 * Sets the nonce domain to be consulted for the anti-replay token during
376 * manifest enforcement.
379 * The Image4 to modify.
382 * The nonce domain to use for anti-replay.
385 * See discussion for {@link img4_set_nonce}.
387 #if !MACH_KERNEL_PRIVATE
388 IMG4_API_AVAILABLE_20181106
389 OS_EXPORT OS_NONNULL1 OS_NONNULL2
391 img4_set_nonce_domain(img4_t
*i4
, const img4_nonce_domain_t
*nd
);
393 #define img4_set_nonce_domain(...) \
394 (img4if->i4if_v1.set_nonce_domain(__VA_ARGS__))
398 * @function img4_get_trusted_payload
399 * Obtains the trusted payload bytes from the Image4.
402 * The Image4 to query.
405 * The tag for the payload to obtain.
408 * The environment against which to validate the Image4.
411 * A pointer to the storage where the pointer to the payload buffer will be
412 * written on success.
415 * A pointer to the storage where the length of the payload buffer will be
416 * written on success.
419 * Upon success, zero is returned. The implementation may also return one of the
420 * following error codes directly:
422 * [ENOENT] The Image4 does not contain a payload for the specified tag
423 * [EAUTH] The Image4 manifest was not authentic
424 * [EACCES] The environment given does not satisfy the manifest
426 * [ESTALE] The nonce specified is not valid
427 * [EACCES] The environment and manifest do not agree on a digest
429 * [EILSEQ] The payload for the given tag does not match its description
431 * [EIO] The payload could not be fetched
433 * Additionally, errors from the routines specified in the
434 * {@link img4_environment_t} may be returned.
437 * This routine will perform the following validation:
439 * 1. Validate that the Image4 manifest is authentic (i.e. was signed by
441 * 2. Validate that the given environment satisfies the constraints in the
443 * 3. Validate that the measurement of the payload for the given tag matches
444 * the measurement in the manifest
446 * If any one of these validation checks fails, the payload is considered
447 * untrustworthy and is not returned.
449 #if !MACH_KERNEL_PRIVATE
450 IMG4_API_AVAILABLE_20180112
451 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL3 OS_NONNULL4 OS_NONNULL5
453 img4_get_trusted_payload(img4_t
*i4
, img4_tag_t tag
,
454 const img4_environment_t
*env
, const uint8_t **bytes
, size_t *len
);
456 #define img4_get_trusted_payload(...) \
457 (img4if->i4if_get_trusted_payload(__VA_ARGS__))
461 * @function img4_get_trusted_external_payload
462 * Obtains the trusted payload bytes from the external Image4 payload after
463 * validating them against the object description in the Image4's manifest.
466 * The Image4 to query.
469 * The payload to validate.
472 * The environment against which to validate the Image4.
475 * A pointer to the storage where the pointer to the payload buffer will be
476 * written on success.
479 * A pointer to the storage where the length of the payload buffer will be
480 * written on success.
483 * Upon success, zero is returned. The implementation may also return one of the
484 * following error codes directly:
486 * [ENOENT] The Image4 does not contain an object describing the given
488 * [EAUTH] The Image4 manifest was not authentic
489 * [EACCES] The environment given does not satisfy the manifest
491 * [ESTALE] The nonce specified is not valid
492 * [EACCES] The environment and manifest do not agree on a digest
494 * [EILSEQ] The payload for the given tag does not match its description
496 * [EIO] The payload could not be fetched
498 * Otherwise, an error from the underlying Image4 implementation will be
502 * This routine performs the same validation steps as
503 * {@link img4_get_trusted_payload}.
505 #if !MACH_KERNEL_PRIVATE
506 IMG4_API_AVAILABLE_20180112
507 OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3 OS_NONNULL4
510 img4_get_trusted_external_payload(img4_t
*i4
, img4_payload_t
*payload
,
511 const img4_environment_t
*env
, const uint8_t **bytes
, size_t *len
);
513 #define img4_get_trusted_external_payload(...) \
514 (img4if->i4if_get_trusted_external_payload(__VA_ARGS__))
518 * @function img4_destroy
519 * Destroys an Image4 and disposes of associated resources.
522 * The Image4 to destroy.
525 * The destructor passed to {@link img4_init} is called as a result of this
526 * routine, if any was set.
528 #if !MACH_KERNEL_PRIVATE
529 IMG4_API_AVAILABLE_20180112
530 OS_EXPORT OS_NONNULL1
532 img4_destroy(img4_t
*i4
);
534 #define img4_destroy(...) (img4if->i4if_destroy(__VA_ARGS__))