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