avb_slot_verify.c 63 KB

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