• Home
  • 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 #include "avb_slot_verify.h"
26 #include "avb_chain_partition_descriptor.h"
27 #include "avb_cmdline.h"
28 #include "avb_footer.h"
29 #include "avb_hash_descriptor.h"
30 #include "avb_hashtree_descriptor.h"
31 #include "avb_kernel_cmdline_descriptor.h"
32 #include "avb_sha.h"
33 #include "avb_util.h"
34 #include "avb_vbmeta_image.h"
35 #include "avb_version.h"
36 
37 /* Maximum number of partitions that can be loaded with avb_slot_verify(). */
38 #define MAX_NUMBER_OF_LOADED_PARTITIONS 32
39 
40 /* Maximum number of vbmeta images that can be loaded with avb_slot_verify(). */
41 #define MAX_NUMBER_OF_VBMETA_IMAGES 32
42 
43 /* Maximum size of a vbmeta image - 64 KiB. */
44 #define VBMETA_MAX_SIZE (64 * 1024)
45 
46 static AvbSlotVerifyResult initialize_persistent_digest(
47     AvbOps* ops,
48     const char* part_name,
49     const char* persistent_value_name,
50     size_t digest_size,
51     const uint8_t* initial_digest,
52     uint8_t* out_digest);
53 
54 /* Helper function to see if we should continue with verification in
55  * allow_verification_error=true mode if something goes wrong. See the
56  * comments for the avb_slot_verify() function for more information.
57  */
result_should_continue(AvbSlotVerifyResult result)58 static inline bool result_should_continue(AvbSlotVerifyResult result) {
59   switch (result) {
60     case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
61     case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
62     case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
63     case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
64     case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
65       return false;
66 
67     case AVB_SLOT_VERIFY_RESULT_OK:
68     case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
69     case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
70     case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
71       return true;
72   }
73 
74   return false;
75 }
76 
load_full_partition(AvbOps * ops,const char * part_name,uint64_t image_size,uint8_t ** out_image_buf,bool * out_image_preloaded)77 static AvbSlotVerifyResult load_full_partition(AvbOps* ops,
78                                                const char* part_name,
79                                                uint64_t image_size,
80                                                uint8_t** out_image_buf,
81                                                bool* out_image_preloaded) {
82   size_t part_num_read;
83   AvbIOResult io_ret;
84 
85   /* Make sure that we do not overwrite existing data. */
86   avb_assert(*out_image_buf == NULL);
87   avb_assert(!*out_image_preloaded);
88 
89   /* We are going to implicitly cast image_size from uint64_t to size_t in the
90    * following code, so we need to make sure that the cast is safe. */
91   if (image_size != (size_t)(image_size)) {
92     avb_errorv(part_name, ": Partition size too large to load.\n", NULL);
93     return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
94   }
95 
96   /* Try use a preloaded one. */
97   if (ops->get_preloaded_partition != NULL) {
98     io_ret = ops->get_preloaded_partition(
99         ops, part_name, image_size, out_image_buf, &part_num_read);
100     if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
101       return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
102     } else if (io_ret != AVB_IO_RESULT_OK) {
103       avb_errorv(part_name, ": Error loading data from partition.\n", NULL);
104       return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
105     }
106 
107     if (*out_image_buf != NULL) {
108       *out_image_preloaded = true;
109       if (part_num_read != image_size) {
110         avb_errorv(part_name, ": Read incorrect number of bytes.\n", NULL);
111         return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
112       }
113     }
114   }
115 
116   /* Allocate and copy the partition. */
117   if (!*out_image_preloaded) {
118     *out_image_buf = avb_malloc(image_size);
119     if (*out_image_buf == NULL) {
120       return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
121     }
122 
123     io_ret = ops->read_from_partition(ops,
124                                       part_name,
125                                       0 /* offset */,
126                                       image_size,
127                                       *out_image_buf,
128                                       &part_num_read);
129     if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
130       return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
131     } else if (io_ret != AVB_IO_RESULT_OK) {
132       avb_errorv(part_name, ": Error loading data from partition.\n", NULL);
133       return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
134     }
135     if (part_num_read != image_size) {
136       avb_errorv(part_name, ": Read incorrect number of bytes.\n", NULL);
137       return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
138     }
139   }
140 
141   return AVB_SLOT_VERIFY_RESULT_OK;
142 }
143 
144 /* Reads a persistent digest stored as a named persistent value corresponding to
145  * the given |part_name|. The value is returned in |out_digest| which must point
146  * to |expected_digest_size| bytes. If there is no digest stored for |part_name|
147  * it can be initialized by providing a non-NULL |initial_digest| of length
148  * |expected_digest_size|. This automatic initialization will only occur if the
149  * device is currently locked. The |initial_digest| may be NULL.
150  *
151  * Returns AVB_SLOT_VERIFY_RESULT_OK on success, otherwise returns an
152  * AVB_SLOT_VERIFY_RESULT_ERROR_* error code.
153  *
154  * If the value does not exist, is not supported, or is not populated, and
155  * |initial_digest| is NULL, returns
156  * AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA. If |expected_digest_size| does
157  * not match the stored digest size, also returns
158  * AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA.
159  */
read_persistent_digest(AvbOps * ops,const char * part_name,size_t expected_digest_size,const uint8_t * initial_digest,uint8_t * out_digest)160 static AvbSlotVerifyResult read_persistent_digest(AvbOps* ops,
161                                                   const char* part_name,
162                                                   size_t expected_digest_size,
163                                                   const uint8_t* initial_digest,
164                                                   uint8_t* out_digest) {
165   char* persistent_value_name = NULL;
166   AvbIOResult io_ret = AVB_IO_RESULT_OK;
167   size_t stored_digest_size = 0;
168 
169   if (ops->read_persistent_value == NULL) {
170     avb_errorv(part_name, ": Persistent values are not implemented.\n", NULL);
171     return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
172   }
173   persistent_value_name =
174       avb_strdupv(AVB_NPV_PERSISTENT_DIGEST_PREFIX, part_name, NULL);
175   if (persistent_value_name == NULL) {
176     return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
177   }
178 
179   io_ret = ops->read_persistent_value(ops,
180                                       persistent_value_name,
181                                       expected_digest_size,
182                                       out_digest,
183                                       &stored_digest_size);
184 
185   // If no such named persistent value exists and an initial digest value was
186   // given, initialize the named persistent value with the given digest. If
187   // initialized successfully, this will recurse into this function but with a
188   // NULL initial_digest.
189   if (io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_VALUE && initial_digest) {
190     AvbSlotVerifyResult ret =
191         initialize_persistent_digest(ops,
192                                      part_name,
193                                      persistent_value_name,
194                                      expected_digest_size,
195                                      initial_digest,
196                                      out_digest);
197     avb_free(persistent_value_name);
198     return ret;
199   }
200   avb_free(persistent_value_name);
201 
202   if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
203     return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
204   } else if (io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_VALUE) {
205     // Treat a missing persistent value as a verification error, which is
206     // ignoreable, rather than a metadata error which is not.
207     avb_errorv(part_name, ": Persistent digest does not exist.\n", NULL);
208     return AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
209   } else if (io_ret == AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE ||
210              io_ret == AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE) {
211     avb_errorv(
212         part_name, ": Persistent digest is not of expected size.\n", NULL);
213     return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
214   } else if (io_ret != AVB_IO_RESULT_OK) {
215     avb_errorv(part_name, ": Error reading persistent digest.\n", NULL);
216     return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
217   } else if (expected_digest_size != stored_digest_size) {
218     avb_errorv(
219         part_name, ": Persistent digest is not of expected size.\n", NULL);
220     return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
221   }
222   return AVB_SLOT_VERIFY_RESULT_OK;
223 }
224 
initialize_persistent_digest(AvbOps * ops,const char * part_name,const char * persistent_value_name,size_t digest_size,const uint8_t * initial_digest,uint8_t * out_digest)225 static AvbSlotVerifyResult initialize_persistent_digest(
226     AvbOps* ops,
227     const char* part_name,
228     const char* persistent_value_name,
229     size_t digest_size,
230     const uint8_t* initial_digest,
231     uint8_t* out_digest) {
232   AvbSlotVerifyResult ret;
233   AvbIOResult io_ret = AVB_IO_RESULT_OK;
234   bool is_device_unlocked = true;
235 
236   io_ret = ops->read_is_device_unlocked(ops, &is_device_unlocked);
237   if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
238     return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
239   } else if (io_ret != AVB_IO_RESULT_OK) {
240     avb_error("Error getting device lock state.\n");
241     return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
242   }
243 
244   if (is_device_unlocked) {
245     avb_debugv(part_name,
246                ": Digest does not exist, device unlocked so not initializing "
247                "digest.\n",
248                NULL);
249     return AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
250   }
251 
252   // Device locked; initialize digest with given initial value.
253   avb_debugv(part_name,
254              ": Digest does not exist, initializing persistent digest.\n",
255              NULL);
256   io_ret = ops->write_persistent_value(
257       ops, persistent_value_name, digest_size, initial_digest);
258   if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
259     return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
260   } else if (io_ret != AVB_IO_RESULT_OK) {
261     avb_errorv(part_name, ": Error initializing persistent digest.\n", NULL);
262     return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
263   }
264 
265   // To ensure that the digest value was written successfully - and avoid a
266   // scenario where the digest is simply 'initialized' on every verify - recurse
267   // into read_persistent_digest to read back the written value. The NULL
268   // initial_digest ensures that this will not recurse again.
269   ret = read_persistent_digest(ops, part_name, digest_size, NULL, out_digest);
270   if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
271     avb_errorv(part_name,
272                ": Reading back initialized persistent digest failed!\n",
273                NULL);
274   }
275   return ret;
276 }
277 
load_and_verify_hash_partition(AvbOps * ops,const char * const * requested_partitions,const char * ab_suffix,bool allow_verification_error,const AvbDescriptor * descriptor,AvbSlotVerifyData * slot_data)278 static AvbSlotVerifyResult load_and_verify_hash_partition(
279     AvbOps* ops,
280     const char* const* requested_partitions,
281     const char* ab_suffix,
282     bool allow_verification_error,
283     const AvbDescriptor* descriptor,
284     AvbSlotVerifyData* slot_data) {
285   AvbHashDescriptor hash_desc;
286   const uint8_t* desc_partition_name = NULL;
287   const uint8_t* desc_salt;
288   const uint8_t* desc_digest;
289   char part_name[AVB_PART_NAME_MAX_SIZE];
290   AvbSlotVerifyResult ret;
291   AvbIOResult io_ret;
292   uint8_t* image_buf = NULL;
293   bool image_preloaded = false;
294   uint8_t* digest;
295   size_t digest_len;
296   const char* found;
297   uint64_t image_size;
298   size_t expected_digest_len = 0;
299   uint8_t expected_digest_buf[AVB_SHA512_DIGEST_SIZE];
300   const uint8_t* expected_digest = NULL;
301 
302   if (!avb_hash_descriptor_validate_and_byteswap(
303           (const AvbHashDescriptor*)descriptor, &hash_desc)) {
304     ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
305     goto out;
306   }
307 
308   desc_partition_name =
309       ((const uint8_t*)descriptor) + sizeof(AvbHashDescriptor);
310   desc_salt = desc_partition_name + hash_desc.partition_name_len;
311   desc_digest = desc_salt + hash_desc.salt_len;
312 
313   if (!avb_validate_utf8(desc_partition_name, hash_desc.partition_name_len)) {
314     avb_error("Partition name is not valid UTF-8.\n");
315     ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
316     goto out;
317   }
318 
319   /* Don't bother loading or validating unless the partition was
320    * requested in the first place.
321    */
322   found = avb_strv_find_str(requested_partitions,
323                             (const char*)desc_partition_name,
324                             hash_desc.partition_name_len);
325   if (found == NULL) {
326     ret = AVB_SLOT_VERIFY_RESULT_OK;
327     goto out;
328   }
329 
330   if ((hash_desc.flags & AVB_HASH_DESCRIPTOR_FLAGS_DO_NOT_USE_AB) != 0) {
331     /* No ab_suffix, just copy the partition name as is. */
332     if (hash_desc.partition_name_len >= AVB_PART_NAME_MAX_SIZE) {
333       avb_error("Partition name does not fit.\n");
334       ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
335       goto out;
336     }
337     avb_memcpy(part_name, desc_partition_name, hash_desc.partition_name_len);
338     part_name[hash_desc.partition_name_len] = '\0';
339   } else if (hash_desc.digest_len == 0 && avb_strlen(ab_suffix) != 0) {
340     /* No ab_suffix allowed for partitions without a digest in the descriptor
341      * because these partitions hold data unique to this device and are not
342      * updated using an A/B scheme.
343      */
344     avb_error("Cannot use A/B with a persistent digest.\n");
345     ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
346     goto out;
347   } else {
348     /* Add ab_suffix to the partition name. */
349     if (!avb_str_concat(part_name,
350                         sizeof part_name,
351                         (const char*)desc_partition_name,
352                         hash_desc.partition_name_len,
353                         ab_suffix,
354                         avb_strlen(ab_suffix))) {
355       avb_error("Partition name and suffix does not fit.\n");
356       ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
357       goto out;
358     }
359   }
360 
361   /* If we're allowing verification errors then hash_desc.image_size
362    * may no longer match what's in the partition... so in this case
363    * just load the entire partition.
364    *
365    * For example, this can happen if a developer does 'fastboot flash
366    * boot /path/to/new/and/bigger/boot.img'. We want this to work
367    * since it's such a common workflow.
368    */
369   image_size = hash_desc.image_size;
370   if (allow_verification_error) {
371     io_ret = ops->get_size_of_partition(ops, part_name, &image_size);
372     if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
373       ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
374       goto out;
375     } else if (io_ret != AVB_IO_RESULT_OK) {
376       avb_errorv(part_name, ": Error determining partition size.\n", NULL);
377       ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
378       goto out;
379     }
380     avb_debugv(part_name, ": Loading entire partition.\n", NULL);
381   }
382 
383   ret = load_full_partition(
384       ops, part_name, image_size, &image_buf, &image_preloaded);
385   if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
386     goto out;
387   }
388   // Although only one of the type might be used, we have to defined the
389   // structure here so that they would live outside the 'if/else' scope to be
390   // used later.
391   AvbSHA256Ctx sha256_ctx;
392   AvbSHA512Ctx sha512_ctx;
393   size_t image_size_to_hash = hash_desc.image_size;
394   // If we allow verification error and the whole partition is smaller than
395   // image size in hash descriptor, we just hash the whole partition.
396   if (image_size_to_hash > image_size) {
397     image_size_to_hash = image_size;
398   }
399   if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha256") == 0) {
400     avb_sha256_init(&sha256_ctx);
401     avb_sha256_update(&sha256_ctx, desc_salt, hash_desc.salt_len);
402     avb_sha256_update(&sha256_ctx, image_buf, image_size_to_hash);
403     digest = avb_sha256_final(&sha256_ctx);
404     digest_len = AVB_SHA256_DIGEST_SIZE;
405   } else if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha512") == 0) {
406     avb_sha512_init(&sha512_ctx);
407     avb_sha512_update(&sha512_ctx, desc_salt, hash_desc.salt_len);
408     avb_sha512_update(&sha512_ctx, image_buf, image_size_to_hash);
409     digest = avb_sha512_final(&sha512_ctx);
410     digest_len = AVB_SHA512_DIGEST_SIZE;
411   } else {
412     avb_errorv(part_name, ": Unsupported hash algorithm.\n", NULL);
413     ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
414     goto out;
415   }
416 
417   if (hash_desc.digest_len == 0) {
418     /* Expect a match to a persistent digest. */
419     avb_debugv(part_name, ": No digest, using persistent digest.\n", NULL);
420     expected_digest_len = digest_len;
421     expected_digest = expected_digest_buf;
422     avb_assert(expected_digest_len <= sizeof(expected_digest_buf));
423     /* Pass |digest| as the |initial_digest| so devices not yet initialized get
424      * initialized to the current partition digest.
425      */
426     ret = read_persistent_digest(
427         ops, part_name, digest_len, digest, expected_digest_buf);
428     if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
429       goto out;
430     }
431   } else {
432     /* Expect a match to the digest in the descriptor. */
433     expected_digest_len = hash_desc.digest_len;
434     expected_digest = desc_digest;
435   }
436 
437   if (digest_len != expected_digest_len) {
438     avb_errorv(
439         part_name, ": Digest in descriptor not of expected size.\n", NULL);
440     ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
441     goto out;
442   }
443 
444   if (avb_safe_memcmp(digest, expected_digest, digest_len) != 0) {
445     avb_errorv(part_name,
446                ": Hash of data does not match digest in descriptor.\n",
447                NULL);
448     ret = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
449     goto out;
450   }
451 
452   ret = AVB_SLOT_VERIFY_RESULT_OK;
453 
454 out:
455 
456   /* If it worked and something was loaded, copy to slot_data. */
457   if ((ret == AVB_SLOT_VERIFY_RESULT_OK || result_should_continue(ret)) &&
458       image_buf != NULL) {
459     AvbPartitionData* loaded_partition;
460     if (slot_data->num_loaded_partitions == MAX_NUMBER_OF_LOADED_PARTITIONS) {
461       avb_errorv(part_name, ": Too many loaded partitions.\n", NULL);
462       ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
463       goto fail;
464     }
465     loaded_partition =
466         &slot_data->loaded_partitions[slot_data->num_loaded_partitions++];
467     loaded_partition->partition_name = avb_strdup(found);
468     loaded_partition->data_size = image_size;
469     loaded_partition->data = image_buf;
470     loaded_partition->preloaded = image_preloaded;
471     image_buf = NULL;
472   }
473 
474 fail:
475   if (image_buf != NULL && !image_preloaded) {
476     avb_free(image_buf);
477   }
478   return ret;
479 }
480 
load_requested_partitions(AvbOps * ops,const char * const * requested_partitions,const char * ab_suffix,AvbSlotVerifyData * slot_data)481 static AvbSlotVerifyResult load_requested_partitions(
482     AvbOps* ops,
483     const char* const* requested_partitions,
484     const char* ab_suffix,
485     AvbSlotVerifyData* slot_data) {
486   AvbSlotVerifyResult ret;
487   uint8_t* image_buf = NULL;
488   bool image_preloaded = false;
489   size_t n;
490 
491   for (n = 0; requested_partitions[n] != NULL; n++) {
492     char part_name[AVB_PART_NAME_MAX_SIZE];
493     AvbIOResult io_ret;
494     uint64_t image_size;
495     AvbPartitionData* loaded_partition;
496 
497     if (!avb_str_concat(part_name,
498                         sizeof part_name,
499                         requested_partitions[n],
500                         avb_strlen(requested_partitions[n]),
501                         ab_suffix,
502                         avb_strlen(ab_suffix))) {
503       avb_error("Partition name and suffix does not fit.\n");
504       ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
505       goto out;
506     }
507 
508     io_ret = ops->get_size_of_partition(ops, part_name, &image_size);
509     if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
510       ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
511       goto out;
512     } else if (io_ret != AVB_IO_RESULT_OK) {
513       avb_errorv(part_name, ": Error determining partition size.\n", NULL);
514       ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
515       goto out;
516     }
517     avb_debugv(part_name, ": Loading entire partition.\n", NULL);
518 
519     ret = load_full_partition(
520         ops, part_name, image_size, &image_buf, &image_preloaded);
521     if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
522       goto out;
523     }
524 
525     /* Move to slot_data. */
526     if (slot_data->num_loaded_partitions == MAX_NUMBER_OF_LOADED_PARTITIONS) {
527       avb_errorv(part_name, ": Too many loaded partitions.\n", NULL);
528       ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
529       goto out;
530     }
531     loaded_partition =
532         &slot_data->loaded_partitions[slot_data->num_loaded_partitions++];
533     loaded_partition->partition_name = avb_strdup(requested_partitions[n]);
534     if (loaded_partition->partition_name == NULL) {
535       ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
536       goto out;
537     }
538     loaded_partition->data_size = image_size;
539     loaded_partition->data = image_buf; /* Transferring the owner. */
540     loaded_partition->preloaded = image_preloaded;
541     image_buf = NULL;
542     image_preloaded = false;
543   }
544 
545   ret = AVB_SLOT_VERIFY_RESULT_OK;
546 
547 out:
548   /* Free the current buffer if any. */
549   if (image_buf != NULL && !image_preloaded) {
550     avb_free(image_buf);
551   }
552   /* Buffers that are already saved in slot_data will be handled by the caller
553    * even on failure. */
554   return ret;
555 }
556 
load_and_verify_vbmeta(AvbOps * ops,const char * const * requested_partitions,const char * ab_suffix,AvbSlotVerifyFlags flags,bool allow_verification_error,AvbVBMetaImageFlags toplevel_vbmeta_flags,uint32_t rollback_index_location,const char * partition_name,size_t partition_name_len,const uint8_t * expected_public_key,size_t expected_public_key_length,AvbSlotVerifyData * slot_data,AvbAlgorithmType * out_algorithm_type,AvbCmdlineSubstList * out_additional_cmdline_subst)557 static AvbSlotVerifyResult load_and_verify_vbmeta(
558     AvbOps* ops,
559     const char* const* requested_partitions,
560     const char* ab_suffix,
561     AvbSlotVerifyFlags flags,
562     bool allow_verification_error,
563     AvbVBMetaImageFlags toplevel_vbmeta_flags,
564     uint32_t rollback_index_location,
565     const char* partition_name,
566     size_t partition_name_len,
567     const uint8_t* expected_public_key,
568     size_t expected_public_key_length,
569     AvbSlotVerifyData* slot_data,
570     AvbAlgorithmType* out_algorithm_type,
571     AvbCmdlineSubstList* out_additional_cmdline_subst) {
572   char full_partition_name[AVB_PART_NAME_MAX_SIZE];
573   AvbSlotVerifyResult ret;
574   AvbIOResult io_ret;
575   uint64_t vbmeta_offset;
576   size_t vbmeta_size;
577   uint8_t* vbmeta_buf = NULL;
578   size_t vbmeta_num_read;
579   AvbVBMetaVerifyResult vbmeta_ret;
580   const uint8_t* pk_data;
581   size_t pk_len;
582   AvbVBMetaImageHeader vbmeta_header;
583   uint64_t stored_rollback_index;
584   const AvbDescriptor** descriptors = NULL;
585   size_t num_descriptors;
586   size_t n;
587   bool is_main_vbmeta;
588   bool look_for_vbmeta_footer;
589   AvbVBMetaData* vbmeta_image_data = NULL;
590 
591   ret = AVB_SLOT_VERIFY_RESULT_OK;
592 
593   avb_assert(slot_data != NULL);
594 
595   /* Since we allow top-level vbmeta in 'boot', use
596    * rollback_index_location to determine whether we're the main
597    * vbmeta struct.
598    */
599   is_main_vbmeta = false;
600   if (rollback_index_location == 0) {
601     if ((flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION) == 0) {
602       is_main_vbmeta = true;
603     }
604   }
605 
606   /* Don't use footers for vbmeta partitions ('vbmeta' or
607    * 'vbmeta_<partition_name>').
608    */
609   look_for_vbmeta_footer = true;
610   if (avb_strncmp(partition_name, "vbmeta", avb_strlen("vbmeta")) == 0) {
611     look_for_vbmeta_footer = false;
612   }
613 
614   if (!avb_validate_utf8((const uint8_t*)partition_name, partition_name_len)) {
615     avb_error("Partition name is not valid UTF-8.\n");
616     ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
617     goto out;
618   }
619 
620   /* Construct full partition name e.g. system_a. */
621   if (!avb_str_concat(full_partition_name,
622                       sizeof full_partition_name,
623                       partition_name,
624                       partition_name_len,
625                       ab_suffix,
626                       avb_strlen(ab_suffix))) {
627     avb_error("Partition name and suffix does not fit.\n");
628     ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
629     goto out;
630   }
631 
632   /* If we're loading from the main vbmeta partition, the vbmeta struct is in
633    * the beginning. Otherwise we may have to locate it via a footer... if no
634    * footer is found, we look in the beginning to support e.g. vbmeta_<org>
635    * partitions holding data for e.g. super partitions (b/80195851 for
636    * rationale).
637    */
638   vbmeta_offset = 0;
639   vbmeta_size = VBMETA_MAX_SIZE;
640   if (look_for_vbmeta_footer) {
641     uint8_t footer_buf[AVB_FOOTER_SIZE];
642     size_t footer_num_read;
643     AvbFooter footer;
644 
645     io_ret = ops->read_from_partition(ops,
646                                       full_partition_name,
647                                       -AVB_FOOTER_SIZE,
648                                       AVB_FOOTER_SIZE,
649                                       footer_buf,
650                                       &footer_num_read);
651     if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
652       ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
653       goto out;
654     } else if (io_ret != AVB_IO_RESULT_OK) {
655       avb_errorv(full_partition_name, ": Error loading footer.\n", NULL);
656       ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
657       goto out;
658     }
659     avb_assert(footer_num_read == AVB_FOOTER_SIZE);
660 
661     if (!avb_footer_validate_and_byteswap((const AvbFooter*)footer_buf,
662                                           &footer)) {
663       avb_debugv(full_partition_name, ": No footer detected.\n", NULL);
664     } else {
665       /* Basic footer sanity check since the data is untrusted. */
666       if (footer.vbmeta_size > VBMETA_MAX_SIZE) {
667         avb_errorv(
668             full_partition_name, ": Invalid vbmeta size in footer.\n", NULL);
669       } else {
670         vbmeta_offset = footer.vbmeta_offset;
671         vbmeta_size = footer.vbmeta_size;
672       }
673     }
674   }
675 
676   vbmeta_buf = avb_malloc(vbmeta_size);
677   if (vbmeta_buf == NULL) {
678     ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
679     goto out;
680   }
681 
682   if (vbmeta_offset != 0) {
683     avb_debugv("Loading vbmeta struct in footer from partition '",
684                full_partition_name,
685                "'.\n",
686                NULL);
687   } else {
688     avb_debugv("Loading vbmeta struct from partition '",
689                full_partition_name,
690                "'.\n",
691                NULL);
692   }
693 
694   io_ret = ops->read_from_partition(ops,
695                                     full_partition_name,
696                                     vbmeta_offset,
697                                     vbmeta_size,
698                                     vbmeta_buf,
699                                     &vbmeta_num_read);
700   if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
701     ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
702     goto out;
703   } else if (io_ret != AVB_IO_RESULT_OK) {
704     /* If we're looking for 'vbmeta' but there is no such partition,
705      * go try to get it from the boot partition instead.
706      */
707     if (is_main_vbmeta && io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION &&
708         !look_for_vbmeta_footer) {
709       avb_debugv(full_partition_name,
710                  ": No such partition. Trying 'boot' instead.\n",
711                  NULL);
712       ret = load_and_verify_vbmeta(ops,
713                                    requested_partitions,
714                                    ab_suffix,
715                                    flags,
716                                    allow_verification_error,
717                                    0 /* toplevel_vbmeta_flags */,
718                                    0 /* rollback_index_location */,
719                                    "boot",
720                                    avb_strlen("boot"),
721                                    NULL /* expected_public_key */,
722                                    0 /* expected_public_key_length */,
723                                    slot_data,
724                                    out_algorithm_type,
725                                    out_additional_cmdline_subst);
726       goto out;
727     } else {
728       avb_errorv(full_partition_name, ": Error loading vbmeta data.\n", NULL);
729       ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
730       goto out;
731     }
732   }
733   avb_assert(vbmeta_num_read <= vbmeta_size);
734 
735   /* Check if the image is properly signed and get the public key used
736    * to sign the image.
737    */
738   vbmeta_ret =
739       avb_vbmeta_image_verify(vbmeta_buf, vbmeta_num_read, &pk_data, &pk_len);
740   switch (vbmeta_ret) {
741     case AVB_VBMETA_VERIFY_RESULT_OK:
742       avb_assert(pk_data != NULL && pk_len > 0);
743       break;
744 
745     case AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED:
746     case AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH:
747     case AVB_VBMETA_VERIFY_RESULT_SIGNATURE_MISMATCH:
748       ret = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
749       avb_errorv(full_partition_name,
750                  ": Error verifying vbmeta image: ",
751                  avb_vbmeta_verify_result_to_string(vbmeta_ret),
752                  "\n",
753                  NULL);
754       if (!allow_verification_error) {
755         goto out;
756       }
757       break;
758 
759     case AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER:
760       /* No way to continue this case. */
761       ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
762       avb_errorv(full_partition_name,
763                  ": Error verifying vbmeta image: invalid vbmeta header\n",
764                  NULL);
765       goto out;
766 
767     case AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION:
768       /* No way to continue this case. */
769       ret = AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION;
770       avb_errorv(full_partition_name,
771                  ": Error verifying vbmeta image: unsupported AVB version\n",
772                  NULL);
773       goto out;
774   }
775 
776   /* Byteswap the header. */
777   avb_vbmeta_image_header_to_host_byte_order((AvbVBMetaImageHeader*)vbmeta_buf,
778                                              &vbmeta_header);
779 
780   /* If we're the toplevel, assign flags so they'll be passed down. */
781   if (is_main_vbmeta) {
782     toplevel_vbmeta_flags = (AvbVBMetaImageFlags)vbmeta_header.flags;
783   } else {
784     if (vbmeta_header.flags != 0) {
785       ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
786       avb_errorv(full_partition_name,
787                  ": chained vbmeta image has non-zero flags\n",
788                  NULL);
789       goto out;
790     }
791   }
792 
793   uint32_t rollback_index_location_to_use = rollback_index_location;
794   if (is_main_vbmeta) {
795     rollback_index_location_to_use = vbmeta_header.rollback_index_location;
796   }
797 
798   /* Check if key used to make signature matches what is expected. */
799   if (pk_data != NULL) {
800     if (expected_public_key != NULL) {
801       avb_assert(!is_main_vbmeta);
802       if (expected_public_key_length != pk_len ||
803           avb_safe_memcmp(expected_public_key, pk_data, pk_len) != 0) {
804         avb_errorv(full_partition_name,
805                    ": Public key used to sign data does not match key in chain "
806                    "partition descriptor.\n",
807                    NULL);
808         ret = AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED;
809         if (!allow_verification_error) {
810           goto out;
811         }
812       }
813     } else {
814       bool key_is_trusted = false;
815       const uint8_t* pk_metadata = NULL;
816       size_t pk_metadata_len = 0;
817 
818       if (vbmeta_header.public_key_metadata_size > 0) {
819         pk_metadata = vbmeta_buf + sizeof(AvbVBMetaImageHeader) +
820                       vbmeta_header.authentication_data_block_size +
821                       vbmeta_header.public_key_metadata_offset;
822         pk_metadata_len = vbmeta_header.public_key_metadata_size;
823       }
824 
825       // If we're not using a vbmeta partition, need to use another AvbOps...
826       if (flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION) {
827         io_ret = ops->validate_public_key_for_partition(
828             ops,
829             full_partition_name,
830             pk_data,
831             pk_len,
832             pk_metadata,
833             pk_metadata_len,
834             &key_is_trusted,
835             &rollback_index_location_to_use);
836       } else {
837         avb_assert(is_main_vbmeta);
838         io_ret = ops->validate_vbmeta_public_key(ops,
839                                                  pk_data,
840                                                  pk_len,
841                                                  pk_metadata,
842                                                  pk_metadata_len,
843                                                  &key_is_trusted);
844       }
845 
846       if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
847         ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
848         goto out;
849       } else if (io_ret != AVB_IO_RESULT_OK) {
850         avb_errorv(full_partition_name,
851                    ": Error while checking public key used to sign data.\n",
852                    NULL);
853         ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
854         goto out;
855       }
856       if (!key_is_trusted) {
857         avb_errorv(full_partition_name,
858                    ": Public key used to sign data rejected.\n",
859                    NULL);
860         ret = AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED;
861         if (!allow_verification_error) {
862           goto out;
863         }
864       }
865     }
866   }
867 
868   /* Check rollback index. */
869   io_ret = ops->read_rollback_index(
870       ops, rollback_index_location_to_use, &stored_rollback_index);
871   if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
872     ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
873     goto out;
874   } else if (io_ret != AVB_IO_RESULT_OK) {
875     avb_errorv(full_partition_name,
876                ": Error getting rollback index for location.\n",
877                NULL);
878     ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
879     goto out;
880   }
881   if (vbmeta_header.rollback_index < stored_rollback_index) {
882     avb_errorv(
883         full_partition_name,
884         ": Image rollback index is less than the stored rollback index.\n",
885         NULL);
886     ret = AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX;
887     if (!allow_verification_error) {
888       goto out;
889     }
890   }
891 
892   /* Copy vbmeta to vbmeta_images before recursing. */
893   if (is_main_vbmeta) {
894     avb_assert(slot_data->num_vbmeta_images == 0);
895   } else {
896     if (!(flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION)) {
897       avb_assert(slot_data->num_vbmeta_images > 0);
898     }
899   }
900   if (slot_data->num_vbmeta_images == MAX_NUMBER_OF_VBMETA_IMAGES) {
901     avb_errorv(full_partition_name, ": Too many vbmeta images.\n", NULL);
902     ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
903     goto out;
904   }
905   vbmeta_image_data = &slot_data->vbmeta_images[slot_data->num_vbmeta_images++];
906   vbmeta_image_data->partition_name = avb_strdup(partition_name);
907   vbmeta_image_data->vbmeta_data = vbmeta_buf;
908   /* Note that |vbmeta_buf| is actually |vbmeta_num_read| bytes long
909    * and this includes data past the end of the image. Pass the
910    * actual size of the vbmeta image. Also, no need to use
911    * avb_safe_add() since the header has already been verified.
912    */
913   vbmeta_image_data->vbmeta_size =
914       sizeof(AvbVBMetaImageHeader) +
915       vbmeta_header.authentication_data_block_size +
916       vbmeta_header.auxiliary_data_block_size;
917   vbmeta_image_data->verify_result = vbmeta_ret;
918 
919   /* If verification has been disabled by setting a bit in the image,
920    * we're done... except that we need to load the entirety of the
921    * requested partitions.
922    */
923   if (vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) {
924     AvbSlotVerifyResult sub_ret;
925     avb_debugv(
926         full_partition_name, ": VERIFICATION_DISABLED bit is set.\n", NULL);
927     /* If load_requested_partitions() fail it is always a fatal
928      * failure (e.g. ERROR_INVALID_ARGUMENT, ERROR_OOM, etc.) rather
929      * than recoverable (e.g. one where result_should_continue()
930      * returns true) and we want to convey that error.
931      */
932     sub_ret = load_requested_partitions(
933         ops, requested_partitions, ab_suffix, slot_data);
934     if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
935       ret = sub_ret;
936     }
937     goto out;
938   }
939 
940   /* Now go through all descriptors and take the appropriate action:
941    *
942    * - hash descriptor: Load data from partition, calculate hash, and
943    *   checks that it matches what's in the hash descriptor.
944    *
945    * - hashtree descriptor: Do nothing since verification happens
946    *   on-the-fly from within the OS. (Unless the descriptor uses a
947    *   persistent digest, in which case we need to find it).
948    *
949    * - chained partition descriptor: Load the footer, load the vbmeta
950    *   image, verify vbmeta image (includes rollback checks, hash
951    *   checks, bail on chained partitions).
952    */
953   descriptors =
954       avb_descriptor_get_all(vbmeta_buf, vbmeta_num_read, &num_descriptors);
955   for (n = 0; n < num_descriptors; n++) {
956     AvbDescriptor desc;
957 
958     if (!avb_descriptor_validate_and_byteswap(descriptors[n], &desc)) {
959       avb_errorv(full_partition_name, ": Descriptor is invalid.\n", NULL);
960       ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
961       goto out;
962     }
963 
964     switch (desc.tag) {
965       case AVB_DESCRIPTOR_TAG_HASH: {
966         AvbSlotVerifyResult sub_ret;
967         sub_ret = load_and_verify_hash_partition(ops,
968                                                  requested_partitions,
969                                                  ab_suffix,
970                                                  allow_verification_error,
971                                                  descriptors[n],
972                                                  slot_data);
973         if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
974           ret = sub_ret;
975           if (!allow_verification_error || !result_should_continue(ret)) {
976             goto out;
977           }
978         }
979       } break;
980 
981       case AVB_DESCRIPTOR_TAG_CHAIN_PARTITION: {
982         AvbSlotVerifyResult sub_ret;
983         AvbChainPartitionDescriptor chain_desc;
984         const uint8_t* chain_partition_name;
985         const uint8_t* chain_public_key;
986 
987         /* Only allow CHAIN_PARTITION descriptors in the main vbmeta image. */
988         if (!is_main_vbmeta) {
989           avb_errorv(full_partition_name,
990                      ": Encountered chain descriptor not in main image.\n",
991                      NULL);
992           ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
993           goto out;
994         }
995 
996         if (!avb_chain_partition_descriptor_validate_and_byteswap(
997                 (AvbChainPartitionDescriptor*)descriptors[n], &chain_desc)) {
998           avb_errorv(full_partition_name,
999                      ": Chain partition descriptor is invalid.\n",
1000                      NULL);
1001           ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
1002           goto out;
1003         }
1004 
1005         if (chain_desc.rollback_index_location == 0) {
1006           avb_errorv(full_partition_name,
1007                      ": Chain partition has invalid "
1008                      "rollback_index_location field.\n",
1009                      NULL);
1010           ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
1011           goto out;
1012         }
1013 
1014         chain_partition_name = ((const uint8_t*)descriptors[n]) +
1015                                sizeof(AvbChainPartitionDescriptor);
1016         chain_public_key = chain_partition_name + chain_desc.partition_name_len;
1017 
1018         sub_ret =
1019             load_and_verify_vbmeta(ops,
1020                                    requested_partitions,
1021                                    ab_suffix,
1022                                    flags,
1023                                    allow_verification_error,
1024                                    toplevel_vbmeta_flags,
1025                                    chain_desc.rollback_index_location,
1026                                    (const char*)chain_partition_name,
1027                                    chain_desc.partition_name_len,
1028                                    chain_public_key,
1029                                    chain_desc.public_key_len,
1030                                    slot_data,
1031                                    NULL, /* out_algorithm_type */
1032                                    NULL /* out_additional_cmdline_subst */);
1033         if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
1034           ret = sub_ret;
1035           if (!result_should_continue(ret)) {
1036             goto out;
1037           }
1038         }
1039       } break;
1040 
1041       case AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE: {
1042         const uint8_t* kernel_cmdline;
1043         AvbKernelCmdlineDescriptor kernel_cmdline_desc;
1044         bool apply_cmdline;
1045 
1046         if (!avb_kernel_cmdline_descriptor_validate_and_byteswap(
1047                 (AvbKernelCmdlineDescriptor*)descriptors[n],
1048                 &kernel_cmdline_desc)) {
1049           avb_errorv(full_partition_name,
1050                      ": Kernel cmdline descriptor is invalid.\n",
1051                      NULL);
1052           ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
1053           goto out;
1054         }
1055 
1056         kernel_cmdline = ((const uint8_t*)descriptors[n]) +
1057                          sizeof(AvbKernelCmdlineDescriptor);
1058 
1059         if (!avb_validate_utf8(kernel_cmdline,
1060                                kernel_cmdline_desc.kernel_cmdline_length)) {
1061           avb_errorv(full_partition_name,
1062                      ": Kernel cmdline is not valid UTF-8.\n",
1063                      NULL);
1064           ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
1065           goto out;
1066         }
1067 
1068         /* Compare the flags for top-level VBMeta struct with flags in
1069          * the command-line descriptor so command-line snippets only
1070          * intended for a certain mode (dm-verity enabled/disabled)
1071          * are skipped if applicable.
1072          */
1073         apply_cmdline = true;
1074         if (toplevel_vbmeta_flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED) {
1075           if (kernel_cmdline_desc.flags &
1076               AVB_KERNEL_CMDLINE_FLAGS_USE_ONLY_IF_HASHTREE_NOT_DISABLED) {
1077             apply_cmdline = false;
1078           }
1079         } else {
1080           if (kernel_cmdline_desc.flags &
1081               AVB_KERNEL_CMDLINE_FLAGS_USE_ONLY_IF_HASHTREE_DISABLED) {
1082             apply_cmdline = false;
1083           }
1084         }
1085 
1086         if (apply_cmdline) {
1087           if (slot_data->cmdline == NULL) {
1088             slot_data->cmdline =
1089                 avb_calloc(kernel_cmdline_desc.kernel_cmdline_length + 1);
1090             if (slot_data->cmdline == NULL) {
1091               ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
1092               goto out;
1093             }
1094             avb_memcpy(slot_data->cmdline,
1095                        kernel_cmdline,
1096                        kernel_cmdline_desc.kernel_cmdline_length);
1097           } else {
1098             /* new cmdline is: <existing_cmdline> + ' ' + <newcmdline> + '\0' */
1099             size_t orig_size = avb_strlen(slot_data->cmdline);
1100             size_t new_size =
1101                 orig_size + 1 + kernel_cmdline_desc.kernel_cmdline_length + 1;
1102             char* new_cmdline = avb_calloc(new_size);
1103             if (new_cmdline == NULL) {
1104               ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
1105               goto out;
1106             }
1107             avb_memcpy(new_cmdline, slot_data->cmdline, orig_size);
1108             new_cmdline[orig_size] = ' ';
1109             avb_memcpy(new_cmdline + orig_size + 1,
1110                        kernel_cmdline,
1111                        kernel_cmdline_desc.kernel_cmdline_length);
1112             avb_free(slot_data->cmdline);
1113             slot_data->cmdline = new_cmdline;
1114           }
1115         }
1116       } break;
1117 
1118       case AVB_DESCRIPTOR_TAG_HASHTREE: {
1119         AvbHashtreeDescriptor hashtree_desc;
1120 
1121         if (!avb_hashtree_descriptor_validate_and_byteswap(
1122                 (AvbHashtreeDescriptor*)descriptors[n], &hashtree_desc)) {
1123           avb_errorv(
1124               full_partition_name, ": Hashtree descriptor is invalid.\n", NULL);
1125           ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
1126           goto out;
1127         }
1128 
1129         /* We only need to continue when there is no digest in the descriptor.
1130          * This is because the only processing here is to find the digest and
1131          * make it available on the kernel command line.
1132          */
1133         if (hashtree_desc.root_digest_len == 0) {
1134           char part_name[AVB_PART_NAME_MAX_SIZE];
1135           size_t digest_len = 0;
1136           uint8_t digest_buf[AVB_SHA512_DIGEST_SIZE];
1137           const uint8_t* desc_partition_name =
1138               ((const uint8_t*)descriptors[n]) + sizeof(AvbHashtreeDescriptor);
1139 
1140           if (!avb_validate_utf8(desc_partition_name,
1141                                  hashtree_desc.partition_name_len)) {
1142             avb_error("Partition name is not valid UTF-8.\n");
1143             ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
1144             goto out;
1145           }
1146 
1147           /* No ab_suffix for partitions without a digest in the descriptor
1148            * because these partitions hold data unique to this device and are
1149            * not updated using an A/B scheme.
1150            */
1151           if ((hashtree_desc.flags &
1152                AVB_HASHTREE_DESCRIPTOR_FLAGS_DO_NOT_USE_AB) == 0 &&
1153               avb_strlen(ab_suffix) != 0) {
1154             avb_error("Cannot use A/B with a persistent root digest.\n");
1155             ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
1156             goto out;
1157           }
1158           if (hashtree_desc.partition_name_len >= AVB_PART_NAME_MAX_SIZE) {
1159             avb_error("Partition name does not fit.\n");
1160             ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
1161             goto out;
1162           }
1163           avb_memcpy(
1164               part_name, desc_partition_name, hashtree_desc.partition_name_len);
1165           part_name[hashtree_desc.partition_name_len] = '\0';
1166 
1167           /* Determine the expected digest size from the hash algorithm. */
1168           if (avb_strcmp((const char*)hashtree_desc.hash_algorithm, "sha1") ==
1169               0) {
1170             digest_len = AVB_SHA1_DIGEST_SIZE;
1171           } else if (avb_strcmp((const char*)hashtree_desc.hash_algorithm,
1172                                 "sha256") == 0) {
1173             digest_len = AVB_SHA256_DIGEST_SIZE;
1174           } else if (avb_strcmp((const char*)hashtree_desc.hash_algorithm,
1175                                 "sha512") == 0) {
1176             digest_len = AVB_SHA512_DIGEST_SIZE;
1177           } else {
1178             avb_errorv(part_name, ": Unsupported hash algorithm.\n", NULL);
1179             ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
1180             goto out;
1181           }
1182 
1183           ret = read_persistent_digest(ops,
1184                                        part_name,
1185                                        digest_len,
1186                                        NULL /* initial_digest */,
1187                                        digest_buf);
1188           if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
1189             goto out;
1190           }
1191 
1192           if (out_additional_cmdline_subst) {
1193             ret =
1194                 avb_add_root_digest_substitution(part_name,
1195                                                  digest_buf,
1196                                                  digest_len,
1197                                                  out_additional_cmdline_subst);
1198             if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
1199               goto out;
1200             }
1201           }
1202         }
1203       } break;
1204 
1205       case AVB_DESCRIPTOR_TAG_PROPERTY:
1206         /* Do nothing. */
1207         break;
1208     }
1209   }
1210 
1211   if (rollback_index_location_to_use >=
1212       AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS) {
1213     avb_errorv(
1214         full_partition_name, ": Invalid rollback_index_location.\n", NULL);
1215     ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
1216     goto out;
1217   }
1218 
1219   slot_data->rollback_indexes[rollback_index_location_to_use] =
1220       vbmeta_header.rollback_index;
1221 
1222   if (out_algorithm_type != NULL) {
1223     *out_algorithm_type = (AvbAlgorithmType)vbmeta_header.algorithm_type;
1224   }
1225 
1226 out:
1227   /* If |vbmeta_image_data| isn't NULL it means that it adopted
1228    * |vbmeta_buf| so in that case don't free it here.
1229    */
1230   if (vbmeta_image_data == NULL) {
1231     if (vbmeta_buf != NULL) {
1232       avb_free(vbmeta_buf);
1233     }
1234   }
1235   if (descriptors != NULL) {
1236     avb_free(descriptors);
1237   }
1238   return ret;
1239 }
1240 
avb_manage_hashtree_error_mode(AvbOps * ops,AvbSlotVerifyFlags flags,AvbSlotVerifyData * data,AvbHashtreeErrorMode * out_hashtree_error_mode)1241 static AvbIOResult avb_manage_hashtree_error_mode(
1242     AvbOps* ops,
1243     AvbSlotVerifyFlags flags,
1244     AvbSlotVerifyData* data,
1245     AvbHashtreeErrorMode* out_hashtree_error_mode) {
1246   AvbHashtreeErrorMode ret = AVB_HASHTREE_ERROR_MODE_RESTART;
1247   AvbIOResult io_ret = AVB_IO_RESULT_OK;
1248   uint8_t vbmeta_digest_sha256[AVB_SHA256_DIGEST_SIZE];
1249   uint8_t stored_vbmeta_digest_sha256[AVB_SHA256_DIGEST_SIZE];
1250   size_t num_bytes_read;
1251 
1252   avb_assert(out_hashtree_error_mode != NULL);
1253   avb_assert(ops->read_persistent_value != NULL);
1254   avb_assert(ops->write_persistent_value != NULL);
1255 
1256   // If we're rebooting because of dm-verity corruption, make a note of
1257   // the vbmeta hash so we can stay in 'eio' mode until things change.
1258   if (flags & AVB_SLOT_VERIFY_FLAGS_RESTART_CAUSED_BY_HASHTREE_CORRUPTION) {
1259     avb_debug(
1260         "Rebooting because of dm-verity corruption - "
1261         "recording OS instance and using 'eio' mode.\n");
1262     avb_slot_verify_data_calculate_vbmeta_digest(
1263         data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest_sha256);
1264     io_ret = ops->write_persistent_value(ops,
1265                                          AVB_NPV_MANAGED_VERITY_MODE,
1266                                          AVB_SHA256_DIGEST_SIZE,
1267                                          vbmeta_digest_sha256);
1268     if (io_ret != AVB_IO_RESULT_OK) {
1269       avb_error("Error writing to " AVB_NPV_MANAGED_VERITY_MODE ".\n");
1270       goto out;
1271     }
1272     ret = AVB_HASHTREE_ERROR_MODE_EIO;
1273     io_ret = AVB_IO_RESULT_OK;
1274     goto out;
1275   }
1276 
1277   // See if we're in 'eio' mode.
1278   io_ret = ops->read_persistent_value(ops,
1279                                       AVB_NPV_MANAGED_VERITY_MODE,
1280                                       AVB_SHA256_DIGEST_SIZE,
1281                                       stored_vbmeta_digest_sha256,
1282                                       &num_bytes_read);
1283   if (io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_VALUE ||
1284       (io_ret == AVB_IO_RESULT_OK && num_bytes_read == 0)) {
1285     // This is the usual case ('eio' mode not set).
1286     avb_debug("No dm-verity corruption - using in 'restart' mode.\n");
1287     ret = AVB_HASHTREE_ERROR_MODE_RESTART;
1288     io_ret = AVB_IO_RESULT_OK;
1289     goto out;
1290   } else if (io_ret != AVB_IO_RESULT_OK) {
1291     avb_error("Error reading from " AVB_NPV_MANAGED_VERITY_MODE ".\n");
1292     goto out;
1293   }
1294   if (num_bytes_read != AVB_SHA256_DIGEST_SIZE) {
1295     avb_error(
1296         "Unexpected number of bytes read from " AVB_NPV_MANAGED_VERITY_MODE
1297         ".\n");
1298     io_ret = AVB_IO_RESULT_ERROR_IO;
1299     goto out;
1300   }
1301 
1302   // OK, so we're currently in 'eio' mode and the vbmeta digest of the OS
1303   // that caused this is in |stored_vbmeta_digest_sha256| ... now see if
1304   // the OS we're dealing with now is the same.
1305   avb_slot_verify_data_calculate_vbmeta_digest(
1306       data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest_sha256);
1307   if (avb_memcmp(vbmeta_digest_sha256,
1308                  stored_vbmeta_digest_sha256,
1309                  AVB_SHA256_DIGEST_SIZE) == 0) {
1310     // It's the same so we're still in 'eio' mode.
1311     avb_debug("Same OS instance detected - staying in 'eio' mode.\n");
1312     ret = AVB_HASHTREE_ERROR_MODE_EIO;
1313     io_ret = AVB_IO_RESULT_OK;
1314   } else {
1315     // It did change!
1316     avb_debug(
1317         "New OS instance detected - changing from 'eio' to 'restart' mode.\n");
1318     io_ret =
1319         ops->write_persistent_value(ops,
1320                                     AVB_NPV_MANAGED_VERITY_MODE,
1321                                     0,  // This clears the persistent property.
1322                                     vbmeta_digest_sha256);
1323     if (io_ret != AVB_IO_RESULT_OK) {
1324       avb_error("Error clearing " AVB_NPV_MANAGED_VERITY_MODE ".\n");
1325       goto out;
1326     }
1327     ret = AVB_HASHTREE_ERROR_MODE_RESTART;
1328     io_ret = AVB_IO_RESULT_OK;
1329   }
1330 
1331 out:
1332   *out_hashtree_error_mode = ret;
1333   return io_ret;
1334 }
1335 
has_system_partition(AvbOps * ops,const char * ab_suffix)1336 static bool has_system_partition(AvbOps* ops, const char* ab_suffix) {
1337   char part_name[AVB_PART_NAME_MAX_SIZE];
1338   const char* system_part_name = "system";
1339   char guid_buf[37];
1340   AvbIOResult io_ret;
1341 
1342   if (!avb_str_concat(part_name,
1343                       sizeof part_name,
1344                       system_part_name,
1345                       avb_strlen(system_part_name),
1346                       ab_suffix,
1347                       avb_strlen(ab_suffix))) {
1348     avb_error("System partition name and suffix does not fit.\n");
1349     return false;
1350   }
1351 
1352   io_ret = ops->get_unique_guid_for_partition(
1353       ops, part_name, guid_buf, sizeof guid_buf);
1354   if (io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION) {
1355     avb_debug("No system partition.\n");
1356     return false;
1357   } else if (io_ret != AVB_IO_RESULT_OK) {
1358     avb_error("Error getting unique GUID for system partition.\n");
1359     return false;
1360   }
1361 
1362   return true;
1363 }
1364 
avb_slot_verify(AvbOps * ops,const char * const * requested_partitions,const char * ab_suffix,AvbSlotVerifyFlags flags,AvbHashtreeErrorMode hashtree_error_mode,AvbSlotVerifyData ** out_data)1365 AvbSlotVerifyResult avb_slot_verify(AvbOps* ops,
1366                                     const char* const* requested_partitions,
1367                                     const char* ab_suffix,
1368                                     AvbSlotVerifyFlags flags,
1369                                     AvbHashtreeErrorMode hashtree_error_mode,
1370                                     AvbSlotVerifyData** out_data) {
1371   AvbSlotVerifyResult ret;
1372   AvbSlotVerifyData* slot_data = NULL;
1373   AvbAlgorithmType algorithm_type = AVB_ALGORITHM_TYPE_NONE;
1374   bool using_boot_for_vbmeta = false;
1375   AvbVBMetaImageHeader toplevel_vbmeta;
1376   bool allow_verification_error =
1377       (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
1378   AvbCmdlineSubstList* additional_cmdline_subst = NULL;
1379 
1380   /* Fail early if we're missing the AvbOps needed for slot verification. */
1381   avb_assert(ops->read_is_device_unlocked != NULL);
1382   avb_assert(ops->read_from_partition != NULL);
1383   avb_assert(ops->get_size_of_partition != NULL);
1384   avb_assert(ops->read_rollback_index != NULL);
1385   avb_assert(ops->get_unique_guid_for_partition != NULL);
1386 
1387   if (out_data != NULL) {
1388     *out_data = NULL;
1389   }
1390 
1391   /* Allowing dm-verity errors defeats the purpose of verified boot so
1392    * only allow this if set up to allow verification errors
1393    * (e.g. typically only UNLOCKED mode).
1394    */
1395   if (hashtree_error_mode == AVB_HASHTREE_ERROR_MODE_LOGGING &&
1396       !allow_verification_error) {
1397     ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT;
1398     goto fail;
1399   }
1400 
1401   /* Make sure passed-in AvbOps support persistent values if
1402    * asking for libavb to manage verity state.
1403    */
1404   if (hashtree_error_mode == AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO) {
1405     if (ops->read_persistent_value == NULL ||
1406         ops->write_persistent_value == NULL) {
1407       avb_error(
1408           "Persistent values required for "
1409           "AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO "
1410           "but are not implemented in given AvbOps.\n");
1411       ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT;
1412       goto fail;
1413     }
1414   }
1415 
1416   /* Make sure passed-in AvbOps support verifying public keys and getting
1417    * rollback index location if not using a vbmeta partition.
1418    */
1419   if (flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION) {
1420     if (ops->validate_public_key_for_partition == NULL) {
1421       avb_error(
1422           "AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION was passed but the "
1423           "validate_public_key_for_partition() operation isn't implemented.\n");
1424       ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT;
1425       goto fail;
1426     }
1427   } else {
1428     avb_assert(ops->validate_vbmeta_public_key != NULL);
1429   }
1430 
1431   slot_data = avb_calloc(sizeof(AvbSlotVerifyData));
1432   if (slot_data == NULL) {
1433     ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
1434     goto fail;
1435   }
1436   slot_data->vbmeta_images =
1437       avb_calloc(sizeof(AvbVBMetaData) * MAX_NUMBER_OF_VBMETA_IMAGES);
1438   if (slot_data->vbmeta_images == NULL) {
1439     ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
1440     goto fail;
1441   }
1442   slot_data->loaded_partitions =
1443       avb_calloc(sizeof(AvbPartitionData) * MAX_NUMBER_OF_LOADED_PARTITIONS);
1444   if (slot_data->loaded_partitions == NULL) {
1445     ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
1446     goto fail;
1447   }
1448 
1449   additional_cmdline_subst = avb_new_cmdline_subst_list();
1450   if (additional_cmdline_subst == NULL) {
1451     ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
1452     goto fail;
1453   }
1454 
1455   if (flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION) {
1456     if (requested_partitions == NULL || requested_partitions[0] == NULL) {
1457       avb_fatal(
1458           "Requested partitions cannot be empty when using "
1459           "AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION");
1460       ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT;
1461       goto fail;
1462     }
1463 
1464     /* No vbmeta partition, go through each of the requested partitions... */
1465     for (size_t n = 0; requested_partitions[n] != NULL; n++) {
1466       ret = load_and_verify_vbmeta(ops,
1467                                    requested_partitions,
1468                                    ab_suffix,
1469                                    flags,
1470                                    allow_verification_error,
1471                                    0 /* toplevel_vbmeta_flags */,
1472                                    0 /* rollback_index_location */,
1473                                    requested_partitions[n],
1474                                    avb_strlen(requested_partitions[n]),
1475                                    NULL /* expected_public_key */,
1476                                    0 /* expected_public_key_length */,
1477                                    slot_data,
1478                                    &algorithm_type,
1479                                    additional_cmdline_subst);
1480       if (!allow_verification_error && ret != AVB_SLOT_VERIFY_RESULT_OK) {
1481         goto fail;
1482       }
1483     }
1484 
1485   } else {
1486     /* Usual path, load "vbmeta"... */
1487     ret = load_and_verify_vbmeta(ops,
1488                                  requested_partitions,
1489                                  ab_suffix,
1490                                  flags,
1491                                  allow_verification_error,
1492                                  0 /* toplevel_vbmeta_flags */,
1493                                  0 /* rollback_index_location */,
1494                                  "vbmeta",
1495                                  avb_strlen("vbmeta"),
1496                                  NULL /* expected_public_key */,
1497                                  0 /* expected_public_key_length */,
1498                                  slot_data,
1499                                  &algorithm_type,
1500                                  additional_cmdline_subst);
1501     if (!allow_verification_error && ret != AVB_SLOT_VERIFY_RESULT_OK) {
1502       goto fail;
1503     }
1504   }
1505 
1506   if (!result_should_continue(ret)) {
1507     goto fail;
1508   }
1509 
1510   /* If things check out, mangle the kernel command-line as needed. */
1511   if (!(flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION)) {
1512     if (avb_strcmp(slot_data->vbmeta_images[0].partition_name, "vbmeta") != 0) {
1513       avb_assert(
1514           avb_strcmp(slot_data->vbmeta_images[0].partition_name, "boot") == 0);
1515       using_boot_for_vbmeta = true;
1516     }
1517   }
1518 
1519   /* Byteswap top-level vbmeta header since we'll need it below. */
1520   avb_vbmeta_image_header_to_host_byte_order(
1521       (const AvbVBMetaImageHeader*)slot_data->vbmeta_images[0].vbmeta_data,
1522       &toplevel_vbmeta);
1523 
1524   /* Fill in |ab_suffix| field. */
1525   slot_data->ab_suffix = avb_strdup(ab_suffix);
1526   if (slot_data->ab_suffix == NULL) {
1527     ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
1528     goto fail;
1529   }
1530 
1531   /* If verification is disabled, we are done ... we specifically
1532    * don't want to add any androidboot.* options since verification
1533    * is disabled.
1534    */
1535   if (toplevel_vbmeta.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) {
1536     /* Since verification is disabled we didn't process any
1537      * descriptors and thus there's no cmdline... so set root= such
1538      * that the system partition is mounted.
1539      */
1540     avb_assert(slot_data->cmdline == NULL);
1541     // Devices with dynamic partitions won't have system partition.
1542     // Instead, it has a large super partition to accommodate *.img files.
1543     // See b/119551429 for details.
1544     if (has_system_partition(ops, ab_suffix)) {
1545       slot_data->cmdline =
1546           avb_strdup("root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)");
1547     } else {
1548       // The |cmdline| field should be a NUL-terminated string.
1549       slot_data->cmdline = avb_strdup("");
1550     }
1551     if (slot_data->cmdline == NULL) {
1552       ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
1553       goto fail;
1554     }
1555   } else {
1556     /* If requested, manage dm-verity mode... */
1557     AvbHashtreeErrorMode resolved_hashtree_error_mode = hashtree_error_mode;
1558     if (hashtree_error_mode ==
1559         AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO) {
1560       AvbIOResult io_ret;
1561       io_ret = avb_manage_hashtree_error_mode(
1562           ops, flags, slot_data, &resolved_hashtree_error_mode);
1563       if (io_ret != AVB_IO_RESULT_OK) {
1564         ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
1565         if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
1566           ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
1567         }
1568         goto fail;
1569       }
1570     }
1571     slot_data->resolved_hashtree_error_mode = resolved_hashtree_error_mode;
1572 
1573     /* Add options... */
1574     AvbSlotVerifyResult sub_ret;
1575     sub_ret = avb_append_options(ops,
1576                                  flags,
1577                                  slot_data,
1578                                  &toplevel_vbmeta,
1579                                  algorithm_type,
1580                                  hashtree_error_mode,
1581                                  resolved_hashtree_error_mode);
1582     if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
1583       ret = sub_ret;
1584       goto fail;
1585     }
1586   }
1587 
1588   /* Substitute $(ANDROID_SYSTEM_PARTUUID) and friends. */
1589   if (slot_data->cmdline != NULL && avb_strlen(slot_data->cmdline) != 0) {
1590     char* new_cmdline;
1591     new_cmdline = avb_sub_cmdline(ops,
1592                                   slot_data->cmdline,
1593                                   ab_suffix,
1594                                   using_boot_for_vbmeta,
1595                                   additional_cmdline_subst);
1596     if (new_cmdline != slot_data->cmdline) {
1597       if (new_cmdline == NULL) {
1598         ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
1599         goto fail;
1600       }
1601       avb_free(slot_data->cmdline);
1602       slot_data->cmdline = new_cmdline;
1603     }
1604   }
1605 
1606   if (out_data != NULL) {
1607     *out_data = slot_data;
1608   } else {
1609     avb_slot_verify_data_free(slot_data);
1610   }
1611 
1612   avb_free_cmdline_subst_list(additional_cmdline_subst);
1613   additional_cmdline_subst = NULL;
1614 
1615   if (!allow_verification_error) {
1616     avb_assert(ret == AVB_SLOT_VERIFY_RESULT_OK);
1617   }
1618 
1619   return ret;
1620 
1621 fail:
1622   if (slot_data != NULL) {
1623     avb_slot_verify_data_free(slot_data);
1624   }
1625   if (additional_cmdline_subst != NULL) {
1626     avb_free_cmdline_subst_list(additional_cmdline_subst);
1627   }
1628   return ret;
1629 }
1630 
avb_slot_verify_data_free(AvbSlotVerifyData * data)1631 void avb_slot_verify_data_free(AvbSlotVerifyData* data) {
1632   if (data->ab_suffix != NULL) {
1633     avb_free(data->ab_suffix);
1634   }
1635   if (data->cmdline != NULL) {
1636     avb_free(data->cmdline);
1637   }
1638   if (data->vbmeta_images != NULL) {
1639     size_t n;
1640     for (n = 0; n < data->num_vbmeta_images; n++) {
1641       AvbVBMetaData* vbmeta_image = &data->vbmeta_images[n];
1642       if (vbmeta_image->partition_name != NULL) {
1643         avb_free(vbmeta_image->partition_name);
1644       }
1645       if (vbmeta_image->vbmeta_data != NULL) {
1646         avb_free(vbmeta_image->vbmeta_data);
1647       }
1648     }
1649     avb_free(data->vbmeta_images);
1650   }
1651   if (data->loaded_partitions != NULL) {
1652     size_t n;
1653     for (n = 0; n < data->num_loaded_partitions; n++) {
1654       AvbPartitionData* loaded_partition = &data->loaded_partitions[n];
1655       if (loaded_partition->partition_name != NULL) {
1656         avb_free(loaded_partition->partition_name);
1657       }
1658       if (loaded_partition->data != NULL && !loaded_partition->preloaded) {
1659         avb_free(loaded_partition->data);
1660       }
1661     }
1662     avb_free(data->loaded_partitions);
1663   }
1664   avb_free(data);
1665 }
1666 
avb_slot_verify_result_to_string(AvbSlotVerifyResult result)1667 const char* avb_slot_verify_result_to_string(AvbSlotVerifyResult result) {
1668   const char* ret = NULL;
1669 
1670   switch (result) {
1671     case AVB_SLOT_VERIFY_RESULT_OK:
1672       ret = "OK";
1673       break;
1674     case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
1675       ret = "ERROR_OOM";
1676       break;
1677     case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
1678       ret = "ERROR_IO";
1679       break;
1680     case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
1681       ret = "ERROR_VERIFICATION";
1682       break;
1683     case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
1684       ret = "ERROR_ROLLBACK_INDEX";
1685       break;
1686     case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
1687       ret = "ERROR_PUBLIC_KEY_REJECTED";
1688       break;
1689     case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
1690       ret = "ERROR_INVALID_METADATA";
1691       break;
1692     case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
1693       ret = "ERROR_UNSUPPORTED_VERSION";
1694       break;
1695     case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
1696       ret = "ERROR_INVALID_ARGUMENT";
1697       break;
1698       /* Do not add a 'default:' case here because of -Wswitch. */
1699   }
1700 
1701   if (ret == NULL) {
1702     avb_error("Unknown AvbSlotVerifyResult value.\n");
1703     ret = "(unknown)";
1704   }
1705 
1706   return ret;
1707 }
1708 
avb_slot_verify_data_calculate_vbmeta_digest(AvbSlotVerifyData * data,AvbDigestType digest_type,uint8_t * out_digest)1709 void avb_slot_verify_data_calculate_vbmeta_digest(AvbSlotVerifyData* data,
1710                                                   AvbDigestType digest_type,
1711                                                   uint8_t* out_digest) {
1712   bool ret = false;
1713   size_t n;
1714 
1715   switch (digest_type) {
1716     case AVB_DIGEST_TYPE_SHA256: {
1717       AvbSHA256Ctx ctx;
1718       avb_sha256_init(&ctx);
1719       for (n = 0; n < data->num_vbmeta_images; n++) {
1720         avb_sha256_update(&ctx,
1721                           data->vbmeta_images[n].vbmeta_data,
1722                           data->vbmeta_images[n].vbmeta_size);
1723       }
1724       avb_memcpy(out_digest, avb_sha256_final(&ctx), AVB_SHA256_DIGEST_SIZE);
1725       ret = true;
1726     } break;
1727 
1728     case AVB_DIGEST_TYPE_SHA512: {
1729       AvbSHA512Ctx ctx;
1730       avb_sha512_init(&ctx);
1731       for (n = 0; n < data->num_vbmeta_images; n++) {
1732         avb_sha512_update(&ctx,
1733                           data->vbmeta_images[n].vbmeta_data,
1734                           data->vbmeta_images[n].vbmeta_size);
1735       }
1736       avb_memcpy(out_digest, avb_sha512_final(&ctx), AVB_SHA512_DIGEST_SIZE);
1737       ret = true;
1738     } break;
1739 
1740       /* Do not add a 'default:' case here because of -Wswitch. */
1741   }
1742 
1743   if (!ret) {
1744     avb_fatal("Unknown digest type");
1745   }
1746 }
1747