• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_AB_H) && !defined(AVB_COMPILATION)
26  #error \
27      "Never include this file directly, include libavb_ab/libavb_ab.h instead."
28  #endif
29  
30  #ifndef AVB_AB_FLOW_H_
31  #define AVB_AB_FLOW_H_
32  
33  #include "avb_ab_ops.h"
34  
35  #ifdef __cplusplus
36  extern "C" {
37  #endif
38  
39  /* Magic for the A/B struct when serialized. */
40  #define AVB_AB_MAGIC "\0AB0"
41  #define AVB_AB_MAGIC_LEN 4
42  
43  /* Versioning for the on-disk A/B metadata - keep in sync with avbtool. */
44  #define AVB_AB_MAJOR_VERSION 1
45  #define AVB_AB_MINOR_VERSION 0
46  
47  /* Size of AvbABData struct. */
48  #define AVB_AB_DATA_SIZE 32
49  
50  /* Maximum values for slot data */
51  #define AVB_AB_MAX_PRIORITY 15
52  #define AVB_AB_MAX_TRIES_REMAINING 7
53  
54  /* Struct used for recording per-slot metadata.
55   *
56   * When serialized, data is stored in network byte-order.
57   */
58  typedef struct AvbABSlotData {
59    /* Slot priority. Valid values range from 0 to AVB_AB_MAX_PRIORITY,
60     * both inclusive with 1 being the lowest and AVB_AB_MAX_PRIORITY
61     * being the highest. The special value 0 is used to indicate the
62     * slot is unbootable.
63     */
64    uint8_t priority;
65  
66    /* Number of times left attempting to boot this slot ranging from 0
67     * to AVB_AB_MAX_TRIES_REMAINING.
68     */
69    uint8_t tries_remaining;
70  
71    /* Non-zero if this slot has booted successfully, 0 otherwise. */
72    uint8_t successful_boot;
73  
74    /* Reserved for future use. */
75    uint8_t reserved[1];
76  } AVB_ATTR_PACKED AvbABSlotData;
77  
78  /* Struct used for recording A/B metadata.
79   *
80   * When serialized, data is stored in network byte-order.
81   */
82  typedef struct AvbABData {
83    /* Magic number used for identification - see AVB_AB_MAGIC. */
84    uint8_t magic[AVB_AB_MAGIC_LEN];
85  
86    /* Version of on-disk struct - see AVB_AB_{MAJOR,MINOR}_VERSION. */
87    uint8_t version_major;
88    uint8_t version_minor;
89  
90    /* Padding to ensure |slots| field start eight bytes in. */
91    uint8_t reserved1[2];
92  
93    /* Per-slot metadata. */
94    AvbABSlotData slots[2];
95  
96    /* Reserved for future use. */
97    uint8_t reserved2[12];
98  
99    /* CRC32 of all 28 bytes preceding this field. */
100    uint32_t crc32;
101  } AVB_ATTR_PACKED AvbABData;
102  
103  /* Copies |src| to |dest|, byte-swapping fields in the
104   * process. Returns false if the data is invalid (e.g. wrong magic,
105   * wrong CRC32 etc.), true otherwise.
106   */
107  bool avb_ab_data_verify_and_byteswap(const AvbABData* src, AvbABData* dest);
108  
109  /* Copies |src| to |dest|, byte-swapping fields in the process. Also
110   * updates the |crc32| field in |dest|.
111   */
112  void avb_ab_data_update_crc_and_byteswap(const AvbABData* src, AvbABData* dest);
113  
114  /* Initializes |data| such that it has two slots and both slots have
115   * maximum tries remaining. The CRC is not set.
116   */
117  void avb_ab_data_init(AvbABData* data);
118  
119  /* Reads A/B metadata from the 'misc' partition using |ops|. Returned
120   * data is properly byteswapped. Returns AVB_IO_RESULT_OK on
121   * success, error code otherwise.
122   *
123   * If the data read from disk is invalid (e.g. wrong magic or CRC
124   * checksum failure), the metadata will be reset using
125   * avb_ab_data_init() and then written to disk.
126   */
127  AvbIOResult avb_ab_data_read(AvbABOps* ab_ops, AvbABData* data);
128  
129  /* Writes A/B metadata to the 'misc' partition using |ops|. This will
130   * byteswap and update the CRC as needed. Returns AVB_IO_RESULT_OK on
131   * success, error code otherwise.
132   */
133  AvbIOResult avb_ab_data_write(AvbABOps* ab_ops, const AvbABData* data);
134  
135  /* Return codes used in avb_ab_flow(), see that function for
136   * documentation of each value.
137   */
138  typedef enum {
139    AVB_AB_FLOW_RESULT_OK,
140    AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR,
141    AVB_AB_FLOW_RESULT_ERROR_OOM,
142    AVB_AB_FLOW_RESULT_ERROR_IO,
143    AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
144    AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT
145  } AvbABFlowResult;
146  
147  /* Get a textual representation of |result|. */
148  const char* avb_ab_flow_result_to_string(AvbABFlowResult result);
149  
150  /* High-level function to select a slot to boot. The following
151   * algorithm is used:
152   *
153   * 1. A/B metadata is loaded and validated using the
154   * read_ab_metadata() operation. Typically this means it's read from
155   * the 'misc' partition and if it's invalid then it's reset using
156   * avb_ab_data_init() and this reset metadata is returned.
157   *
158   * 2. All bootable slots listed in the A/B metadata are verified using
159   * avb_slot_verify(). If a slot is invalid or if it fails verification
160   * (and AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR is not set, see
161   * below), it will be marked as unbootable in the A/B metadata and the
162   * metadata will be saved to disk before returning.
163   *
164   * 3. If there are no bootable slots, the value
165   * AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS is returned.
166   *
167   * 4. For each bootable slot, the Stored Rollback Indexes are updated
168   * such that for each rollback index location, the Stored Rollback
169   * Index is the largest number smaller than or equal to the Rollback
170   * Index of each slot.
171   *
172   * 5. The bootable slot with the highest priority is selected and
173   * returned in |out_data|. If this slot is already marked as
174   * successful, the A/B metadata is not modified. However, if the slot
175   * is not marked as bootable its |tries_remaining| count is
176   * decremented and the A/B metadata is saved to disk before returning.
177   * In either case the value AVB_AB_FLOW_RESULT_OK is returning.
178   *
179   * The partitions to load is given in |requested_partitions| as a
180   * NULL-terminated array of NUL-terminated strings. Typically the
181   * |requested_partitions| array only contains a single item for the
182   * boot partition, 'boot'.
183   *
184   * If the device is unlocked (and _only_ if it's unlocked), the
185   * AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR flag should be set
186   * in the |flags| parameter. This will allow considering slots as
187   * verified even when avb_slot_verify() returns
188   * AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
189   * AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION, or
190   * AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX for the slot in
191   * question.
192   *
193   * Note that neither androidboot.slot_suffix nor androidboot.slot are
194   * set in the |cmdline| field in |AvbSlotVerifyData| - you will have
195   * to pass these yourself.
196   *
197   * If a slot was selected and it verified then AVB_AB_FLOW_RESULT_OK
198   * is returned.
199   *
200   * If a slot was selected but it didn't verify then
201   * AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR is returned. This can
202   * only happen when the AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
203   * flag is set.
204   *
205   * If an I/O operation - such as loading/saving metadata or checking
206   * rollback indexes - fail, the value AVB_AB_FLOW_RESULT_ERROR_IO is
207   * returned.
208   *
209   * If memory allocation fails, AVB_AB_FLOW_RESULT_ERROR_OOM is
210   * returned.
211   *
212   * If invalid arguments are passed,
213   * AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT is returned. For example
214   * this can happen if using AVB_HASHTREE_ERROR_MODE_LOGGING without
215   * AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR.
216   *
217   * Reasonable behavior for handling AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS
218   * is to initiate device repair (which is device-dependent).
219   */
220  AvbABFlowResult avb_ab_flow(AvbABOps* ab_ops,
221                              const char* const* requested_partitions,
222                              AvbSlotVerifyFlags flags,
223                              AvbHashtreeErrorMode hashtree_error_mode,
224                              AvbSlotVerifyData** out_data);
225  
226  /* Marks the slot with the given slot number as active. Returns
227   * AVB_IO_RESULT_OK on success, error code otherwise.
228   *
229   * This function is typically used by the OS updater when completing
230   * an update. It can also used by the firmware for implementing the
231   * "set_active" command.
232   */
233  AvbIOResult avb_ab_mark_slot_active(AvbABOps* ab_ops, unsigned int slot_number);
234  
235  /* Marks the slot with the given slot number as unbootable. Returns
236   * AVB_IO_RESULT_OK on success, error code otherwise.
237   *
238   * This function is typically used by the OS updater before writing to
239   * a slot.
240   */
241  AvbIOResult avb_ab_mark_slot_unbootable(AvbABOps* ab_ops,
242                                          unsigned int slot_number);
243  
244  /* Marks the slot with the given slot number as having booted
245   * successfully. Returns AVB_IO_RESULT_OK on success, error code
246   * otherwise.
247   *
248   * Calling this on an unbootable slot is an error - AVB_IO_RESULT_OK
249   * will be returned yet the function will have no side-effects.
250   *
251   * This function is typically used by the OS updater after having
252   * confirmed that the slot works as intended.
253   */
254  AvbIOResult avb_ab_mark_slot_successful(AvbABOps* ab_ops,
255                                          unsigned int slot_number);
256  
257  #ifdef __cplusplus
258  }
259  #endif
260  
261  #endif /* AVB_AB_FLOW_H_ */
262