xref: /rk3399_rockchip-uboot/include/android_avb/avb_ops.h (revision bc04a3dd9a41813372820ba50655022a6a28bfbf)
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