avb_slot_verify.c 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366
  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. /* Maximum number of partitions that can be loaded with avb_slot_verify(). */
  17. #define MAX_NUMBER_OF_LOADED_PARTITIONS 32
  18. /* Maximum number of vbmeta images that can be loaded with avb_slot_verify(). */
  19. #define MAX_NUMBER_OF_VBMETA_IMAGES 32
  20. /* Maximum size of a vbmeta image - 64 KiB. */
  21. #define VBMETA_MAX_SIZE (64 * 1024)
  22. /* Helper function to see if we should continue with verification in
  23. * allow_verification_error=true mode if something goes wrong. See the
  24. * comments for the avb_slot_verify() function for more information.
  25. */
  26. static inline bool result_should_continue(AvbSlotVerifyResult result) {
  27. switch (result) {
  28. case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
  29. case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
  30. case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
  31. case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
  32. case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
  33. return false;
  34. case AVB_SLOT_VERIFY_RESULT_OK:
  35. case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
  36. case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
  37. case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
  38. return true;
  39. }
  40. return false;
  41. }
  42. static AvbSlotVerifyResult load_full_partition(AvbOps* ops,
  43. const char* part_name,
  44. uint64_t image_size,
  45. uint8_t** out_image_buf,
  46. bool* out_image_preloaded) {
  47. size_t part_num_read;
  48. AvbIOResult io_ret;
  49. /* Make sure that we do not overwrite existing data. */
  50. avb_assert(*out_image_buf == NULL);
  51. avb_assert(!*out_image_preloaded);
  52. /* We are going to implicitly cast image_size from uint64_t to size_t in the
  53. * following code, so we need to make sure that the cast is safe. */
  54. if (image_size != (size_t)(image_size)) {
  55. avb_errorv(part_name, ": Partition size too large to load.\n", NULL);
  56. return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  57. }
  58. /* Try use a preloaded one. */
  59. if (ops->get_preloaded_partition != NULL) {
  60. io_ret = ops->get_preloaded_partition(
  61. ops, part_name, image_size, out_image_buf, &part_num_read);
  62. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  63. return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  64. } else if (io_ret != AVB_IO_RESULT_OK) {
  65. avb_errorv(part_name, ": Error loading data from partition.\n", NULL);
  66. return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
  67. }
  68. if (*out_image_buf != NULL) {
  69. if (part_num_read != image_size) {
  70. avb_errorv(part_name, ": Read incorrect number of bytes.\n", NULL);
  71. return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
  72. }
  73. *out_image_preloaded = true;
  74. }
  75. }
  76. /* Allocate and copy the partition. */
  77. if (!*out_image_preloaded) {
  78. *out_image_buf = avb_malloc(image_size);
  79. if (*out_image_buf == NULL) {
  80. return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  81. }
  82. io_ret = ops->read_from_partition(ops,
  83. part_name,
  84. 0 /* offset */,
  85. image_size,
  86. *out_image_buf,
  87. &part_num_read);
  88. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  89. return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  90. } else if (io_ret != AVB_IO_RESULT_OK) {
  91. avb_errorv(part_name, ": Error loading data from partition.\n", NULL);
  92. return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
  93. }
  94. if (part_num_read != image_size) {
  95. avb_errorv(part_name, ": Read incorrect number of bytes.\n", NULL);
  96. return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
  97. }
  98. }
  99. return AVB_SLOT_VERIFY_RESULT_OK;
  100. }
  101. static AvbSlotVerifyResult read_persistent_digest(AvbOps* ops,
  102. const char* part_name,
  103. size_t expected_digest_size,
  104. uint8_t* out_digest) {
  105. char* persistent_value_name = NULL;
  106. AvbIOResult io_ret = AVB_IO_RESULT_OK;
  107. size_t stored_digest_size = 0;
  108. if (ops->read_persistent_value == NULL) {
  109. avb_errorv(part_name, ": Persistent values are not implemented.\n", NULL);
  110. return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  111. }
  112. persistent_value_name =
  113. avb_strdupv(AVB_NPV_PERSISTENT_DIGEST_PREFIX, part_name, NULL);
  114. if (persistent_value_name == NULL) {
  115. return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  116. }
  117. io_ret = ops->read_persistent_value(ops,
  118. persistent_value_name,
  119. expected_digest_size,
  120. out_digest,
  121. &stored_digest_size);
  122. avb_free(persistent_value_name);
  123. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  124. return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  125. } else if (io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_VALUE) {
  126. avb_errorv(part_name, ": Persistent digest does not exist.\n", NULL);
  127. return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  128. } else if (io_ret == AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE ||
  129. io_ret == AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE ||
  130. expected_digest_size != stored_digest_size) {
  131. avb_errorv(
  132. part_name, ": Persistent digest is not of expected size.\n", NULL);
  133. return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  134. } else if (io_ret != AVB_IO_RESULT_OK) {
  135. avb_errorv(part_name, ": Error reading persistent digest.\n", NULL);
  136. return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
  137. }
  138. return AVB_SLOT_VERIFY_RESULT_OK;
  139. }
  140. static AvbSlotVerifyResult load_and_verify_hash_partition(
  141. AvbOps* ops,
  142. const char* const* requested_partitions,
  143. const char* ab_suffix,
  144. bool allow_verification_error,
  145. const AvbDescriptor* descriptor,
  146. AvbSlotVerifyData* slot_data) {
  147. AvbHashDescriptor hash_desc;
  148. const uint8_t* desc_partition_name = NULL;
  149. const uint8_t* desc_salt;
  150. const uint8_t* desc_digest;
  151. char part_name[AVB_PART_NAME_MAX_SIZE];
  152. AvbSlotVerifyResult ret;
  153. AvbIOResult io_ret;
  154. uint8_t* image_buf = NULL;
  155. bool image_preloaded = false;
  156. uint8_t* digest;
  157. size_t digest_len;
  158. const char* found;
  159. uint64_t image_size;
  160. size_t expected_digest_len = 0;
  161. uint8_t expected_digest_buf[AVB_SHA512_DIGEST_SIZE];
  162. const uint8_t* expected_digest = NULL;
  163. if (!avb_hash_descriptor_validate_and_byteswap(
  164. (const AvbHashDescriptor*)descriptor, &hash_desc)) {
  165. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  166. goto out;
  167. }
  168. desc_partition_name =
  169. ((const uint8_t*)descriptor) + sizeof(AvbHashDescriptor);
  170. desc_salt = desc_partition_name + hash_desc.partition_name_len;
  171. desc_digest = desc_salt + hash_desc.salt_len;
  172. if (!avb_validate_utf8(desc_partition_name, hash_desc.partition_name_len)) {
  173. avb_error("Partition name is not valid UTF-8.\n");
  174. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  175. goto out;
  176. }
  177. /* Don't bother loading or validating unless the partition was
  178. * requested in the first place.
  179. */
  180. found = avb_strv_find_str(requested_partitions,
  181. (const char*)desc_partition_name,
  182. hash_desc.partition_name_len);
  183. if (found == NULL) {
  184. ret = AVB_SLOT_VERIFY_RESULT_OK;
  185. goto out;
  186. }
  187. if ((hash_desc.flags & AVB_HASH_DESCRIPTOR_FLAGS_DO_NOT_USE_AB) != 0) {
  188. /* No ab_suffix, just copy the partition name as is. */
  189. if (hash_desc.partition_name_len >= AVB_PART_NAME_MAX_SIZE) {
  190. avb_error("Partition name does not fit.\n");
  191. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  192. goto out;
  193. }
  194. avb_memcpy(part_name, desc_partition_name, hash_desc.partition_name_len);
  195. part_name[hash_desc.partition_name_len] = '\0';
  196. } else if (hash_desc.digest_len == 0 && avb_strlen(ab_suffix) != 0) {
  197. /* No ab_suffix allowed for partitions without a digest in the descriptor
  198. * because these partitions hold data unique to this device and are not
  199. * updated using an A/B scheme.
  200. */
  201. avb_error("Cannot use A/B with a persistent digest.\n");
  202. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  203. goto out;
  204. } else {
  205. /* Add ab_suffix to the partition name. */
  206. if (!avb_str_concat(part_name,
  207. sizeof part_name,
  208. (const char*)desc_partition_name,
  209. hash_desc.partition_name_len,
  210. ab_suffix,
  211. avb_strlen(ab_suffix))) {
  212. avb_error("Partition name and suffix does not fit.\n");
  213. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  214. goto out;
  215. }
  216. }
  217. /* If we're allowing verification errors then hash_desc.image_size
  218. * may no longer match what's in the partition... so in this case
  219. * just load the entire partition.
  220. *
  221. * For example, this can happen if a developer does 'fastboot flash
  222. * boot /path/to/new/and/bigger/boot.img'. We want this to work
  223. * since it's such a common workflow.
  224. */
  225. image_size = hash_desc.image_size;
  226. if (allow_verification_error) {
  227. if (ops->get_size_of_partition == NULL) {
  228. avb_errorv(part_name,
  229. ": The get_size_of_partition() operation is "
  230. "not implemented so we may not load the entire partition. "
  231. "Please implement.",
  232. NULL);
  233. } else {
  234. io_ret = ops->get_size_of_partition(ops, part_name, &image_size);
  235. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  236. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  237. goto out;
  238. } else if (io_ret != AVB_IO_RESULT_OK) {
  239. avb_errorv(part_name, ": Error determining partition size.\n", NULL);
  240. ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
  241. goto out;
  242. }
  243. avb_debugv(part_name, ": Loading entire partition.\n", NULL);
  244. }
  245. }
  246. ret = load_full_partition(
  247. ops, part_name, image_size, &image_buf, &image_preloaded);
  248. if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
  249. goto out;
  250. }
  251. if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha256") == 0) {
  252. AvbSHA256Ctx sha256_ctx;
  253. avb_sha256_init(&sha256_ctx);
  254. avb_sha256_update(&sha256_ctx, desc_salt, hash_desc.salt_len);
  255. avb_sha256_update(&sha256_ctx, image_buf, hash_desc.image_size);
  256. digest = avb_sha256_final(&sha256_ctx);
  257. digest_len = AVB_SHA256_DIGEST_SIZE;
  258. } else if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha512") == 0) {
  259. AvbSHA512Ctx sha512_ctx;
  260. avb_sha512_init(&sha512_ctx);
  261. avb_sha512_update(&sha512_ctx, desc_salt, hash_desc.salt_len);
  262. avb_sha512_update(&sha512_ctx, image_buf, hash_desc.image_size);
  263. digest = avb_sha512_final(&sha512_ctx);
  264. digest_len = AVB_SHA512_DIGEST_SIZE;
  265. } else {
  266. avb_errorv(part_name, ": Unsupported hash algorithm.\n", NULL);
  267. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  268. goto out;
  269. }
  270. if (hash_desc.digest_len == 0) {
  271. // Expect a match to a persistent digest.
  272. avb_debugv(part_name, ": No digest, using persistent digest.\n", NULL);
  273. expected_digest_len = digest_len;
  274. expected_digest = expected_digest_buf;
  275. avb_assert(expected_digest_len <= sizeof(expected_digest_buf));
  276. ret =
  277. read_persistent_digest(ops, part_name, digest_len, expected_digest_buf);
  278. if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
  279. goto out;
  280. }
  281. } else {
  282. // Expect a match to the digest in the descriptor.
  283. expected_digest_len = hash_desc.digest_len;
  284. expected_digest = desc_digest;
  285. }
  286. if (digest_len != expected_digest_len) {
  287. avb_errorv(
  288. part_name, ": Digest in descriptor not of expected size.\n", NULL);
  289. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  290. goto out;
  291. }
  292. if (avb_safe_memcmp(digest, expected_digest, digest_len) != 0) {
  293. avb_errorv(part_name,
  294. ": Hash of data does not match digest in descriptor.\n",
  295. NULL);
  296. ret = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
  297. goto out;
  298. }
  299. ret = AVB_SLOT_VERIFY_RESULT_OK;
  300. out:
  301. /* If it worked and something was loaded, copy to slot_data. */
  302. if ((ret == AVB_SLOT_VERIFY_RESULT_OK || result_should_continue(ret)) &&
  303. image_buf != NULL) {
  304. AvbPartitionData* loaded_partition;
  305. if (slot_data->num_loaded_partitions == MAX_NUMBER_OF_LOADED_PARTITIONS) {
  306. avb_errorv(part_name, ": Too many loaded partitions.\n", NULL);
  307. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  308. goto fail;
  309. }
  310. loaded_partition =
  311. &slot_data->loaded_partitions[slot_data->num_loaded_partitions++];
  312. loaded_partition->partition_name = avb_strdup(found);
  313. loaded_partition->data_size = image_size;
  314. loaded_partition->data = image_buf;
  315. loaded_partition->preloaded = image_preloaded;
  316. image_buf = NULL;
  317. }
  318. fail:
  319. if (image_buf != NULL && !image_preloaded) {
  320. avb_free(image_buf);
  321. }
  322. return ret;
  323. }
  324. static AvbSlotVerifyResult load_requested_partitions(
  325. AvbOps* ops,
  326. const char* const* requested_partitions,
  327. const char* ab_suffix,
  328. AvbSlotVerifyData* slot_data) {
  329. AvbSlotVerifyResult ret;
  330. uint8_t* image_buf = NULL;
  331. bool image_preloaded = false;
  332. size_t n;
  333. if (ops->get_size_of_partition == NULL) {
  334. avb_error("get_size_of_partition() not implemented.\n");
  335. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT;
  336. goto out;
  337. }
  338. for (n = 0; requested_partitions[n] != NULL; n++) {
  339. char part_name[AVB_PART_NAME_MAX_SIZE];
  340. AvbIOResult io_ret;
  341. uint64_t image_size;
  342. AvbPartitionData* loaded_partition;
  343. if (!avb_str_concat(part_name,
  344. sizeof part_name,
  345. requested_partitions[n],
  346. avb_strlen(requested_partitions[n]),
  347. ab_suffix,
  348. avb_strlen(ab_suffix))) {
  349. avb_error("Partition name and suffix does not fit.\n");
  350. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  351. goto out;
  352. }
  353. io_ret = ops->get_size_of_partition(ops, part_name, &image_size);
  354. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  355. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  356. goto out;
  357. } else if (io_ret != AVB_IO_RESULT_OK) {
  358. avb_errorv(part_name, ": Error determining partition size.\n", NULL);
  359. ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
  360. goto out;
  361. }
  362. avb_debugv(part_name, ": Loading entire partition.\n", NULL);
  363. ret = load_full_partition(
  364. ops, part_name, image_size, &image_buf, &image_preloaded);
  365. if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
  366. goto out;
  367. }
  368. /* Move to slot_data. */
  369. if (slot_data->num_loaded_partitions == MAX_NUMBER_OF_LOADED_PARTITIONS) {
  370. avb_errorv(part_name, ": Too many loaded partitions.\n", NULL);
  371. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  372. goto out;
  373. }
  374. loaded_partition =
  375. &slot_data->loaded_partitions[slot_data->num_loaded_partitions++];
  376. loaded_partition->partition_name = avb_strdup(requested_partitions[n]);
  377. if (loaded_partition->partition_name == NULL) {
  378. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  379. goto out;
  380. }
  381. loaded_partition->data_size = image_size;
  382. loaded_partition->data = image_buf; /* Transferring the owner. */
  383. loaded_partition->preloaded = image_preloaded;
  384. image_buf = NULL;
  385. image_preloaded = false;
  386. }
  387. ret = AVB_SLOT_VERIFY_RESULT_OK;
  388. out:
  389. /* Free the current buffer if any. */
  390. if (image_buf != NULL && !image_preloaded) {
  391. avb_free(image_buf);
  392. }
  393. /* Buffers that are already saved in slot_data will be handled by the caller
  394. * even on failure. */
  395. return ret;
  396. }
  397. static AvbSlotVerifyResult load_and_verify_vbmeta(
  398. AvbOps* ops,
  399. const char* const* requested_partitions,
  400. const char* ab_suffix,
  401. bool allow_verification_error,
  402. AvbVBMetaImageFlags toplevel_vbmeta_flags,
  403. int rollback_index_location,
  404. const char* partition_name,
  405. size_t partition_name_len,
  406. const uint8_t* expected_public_key,
  407. size_t expected_public_key_length,
  408. AvbSlotVerifyData* slot_data,
  409. AvbAlgorithmType* out_algorithm_type,
  410. AvbCmdlineSubstList* out_additional_cmdline_subst) {
  411. char full_partition_name[AVB_PART_NAME_MAX_SIZE];
  412. AvbSlotVerifyResult ret;
  413. AvbIOResult io_ret;
  414. size_t vbmeta_offset;
  415. size_t vbmeta_size;
  416. uint8_t* vbmeta_buf = NULL;
  417. size_t vbmeta_num_read;
  418. AvbVBMetaVerifyResult vbmeta_ret;
  419. const uint8_t* pk_data;
  420. size_t pk_len;
  421. AvbVBMetaImageHeader vbmeta_header;
  422. uint64_t stored_rollback_index;
  423. const AvbDescriptor** descriptors = NULL;
  424. size_t num_descriptors;
  425. size_t n;
  426. bool is_main_vbmeta;
  427. bool is_vbmeta_partition;
  428. AvbVBMetaData* vbmeta_image_data = NULL;
  429. ret = AVB_SLOT_VERIFY_RESULT_OK;
  430. avb_assert(slot_data != NULL);
  431. /* Since we allow top-level vbmeta in 'boot', use
  432. * rollback_index_location to determine whether we're the main
  433. * vbmeta struct.
  434. */
  435. is_main_vbmeta = (rollback_index_location == 0);
  436. is_vbmeta_partition = (avb_strcmp(partition_name, "vbmeta") == 0);
  437. if (!avb_validate_utf8((const uint8_t*)partition_name, partition_name_len)) {
  438. avb_error("Partition name is not valid UTF-8.\n");
  439. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  440. goto out;
  441. }
  442. /* Construct full partition name. */
  443. if (!avb_str_concat(full_partition_name,
  444. sizeof full_partition_name,
  445. partition_name,
  446. partition_name_len,
  447. ab_suffix,
  448. avb_strlen(ab_suffix))) {
  449. avb_error("Partition name and suffix does not fit.\n");
  450. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  451. goto out;
  452. }
  453. avb_debugv("Loading vbmeta struct from partition '",
  454. full_partition_name,
  455. "'.\n",
  456. NULL);
  457. /* If we're loading from the main vbmeta partition, the vbmeta
  458. * struct is in the beginning. Otherwise we have to locate it via a
  459. * footer.
  460. */
  461. if (is_vbmeta_partition) {
  462. vbmeta_offset = 0;
  463. vbmeta_size = VBMETA_MAX_SIZE;
  464. } else {
  465. uint8_t footer_buf[AVB_FOOTER_SIZE];
  466. size_t footer_num_read;
  467. AvbFooter footer;
  468. io_ret = ops->read_from_partition(ops,
  469. full_partition_name,
  470. -AVB_FOOTER_SIZE,
  471. AVB_FOOTER_SIZE,
  472. footer_buf,
  473. &footer_num_read);
  474. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  475. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  476. goto out;
  477. } else if (io_ret != AVB_IO_RESULT_OK) {
  478. avb_errorv(full_partition_name, ": Error loading footer.\n", NULL);
  479. ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
  480. goto out;
  481. }
  482. avb_assert(footer_num_read == AVB_FOOTER_SIZE);
  483. if (!avb_footer_validate_and_byteswap((const AvbFooter*)footer_buf,
  484. &footer)) {
  485. avb_errorv(full_partition_name, ": Error validating footer.\n", NULL);
  486. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  487. goto out;
  488. }
  489. /* Basic footer sanity check since the data is untrusted. */
  490. if (footer.vbmeta_size > VBMETA_MAX_SIZE) {
  491. avb_errorv(
  492. full_partition_name, ": Invalid vbmeta size in footer.\n", NULL);
  493. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  494. goto out;
  495. }
  496. vbmeta_offset = footer.vbmeta_offset;
  497. vbmeta_size = footer.vbmeta_size;
  498. }
  499. vbmeta_buf = avb_malloc(vbmeta_size);
  500. if (vbmeta_buf == NULL) {
  501. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  502. goto out;
  503. }
  504. io_ret = ops->read_from_partition(ops,
  505. full_partition_name,
  506. vbmeta_offset,
  507. vbmeta_size,
  508. vbmeta_buf,
  509. &vbmeta_num_read);
  510. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  511. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  512. goto out;
  513. } else if (io_ret != AVB_IO_RESULT_OK) {
  514. /* If we're looking for 'vbmeta' but there is no such partition,
  515. * go try to get it from the boot partition instead.
  516. */
  517. if (is_main_vbmeta && io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION &&
  518. is_vbmeta_partition) {
  519. avb_debugv(full_partition_name,
  520. ": No such partition. Trying 'boot' instead.\n",
  521. NULL);
  522. ret = load_and_verify_vbmeta(ops,
  523. requested_partitions,
  524. ab_suffix,
  525. allow_verification_error,
  526. 0 /* toplevel_vbmeta_flags */,
  527. 0 /* rollback_index_location */,
  528. "boot",
  529. avb_strlen("boot"),
  530. NULL /* expected_public_key */,
  531. 0 /* expected_public_key_length */,
  532. slot_data,
  533. out_algorithm_type,
  534. out_additional_cmdline_subst);
  535. goto out;
  536. } else {
  537. avb_errorv(full_partition_name, ": Error loading vbmeta data.\n", NULL);
  538. ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
  539. goto out;
  540. }
  541. }
  542. avb_assert(vbmeta_num_read <= vbmeta_size);
  543. /* Check if the image is properly signed and get the public key used
  544. * to sign the image.
  545. */
  546. vbmeta_ret =
  547. avb_vbmeta_image_verify(vbmeta_buf, vbmeta_num_read, &pk_data, &pk_len);
  548. switch (vbmeta_ret) {
  549. case AVB_VBMETA_VERIFY_RESULT_OK:
  550. avb_assert(pk_data != NULL && pk_len > 0);
  551. break;
  552. case AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED:
  553. case AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH:
  554. case AVB_VBMETA_VERIFY_RESULT_SIGNATURE_MISMATCH:
  555. ret = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
  556. avb_errorv(full_partition_name,
  557. ": Error verifying vbmeta image: ",
  558. avb_vbmeta_verify_result_to_string(vbmeta_ret),
  559. "\n",
  560. NULL);
  561. if (!allow_verification_error) {
  562. goto out;
  563. }
  564. break;
  565. case AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER:
  566. /* No way to continue this case. */
  567. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  568. avb_errorv(full_partition_name,
  569. ": Error verifying vbmeta image: invalid vbmeta header\n",
  570. NULL);
  571. goto out;
  572. case AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION:
  573. /* No way to continue this case. */
  574. ret = AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION;
  575. avb_errorv(full_partition_name,
  576. ": Error verifying vbmeta image: unsupported AVB version\n",
  577. NULL);
  578. goto out;
  579. }
  580. /* Byteswap the header. */
  581. avb_vbmeta_image_header_to_host_byte_order((AvbVBMetaImageHeader*)vbmeta_buf,
  582. &vbmeta_header);
  583. /* If we're the toplevel, assign flags so they'll be passed down. */
  584. if (is_main_vbmeta) {
  585. toplevel_vbmeta_flags = (AvbVBMetaImageFlags)vbmeta_header.flags;
  586. } else {
  587. if (vbmeta_header.flags != 0) {
  588. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  589. avb_errorv(full_partition_name,
  590. ": chained vbmeta image has non-zero flags\n",
  591. NULL);
  592. goto out;
  593. }
  594. }
  595. /* Check if key used to make signature matches what is expected. */
  596. if (pk_data != NULL) {
  597. if (expected_public_key != NULL) {
  598. avb_assert(!is_main_vbmeta);
  599. if (expected_public_key_length != pk_len ||
  600. avb_safe_memcmp(expected_public_key, pk_data, pk_len) != 0) {
  601. avb_errorv(full_partition_name,
  602. ": Public key used to sign data does not match key in chain "
  603. "partition descriptor.\n",
  604. NULL);
  605. ret = AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED;
  606. if (!allow_verification_error) {
  607. goto out;
  608. }
  609. }
  610. } else {
  611. bool key_is_trusted = false;
  612. const uint8_t* pk_metadata = NULL;
  613. size_t pk_metadata_len = 0;
  614. if (vbmeta_header.public_key_metadata_size > 0) {
  615. pk_metadata = vbmeta_buf + sizeof(AvbVBMetaImageHeader) +
  616. vbmeta_header.authentication_data_block_size +
  617. vbmeta_header.public_key_metadata_offset;
  618. pk_metadata_len = vbmeta_header.public_key_metadata_size;
  619. }
  620. avb_assert(is_main_vbmeta);
  621. io_ret = ops->validate_vbmeta_public_key(
  622. ops, pk_data, pk_len, pk_metadata, pk_metadata_len, &key_is_trusted);
  623. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  624. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  625. goto out;
  626. } else if (io_ret != AVB_IO_RESULT_OK) {
  627. avb_errorv(full_partition_name,
  628. ": Error while checking public key used to sign data.\n",
  629. NULL);
  630. ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
  631. goto out;
  632. }
  633. if (!key_is_trusted) {
  634. avb_errorv(full_partition_name,
  635. ": Public key used to sign data rejected.\n",
  636. NULL);
  637. ret = AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED;
  638. if (!allow_verification_error) {
  639. goto out;
  640. }
  641. }
  642. }
  643. }
  644. /* Check rollback index. */
  645. io_ret = ops->read_rollback_index(
  646. ops, rollback_index_location, &stored_rollback_index);
  647. if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
  648. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  649. goto out;
  650. } else if (io_ret != AVB_IO_RESULT_OK) {
  651. avb_errorv(full_partition_name,
  652. ": Error getting rollback index for location.\n",
  653. NULL);
  654. ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
  655. goto out;
  656. }
  657. if (vbmeta_header.rollback_index < stored_rollback_index) {
  658. avb_errorv(
  659. full_partition_name,
  660. ": Image rollback index is less than the stored rollback index.\n",
  661. NULL);
  662. ret = AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX;
  663. if (!allow_verification_error) {
  664. goto out;
  665. }
  666. }
  667. /* Copy vbmeta to vbmeta_images before recursing. */
  668. if (is_main_vbmeta) {
  669. avb_assert(slot_data->num_vbmeta_images == 0);
  670. } else {
  671. avb_assert(slot_data->num_vbmeta_images > 0);
  672. }
  673. if (slot_data->num_vbmeta_images == MAX_NUMBER_OF_VBMETA_IMAGES) {
  674. avb_errorv(full_partition_name, ": Too many vbmeta images.\n", NULL);
  675. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  676. goto out;
  677. }
  678. vbmeta_image_data = &slot_data->vbmeta_images[slot_data->num_vbmeta_images++];
  679. vbmeta_image_data->partition_name = avb_strdup(partition_name);
  680. vbmeta_image_data->vbmeta_data = vbmeta_buf;
  681. /* Note that |vbmeta_buf| is actually |vbmeta_num_read| bytes long
  682. * and this includes data past the end of the image. Pass the
  683. * actual size of the vbmeta image. Also, no need to use
  684. * avb_safe_add() since the header has already been verified.
  685. */
  686. vbmeta_image_data->vbmeta_size =
  687. sizeof(AvbVBMetaImageHeader) +
  688. vbmeta_header.authentication_data_block_size +
  689. vbmeta_header.auxiliary_data_block_size;
  690. vbmeta_image_data->verify_result = vbmeta_ret;
  691. /* If verification has been disabled by setting a bit in the image,
  692. * we're done... except that we need to load the entirety of the
  693. * requested partitions.
  694. */
  695. if (vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) {
  696. AvbSlotVerifyResult sub_ret;
  697. avb_debugv(
  698. full_partition_name, ": VERIFICATION_DISABLED bit is set.\n", NULL);
  699. /* If load_requested_partitions() fail it is always a fatal
  700. * failure (e.g. ERROR_INVALID_ARGUMENT, ERROR_OOM, etc.) rather
  701. * than recoverable (e.g. one where result_should_continue()
  702. * returns true) and we want to convey that error.
  703. */
  704. sub_ret = load_requested_partitions(
  705. ops, requested_partitions, ab_suffix, slot_data);
  706. if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
  707. ret = sub_ret;
  708. }
  709. goto out;
  710. }
  711. /* Now go through all descriptors and take the appropriate action:
  712. *
  713. * - hash descriptor: Load data from partition, calculate hash, and
  714. * checks that it matches what's in the hash descriptor.
  715. *
  716. * - hashtree descriptor: Do nothing since verification happens
  717. * on-the-fly from within the OS. (Unless the descriptor uses a
  718. * persistent digest, in which case we need to find it).
  719. *
  720. * - chained partition descriptor: Load the footer, load the vbmeta
  721. * image, verify vbmeta image (includes rollback checks, hash
  722. * checks, bail on chained partitions).
  723. */
  724. descriptors =
  725. avb_descriptor_get_all(vbmeta_buf, vbmeta_num_read, &num_descriptors);
  726. for (n = 0; n < num_descriptors; n++) {
  727. AvbDescriptor desc;
  728. if (!avb_descriptor_validate_and_byteswap(descriptors[n], &desc)) {
  729. avb_errorv(full_partition_name, ": Descriptor is invalid.\n", NULL);
  730. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  731. goto out;
  732. }
  733. switch (desc.tag) {
  734. case AVB_DESCRIPTOR_TAG_HASH: {
  735. AvbSlotVerifyResult sub_ret;
  736. sub_ret = load_and_verify_hash_partition(ops,
  737. requested_partitions,
  738. ab_suffix,
  739. allow_verification_error,
  740. descriptors[n],
  741. slot_data);
  742. if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
  743. ret = sub_ret;
  744. if (!allow_verification_error || !result_should_continue(ret)) {
  745. goto out;
  746. }
  747. }
  748. } break;
  749. case AVB_DESCRIPTOR_TAG_CHAIN_PARTITION: {
  750. AvbSlotVerifyResult sub_ret;
  751. AvbChainPartitionDescriptor chain_desc;
  752. const uint8_t* chain_partition_name;
  753. const uint8_t* chain_public_key;
  754. /* Only allow CHAIN_PARTITION descriptors in the main vbmeta image. */
  755. if (!is_main_vbmeta) {
  756. avb_errorv(full_partition_name,
  757. ": Encountered chain descriptor not in main image.\n",
  758. NULL);
  759. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  760. goto out;
  761. }
  762. if (!avb_chain_partition_descriptor_validate_and_byteswap(
  763. (AvbChainPartitionDescriptor*)descriptors[n], &chain_desc)) {
  764. avb_errorv(full_partition_name,
  765. ": Chain partition descriptor is invalid.\n",
  766. NULL);
  767. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  768. goto out;
  769. }
  770. if (chain_desc.rollback_index_location == 0) {
  771. avb_errorv(full_partition_name,
  772. ": Chain partition has invalid "
  773. "rollback_index_location field.\n",
  774. NULL);
  775. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  776. goto out;
  777. }
  778. chain_partition_name = ((const uint8_t*)descriptors[n]) +
  779. sizeof(AvbChainPartitionDescriptor);
  780. chain_public_key = chain_partition_name + chain_desc.partition_name_len;
  781. sub_ret =
  782. load_and_verify_vbmeta(ops,
  783. requested_partitions,
  784. ab_suffix,
  785. allow_verification_error,
  786. toplevel_vbmeta_flags,
  787. chain_desc.rollback_index_location,
  788. (const char*)chain_partition_name,
  789. chain_desc.partition_name_len,
  790. chain_public_key,
  791. chain_desc.public_key_len,
  792. slot_data,
  793. NULL, /* out_algorithm_type */
  794. NULL /* out_additional_cmdline_subst */);
  795. if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
  796. ret = sub_ret;
  797. if (!result_should_continue(ret)) {
  798. goto out;
  799. }
  800. }
  801. } break;
  802. case AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE: {
  803. const uint8_t* kernel_cmdline;
  804. AvbKernelCmdlineDescriptor kernel_cmdline_desc;
  805. bool apply_cmdline;
  806. if (!avb_kernel_cmdline_descriptor_validate_and_byteswap(
  807. (AvbKernelCmdlineDescriptor*)descriptors[n],
  808. &kernel_cmdline_desc)) {
  809. avb_errorv(full_partition_name,
  810. ": Kernel cmdline descriptor is invalid.\n",
  811. NULL);
  812. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  813. goto out;
  814. }
  815. kernel_cmdline = ((const uint8_t*)descriptors[n]) +
  816. sizeof(AvbKernelCmdlineDescriptor);
  817. if (!avb_validate_utf8(kernel_cmdline,
  818. kernel_cmdline_desc.kernel_cmdline_length)) {
  819. avb_errorv(full_partition_name,
  820. ": Kernel cmdline is not valid UTF-8.\n",
  821. NULL);
  822. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  823. goto out;
  824. }
  825. /* Compare the flags for top-level VBMeta struct with flags in
  826. * the command-line descriptor so command-line snippets only
  827. * intended for a certain mode (dm-verity enabled/disabled)
  828. * are skipped if applicable.
  829. */
  830. apply_cmdline = true;
  831. if (toplevel_vbmeta_flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED) {
  832. if (kernel_cmdline_desc.flags &
  833. AVB_KERNEL_CMDLINE_FLAGS_USE_ONLY_IF_HASHTREE_NOT_DISABLED) {
  834. apply_cmdline = false;
  835. }
  836. } else {
  837. if (kernel_cmdline_desc.flags &
  838. AVB_KERNEL_CMDLINE_FLAGS_USE_ONLY_IF_HASHTREE_DISABLED) {
  839. apply_cmdline = false;
  840. }
  841. }
  842. if (apply_cmdline) {
  843. if (slot_data->cmdline == NULL) {
  844. slot_data->cmdline =
  845. avb_calloc(kernel_cmdline_desc.kernel_cmdline_length + 1);
  846. if (slot_data->cmdline == NULL) {
  847. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  848. goto out;
  849. }
  850. avb_memcpy(slot_data->cmdline,
  851. kernel_cmdline,
  852. kernel_cmdline_desc.kernel_cmdline_length);
  853. } else {
  854. /* new cmdline is: <existing_cmdline> + ' ' + <newcmdline> + '\0' */
  855. size_t orig_size = avb_strlen(slot_data->cmdline);
  856. size_t new_size =
  857. orig_size + 1 + kernel_cmdline_desc.kernel_cmdline_length + 1;
  858. char* new_cmdline = avb_calloc(new_size);
  859. if (new_cmdline == NULL) {
  860. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  861. goto out;
  862. }
  863. avb_memcpy(new_cmdline, slot_data->cmdline, orig_size);
  864. new_cmdline[orig_size] = ' ';
  865. avb_memcpy(new_cmdline + orig_size + 1,
  866. kernel_cmdline,
  867. kernel_cmdline_desc.kernel_cmdline_length);
  868. avb_free(slot_data->cmdline);
  869. slot_data->cmdline = new_cmdline;
  870. }
  871. }
  872. } break;
  873. case AVB_DESCRIPTOR_TAG_HASHTREE: {
  874. AvbHashtreeDescriptor hashtree_desc;
  875. if (!avb_hashtree_descriptor_validate_and_byteswap(
  876. (AvbHashtreeDescriptor*)descriptors[n], &hashtree_desc)) {
  877. avb_errorv(
  878. full_partition_name, ": Hashtree descriptor is invalid.\n", NULL);
  879. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  880. goto out;
  881. }
  882. /* We only need to continue when there is no digest in the descriptor.
  883. * This is because the only processing here is to find the digest and
  884. * make it available on the kernel command line.
  885. */
  886. if (hashtree_desc.root_digest_len == 0) {
  887. char part_name[AVB_PART_NAME_MAX_SIZE];
  888. size_t digest_len = 0;
  889. uint8_t digest_buf[AVB_SHA512_DIGEST_SIZE];
  890. const uint8_t* desc_partition_name =
  891. ((const uint8_t*)descriptors[n]) + sizeof(AvbHashtreeDescriptor);
  892. if (!avb_validate_utf8(desc_partition_name,
  893. hashtree_desc.partition_name_len)) {
  894. avb_error("Partition name is not valid UTF-8.\n");
  895. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  896. goto out;
  897. }
  898. /* No ab_suffix for partitions without a digest in the descriptor
  899. * because these partitions hold data unique to this device and are
  900. * not updated using an A/B scheme.
  901. */
  902. if ((hashtree_desc.flags &
  903. AVB_HASHTREE_DESCRIPTOR_FLAGS_DO_NOT_USE_AB) == 0 &&
  904. avb_strlen(ab_suffix) != 0) {
  905. avb_error("Cannot use A/B with a persistent root digest.\n");
  906. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  907. goto out;
  908. }
  909. if (hashtree_desc.partition_name_len >= AVB_PART_NAME_MAX_SIZE) {
  910. avb_error("Partition name does not fit.\n");
  911. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  912. goto out;
  913. }
  914. avb_memcpy(
  915. part_name, desc_partition_name, hashtree_desc.partition_name_len);
  916. part_name[hashtree_desc.partition_name_len] = '\0';
  917. /* Determine the expected digest size from the hash algorithm. */
  918. if (avb_strcmp((const char*)hashtree_desc.hash_algorithm, "sha1") ==
  919. 0) {
  920. digest_len = AVB_SHA1_DIGEST_SIZE;
  921. } else if (avb_strcmp((const char*)hashtree_desc.hash_algorithm,
  922. "sha256") == 0) {
  923. digest_len = AVB_SHA256_DIGEST_SIZE;
  924. } else if (avb_strcmp((const char*)hashtree_desc.hash_algorithm,
  925. "sha512") == 0) {
  926. digest_len = AVB_SHA512_DIGEST_SIZE;
  927. } else {
  928. avb_errorv(part_name, ": Unsupported hash algorithm.\n", NULL);
  929. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  930. goto out;
  931. }
  932. ret = read_persistent_digest(ops, part_name, digest_len, digest_buf);
  933. if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
  934. goto out;
  935. }
  936. if (out_additional_cmdline_subst) {
  937. ret =
  938. avb_add_root_digest_substitution(part_name,
  939. digest_buf,
  940. digest_len,
  941. out_additional_cmdline_subst);
  942. if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
  943. goto out;
  944. }
  945. }
  946. }
  947. } break;
  948. case AVB_DESCRIPTOR_TAG_PROPERTY:
  949. /* Do nothing. */
  950. break;
  951. }
  952. }
  953. if (rollback_index_location >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS) {
  954. avb_errorv(
  955. full_partition_name, ": Invalid rollback_index_location.\n", NULL);
  956. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
  957. goto out;
  958. }
  959. slot_data->rollback_indexes[rollback_index_location] =
  960. vbmeta_header.rollback_index;
  961. if (out_algorithm_type != NULL) {
  962. *out_algorithm_type = (AvbAlgorithmType)vbmeta_header.algorithm_type;
  963. }
  964. out:
  965. /* If |vbmeta_image_data| isn't NULL it means that it adopted
  966. * |vbmeta_buf| so in that case don't free it here.
  967. */
  968. if (vbmeta_image_data == NULL) {
  969. if (vbmeta_buf != NULL) {
  970. avb_free(vbmeta_buf);
  971. }
  972. }
  973. if (descriptors != NULL) {
  974. avb_free(descriptors);
  975. }
  976. return ret;
  977. }
  978. AvbSlotVerifyResult avb_slot_verify(AvbOps* ops,
  979. const char* const* requested_partitions,
  980. const char* ab_suffix,
  981. AvbSlotVerifyFlags flags,
  982. AvbHashtreeErrorMode hashtree_error_mode,
  983. AvbSlotVerifyData** out_data) {
  984. AvbSlotVerifyResult ret;
  985. AvbSlotVerifyData* slot_data = NULL;
  986. AvbAlgorithmType algorithm_type = AVB_ALGORITHM_TYPE_NONE;
  987. bool using_boot_for_vbmeta = false;
  988. AvbVBMetaImageHeader toplevel_vbmeta;
  989. bool allow_verification_error =
  990. (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
  991. AvbCmdlineSubstList* additional_cmdline_subst = NULL;
  992. /* Fail early if we're missing the AvbOps needed for slot verification.
  993. *
  994. * For now, handle get_size_of_partition() not being implemented. In
  995. * a later release we may change that.
  996. */
  997. avb_assert(ops->read_is_device_unlocked != NULL);
  998. avb_assert(ops->read_from_partition != NULL);
  999. avb_assert(ops->validate_vbmeta_public_key != NULL);
  1000. avb_assert(ops->read_rollback_index != NULL);
  1001. avb_assert(ops->get_unique_guid_for_partition != NULL);
  1002. if (out_data != NULL) {
  1003. *out_data = NULL;
  1004. }
  1005. /* Allowing dm-verity errors defeats the purpose of verified boot so
  1006. * only allow this if set up to allow verification errors
  1007. * (e.g. typically only UNLOCKED mode).
  1008. */
  1009. if (hashtree_error_mode == AVB_HASHTREE_ERROR_MODE_LOGGING &&
  1010. !allow_verification_error) {
  1011. ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT;
  1012. goto fail;
  1013. }
  1014. slot_data = avb_calloc(sizeof(AvbSlotVerifyData));
  1015. if (slot_data == NULL) {
  1016. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  1017. goto fail;
  1018. }
  1019. slot_data->vbmeta_images =
  1020. avb_calloc(sizeof(AvbVBMetaData) * MAX_NUMBER_OF_VBMETA_IMAGES);
  1021. if (slot_data->vbmeta_images == NULL) {
  1022. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  1023. goto fail;
  1024. }
  1025. slot_data->loaded_partitions =
  1026. avb_calloc(sizeof(AvbPartitionData) * MAX_NUMBER_OF_LOADED_PARTITIONS);
  1027. if (slot_data->loaded_partitions == NULL) {
  1028. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  1029. goto fail;
  1030. }
  1031. additional_cmdline_subst = avb_new_cmdline_subst_list();
  1032. if (additional_cmdline_subst == NULL) {
  1033. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  1034. goto fail;
  1035. }
  1036. ret = load_and_verify_vbmeta(ops,
  1037. requested_partitions,
  1038. ab_suffix,
  1039. allow_verification_error,
  1040. 0 /* toplevel_vbmeta_flags */,
  1041. 0 /* rollback_index_location */,
  1042. "vbmeta",
  1043. avb_strlen("vbmeta"),
  1044. NULL /* expected_public_key */,
  1045. 0 /* expected_public_key_length */,
  1046. slot_data,
  1047. &algorithm_type,
  1048. additional_cmdline_subst);
  1049. if (!allow_verification_error && ret != AVB_SLOT_VERIFY_RESULT_OK) {
  1050. goto fail;
  1051. }
  1052. /* If things check out, mangle the kernel command-line as needed. */
  1053. if (result_should_continue(ret)) {
  1054. if (avb_strcmp(slot_data->vbmeta_images[0].partition_name, "vbmeta") != 0) {
  1055. avb_assert(
  1056. avb_strcmp(slot_data->vbmeta_images[0].partition_name, "boot") == 0);
  1057. using_boot_for_vbmeta = true;
  1058. }
  1059. /* Byteswap top-level vbmeta header since we'll need it below. */
  1060. avb_vbmeta_image_header_to_host_byte_order(
  1061. (const AvbVBMetaImageHeader*)slot_data->vbmeta_images[0].vbmeta_data,
  1062. &toplevel_vbmeta);
  1063. /* Fill in |ab_suffix| field. */
  1064. slot_data->ab_suffix = avb_strdup(ab_suffix);
  1065. if (slot_data->ab_suffix == NULL) {
  1066. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  1067. goto fail;
  1068. }
  1069. /* If verification is disabled, we are done ... we specifically
  1070. * don't want to add any androidboot.* options since verification
  1071. * is disabled.
  1072. */
  1073. if (toplevel_vbmeta.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) {
  1074. /* Since verification is disabled we didn't process any
  1075. * descriptors and thus there's no cmdline... so set root= such
  1076. * that the system partition is mounted.
  1077. */
  1078. avb_assert(slot_data->cmdline == NULL);
  1079. slot_data->cmdline =
  1080. avb_strdup("root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)");
  1081. if (slot_data->cmdline == NULL) {
  1082. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  1083. goto fail;
  1084. }
  1085. } else {
  1086. /* Add options - any failure in avb_append_options() is either an
  1087. * I/O or OOM error.
  1088. */
  1089. AvbSlotVerifyResult sub_ret = avb_append_options(ops,
  1090. slot_data,
  1091. &toplevel_vbmeta,
  1092. algorithm_type,
  1093. hashtree_error_mode);
  1094. if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
  1095. ret = sub_ret;
  1096. goto fail;
  1097. }
  1098. }
  1099. /* Substitute $(ANDROID_SYSTEM_PARTUUID) and friends. */
  1100. if (slot_data->cmdline != NULL) {
  1101. char* new_cmdline;
  1102. new_cmdline = avb_sub_cmdline(ops,
  1103. slot_data->cmdline,
  1104. ab_suffix,
  1105. using_boot_for_vbmeta,
  1106. additional_cmdline_subst);
  1107. if (new_cmdline != slot_data->cmdline) {
  1108. if (new_cmdline == NULL) {
  1109. ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
  1110. goto fail;
  1111. }
  1112. avb_free(slot_data->cmdline);
  1113. slot_data->cmdline = new_cmdline;
  1114. }
  1115. }
  1116. if (out_data != NULL) {
  1117. *out_data = slot_data;
  1118. } else {
  1119. avb_slot_verify_data_free(slot_data);
  1120. }
  1121. }
  1122. avb_free_cmdline_subst_list(additional_cmdline_subst);
  1123. additional_cmdline_subst = NULL;
  1124. if (!allow_verification_error) {
  1125. avb_assert(ret == AVB_SLOT_VERIFY_RESULT_OK);
  1126. }
  1127. return ret;
  1128. fail:
  1129. if (slot_data != NULL) {
  1130. avb_slot_verify_data_free(slot_data);
  1131. }
  1132. if (additional_cmdline_subst != NULL) {
  1133. avb_free_cmdline_subst_list(additional_cmdline_subst);
  1134. }
  1135. return ret;
  1136. }
  1137. void avb_slot_verify_data_free(AvbSlotVerifyData* data) {
  1138. if (data->ab_suffix != NULL) {
  1139. avb_free(data->ab_suffix);
  1140. }
  1141. if (data->cmdline != NULL) {
  1142. avb_free(data->cmdline);
  1143. }
  1144. if (data->vbmeta_images != NULL) {
  1145. size_t n;
  1146. for (n = 0; n < data->num_vbmeta_images; n++) {
  1147. AvbVBMetaData* vbmeta_image = &data->vbmeta_images[n];
  1148. if (vbmeta_image->partition_name != NULL) {
  1149. avb_free(vbmeta_image->partition_name);
  1150. }
  1151. if (vbmeta_image->vbmeta_data != NULL) {
  1152. avb_free(vbmeta_image->vbmeta_data);
  1153. }
  1154. }
  1155. avb_free(data->vbmeta_images);
  1156. }
  1157. if (data->loaded_partitions != NULL) {
  1158. size_t n;
  1159. for (n = 0; n < data->num_loaded_partitions; n++) {
  1160. AvbPartitionData* loaded_partition = &data->loaded_partitions[n];
  1161. if (loaded_partition->partition_name != NULL) {
  1162. avb_free(loaded_partition->partition_name);
  1163. }
  1164. if (loaded_partition->data != NULL && !loaded_partition->preloaded) {
  1165. avb_free(loaded_partition->data);
  1166. }
  1167. }
  1168. avb_free(data->loaded_partitions);
  1169. }
  1170. avb_free(data);
  1171. }
  1172. const char* avb_slot_verify_result_to_string(AvbSlotVerifyResult result) {
  1173. const char* ret = NULL;
  1174. switch (result) {
  1175. case AVB_SLOT_VERIFY_RESULT_OK:
  1176. ret = "OK";
  1177. break;
  1178. case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
  1179. ret = "ERROR_OOM";
  1180. break;
  1181. case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
  1182. ret = "ERROR_IO";
  1183. break;
  1184. case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
  1185. ret = "ERROR_VERIFICATION";
  1186. break;
  1187. case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
  1188. ret = "ERROR_ROLLBACK_INDEX";
  1189. break;
  1190. case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
  1191. ret = "ERROR_PUBLIC_KEY_REJECTED";
  1192. break;
  1193. case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
  1194. ret = "ERROR_INVALID_METADATA";
  1195. break;
  1196. case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
  1197. ret = "ERROR_UNSUPPORTED_VERSION";
  1198. break;
  1199. case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
  1200. ret = "ERROR_INVALID_ARGUMENT";
  1201. break;
  1202. /* Do not add a 'default:' case here because of -Wswitch. */
  1203. }
  1204. if (ret == NULL) {
  1205. avb_error("Unknown AvbSlotVerifyResult value.\n");
  1206. ret = "(unknown)";
  1207. }
  1208. return ret;
  1209. }
  1210. void avb_slot_verify_data_calculate_vbmeta_digest(AvbSlotVerifyData* data,
  1211. AvbDigestType digest_type,
  1212. uint8_t* out_digest) {
  1213. bool ret = false;
  1214. size_t n;
  1215. switch (digest_type) {
  1216. case AVB_DIGEST_TYPE_SHA256: {
  1217. AvbSHA256Ctx ctx;
  1218. avb_sha256_init(&ctx);
  1219. for (n = 0; n < data->num_vbmeta_images; n++) {
  1220. avb_sha256_update(&ctx,
  1221. data->vbmeta_images[n].vbmeta_data,
  1222. data->vbmeta_images[n].vbmeta_size);
  1223. }
  1224. avb_memcpy(out_digest, avb_sha256_final(&ctx), AVB_SHA256_DIGEST_SIZE);
  1225. ret = true;
  1226. } break;
  1227. case AVB_DIGEST_TYPE_SHA512: {
  1228. AvbSHA512Ctx ctx;
  1229. avb_sha512_init(&ctx);
  1230. for (n = 0; n < data->num_vbmeta_images; n++) {
  1231. avb_sha512_update(&ctx,
  1232. data->vbmeta_images[n].vbmeta_data,
  1233. data->vbmeta_images[n].vbmeta_size);
  1234. }
  1235. avb_memcpy(out_digest, avb_sha512_final(&ctx), AVB_SHA512_DIGEST_SIZE);
  1236. ret = true;
  1237. } break;
  1238. /* Do not add a 'default:' case here because of -Wswitch. */
  1239. }
  1240. if (!ret) {
  1241. avb_fatal("Unknown digest type");
  1242. }
  1243. }