avb_hal.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2019. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. *
  31. * The following software/firmware and/or related documentation ("MediaTek Software")
  32. * have been modified by MediaTek Inc. All revisions are subject to any receiver\'s
  33. * applicable license agreements with MediaTek Inc.
  34. */
  35. #include <string.h>
  36. #include <avbkey.h>
  37. #include <avbkey_recovery.h>
  38. #include <error.h>
  39. #include <pal_typedefs.h>
  40. #include <pal_log.h>
  41. #include <part_interface.h>
  42. #include <partition_error.h>
  43. #include <part_status.h>
  44. #include <lock_state.h>
  45. #include <avb_ops.h>
  46. #include <avb_crypto.h>
  47. #include <avb_util.h>
  48. #include <lock_state.h>
  49. #include <platform/verified_boot.h>
  50. #include <verified_boot_common.h>
  51. #include <preload_partition.h>
  52. #include <avb_persist.h>
  53. static uint32_t g_vb_custom_key_exist = 0;
  54. extern PersistDescriptor *g_persist_des;
  55. uint8_t g_avb_key[AVB_PUBK_SZ] = {AVB_PUBK};
  56. uint8_t g_avb_recovery_key[AVB_RECOVERY_PUBK_SZ] = {AVB_RECOVERY_PUBK};
  57. static int32_t abs(int64_t x)
  58. {
  59. return x > 0 ? x : -x;
  60. }
  61. AvbIOResult get_abs_offset(const char *partition,
  62. int64_t offset,
  63. uint64_t *abs_offset)
  64. {
  65. uint64_t part_sz = 0;
  66. int64_t tmp_size = 0;
  67. if (partition == NULL || abs_offset == NULL)
  68. return AVB_IO_RESULT_ERROR_IO;
  69. *abs_offset = 0;
  70. tmp_size = partition_get_size_by_name(partition);
  71. if (tmp_size < 0)
  72. return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
  73. part_sz = (uint64_t)tmp_size;
  74. if (offset < 0) {
  75. if ((uint64_t)abs(offset) > part_sz)
  76. return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
  77. *abs_offset = part_sz - abs(offset);
  78. } else
  79. *abs_offset = offset;
  80. return AVB_IO_RESULT_OK;
  81. }
  82. uint32_t vb_custom_key_exist(void)
  83. {
  84. return g_vb_custom_key_exist;
  85. }
  86. AvbIOResult avb_hal_read_from_partition(AvbOps *ops,
  87. const char *partition,
  88. int64_t offset,
  89. size_t num_bytes,
  90. void *buffer,
  91. size_t *out_num_read)
  92. {
  93. uint64_t abs_offset = 0;
  94. uint32_t part_err = 0;
  95. ssize_t read_len = 0;
  96. AvbIOResult ret = AVB_IO_RESULT_OK;
  97. if (partition == NULL || buffer == NULL || out_num_read == NULL)
  98. return AVB_IO_RESULT_ERROR_IO;
  99. ret = get_abs_offset(partition, offset, &abs_offset);
  100. if (ret != AVB_IO_RESULT_OK)
  101. return ret;
  102. read_len = partition_read(partition, abs_offset, buffer,
  103. num_bytes);
  104. if (read_len < 0) {
  105. part_err = get_last_error();
  106. if (part_err == ERR_PART_GENERAL_NOT_EXIST)
  107. return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
  108. else if (part_err == ERR_PART_GENERAL_INVALID_RANGE)
  109. return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
  110. else
  111. return AVB_IO_RESULT_ERROR_IO;
  112. } else
  113. *out_num_read = (size_t)read_len;
  114. return AVB_IO_RESULT_OK;
  115. }
  116. AvbIOResult avb_hal_get_preloaded_partition(AvbOps* ops,
  117. const char* partition,
  118. size_t num_bytes,
  119. uint8_t** out_pointer,
  120. size_t* out_num_bytes_preloaded)
  121. {
  122. AvbIOResult ret = AVB_IO_RESULT_OK;
  123. uint32_t preload_ret = 0;
  124. uint32_t preload_addr = 0;
  125. uint32_t preload_sz = 0;
  126. if (partition == NULL ||
  127. out_pointer == NULL ||
  128. out_num_bytes_preloaded == NULL) {
  129. return AVB_IO_RESULT_ERROR_IO;
  130. }
  131. /* the expected behavior is to copy from preloaded partition to
  132. * buffer allocated here and assigned to *out_pointer. We don't
  133. * allocate buffer here actually. Instead, we set *out_pointer
  134. * to load address of preloaded partition */
  135. preload_ret = get_preload_partition_addr_sz(partition, &preload_addr, &preload_sz);
  136. if (preload_ret) {
  137. pal_log_err("use storage partition(%s)\n", partition);
  138. *out_pointer = NULL;
  139. *out_num_bytes_preloaded = 0;
  140. } else {
  141. pal_log_err("use preloaded partition(%s)\n", partition);
  142. if (num_bytes > preload_sz)
  143. return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
  144. *out_pointer = (uint8_t *)(uint32_t)preload_addr;
  145. *out_num_bytes_preloaded = num_bytes;
  146. }
  147. return ret;
  148. }
  149. AvbIOResult avb_hal_write_to_partition(AvbOps *ops,
  150. const char *partition,
  151. int64_t offset,
  152. size_t num_bytes,
  153. const void *buffer)
  154. {
  155. uint64_t abs_offset = 0;
  156. uint32_t part_err = 0;
  157. ssize_t write_len = 0;
  158. AvbIOResult ret = AVB_IO_RESULT_OK;
  159. if (partition == NULL || buffer == NULL)
  160. return AVB_IO_RESULT_ERROR_IO;
  161. ret = get_abs_offset(partition, offset, &abs_offset);
  162. if (ret != AVB_IO_RESULT_OK)
  163. return ret;
  164. write_len = partition_write(partition, abs_offset, (uint8_t *)buffer,
  165. num_bytes);
  166. if (write_len < 0) {
  167. part_err = get_last_error();
  168. if (part_err == ERR_PART_GENERAL_NOT_EXIST)
  169. return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
  170. else if (part_err == ERR_PART_GENERAL_INVALID_RANGE)
  171. return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
  172. else
  173. return AVB_IO_RESULT_ERROR_IO;
  174. }
  175. return AVB_IO_RESULT_OK;
  176. }
  177. AvbIOResult avb_hal_verify_public_key(AvbOps *ops,
  178. const uint8_t *public_key_data,
  179. size_t public_key_length,
  180. const uint8_t *public_key_metadata,
  181. size_t public_key_metadata_length,
  182. bool *out_is_trusted)
  183. {
  184. AvbRSAPublicKeyHeader *key_hdr;
  185. uint8_t *pubk;
  186. uint32_t i = 0;
  187. uint32_t pubk_sz = 0;
  188. AvbIOResult ret = AVB_IO_RESULT_OK;
  189. if (out_is_trusted == NULL || public_key_data == NULL)
  190. return AVB_IO_RESULT_ERROR_IO;
  191. key_hdr = (AvbRSAPublicKeyHeader *)public_key_data;
  192. pubk = (uint8_t *)(public_key_data + sizeof(AvbRSAPublicKeyHeader));
  193. pubk_sz = avb_htobe32(key_hdr->key_num_bits) / 8;
  194. *out_is_trusted = FALSE;
  195. if (pubk_sz != AVB_PUBK_SZ) {
  196. pal_log_err("invalid pubk size\n");
  197. goto end;
  198. }
  199. #ifdef MTK_SECURITY_SW_SUPPORT
  200. if (sec_set_pubk(pubk, pubk_sz) != STATUS_OK) {
  201. pal_log_err("[%s] fails to set public key\n", __func__);
  202. return AVB_IO_RESULT_ERROR_IO;
  203. }
  204. #endif
  205. if (0 == memcmp((void *)g_avb_key, (void *)pubk, pubk_sz))
  206. *out_is_trusted = TRUE;
  207. else {
  208. #ifdef MTK_SECURITY_YELLOW_STATE_SUPPORT
  209. *out_is_trusted = TRUE;
  210. g_vb_custom_key_exist = 1;
  211. #else
  212. pal_log_err("oem_avb_key =\n");
  213. for (i = 0; i < AVB_PUBK_SZ; i++) {
  214. pal_log_err("0x%x ", g_avb_key[i]);
  215. if (((i + 1) % 16) == 0)
  216. pal_log_err("\n");
  217. }
  218. pal_log_err("vbmeta_avb_key =\n");
  219. for (i = 0; i < AVB_PUBK_SZ; i++) {
  220. pal_log_err("0x%x ", pubk[i]);
  221. if (((i + 1) % 16) == 0)
  222. pal_log_err("\n");
  223. }
  224. #endif
  225. }
  226. end:
  227. return ret;
  228. }
  229. AvbIOResult avb_hal_read_rollback_index(AvbOps *ops,
  230. size_t rollback_index_location,
  231. uint64_t *out_rollback_index)
  232. {
  233. #ifdef MTK_SECURITY_ANTI_ROLLBACK
  234. uint32_t ret = 0;
  235. uint32_t tmp_ver = 0;
  236. #endif
  237. if (out_rollback_index == NULL)
  238. return AVB_IO_RESULT_ERROR_IO;
  239. *out_rollback_index = 0;
  240. #ifdef MTK_SECURITY_ANTI_ROLLBACK
  241. /* get otp version of AVB group*/
  242. ret = get_avb_otp_ver(AVB_GROUP, &tmp_ver);
  243. if (ret)
  244. return AVB_IO_RESULT_ERROR_IO;
  245. #ifdef MTK_OTP_FRAMEWORK_V2
  246. /* If AB system is enabled, otp field for recovery group is unused
  247. * since there is no recovery image.
  248. */
  249. #ifndef MTK_AB_OTA_UPDATER
  250. if (rollback_index_location == RECOVERY_ROLLBACK_INDEX) {
  251. /* get otp version of recovery group */
  252. ret = get_avb_otp_ver(RECOVERY_GROUP, &tmp_ver);
  253. if (ret)
  254. return AVB_IO_RESULT_ERROR_IO;
  255. }
  256. #endif
  257. #endif
  258. *out_rollback_index = (uint64_t)tmp_ver;
  259. #endif
  260. return AVB_IO_RESULT_OK;
  261. }
  262. AvbIOResult avb_hal_write_rollback_index(AvbOps *ops,
  263. size_t rollback_index_location,
  264. uint64_t rollback_index)
  265. {
  266. AvbIOResult ret = AVB_IO_RESULT_OK;
  267. /* otp update process is not implemented here. */
  268. return ret;
  269. }
  270. AvbIOResult avb_hal_read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
  271. {
  272. uint32_t ret = 0;
  273. uint32_t lock_state = LKS_DEFAULT;
  274. if (out_is_unlocked == NULL)
  275. return AVB_IO_RESULT_ERROR_IO;
  276. *out_is_unlocked = FALSE;
  277. #ifdef MTK_SECURITY_SW_SUPPORT
  278. ret = get_lock_state(&lock_state);
  279. if (ret != 0)
  280. return AVB_IO_RESULT_ERROR_IO;
  281. if ((lock_state == LKS_DEFAULT) || (lock_state == LKS_MP_DEFAULT) ||
  282. lock_state == LKS_LOCK)
  283. *out_is_unlocked = FALSE;
  284. else
  285. *out_is_unlocked = TRUE;
  286. #else
  287. *out_is_unlocked = TRUE;
  288. #endif
  289. pal_log_err("[AVB20] lock_state = 0x%x\n", lock_state);
  290. return AVB_IO_RESULT_OK;
  291. }
  292. AvbIOResult avb_hal_get_unique_guid_for_partition(AvbOps *ops,
  293. const char *partition,
  294. char *guid_buf,
  295. size_t guid_buf_size)
  296. {
  297. uint8_t *part_uuid = NULL;
  298. if (partition == NULL || guid_buf == NULL)
  299. return AVB_IO_RESULT_ERROR_IO;
  300. if (guid_buf_size < PART_META_INFO_UUIDLEN)
  301. return AVB_IO_RESULT_ERROR_IO;
  302. if (partition_exists(partition) != PART_OK)
  303. return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
  304. part_uuid = partition_get_uuid_by_name(partition);
  305. if (part_uuid == NULL)
  306. return AVB_IO_RESULT_ERROR_IO;
  307. memcpy(guid_buf, part_uuid, PART_META_INFO_UUIDLEN);
  308. return AVB_IO_RESULT_OK;
  309. }
  310. AvbIOResult avb_hal_get_size_of_partition(AvbOps *ops,
  311. const char *partition,
  312. uint64_t *out_size_num_bytes)
  313. {
  314. uint64_t size = 0;
  315. if (partition == NULL || out_size_num_bytes == NULL)
  316. return AVB_IO_RESULT_ERROR_IO;
  317. size = partition_get_size_by_name(partition);
  318. if (size == PART_NOT_EXIST)
  319. return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
  320. *out_size_num_bytes = (uint64_t)size;
  321. return AVB_IO_RESULT_OK;
  322. }
  323. AvbIOResult avb_hal_read_persistent_value(AvbOps *ops,
  324. const char *name,
  325. size_t buffer_sz,
  326. uint8_t *out_buffer,
  327. size_t *out_num_bytes_read)
  328. {
  329. AvbIOResult ret = AVB_IO_RESULT_OK;
  330. uint32_t persist_des_idx = 0;
  331. uint32_t find = 0;
  332. if (name == NULL || out_buffer == NULL || out_num_bytes_read == NULL) {
  333. ret = AVB_IO_RESULT_ERROR_IO;
  334. goto end;
  335. }
  336. if (!get_init_persist_status()) {
  337. ret = AVB_IO_RESULT_ERROR_IO;
  338. goto end;
  339. }
  340. while (persist_des_idx < MAX_PERSIST_TAG_SZ &&
  341. g_persist_des[persist_des_idx].hdr.tag == PERSIST_TAG_MAGIC) {
  342. if (g_persist_des[persist_des_idx].hdr.key_sz == strlen(name)) {
  343. if (!avb_memcmp(g_persist_des[persist_des_idx].key,
  344. name, strlen(name))) {
  345. if (g_persist_des[persist_des_idx].hdr.value_sz > buffer_sz) {
  346. ret = AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE;
  347. goto end;
  348. }
  349. if (g_persist_des[persist_des_idx].value == NULL) {
  350. ret = AVB_IO_RESULT_ERROR_IO;
  351. goto end;
  352. }
  353. avb_memcpy(out_buffer, g_persist_des[persist_des_idx].value,
  354. g_persist_des[persist_des_idx].hdr.value_sz);
  355. *out_num_bytes_read = g_persist_des[persist_des_idx].hdr.value_sz;
  356. find = 1;
  357. break;
  358. }
  359. }
  360. persist_des_idx++;
  361. }
  362. if (find == 0) {
  363. ret = AVB_IO_RESULT_ERROR_NO_SUCH_VALUE;
  364. goto end;
  365. }
  366. end:
  367. return ret;
  368. }
  369. AvbIOResult avb_hal_write_persistent_value(AvbOps *ops,
  370. const char* name,
  371. size_t value_sz,
  372. const uint8_t *value) {
  373. AvbIOResult ret = AVB_IO_RESULT_OK;
  374. uint32_t persist_des_idx = 0;
  375. uint32_t empty_tag_idx = MAX_PERSIST_TAG_SZ;
  376. uint32_t find = 0;
  377. uint8_t *new_buf = NULL;
  378. if (name == NULL || value == NULL) {
  379. ret = AVB_IO_RESULT_ERROR_IO;
  380. goto end;
  381. }
  382. if (!get_init_persist_status()) {
  383. ret = AVB_IO_RESULT_ERROR_IO;
  384. goto end;
  385. }
  386. while (persist_des_idx < MAX_PERSIST_TAG_SZ) {
  387. if (g_persist_des[persist_des_idx].hdr.tag == PERSIST_TAG_MAGIC &&
  388. g_persist_des[persist_des_idx].hdr.key_sz == strlen(name)) {
  389. if (!avb_memcmp(g_persist_des[persist_des_idx].key,
  390. name, strlen(name))) {
  391. if (g_persist_des[persist_des_idx].hdr.value_sz >= value_sz) {
  392. if (value_sz == 0) {
  393. /* delete this item */
  394. g_persist_des[persist_des_idx].hdr.tag = 0x0;
  395. }
  396. avb_memset(g_persist_des[persist_des_idx].value, 0x0,
  397. g_persist_des[persist_des_idx].hdr.value_sz);
  398. if (g_persist_des[persist_des_idx].value == NULL) {
  399. ret = AVB_IO_RESULT_ERROR_IO;
  400. goto end;
  401. }
  402. avb_memcpy(g_persist_des[persist_des_idx].value, value,
  403. value_sz);
  404. g_persist_des[persist_des_idx].hdr.value_sz = value_sz;
  405. } else {
  406. new_buf = avb_malloc(value_sz);
  407. if (new_buf == NULL) {
  408. ret = AVB_IO_RESULT_ERROR_OOM;
  409. goto end;
  410. }
  411. avb_memcpy(new_buf, value, value_sz);
  412. g_persist_des[persist_des_idx].value = new_buf;
  413. }
  414. find = 1;
  415. break;
  416. }
  417. } else if (g_persist_des[persist_des_idx].hdr.tag != PERSIST_TAG_MAGIC &&
  418. empty_tag_idx == MAX_PERSIST_TAG_SZ) {
  419. empty_tag_idx = persist_des_idx;
  420. }
  421. persist_des_idx++;
  422. }
  423. /* create a new item */
  424. if (find == 0) {
  425. if (empty_tag_idx >= MAX_PERSIST_TAG_SZ) {
  426. ret = AVB_IO_RESULT_ERROR_OOM;
  427. goto end;
  428. }
  429. pal_log_info("[AVB] create a new persist item...\n");
  430. g_persist_des[empty_tag_idx].hdr.tag = PERSIST_TAG_MAGIC;
  431. g_persist_des[empty_tag_idx].hdr.key_sz = strlen(name);
  432. g_persist_des[empty_tag_idx].hdr.value_sz = value_sz;
  433. new_buf = avb_malloc(strlen(name));
  434. if (new_buf == NULL) {
  435. ret = AVB_IO_RESULT_ERROR_OOM;
  436. goto end;
  437. }
  438. avb_memcpy(new_buf, name, strlen(name));
  439. g_persist_des[empty_tag_idx].key = new_buf;
  440. new_buf = avb_malloc(value_sz);
  441. if (new_buf == NULL) {
  442. ret = AVB_IO_RESULT_ERROR_OOM;
  443. goto end;
  444. }
  445. avb_memcpy(new_buf, value, value_sz);
  446. g_persist_des[empty_tag_idx].value = new_buf;
  447. }
  448. set_update_persist_status();
  449. end:
  450. return ret;
  451. }
  452. AvbIOResult avb_hal_validate_public_key_for_partition(
  453. AvbOps *ops,
  454. const char *partition,
  455. const uint8_t *public_key_data,
  456. size_t public_key_length,
  457. const uint8_t *public_key_metadata,
  458. size_t public_key_metadata_length,
  459. bool *out_is_trusted,
  460. uint32_t *out_rollback_index_location)
  461. {
  462. AvbRSAPublicKeyHeader *key_hdr;
  463. uint8_t *pubk;
  464. uint32_t i = 0;
  465. uint32_t pubk_sz = 0;
  466. AvbIOResult ret = AVB_IO_RESULT_OK;
  467. if (ops == NULL) {
  468. return AVB_IO_RESULT_ERROR_IO;
  469. }
  470. if (partition == NULL) {
  471. return AVB_IO_RESULT_ERROR_IO;
  472. }
  473. if (out_is_trusted == NULL) {
  474. return AVB_IO_RESULT_ERROR_IO;
  475. }
  476. if (public_key_data == NULL) {
  477. return AVB_IO_RESULT_ERROR_IO;
  478. }
  479. if (out_rollback_index_location == NULL) {
  480. return AVB_IO_RESULT_ERROR_IO;
  481. }
  482. /* We only support recovery partition for now. */
  483. if (0 != memcmp((void *)partition, (void *)"recovery", strlen("recovery"))) {
  484. return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
  485. }
  486. /* We only support recovery partition for now and this value
  487. * must be the same as the value set in device/mediatek/common/
  488. * device.mk for recovery. */
  489. *out_rollback_index_location = 1;
  490. key_hdr = (AvbRSAPublicKeyHeader *)public_key_data;
  491. pubk = (uint8_t *)(public_key_data + sizeof(AvbRSAPublicKeyHeader));
  492. pubk_sz = avb_htobe32(key_hdr->key_num_bits) / 8;
  493. *out_is_trusted = FALSE;
  494. if (pubk_sz != AVB_PUBK_SZ) {
  495. pal_log_err("invalid pubk size\n");
  496. goto end;
  497. }
  498. #ifdef MTK_SECURITY_SW_SUPPORT
  499. if (sec_set_pubk(pubk, pubk_sz) != STATUS_OK) {
  500. pal_log_err("[%s] fails to set public key\n", __func__);
  501. return AVB_IO_RESULT_ERROR_IO;
  502. }
  503. #endif
  504. if (0 == memcmp((void *)g_avb_recovery_key, (void *)pubk, pubk_sz))
  505. *out_is_trusted = TRUE;
  506. else {
  507. pal_log_err("oem_avb_key =\n");
  508. for (i = 0; i < AVB_PUBK_SZ; i++) {
  509. pal_log_err("0x%x ", g_avb_key[i]);
  510. if (((i + 1) % 16) == 0)
  511. pal_log_err("\n");
  512. }
  513. pal_log_err("vbmeta_avb_key =\n");
  514. for (i = 0; i < AVB_PUBK_SZ; i++) {
  515. pal_log_err("0x%x ", pubk[i]);
  516. if (((i + 1) % 16) == 0)
  517. pal_log_err("\n");
  518. }
  519. }
  520. end:
  521. return ret;
  522. }
  523. AvbOps ops = {
  524. .user_data = NULL,
  525. .ab_ops = NULL,
  526. .atx_ops = NULL,
  527. .read_from_partition = avb_hal_read_from_partition,
  528. #ifdef PRELOAD_PARTITION_SUPPORT
  529. .get_preloaded_partition = avb_hal_get_preloaded_partition,
  530. #else
  531. .get_preloaded_partition = NULL,
  532. #endif
  533. .write_to_partition = avb_hal_write_to_partition,
  534. .validate_vbmeta_public_key = avb_hal_verify_public_key,
  535. .read_rollback_index = avb_hal_read_rollback_index,
  536. .write_rollback_index = avb_hal_write_rollback_index,
  537. .read_is_device_unlocked = avb_hal_read_is_device_unlocked,
  538. .get_unique_guid_for_partition = avb_hal_get_unique_guid_for_partition,
  539. .get_size_of_partition = avb_hal_get_size_of_partition,
  540. #ifdef AVB_PERSIST_VALUE_SUPPORT
  541. .read_persistent_value = avb_hal_read_persistent_value,
  542. .write_persistent_value = avb_hal_write_persistent_value,
  543. #else
  544. .read_persistent_value = NULL,
  545. .write_persistent_value = NULL,
  546. #endif
  547. .validate_public_key_for_partition = avb_hal_validate_public_key_for_partition
  548. };