avb_slot_verify.c 60 KB

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