1 /* SPDX-License-Identifier: MIT */ 2 /* 3 * Copyright (C) 2016 The Android Open Source Project 4 */ 5 6 #if !defined(AVB_INSIDE_LIBAVB_H) && !defined(AVB_COMPILATION) 7 #error "Never include this file directly, include libavb.h instead." 8 #endif 9 10 #ifndef AVB_OPS_H_ 11 #define AVB_OPS_H_ 12 13 #include "avb_sysdeps.h" 14 15 #ifdef __cplusplus 16 extern "C" { 17 #endif 18 19 /* Well-known names of named persistent values. */ 20 #define AVB_NPV_PERSISTENT_DIGEST_PREFIX "avb.persistent_digest." 21 #define AVB_NPV_MANAGED_VERITY_MODE "avb.managed_verity_mode" 22 23 /* Return codes used for I/O operations. 24 * 25 * AVB_IO_RESULT_OK is returned if the requested operation was 26 * successful. 27 * 28 * AVB_IO_RESULT_ERROR_IO is returned if the underlying hardware (disk 29 * or other subsystem) encountered an I/O error. 30 * 31 * AVB_IO_RESULT_ERROR_OOM is returned if unable to allocate memory. 32 * 33 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION is returned if the requested 34 * partition does not exist. 35 * 36 * AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION is returned if the 37 * range of bytes requested to be read or written is outside the range 38 * of the partition. 39 * 40 * AVB_IO_RESULT_ERROR_NO_SUCH_VALUE is returned if a named persistent value 41 * does not exist. 42 * 43 * AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE is returned if a named persistent 44 * value size is not supported or does not match the expected size. 45 * 46 * AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE is returned if a buffer is too small 47 * for the requested operation. 48 */ 49 typedef enum { 50 AVB_IO_RESULT_OK, 51 AVB_IO_RESULT_ERROR_OOM, 52 AVB_IO_RESULT_ERROR_IO, 53 AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, 54 AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION, 55 AVB_IO_RESULT_ERROR_NO_SUCH_VALUE, 56 AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE, 57 AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE, 58 } AvbIOResult; 59 60 struct AvbOps; 61 typedef struct AvbOps AvbOps; 62 63 /* Forward-declaration of operations in libavb_ab. */ 64 struct AvbABOps; 65 66 /* Forward-declaration of operations in libavb_atx. */ 67 struct AvbAtxOps; 68 69 /* High-level operations/functions/methods that are platform 70 * dependent. 71 * 72 * Operations may be added in the future so when implementing it 73 * always make sure to zero out sizeof(AvbOps) bytes of the struct to 74 * ensure that unimplemented operations are set to NULL. 75 */ 76 struct AvbOps { 77 /* This pointer can be used by the application/bootloader using 78 * libavb and is typically used in each operation to get a pointer 79 * to platform-specific resources. It cannot be used by libraries. 80 */ 81 void* user_data; 82 83 /* If libavb_ab is used, this should point to the 84 * AvbABOps. Otherwise it must be set to NULL. 85 */ 86 struct AvbABOps* ab_ops; 87 88 /* If libavb_atx is used, this should point to the 89 * AvbAtxOps. Otherwise it must be set to NULL. 90 */ 91 struct AvbAtxOps* atx_ops; 92 93 /* Reads |num_bytes| from offset |offset| from partition with name 94 * |partition| (NUL-terminated UTF-8 string). If |offset| is 95 * negative, its absolute value should be interpreted as the number 96 * of bytes from the end of the partition. 97 * 98 * This function returns AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION if 99 * there is no partition with the given name, 100 * AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION if the requested 101 * |offset| is outside the partition, and AVB_IO_RESULT_ERROR_IO if 102 * there was an I/O error from the underlying I/O subsystem. If the 103 * operation succeeds as requested AVB_IO_RESULT_OK is returned and 104 * the data is available in |buffer|. 105 * 106 * The only time partial I/O may occur is if reading beyond the end 107 * of the partition. In this case the value returned in 108 * |out_num_read| may be smaller than |num_bytes|. 109 */ 110 AvbIOResult (*read_from_partition)(AvbOps* ops, 111 const char* partition, 112 int64_t offset, 113 size_t num_bytes, 114 void* buffer, 115 size_t* out_num_read); 116 117 /* Gets the starting pointer of a partition that is pre-loaded in memory, and 118 * save it to |out_pointer|. The preloaded partition is expected to be 119 * |num_bytes|, where the actual preloaded byte count is returned in 120 * |out_num_bytes_preloaded|. |out_num_bytes_preloaded| must be no larger than 121 * |num_bytes|. 122 * 123 * This provides an alternative way to access a partition that is preloaded 124 * into memory without a full memory copy. When this function pointer is not 125 * set (has value NULL), or when the |out_pointer| is set to NULL as a result, 126 * |read_from_partition| will be used as the fallback. This function is mainly 127 * used for accessing the entire partition content to calculate its hash. 128 * 129 * Preloaded partition data must outlive the lifespan of the 130 * |AvbSlotVerifyData| structure that |avb_slot_verify| outputs. 131 */ 132 AvbIOResult (*get_preloaded_partition)(AvbOps* ops, 133 const char* partition, 134 size_t num_bytes, 135 uint8_t** out_pointer, 136 size_t* out_num_bytes_preloaded); 137 138 /* Writes |num_bytes| from |bffer| at offset |offset| to partition 139 * with name |partition| (NUL-terminated UTF-8 string). If |offset| 140 * is negative, its absolute value should be interpreted as the 141 * number of bytes from the end of the partition. 142 * 143 * This function returns AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION if 144 * there is no partition with the given name, 145 * AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION if the requested 146 * byterange goes outside the partition, and AVB_IO_RESULT_ERROR_IO 147 * if there was an I/O error from the underlying I/O subsystem. If 148 * the operation succeeds as requested AVB_IO_RESULT_OK is 149 * returned. 150 * 151 * This function never does any partial I/O, it either transfers all 152 * of the requested bytes or returns an error. 153 */ 154 AvbIOResult (*write_to_partition)(AvbOps* ops, 155 const char* partition, 156 int64_t offset, 157 size_t num_bytes, 158 const void* buffer); 159 160 /* Checks if the given public key used to sign the 'vbmeta' 161 * partition is trusted. Boot loaders typically compare this with 162 * embedded key material generated with 'avbtool 163 * extract_public_key'. 164 * 165 * The public key is in the array pointed to by |public_key_data| 166 * and is of |public_key_length| bytes. 167 * 168 * If there is no public key metadata (set with the avbtool option 169 * --public_key_metadata) then |public_key_metadata| will be set to 170 * NULL. Otherwise this field points to the data which is 171 * |public_key_metadata_length| bytes long. 172 * 173 * If AVB_IO_RESULT_OK is returned then |out_is_trusted| is set - 174 * true if trusted or false if untrusted. 175 * 176 * NOTE: If AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION is passed to 177 * avb_slot_verify() then this operation is never used. Instead, the 178 * validate_public_key_for_partition() operation is used 179 */ 180 AvbIOResult (*validate_vbmeta_public_key)(AvbOps* ops, 181 const uint8_t* public_key_data, 182 size_t public_key_length, 183 const uint8_t* public_key_metadata, 184 size_t public_key_metadata_length, 185 bool* out_is_trusted); 186 187 /* Gets the rollback index corresponding to the location given by 188 * |rollback_index_location|. The value is returned in 189 * |out_rollback_index|. Returns AVB_IO_RESULT_OK if the rollback 190 * index was retrieved, otherwise an error code. 191 * 192 * A device may have a limited amount of rollback index locations (say, 193 * one or four) so may error out if |rollback_index_location| exceeds 194 * this number. 195 */ 196 AvbIOResult (*read_rollback_index)(AvbOps* ops, 197 size_t rollback_index_location, 198 uint64_t* out_rollback_index); 199 200 /* Sets the rollback index corresponding to the location given by 201 * |rollback_index_location| to |rollback_index|. Returns 202 * AVB_IO_RESULT_OK if the rollback index was set, otherwise an 203 * error code. 204 * 205 * A device may have a limited amount of rollback index locations (say, 206 * one or four) so may error out if |rollback_index_location| exceeds 207 * this number. 208 */ 209 AvbIOResult (*write_rollback_index)(AvbOps* ops, 210 size_t rollback_index_location, 211 uint64_t rollback_index); 212 213 /* Gets whether the device is unlocked. The value is returned in 214 * |out_is_unlocked| (true if unlocked, false otherwise). Returns 215 * AVB_IO_RESULT_OK if the state was retrieved, otherwise an error 216 * code. 217 */ 218 AvbIOResult (*read_is_device_unlocked)(AvbOps* ops, bool* out_is_unlocked); 219 220 /* Gets the unique partition GUID for a partition with name in 221 * |partition| (NUL-terminated UTF-8 string). The GUID is copied as 222 * a string into |guid_buf| of size |guid_buf_size| and will be NUL 223 * terminated. The string must be lower-case and properly 224 * hyphenated. For example: 225 * 226 * 527c1c6d-6361-4593-8842-3c78fcd39219 227 * 228 * Returns AVB_IO_RESULT_OK on success, otherwise an error code. 229 */ 230 AvbIOResult (*get_unique_guid_for_partition)(AvbOps* ops, 231 const char* partition, 232 char* guid_buf, 233 size_t guid_buf_size); 234 235 /* Gets the size of a partition with the name in |partition| 236 * (NUL-terminated UTF-8 string). Returns the value in 237 * |out_size_num_bytes|. 238 * 239 * If the partition doesn't exist the AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION 240 * error code should be returned. 241 * 242 * Returns AVB_IO_RESULT_OK on success, otherwise an error code. 243 */ 244 AvbIOResult (*get_size_of_partition)(AvbOps* ops, 245 const char* partition, 246 uint64_t* out_size_num_bytes); 247 248 /* Reads a persistent value corresponding to the given |name|. The value is 249 * returned in |out_buffer| which must point to |buffer_size| bytes. On 250 * success |out_num_bytes_read| contains the number of bytes read into 251 * |out_buffer|. If AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE is returned, 252 * |out_num_bytes_read| contains the number of bytes that would have been read 253 * which can be used to allocate a buffer. 254 * 255 * The |buffer_size| may be zero and the |out_buffer| may be NULL, but if 256 * |out_buffer| is NULL then |buffer_size| *must* be zero. 257 * 258 * Returns AVB_IO_RESULT_OK on success, otherwise an error code. 259 * 260 * If the value does not exist, is not supported, or is not populated, returns 261 * AVB_IO_RESULT_ERROR_NO_SUCH_VALUE. If |buffer_size| is smaller than the 262 * size of the stored value, returns AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE. 263 * 264 * This operation is currently only used to support persistent digests or the 265 * AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO hashtree error mode. If a 266 * device does not use one of these features this function pointer can be set 267 * to NULL. 268 */ 269 AvbIOResult (*read_persistent_value)(AvbOps* ops, 270 const char* name, 271 size_t buffer_size, 272 uint8_t* out_buffer, 273 size_t* out_num_bytes_read); 274 275 /* Writes a persistent value corresponding to the given |name|. The value is 276 * supplied in |value| which must point to |value_size| bytes. Any existing 277 * value with the same name is overwritten. If |value_size| is zero, future 278 * calls to |read_persistent_value| will return 279 * AVB_IO_RESULT_ERROR_NO_SUCH_VALUE. 280 * 281 * Returns AVB_IO_RESULT_OK on success, otherwise an error code. 282 * 283 * If the value |name| is not supported, returns 284 * AVB_IO_RESULT_ERROR_NO_SUCH_VALUE. If the |value_size| is not supported, 285 * returns AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE. 286 * 287 * This operation is currently only used to support persistent digests or the 288 * AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO hashtree error mode. If a 289 * device does not use one of these features this function pointer can be set 290 * to NULL. 291 */ 292 AvbIOResult (*write_persistent_value)(AvbOps* ops, 293 const char* name, 294 size_t value_size, 295 const uint8_t* value); 296 297 /* Like validate_vbmeta_public_key() but for when the flag 298 * AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION is being used. The name of the 299 * partition to get the public key for is passed in |partition_name|. 300 * 301 * Also returns the rollback index location to use for the partition, in 302 * |out_rollback_index_location|. 303 * 304 * Returns AVB_IO_RESULT_OK on success, otherwise an error code. 305 */ 306 AvbIOResult (*validate_public_key_for_partition)( 307 AvbOps* ops, 308 const char* partition, 309 const uint8_t* public_key_data, 310 size_t public_key_length, 311 const uint8_t* public_key_metadata, 312 size_t public_key_metadata_length, 313 bool* out_is_trusted, 314 uint32_t* out_rollback_index_location); 315 }; 316 317 #ifdef __cplusplus 318 } 319 #endif 320 321 #endif /* AVB_OPS_H_ */ 322