123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- /* SPDX-License-Identifier: MIT */
- /*
- * Copyright (C) 2016 The Android Open Source Project
- */
- #if !defined(AVB_INSIDE_LIBAVB_H) && !defined(AVB_COMPILATION)
- #error "Never include this file directly, include libavb.h instead."
- #endif
- #ifndef AVB_OPS_H_
- #define AVB_OPS_H_
- #include "avb_sysdeps.h"
- #ifdef __cplusplus
- extern "C" {
- #endif
- /* Well-known names of named persistent values. */
- #define AVB_NPV_PERSISTENT_DIGEST_PREFIX "avb.persistent_digest."
- /* Return codes used for I/O operations.
- *
- * AVB_IO_RESULT_OK is returned if the requested operation was
- * successful.
- *
- * AVB_IO_RESULT_ERROR_IO is returned if the underlying hardware (disk
- * or other subsystem) encountered an I/O error.
- *
- * AVB_IO_RESULT_ERROR_OOM is returned if unable to allocate memory.
- *
- * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION is returned if the requested
- * partition does not exist.
- *
- * AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION is returned if the
- * range of bytes requested to be read or written is outside the range
- * of the partition.
- *
- * AVB_IO_RESULT_ERROR_NO_SUCH_VALUE is returned if a named persistent value
- * does not exist.
- *
- * AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE is returned if a named persistent
- * value size is not supported or does not match the expected size.
- *
- * AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE is returned if a buffer is too small
- * for the requested operation.
- */
- typedef enum {
- AVB_IO_RESULT_OK,
- AVB_IO_RESULT_ERROR_OOM,
- AVB_IO_RESULT_ERROR_IO,
- AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION,
- AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION,
- AVB_IO_RESULT_ERROR_NO_SUCH_VALUE,
- AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE,
- AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE,
- } AvbIOResult;
- struct AvbOps;
- typedef struct AvbOps AvbOps;
- /* Forward-declaration of operations in libavb_ab. */
- struct AvbABOps;
- /* Forward-declaration of operations in libavb_atx. */
- struct AvbAtxOps;
- /* High-level operations/functions/methods that are platform
- * dependent.
- *
- * Operations may be added in the future so when implementing it
- * always make sure to zero out sizeof(AvbOps) bytes of the struct to
- * ensure that unimplemented operations are set to NULL.
- */
- struct AvbOps {
- /* This pointer can be used by the application/bootloader using
- * libavb and is typically used in each operation to get a pointer
- * to platform-specific resources. It cannot be used by libraries.
- */
- void* user_data;
- /* If libavb_ab is used, this should point to the
- * AvbABOps. Otherwise it must be set to NULL.
- */
- struct AvbABOps* ab_ops;
- /* If libavb_atx is used, this should point to the
- * AvbAtxOps. Otherwise it must be set to NULL.
- */
- struct AvbAtxOps* atx_ops;
- /* Reads |num_bytes| from offset |offset| from partition with name
- * |partition| (NUL-terminated UTF-8 string). If |offset| is
- * negative, its absolute value should be interpreted as the number
- * of bytes from the end of the partition.
- *
- * This function returns AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION if
- * there is no partition with the given name,
- * AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION if the requested
- * |offset| is outside the partition, and AVB_IO_RESULT_ERROR_IO if
- * there was an I/O error from the underlying I/O subsystem. If the
- * operation succeeds as requested AVB_IO_RESULT_OK is returned and
- * the data is available in |buffer|.
- *
- * The only time partial I/O may occur is if reading beyond the end
- * of the partition. In this case the value returned in
- * |out_num_read| may be smaller than |num_bytes|.
- */
- AvbIOResult (*read_from_partition)(AvbOps* ops,
- const char* partition,
- int64_t offset,
- size_t num_bytes,
- void* buffer,
- size_t* out_num_read);
- /* Gets the starting pointer of a partition that is pre-loaded in memory, and
- * save it to |out_pointer|. The preloaded partition is expected to be
- * |num_bytes|, where the actual preloaded byte count is returned in
- * |out_num_bytes_preloaded|. |out_num_bytes_preloaded| must be no larger than
- * |num_bytes|.
- *
- * This provides an alternative way to access a partition that is preloaded
- * into memory without a full memory copy. When this function pointer is not
- * set (has value NULL), or when the |out_pointer| is set to NULL as a result,
- * |read_from_partition| will be used as the fallback. This function is mainly
- * used for accessing the entire partition content to calculate its hash.
- *
- * Preloaded partition data must outlive the lifespan of the
- * |AvbSlotVerifyData| structure that |avb_slot_verify| outputs.
- */
- AvbIOResult (*get_preloaded_partition)(AvbOps* ops,
- const char* partition,
- size_t num_bytes,
- uint8_t** out_pointer,
- size_t* out_num_bytes_preloaded);
- /* Writes |num_bytes| from |bffer| at offset |offset| to partition
- * with name |partition| (NUL-terminated UTF-8 string). If |offset|
- * is negative, its absolute value should be interpreted as the
- * number of bytes from the end of the partition.
- *
- * This function returns AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION if
- * there is no partition with the given name,
- * AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION if the requested
- * byterange goes outside the partition, and AVB_IO_RESULT_ERROR_IO
- * if there was an I/O error from the underlying I/O subsystem. If
- * the operation succeeds as requested AVB_IO_RESULT_OK is
- * returned.
- *
- * This function never does any partial I/O, it either transfers all
- * of the requested bytes or returns an error.
- */
- AvbIOResult (*write_to_partition)(AvbOps* ops,
- const char* partition,
- int64_t offset,
- size_t num_bytes,
- const void* buffer);
- /* Checks if the given public key used to sign the 'vbmeta'
- * partition is trusted. Boot loaders typically compare this with
- * embedded key material generated with 'avbtool
- * extract_public_key'.
- *
- * The public key is in the array pointed to by |public_key_data|
- * and is of |public_key_length| bytes.
- *
- * If there is no public key metadata (set with the avbtool option
- * --public_key_metadata) then |public_key_metadata| will be set to
- * NULL. Otherwise this field points to the data which is
- * |public_key_metadata_length| bytes long.
- *
- * If AVB_IO_RESULT_OK is returned then |out_is_trusted| is set -
- * true if trusted or false if untrusted.
- */
- AvbIOResult (*validate_vbmeta_public_key)(AvbOps* ops,
- const uint8_t* public_key_data,
- size_t public_key_length,
- const uint8_t* public_key_metadata,
- size_t public_key_metadata_length,
- bool* out_is_trusted);
- /* Gets the rollback index corresponding to the location given by
- * |rollback_index_location|. The value is returned in
- * |out_rollback_index|. Returns AVB_IO_RESULT_OK if the rollback
- * index was retrieved, otherwise an error code.
- *
- * A device may have a limited amount of rollback index locations (say,
- * one or four) so may error out if |rollback_index_location| exceeds
- * this number.
- */
- AvbIOResult (*read_rollback_index)(AvbOps* ops,
- size_t rollback_index_location,
- uint64_t* out_rollback_index);
- /* Sets the rollback index corresponding to the location given by
- * |rollback_index_location| to |rollback_index|. Returns
- * AVB_IO_RESULT_OK if the rollback index was set, otherwise an
- * error code.
- *
- * A device may have a limited amount of rollback index locations (say,
- * one or four) so may error out if |rollback_index_location| exceeds
- * this number.
- */
- AvbIOResult (*write_rollback_index)(AvbOps* ops,
- size_t rollback_index_location,
- uint64_t rollback_index);
- /* Gets whether the device is unlocked. The value is returned in
- * |out_is_unlocked| (true if unlocked, false otherwise). Returns
- * AVB_IO_RESULT_OK if the state was retrieved, otherwise an error
- * code.
- */
- AvbIOResult (*read_is_device_unlocked)(AvbOps* ops, bool* out_is_unlocked);
- /* Gets the unique partition GUID for a partition with name in
- * |partition| (NUL-terminated UTF-8 string). The GUID is copied as
- * a string into |guid_buf| of size |guid_buf_size| and will be NUL
- * terminated. The string must be lower-case and properly
- * hyphenated. For example:
- *
- * 527c1c6d-6361-4593-8842-3c78fcd39219
- *
- * Returns AVB_IO_RESULT_OK on success, otherwise an error code.
- */
- AvbIOResult (*get_unique_guid_for_partition)(AvbOps* ops,
- const char* partition,
- char* guid_buf,
- size_t guid_buf_size);
- /* Gets the size of a partition with the name in |partition|
- * (NUL-terminated UTF-8 string). Returns the value in
- * |out_size_num_bytes|.
- *
- * Returns AVB_IO_RESULT_OK on success, otherwise an error code.
- */
- AvbIOResult (*get_size_of_partition)(AvbOps* ops,
- const char* partition,
- uint64_t* out_size_num_bytes);
- /* Reads a persistent value corresponding to the given |name|. The value is
- * returned in |out_buffer| which must point to |buffer_size| bytes. On
- * success |out_num_bytes_read| contains the number of bytes read into
- * |out_buffer|. If AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE is returned,
- * |out_num_bytes_read| contains the number of bytes that would have been read
- * which can be used to allocate a buffer.
- *
- * The |buffer_size| may be zero and the |out_buffer| may be NULL, but if
- * |out_buffer| is NULL then |buffer_size| *must* be zero.
- *
- * Returns AVB_IO_RESULT_OK on success, otherwise an error code.
- *
- * If the value does not exist, is not supported, or is not populated, returns
- * AVB_IO_RESULT_ERROR_NO_SUCH_VALUE. If |buffer_size| is smaller than the
- * size of the stored value, returns AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE.
- *
- * This operation is currently only used to support persistent digests. If a
- * device does not use persistent digests this function pointer can be set to
- * NULL.
- */
- AvbIOResult (*read_persistent_value)(AvbOps* ops,
- const char* name,
- size_t buffer_size,
- uint8_t* out_buffer,
- size_t* out_num_bytes_read);
- /* Writes a persistent value corresponding to the given |name|. The value is
- * supplied in |value| which must point to |value_size| bytes. Any existing
- * value with the same name is overwritten. If |value_size| is zero, future
- * calls to |read_persistent_value| will return
- * AVB_IO_RESULT_ERROR_NO_SUCH_VALUE.
- *
- * Returns AVB_IO_RESULT_OK on success, otherwise an error code.
- *
- * If the value |name| is not supported, returns
- * AVB_IO_RESULT_ERROR_NO_SUCH_VALUE. If the |value_size| is not supported,
- * returns AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE.
- *
- * This operation is currently only used to support persistent digests. If a
- * device does not use persistent digests this function pointer can be set to
- * NULL.
- */
- AvbIOResult (*write_persistent_value)(AvbOps* ops,
- const char* name,
- size_t value_size,
- const uint8_t* value);
- };
- #ifdef __cplusplus
- }
- #endif
- #endif /* AVB_OPS_H_ */
|