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