avb_slot_verify.c 63 KB

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