Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | /* 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." #define AVB_NPV_MANAGED_VERITY_MODE "avb.managed_verity_mode" /* 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. * * NOTE: If AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION is passed to * avb_slot_verify() then this operation is never used. Instead, the * validate_public_key_for_partition() operation is used */ 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|. * * If the partition doesn't exist the AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION * error code should be returned. * * 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 or the * AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO hashtree error mode. If a * device does not use one of these features 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 or the * AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO hashtree error mode. If a * device does not use one of these features 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); /* Like validate_vbmeta_public_key() but for when the flag * AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION is being used. The name of the * partition to get the public key for is passed in |partition_name|. * * Also returns the rollback index location to use for the partition, in * |out_rollback_index_location|. * * Returns AVB_IO_RESULT_OK on success, otherwise an error code. */ AvbIOResult (*validate_public_key_for_partition)( AvbOps* ops, const char* partition, 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, uint32_t* out_rollback_index_location); }; #ifdef __cplusplus } #endif #endif /* AVB_OPS_H_ */ |