/* 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_ */
