gems-kernel/source/THIRDPARTY/xnu/EXTERNAL_HEADERS/image4/trust.h
2024-06-03 11:29:39 -05:00

516 lines
16 KiB
C

/*!
* @header
* Encapsulation which describes an Image4 trust object. This object can perform
* an evaluation in the context of a given environment, record properties that
* were encountered during evaluation, and deliver the evaluation result to the
* caller according to the type of evaluation being performed.
*/
#ifndef __IMAGE4_API_TRUST_H
#define __IMAGE4_API_TRUST_H
#include <image4/image4.h>
#include <image4/types.h>
#include <stdint.h>
#include <stdbool.h>
#if __has_include(<sys/types.h>)
#include <sys/types.h>
#else
typedef int errno_t;
#endif
__BEGIN_DECLS
OS_ASSUME_NONNULL_BEGIN
OS_ASSUME_PTR_ABI_SINGLE_BEGIN
#pragma mark Supporting Types
/*!
* @typedef image4_trust_flags_t
* Flags that may be provided to influence the behavior of an
* {@link image4_trust_t} object.
*
* @const IMAGE4_TRUST_FLAG_INIT
* No flags set. This value is suitable for initialization purposes.
*
* @const IMAGE4_TRUST_FLAG_VIOLATION_PANIC
* Upon encountering a violation during trust evaluation, the implementation
* should abort the current context.
*/
OS_CLOSED_OPTIONS(image4_trust_flags, uint64_t,
IMAGE4_TRUST_FLAG_INIT = 0,
IMAGE4_TRUST_FLAG_VIOLATION_PANIC = (1 << 0),
);
/*!
* @typedef image4_trust_section_t
* An enumeration of property sections in an Image4 manifest or object. Note
* that this is not strictly aligned with the concept of a "section" as defined
* in the Image4 specification.
*
* @const IMAGE4_TRUST_SECTION_CERTIFICATE
* The certificate properties within the manifest section.
*
* @const IMAGE4_TRUST_SECTION_MANIFEST
* The top-level properties in the manifest section.
*
* @const IMAGE4_TRUST_SECTION_OBJECT
* The properties associated with a particular object in the manifest section.
*
* @const IMAGE4_TRUST_SECTION_RESTORE_INFO
* The top-level properties in the RestoreInfo section. The RestoreInfo section
* is only recognized by the implementation when the trust object has been
* initialized with an IMG4 object that contains an IM4R section.
*
* This constant first became available in API version 20231103.
*
* @const IMAGE4_TRUST_SECTION_PAYLOAD_PROPERTIES
* The properties associated with the payload that is associated with the trust
* object, either by initializing the object with an IMG4 object, or by setting
* a payload with {@link image4_trust_set_payload}.
*
* This constant first became available in API version 20231103.
*/
OS_CLOSED_ENUM(image4_trust_section, uint64_t,
IMAGE4_TRUST_SECTION_CERTIFICATE,
IMAGE4_TRUST_SECTION_MANIFEST,
IMAGE4_TRUST_SECTION_OBJECT,
IMAGE4_TRUST_SECTION_RESTORE_INFO,
IMAGE4_TRUST_SECTION_PAYLOAD_PROPERTIES,
_IMAGE4_TRUST_SECTION_CNT,
);
/*!
* @typedef image4_trust_evaluation_result_t
* A callback for the result of a trust evaluation.
*
* @param trst
* The trust object.
*
* @param result
* Upon success, the prescribed payload resulting from the type of trust
* evaluation. If the trust evaluation type does not deliver a payload, or the
* trust evaluation failed, NULL will be passed.
*
* @param result_len
* The length of the buffer referenced by {@link payload}. If {@link payload} is
* NULL, zero will be passed.
*
* @param error
* A POSIX error code describing the result of the trust evaluation. Upon
* success, zero will be passed.
*
* @param context
* The caller-provided context pointer. If no context pointer was set, NULL will
* be passed.
*/
typedef void (*image4_trust_evaluation_result_t)(
const image4_trust_t *trst,
const void *_Nullable result,
size_t result_len,
errno_t error,
void *_Nullable context
);
/*!
* @const IMAGE4_TRUST_STRUCT_VERSION
* The version of the {@link image4_trust_t} structure supported by the
* implementation.
*/
#define IMAGE4_TRUST_STRUCT_VERSION (0u)
/*!
* @header image4_trust_storage_t
* An opaque structure which is guaranteed to be large enough to accommodate an
* {@link image4_trust_t}.
*
* @field __opaque
* The opaque storage.
*
* @discussion
* The size of this object was set in API version 20231103.
*/
typedef struct _image4_trust_storage {
uint8_t __opaque[1920];
} image4_trust_storage_t;
/*!
* @const IMAGE4_TRUST_STORAGE_INIT
* Initializer for a {@link image4_trust_storage_t} object.
*/
#define IMAGE4_TRUST_STORAGE_INIT (image4_trust_storage_t){ \
.__opaque = { 0x00 }, \
}
#pragma mark API
/*!
* @function image4_trust_init
* Convert a {@link image4_trust_storage_t} to an initialized
* {@link image4_trust_t} object.
*
* @param storage
* The storage structure.
*
* @param environment
* The environment in which the trust evaluation should be performed.
*
* @param evaluation
* The trust evaluation type that should be performed.
*
* @param manifest
* A pointer to the Image4 manifest bytes. This buffer may refer to a stitched
* manifest and payload object, in which case the implementation will extract
* the manifest portion.
*
* These bytes are not copied into any implementation storage, and the caller is
* responsible for ensuring that this memory remains valid for the duration of
* the trust object's use.
*
* @param manifest_len
* The length of the buffer referenced by {@link manifest}.
*
* @param flags
* Flags to influence the behavior of the resulting trust object.
*
* @result
* An initialized {@link image4_trust_t} object.
*/
IMAGE4_API_AVAILABLE_SPRING_2024
OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3 OS_NONNULL4
image4_trust_t *
_image4_trust_init(
image4_trust_storage_t *storage,
const image4_environment_t *environment,
const image4_trust_evaluation_t *evaluation,
const void *__sized_by(manifest_len) manifest,
size_t manifest_len,
image4_trust_flags_t flags,
image4_struct_version_t v);
#define image4_trust_init(_storage, _environment, _evaluation, \
_manifest, _manifest_len, _flags) \
_image4_trust_init( \
(_storage), \
(_environment), \
(_evaluation), \
(_manifest), \
(_manifest_len), \
(_flags), \
IMAGE4_TRUST_STRUCT_VERSION)
IMAGE4_XNU_AVAILABLE_INDIRECT(_image4_trust_init);
/*!
* @function image4_trust_new
* Allocates a trust object.
*
* @param nv
* The environment in which the trust evaluation should be performed.
*
* @param eval
* The trust evaluation type that should be performed.
*
* @param manifest
* A pointer to the Image4 manifest bytes. This buffer may refer to a stitched
* manifest and payload object, in which case the implementation will extract
* the manifest portion.
*
* These bytes are not copied into any implementation storage, and the caller is
* responsible for ensuring that this memory remains valid for the duration of
* the trust object's use.
*
* @param manifest_len
* The length of the buffer referenced by {@link manifest}.
*
* @param flags
* Flags to influence the behavior of the resulting trust object.
*
* @result
* A newly-allocated and initialized {@link image4_trust_t} object. The caller
* is responsible for disposing of this object with {@link image4_trust_destroy}
* when it is no longer needed.
*
* If insufficient resources were available to allocate the object, or if the
* host runtime does not have an allocator, NULL is returned.
*/
IMAGE4_API_AVAILABLE_SPRING_2024
OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3
image4_trust_t *_Nullable
image4_trust_new(
const image4_environment_t *nv,
const image4_trust_evaluation_t *eval,
const void *__sized_by(manifest_len) manifest,
size_t manifest_len,
image4_trust_flags_t flags);
IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_new);
/*!
* @function image4_trust_set_payload
* Sets the payload to be used during the trust evaluation.
*
* @param trst
* The trust object.
*
* @param type
* The four-character code of the payload.
*
* @param bytes
* A pointer to the payload bytes to authenticate during trust evaluation. This
* buffer may refer to a stitched manifest and payload object, in which case the
* implementation will extract the payload portion.
*
* If the buffer does not refer to either a valid Image4 manifest or payload,
* the implementation will conclude that it is a bare Image4 payload -- that is,
* a payload which is not Image4-wrapped.
*
* These bytes are not copied into any implementation storage, and the caller is
* responsible for ensuring that this memory remains valid for the duration of
* the trust object's use.
*
* @param len
* The length of the buffer referenced by {@link bytes}.
*/
IMAGE4_API_AVAILABLE_SPRING_2024
OS_EXPORT OS_NONNULL1 OS_NONNULL3
void
image4_trust_set_payload(
image4_trust_t *trst,
uint32_t type,
const void *__sized_by(len) bytes,
size_t len);
IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_set_payload);
/*!
* @function image4_trust_set_booter
* Establish a link between the trust object and another trust object
* representing a previous stage of boot, securing it to that stage of boot.
* This may be called multiple times. Successive calls secure the previously-
* specified booter stage to the newly-specified booter stage, establishing a
* chain of trust from the last stage to the first stage.
*
* @param trst
* The trust object. This object must have been created with one of the
* following trust evaluation types:
*
* - {@link IMAGE4_TRUST_EVALUATION_PREFLIGHT}
* - {@link IMAGE4_TRUST_EVALUATION_SIGN}
*
* @param booter
* The trust object representing the previous stage of boot for {@link trst}.
* This object must have been created with the
* {@link IMAGE4_TRUST_EVALUATION_BOOT} trust evaluation type.
*
* This object is not copied into any implementation storage, and the caller is
* responsible for ensuring that it remains valid for the duration of the trust
* object's use.
*
* @discussion
* Trust objects with booter stages cannot be used to execute firmware because
* they are only intended to simulate a boot by replicating side effects of
* previous evaluations into the ultimate environment used by the trust object.
*
* In order to execute firmware, the environment must be consistent with the
* requirements of the manifest without modifications being required.
*/
IMAGE4_API_AVAILABLE_SPRING_2024
OS_EXPORT OS_NONNULL1 OS_NONNULL2
void
image4_trust_set_booter(
image4_trust_t *trst,
const image4_trust_t *booter);
IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_set_booter);
/*!
* @function image4_trust_record_property_bool
* Records the specified Boolean value into caller-provided storage.
*
* @param trst
* The trust object.
*
* @param type
* The type of property to be recorded (currently either manifest or object).
*
* @param tag
* The four character code of the property to capture.
*
* @param vp
* A pointer to the storage where the value should be written.
*
* @param vpp
* A pointer to storage where a pointer to the value should be written. This
* allows the caller to know whether the property was encountered during the
* trust evaluation at all. If the property was encountered, the storage
* referred to by this pointer will hold the same pointer given in the
* {@link vp} parameter.
*
* If the property was not encountered during trust evaluation, the contents of
* this storage are undefined. The caller should initialize the storage to a
* reasonable default.
*
* This may be NULL.
*
* @discussion
* If the property represented a constraint which was not satisfied, the
* implementation will not record its value.
*
* If the property associated with the given tag is present, but is not a
* Boolean, the implementation will not record its value.
*/
IMAGE4_API_AVAILABLE_SPRING_2024
OS_EXPORT OS_NONNULL1 OS_NONNULL4
void
image4_trust_record_property_bool(
image4_trust_t *trst,
image4_trust_section_t type,
uint32_t tag,
bool *vp,
const bool *_Nullable *_Nullable vpp);
IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_record_property_bool);
/*!
* @function image4_trust_record_property_integer
* Records the specified unsigned integer value into caller-provided storage.
*
* @param trst
* The trust object.
*
* @param type
* The type of property to be recorded (currently either manifest or object).
*
* @param tag
* The four character code of the property to capture.
*
* @param vp
* A pointer to the storage where the value should be written.
*
* @param vpp
* A pointer to storage where a pointer to the value should be written. This
* allows the caller to know whether the property was encountered during the
* trust evaluation at all. If the property was encountered, the storage
* referred to by this pointer will hold the same pointer given in the
* {@link vp} parameter.
*
* If the property was not encountered during trust evaluation, the contents of
* this storage are undefined. The caller should initialize the storage to a
* reasonable default.
*
* This may be NULL.
*
* @discussion
* For boring implementation reasons, all integer properties are expressed as
* 64-bit unsigned integers. The caller is responsible for enforcing boundaries
* on the value recorded.
*
* If the property represented a constraint which was not satisfied, the
* implementation will not record its value.
*
* If the property associated with the given tag is present, but is not an
* integer, the implementation will not record its value.
*/
IMAGE4_API_AVAILABLE_SPRING_2024
OS_EXPORT OS_NONNULL1 OS_NONNULL4
void
image4_trust_record_property_integer(
image4_trust_t *trst,
image4_trust_section_t type,
uint32_t tag,
uint64_t *vp,
const uint64_t *_Nullable *_Nullable vpp);
IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_record_property_integer);
/*!
* @function image4_trust_record_property_data
* Records a pointer to the specified octet string value into caller-provided
* storage.
*
* @param trst
* The trust object.
*
* @param type
* The type of property to be recorded (currently either manifest or object).
*
* @param tag
* The four character code of the property to capture.
*
* @param vp
* A pointer to the storage where the value should be written. The storage
* referenced by this pointer ultimately refers to the caller-provided memory
* which contains the Image4 manifest, and therefore its lifetime is tied to the
* caller's management of that storage.
*
* If the property was not encountered during trust evaluation, the contents of
* this storage are undefined. The caller should initialize the storage to a
* reasonable default.
*
* @param vp_len
* A pointer to the storage where the length of the octet string should be
* written.
*
* @discussion
* If the property represented a constraint which was not satisfied, the
* implementation will not record its value.
*
* If the property associated with the given tag is present, but is not an octet
* string, the implementation will not record its value.
*
* Properties which are intended to be used as C strings are represented in the
* manifest as simple octet strings which may or may not be null-terminated. The
* caller should take care to ensure null termination when the data is used,
* e.g. by copying the data into a local buffer using strlcpy(3).
*/
IMAGE4_API_AVAILABLE_SPRING_2024
OS_EXPORT OS_NONNULL1 OS_NONNULL4 OS_NONNULL5
void
image4_trust_record_property_data(
image4_trust_t *trst,
image4_trust_section_t type,
uint32_t tag,
const void *_Nullable *_Nonnull vp,
size_t *vp_len);
IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_record_property_data);
/*!
* @function image4_trust_evaluate
* Perform the trust evaluation.
*
* @param trst
* The trust object.
*
* @param _ctx
* A context parameter to be delivered to the result callback.
*
* @param result
* The callback to invoke with the result of the trust evaluation. This callback
* is called directly inline from the implementation and must not re-enter the
* calling scope.
*/
IMAGE4_API_AVAILABLE_SPRING_2024
OS_EXPORT OS_NONNULL1 OS_NONNULL3
void
image4_trust_evaluate(
const image4_trust_t *trst,
void *_Nullable _ctx,
image4_trust_evaluation_result_t result);
IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_evaluate);
/*!
* @function image4_trust_destroy
* Disposes a trust object which was created via {@link image4_trust_new}.
*
* @param nv
* A pointer to the trust object. Upon return, this storage will be set to NULL.
* If the object pointed to by this parameter is NULL, this is a no-op.
*
* @discussion
* If this routine is called on an environment object which was not allocated,
* it is a no-op.
*/
IMAGE4_API_AVAILABLE_SPRING_2024
OS_EXPORT OS_NONNULL1
void
image4_trust_destroy(
image4_trust_t *_Nonnull *_Nullable trst);
IMAGE4_XNU_AVAILABLE_DIRECT(image4_trust_destroy);
OS_ASSUME_PTR_ABI_SINGLE_END
OS_ASSUME_NONNULL_END
__END_DECLS
#endif // __IMAGE4_API_TRUST_H