137a7bc39SJason Zhu /*
237a7bc39SJason Zhu * (C) Copyright 2017 Rockchip Electronics Co., Ltd
337a7bc39SJason Zhu *
437a7bc39SJason Zhu * SPDX-License-Identifier: GPL-2.0+
537a7bc39SJason Zhu */
637a7bc39SJason Zhu
737a7bc39SJason Zhu #include <common.h>
837a7bc39SJason Zhu #include <image.h>
937a7bc39SJason Zhu #include <android_image.h>
1037a7bc39SJason Zhu #include <malloc.h>
1137a7bc39SJason Zhu #include <mapmem.h>
1237a7bc39SJason Zhu #include <errno.h>
1337a7bc39SJason Zhu #include <command.h>
1437a7bc39SJason Zhu #include <mmc.h>
1537a7bc39SJason Zhu #include <blk.h>
1637a7bc39SJason Zhu #include <part.h>
1737a7bc39SJason Zhu #include <android_avb/avb_ops_user.h>
1837a7bc39SJason Zhu #include <android_avb/libavb_ab.h>
1937a7bc39SJason Zhu #include <android_avb/avb_atx_validate.h>
2037a7bc39SJason Zhu #include <android_avb/avb_atx_types.h>
2137a7bc39SJason Zhu #include <optee_include/OpteeClientInterface.h>
2237a7bc39SJason Zhu #include <optee_include/tee_api_defines.h>
2337a7bc39SJason Zhu #include <android_avb/avb_vbmeta_image.h>
2437a7bc39SJason Zhu #include <android_avb/avb_atx_validate.h>
2537a7bc39SJason Zhu #include <android_avb/rk_avb_ops_user.h>
26459bc933SJason Zhu #include <boot_rkimg.h>
276e2db7c2SWu Liangqing #include <u-boot/sha256.h>
281f670f7cSJason Zhu #include <asm/arch/rk_atags.h>
2937a7bc39SJason Zhu
3037a7bc39SJason Zhu /* rk used */
rk_avb_get_pub_key(struct rk_pub_key * pub_key)311f670f7cSJason Zhu int rk_avb_get_pub_key(struct rk_pub_key *pub_key)
321f670f7cSJason Zhu {
331f670f7cSJason Zhu struct tag *t = NULL;
341f670f7cSJason Zhu
351f670f7cSJason Zhu t = atags_get_tag(ATAG_PUB_KEY);
361f670f7cSJason Zhu if (!t)
371f670f7cSJason Zhu return -1;
381f670f7cSJason Zhu
391f670f7cSJason Zhu memcpy(pub_key, t->u.pub_key.data, sizeof(struct rk_pub_key));
401f670f7cSJason Zhu
411f670f7cSJason Zhu return 0;
421f670f7cSJason Zhu }
4308f7f19aSJason Zhu
rk_avb_get_perm_attr_cer(uint8_t * cer,uint32_t size)449b83ce70SJason Zhu int rk_avb_get_perm_attr_cer(uint8_t *cer, uint32_t size)
459b83ce70SJason Zhu {
469b83ce70SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
47c2bb0fd1SJason Zhu if (trusty_read_permanent_attributes_cer((uint8_t *)cer, size)) {
48c2bb0fd1SJason Zhu printf("AVB: perm attr cer is not exist.\n");
499b83ce70SJason Zhu return -EIO;
50c2bb0fd1SJason Zhu }
519b83ce70SJason Zhu
529b83ce70SJason Zhu return 0;
539b83ce70SJason Zhu #else
549b83ce70SJason Zhu return -1;
559b83ce70SJason Zhu #endif
569b83ce70SJason Zhu }
579b83ce70SJason Zhu
rk_avb_set_perm_attr_cer(uint8_t * cer,uint32_t size)589b83ce70SJason Zhu int rk_avb_set_perm_attr_cer(uint8_t *cer, uint32_t size)
599b83ce70SJason Zhu {
609b83ce70SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
619b83ce70SJason Zhu if (trusty_write_permanent_attributes_cer((uint8_t *)cer, size))
629b83ce70SJason Zhu return -EIO;
639b83ce70SJason Zhu
649b83ce70SJason Zhu return 0;
659b83ce70SJason Zhu #else
669b83ce70SJason Zhu return -1;
679b83ce70SJason Zhu #endif
689b83ce70SJason Zhu }
699b83ce70SJason Zhu
rk_avb_read_permanent_attributes(uint8_t * attributes,uint32_t size)7037a7bc39SJason Zhu int rk_avb_read_permanent_attributes(uint8_t *attributes, uint32_t size)
7137a7bc39SJason Zhu {
7237a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
7337a7bc39SJason Zhu if(trusty_read_permanent_attributes(attributes, size) != 0) {
7437a7bc39SJason Zhu printf("trusty_read_permanent_attributes failed!\n");
7537a7bc39SJason Zhu return -1;
7637a7bc39SJason Zhu }
7737a7bc39SJason Zhu
7837a7bc39SJason Zhu return 0;
7937a7bc39SJason Zhu #else
8037a7bc39SJason Zhu return -1;
8137a7bc39SJason Zhu #endif
8237a7bc39SJason Zhu }
8337a7bc39SJason Zhu
rk_avb_write_permanent_attributes(uint8_t * attributes,uint32_t size)8437a7bc39SJason Zhu int rk_avb_write_permanent_attributes(uint8_t *attributes, uint32_t size)
8537a7bc39SJason Zhu {
8637a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
8737a7bc39SJason Zhu if(trusty_write_permanent_attributes(attributes, size) != 0) {
8837a7bc39SJason Zhu printf("trusty_write_permanent_attributes failed!\n");
8937a7bc39SJason Zhu return -1;
9037a7bc39SJason Zhu }
9137a7bc39SJason Zhu
9237a7bc39SJason Zhu return 0;
9337a7bc39SJason Zhu #else
9437a7bc39SJason Zhu return -1;
9537a7bc39SJason Zhu #endif
9637a7bc39SJason Zhu }
9737a7bc39SJason Zhu
rk_avb_read_flash_lock_state(uint8_t * flash_lock_state)9837a7bc39SJason Zhu int rk_avb_read_flash_lock_state(uint8_t *flash_lock_state)
9937a7bc39SJason Zhu {
10037a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
10137a7bc39SJason Zhu int ret;
10237a7bc39SJason Zhu
10337a7bc39SJason Zhu ret = trusty_read_flash_lock_state(flash_lock_state);
1047c1937d6SJason Zhu switch (ret) {
1057c1937d6SJason Zhu case TEE_SUCCESS:
1067c1937d6SJason Zhu break;
1077c1937d6SJason Zhu case TEE_ERROR_GENERIC:
1087c1937d6SJason Zhu case TEE_ERROR_NO_DATA:
1097c1937d6SJason Zhu case TEE_ERROR_ITEM_NOT_FOUND:
11037a7bc39SJason Zhu *flash_lock_state = 1;
11137a7bc39SJason Zhu if (trusty_write_flash_lock_state(*flash_lock_state)) {
112647502d6SJason Zhu printf("trusty_write_flash_lock_state error!");
1137c1937d6SJason Zhu ret = -1;
1147c1937d6SJason Zhu } else {
11537a7bc39SJason Zhu ret = trusty_read_flash_lock_state(flash_lock_state);
1167c1937d6SJason Zhu }
1177c1937d6SJason Zhu break;
1187c1937d6SJason Zhu default:
1197c1937d6SJason Zhu printf("%s: trusty_read_flash_lock_state failed\n", __FILE__);
1207c1937d6SJason Zhu }
12199ff1ad0SJason Zhu
12299ff1ad0SJason Zhu return ret;
12337a7bc39SJason Zhu #else
12468e2a287SJason Zhu *flash_lock_state = 1;
12568e2a287SJason Zhu
12668e2a287SJason Zhu return 0;
12737a7bc39SJason Zhu #endif
12837a7bc39SJason Zhu }
12937a7bc39SJason Zhu
rk_avb_write_flash_lock_state(uint8_t flash_lock_state)13037a7bc39SJason Zhu int rk_avb_write_flash_lock_state(uint8_t flash_lock_state)
13137a7bc39SJason Zhu {
13237a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
13337a7bc39SJason Zhu if (trusty_write_flash_lock_state(flash_lock_state)) {
13437a7bc39SJason Zhu printf("trusty_write_flash_lock_state error!\n");
13537a7bc39SJason Zhu return -1;
13637a7bc39SJason Zhu }
13737a7bc39SJason Zhu
13837a7bc39SJason Zhu return 0;
13937a7bc39SJason Zhu #else
14037a7bc39SJason Zhu return -1;
14137a7bc39SJason Zhu #endif
14237a7bc39SJason Zhu }
14337a7bc39SJason Zhu
rk_avb_write_lock_state(uint8_t lock_state)14437a7bc39SJason Zhu int rk_avb_write_lock_state(uint8_t lock_state)
14537a7bc39SJason Zhu {
14637a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
14737a7bc39SJason Zhu if (trusty_write_lock_state(lock_state)) {
14837a7bc39SJason Zhu printf("trusty_write_lock_state error!\n");
14937a7bc39SJason Zhu return -1;
15037a7bc39SJason Zhu }
15137a7bc39SJason Zhu
15237a7bc39SJason Zhu return 0;
15337a7bc39SJason Zhu #else
15437a7bc39SJason Zhu return -1;
15537a7bc39SJason Zhu #endif
15637a7bc39SJason Zhu }
15737a7bc39SJason Zhu
rk_avb_read_lock_state(uint8_t * lock_state)15837a7bc39SJason Zhu int rk_avb_read_lock_state(uint8_t *lock_state)
15937a7bc39SJason Zhu {
16037a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
161*53e4c065SJason Zhu uint8_t vboot_flag = 0;
16237a7bc39SJason Zhu int ret;
16337a7bc39SJason Zhu
16437a7bc39SJason Zhu ret = trusty_read_lock_state(lock_state);
1657c1937d6SJason Zhu switch (ret) {
1667c1937d6SJason Zhu case TEE_SUCCESS:
1677c1937d6SJason Zhu break;
1687c1937d6SJason Zhu case TEE_ERROR_GENERIC:
1697c1937d6SJason Zhu case TEE_ERROR_NO_DATA:
1707c1937d6SJason Zhu case TEE_ERROR_ITEM_NOT_FOUND:
171*53e4c065SJason Zhu if (trusty_read_vbootkey_enable_flag(&vboot_flag)) {
172*53e4c065SJason Zhu printf("Can't read vboot flag\n");
173*53e4c065SJason Zhu return -1;
174*53e4c065SJason Zhu }
175*53e4c065SJason Zhu
176*53e4c065SJason Zhu if (vboot_flag)
177*53e4c065SJason Zhu *lock_state = 0;
178*53e4c065SJason Zhu else
17937a7bc39SJason Zhu *lock_state = 1;
180*53e4c065SJason Zhu
18137a7bc39SJason Zhu if (rk_avb_write_lock_state(*lock_state)) {
182647502d6SJason Zhu printf("avb_write_lock_state error!");
1837c1937d6SJason Zhu ret = -1;
1847c1937d6SJason Zhu } else {
18537a7bc39SJason Zhu ret = trusty_read_lock_state(lock_state);
1867c1937d6SJason Zhu }
1877c1937d6SJason Zhu break;
1887c1937d6SJason Zhu default:
1897c1937d6SJason Zhu printf("%s: trusty_read_lock_state failed\n", __FILE__);
1907c1937d6SJason Zhu }
19199ff1ad0SJason Zhu
19299ff1ad0SJason Zhu return ret;
19337a7bc39SJason Zhu #else
19437a7bc39SJason Zhu return -1;
19537a7bc39SJason Zhu #endif
19637a7bc39SJason Zhu }
19737a7bc39SJason Zhu
rk_avb_write_perm_attr_flag(uint8_t flag)19837a7bc39SJason Zhu int rk_avb_write_perm_attr_flag(uint8_t flag)
19937a7bc39SJason Zhu {
20037a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
20137a7bc39SJason Zhu if (trusty_write_permanent_attributes_flag(flag)) {
20237a7bc39SJason Zhu printf("trusty_write_permanent_attributes_flag error!\n");
20337a7bc39SJason Zhu return -1;
20437a7bc39SJason Zhu }
20537a7bc39SJason Zhu
20637a7bc39SJason Zhu return 0;
20737a7bc39SJason Zhu #else
20837a7bc39SJason Zhu return -1;
20937a7bc39SJason Zhu #endif
21037a7bc39SJason Zhu }
21137a7bc39SJason Zhu
rk_avb_read_perm_attr_flag(uint8_t * flag)21237a7bc39SJason Zhu int rk_avb_read_perm_attr_flag(uint8_t *flag)
21337a7bc39SJason Zhu {
21437a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
21537a7bc39SJason Zhu int ret;
21637a7bc39SJason Zhu
21737a7bc39SJason Zhu ret = trusty_read_permanent_attributes_flag(flag);
2187c1937d6SJason Zhu switch (ret) {
2197c1937d6SJason Zhu case TEE_SUCCESS:
2207c1937d6SJason Zhu break;
2217c1937d6SJason Zhu case TEE_ERROR_GENERIC:
2227c1937d6SJason Zhu case TEE_ERROR_NO_DATA:
2237c1937d6SJason Zhu case TEE_ERROR_ITEM_NOT_FOUND:
22437a7bc39SJason Zhu *flag = 0;
22537a7bc39SJason Zhu if (rk_avb_write_perm_attr_flag(*flag)) {
226647502d6SJason Zhu printf("avb_write_perm_attr_flag error!");
2277c1937d6SJason Zhu ret = -1;
2287c1937d6SJason Zhu } else {
22937a7bc39SJason Zhu ret = trusty_read_permanent_attributes_flag(flag);
2307c1937d6SJason Zhu }
2317c1937d6SJason Zhu break;
2327c1937d6SJason Zhu default:
2337c1937d6SJason Zhu printf("%s: trusty_read_permanent_attributes_flag failed",
2347c1937d6SJason Zhu __FILE__);
2357c1937d6SJason Zhu }
23699ff1ad0SJason Zhu
23799ff1ad0SJason Zhu return ret;
23837a7bc39SJason Zhu #else
23937a7bc39SJason Zhu return -1;
24037a7bc39SJason Zhu #endif
24137a7bc39SJason Zhu }
24237a7bc39SJason Zhu
rk_avb_read_vbootkey_hash(uint8_t * buf,uint8_t length)24337a7bc39SJason Zhu int rk_avb_read_vbootkey_hash(uint8_t *buf, uint8_t length)
24437a7bc39SJason Zhu {
24537a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
24637a7bc39SJason Zhu if (trusty_read_vbootkey_hash((uint32_t *)buf,
24737a7bc39SJason Zhu (uint32_t)length / sizeof(uint32_t))) {
24837a7bc39SJason Zhu printf("trusty_read_vbootkey_hash error!\n");
24937a7bc39SJason Zhu return -1;
25037a7bc39SJason Zhu }
25137a7bc39SJason Zhu
25237a7bc39SJason Zhu return 0;
25337a7bc39SJason Zhu #else
25437a7bc39SJason Zhu return -1;
25537a7bc39SJason Zhu #endif
25637a7bc39SJason Zhu }
25737a7bc39SJason Zhu
rk_avb_write_vbootkey_hash(uint8_t * buf,uint8_t length)25837a7bc39SJason Zhu int rk_avb_write_vbootkey_hash(uint8_t *buf, uint8_t length)
25937a7bc39SJason Zhu {
26037a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
26137a7bc39SJason Zhu if (trusty_write_vbootkey_hash((uint32_t *)buf,
26237a7bc39SJason Zhu (uint32_t)length / sizeof(uint32_t))) {
26337a7bc39SJason Zhu printf("trusty_write_vbootkey_hash error!\n");
26437a7bc39SJason Zhu return -1;
26537a7bc39SJason Zhu }
26637a7bc39SJason Zhu
26737a7bc39SJason Zhu return 0;
26837a7bc39SJason Zhu #else
26937a7bc39SJason Zhu return -1;
27037a7bc39SJason Zhu #endif
27137a7bc39SJason Zhu }
27237a7bc39SJason Zhu
rk_avb_close_optee_client(void)27337a7bc39SJason Zhu int rk_avb_close_optee_client(void)
27437a7bc39SJason Zhu {
27537a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
27637a7bc39SJason Zhu if(trusty_notify_optee_uboot_end()) {
27737a7bc39SJason Zhu printf("trusty_notify_optee_uboot_end error!\n");
27837a7bc39SJason Zhu return -1;
27937a7bc39SJason Zhu }
28037a7bc39SJason Zhu
28137a7bc39SJason Zhu return 0;
28237a7bc39SJason Zhu #else
28337a7bc39SJason Zhu return -1;
28437a7bc39SJason Zhu #endif
28537a7bc39SJason Zhu }
28637a7bc39SJason Zhu
rk_avb_read_attribute_hash(uint8_t * buf,uint8_t length)28737a7bc39SJason Zhu int rk_avb_read_attribute_hash(uint8_t *buf, uint8_t length)
28837a7bc39SJason Zhu {
28937a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
29037a7bc39SJason Zhu if (trusty_read_attribute_hash((uint32_t *)buf,
29137a7bc39SJason Zhu (uint32_t)(length/sizeof(uint32_t)))) {
29237a7bc39SJason Zhu printf("trusty_read_attribute_hash error!\n");
29337a7bc39SJason Zhu return -1;
29437a7bc39SJason Zhu }
29537a7bc39SJason Zhu
29637a7bc39SJason Zhu return 0;
29737a7bc39SJason Zhu #else
29837a7bc39SJason Zhu return -1;
29937a7bc39SJason Zhu #endif
30037a7bc39SJason Zhu }
30137a7bc39SJason Zhu
rk_avb_write_attribute_hash(uint8_t * buf,uint8_t length)30237a7bc39SJason Zhu int rk_avb_write_attribute_hash(uint8_t *buf, uint8_t length)
30337a7bc39SJason Zhu {
30437a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
30537a7bc39SJason Zhu if (trusty_write_attribute_hash((uint32_t *)buf,
30637a7bc39SJason Zhu (uint32_t)(length/sizeof(uint32_t)))) {
30737a7bc39SJason Zhu printf("trusty_write_attribute_hash error!\n");
30837a7bc39SJason Zhu return -1;
30937a7bc39SJason Zhu }
31037a7bc39SJason Zhu
31137a7bc39SJason Zhu return 0;
31237a7bc39SJason Zhu #else
31337a7bc39SJason Zhu return -1;
31437a7bc39SJason Zhu #endif
31537a7bc39SJason Zhu }
31637a7bc39SJason Zhu
rk_avb_read_all_rollback_index(char * buffer)31737a7bc39SJason Zhu int rk_avb_read_all_rollback_index(char *buffer)
31837a7bc39SJason Zhu {
31937a7bc39SJason Zhu AvbOps* ops;
32037a7bc39SJason Zhu uint64_t stored_rollback_index = 0;
32137a7bc39SJason Zhu AvbIOResult io_ret;
32237a7bc39SJason Zhu char temp[ROLLBACK_MAX_SIZE] = {0};
32337a7bc39SJason Zhu
32437a7bc39SJason Zhu ops = avb_ops_user_new();
32537a7bc39SJason Zhu if (ops == NULL) {
32637a7bc39SJason Zhu printf("avb_ops_user_new() failed!\n");
32737a7bc39SJason Zhu return -1;
32837a7bc39SJason Zhu }
32937a7bc39SJason Zhu
330926664c9SJason Zhu /* Actually the rollback_index_location 0 is used. */
331926664c9SJason Zhu io_ret = ops->read_rollback_index(ops, 0, &stored_rollback_index);
33237a7bc39SJason Zhu if (io_ret != AVB_IO_RESULT_OK)
33337a7bc39SJason Zhu goto out;
334926664c9SJason Zhu snprintf(temp, sizeof(int) + 1, "%d", 0);
33537a7bc39SJason Zhu strncat(buffer, temp, ROLLBACK_MAX_SIZE);
33637a7bc39SJason Zhu strncat(buffer, ":", 1);
33737a7bc39SJason Zhu snprintf(temp, sizeof(uint64_t) + 1, "%lld",
338df50318eSJason Zhu stored_rollback_index);
33937a7bc39SJason Zhu strncat(buffer, temp, ROLLBACK_MAX_SIZE);
34037a7bc39SJason Zhu strncat(buffer, ",", 1);
34137a7bc39SJason Zhu
34237a7bc39SJason Zhu io_ret =
34337a7bc39SJason Zhu ops->read_rollback_index(ops,
34437a7bc39SJason Zhu AVB_ATX_PIK_VERSION_LOCATION,
34537a7bc39SJason Zhu &stored_rollback_index);
34637a7bc39SJason Zhu if (io_ret != AVB_IO_RESULT_OK) {
347647502d6SJason Zhu printf("Failed to read PIK minimum version.\n");
34837a7bc39SJason Zhu goto out;
34937a7bc39SJason Zhu }
35037a7bc39SJason Zhu /* PIK rollback index */
351df50318eSJason Zhu snprintf(temp, sizeof(int) + 1, "%d", AVB_ATX_PIK_VERSION_LOCATION);
35237a7bc39SJason Zhu strncat(buffer, temp, ROLLBACK_MAX_SIZE);
35337a7bc39SJason Zhu strncat(buffer, ":", 1);
354df50318eSJason Zhu snprintf(temp, sizeof(uint64_t) + 1, "%lld", stored_rollback_index);
35537a7bc39SJason Zhu strncat(buffer, temp, ROLLBACK_MAX_SIZE);
35637a7bc39SJason Zhu strncat(buffer, ",", 1);
35737a7bc39SJason Zhu io_ret = ops->read_rollback_index(ops,
35837a7bc39SJason Zhu AVB_ATX_PSK_VERSION_LOCATION,
35937a7bc39SJason Zhu &stored_rollback_index);
36037a7bc39SJason Zhu if (io_ret != AVB_IO_RESULT_OK) {
361647502d6SJason Zhu printf("Failed to read PSK minimum version.\n");
36237a7bc39SJason Zhu goto out;
36337a7bc39SJason Zhu }
36437a7bc39SJason Zhu /* PSK rollback index */
365df50318eSJason Zhu snprintf(temp, sizeof(int) + 1, "%d", AVB_ATX_PSK_VERSION_LOCATION);
36637a7bc39SJason Zhu strncat(buffer, temp, ROLLBACK_MAX_SIZE);
36737a7bc39SJason Zhu strncat(buffer, ":", 1);
368df50318eSJason Zhu snprintf(temp, sizeof(uint64_t) + 1, "%lld", stored_rollback_index);
36937a7bc39SJason Zhu strncat(buffer, temp, ROLLBACK_MAX_SIZE);
37037a7bc39SJason Zhu debug("%s\n", buffer);
37137a7bc39SJason Zhu avb_ops_user_free(ops);
37237a7bc39SJason Zhu
37337a7bc39SJason Zhu return 0;
37437a7bc39SJason Zhu out:
37537a7bc39SJason Zhu avb_ops_user_free(ops);
37637a7bc39SJason Zhu
37737a7bc39SJason Zhu return -1;
37837a7bc39SJason Zhu }
37937a7bc39SJason Zhu
rk_avb_read_bootloader_locked_flag(uint8_t * flag)38037a7bc39SJason Zhu int rk_avb_read_bootloader_locked_flag(uint8_t *flag)
38137a7bc39SJason Zhu {
38237a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
383ae205b95SJoseph Chen if (trusty_read_vbootkey_enable_flag(flag))
38437a7bc39SJason Zhu return -1;
38537a7bc39SJason Zhu #endif
386ae205b95SJoseph Chen return 0;
38737a7bc39SJason Zhu }
38837a7bc39SJason Zhu
389c3230cf0SJason Zhu #ifdef CONFIG_SUPPORT_EMMC_RPMB
390c3230cf0SJason Zhu static int curr_device = -1;
391c3230cf0SJason Zhu
rk_bootloader_rollback_index_read(uint32_t offset,uint32_t bytes,void * rb_index)392c3230cf0SJason Zhu int rk_bootloader_rollback_index_read(uint32_t offset, uint32_t bytes,
393c3230cf0SJason Zhu void *rb_index)
394c3230cf0SJason Zhu {
395c3230cf0SJason Zhu
396c3230cf0SJason Zhu struct mmc *mmc;
397c3230cf0SJason Zhu uint8_t rpmb_buf[256] = {0};
398c3230cf0SJason Zhu uint32_t n;
399c3230cf0SJason Zhu char original_part;
400c3230cf0SJason Zhu
401c3230cf0SJason Zhu if ((offset + bytes) > 256)
402c3230cf0SJason Zhu return -1;
403c3230cf0SJason Zhu
404c3230cf0SJason Zhu if (curr_device < 0) {
405c3230cf0SJason Zhu if (get_mmc_num() > 0)
406c3230cf0SJason Zhu curr_device = 0;
407c3230cf0SJason Zhu else {
408647502d6SJason Zhu printf("No MMC device available");
409c3230cf0SJason Zhu return -1;
410c3230cf0SJason Zhu }
411c3230cf0SJason Zhu }
412c3230cf0SJason Zhu
413c3230cf0SJason Zhu mmc = find_mmc_device(curr_device);
414c3230cf0SJason Zhu /* Switch to the RPMB partition */
415c3230cf0SJason Zhu #ifndef CONFIG_BLK
416c3230cf0SJason Zhu original_part = mmc->block_dev.hwpart;
417c3230cf0SJason Zhu #else
418c3230cf0SJason Zhu original_part = mmc_get_blk_desc(mmc)->hwpart;
419c3230cf0SJason Zhu #endif
420c3230cf0SJason Zhu if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, MMC_PART_RPMB) !=
421c3230cf0SJason Zhu 0)
422c3230cf0SJason Zhu return -1;
423c3230cf0SJason Zhu
424c3230cf0SJason Zhu n = mmc_rpmb_read(mmc, rpmb_buf, RPMB_BASE_ADDR, 1, NULL);
425c3230cf0SJason Zhu if (n != 1)
426c3230cf0SJason Zhu return -1;
427c3230cf0SJason Zhu
428c3230cf0SJason Zhu /* Return to original partition */
429c3230cf0SJason Zhu if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, original_part) !=
430c3230cf0SJason Zhu 0)
431c3230cf0SJason Zhu return -1;
432c3230cf0SJason Zhu
433c3230cf0SJason Zhu memcpy(rb_index, (void*)&rpmb_buf[offset], bytes);
434c3230cf0SJason Zhu
435c3230cf0SJason Zhu return 0;
436c3230cf0SJason Zhu }
437c3230cf0SJason Zhu
rk_avb_get_bootloader_min_version(char * buffer)438c3230cf0SJason Zhu int rk_avb_get_bootloader_min_version(char *buffer)
439c3230cf0SJason Zhu {
440c3230cf0SJason Zhu uint32_t rb_index;
441c3230cf0SJason Zhu char temp[ROLLBACK_MAX_SIZE] = {0};
442c3230cf0SJason Zhu
443c3230cf0SJason Zhu if (rk_bootloader_rollback_index_read(UBOOT_RB_INDEX_OFFSET,
444c3230cf0SJason Zhu sizeof(uint32_t), &rb_index)) {
445647502d6SJason Zhu printf("Can not read uboot rollback index");
446c3230cf0SJason Zhu return -1;
447c3230cf0SJason Zhu }
448c3230cf0SJason Zhu snprintf(temp, sizeof(int) + 1, "%d", 0);
449c3230cf0SJason Zhu strncat(buffer, temp, ROLLBACK_MAX_SIZE);
450c3230cf0SJason Zhu strncat(buffer, ":", 1);
451c3230cf0SJason Zhu snprintf(temp, sizeof(uint32_t) + 1, "%d", rb_index);
452c3230cf0SJason Zhu strncat(buffer, temp, ROLLBACK_MAX_SIZE);
453c3230cf0SJason Zhu strncat(buffer, ",", 1);
454c3230cf0SJason Zhu
455c3230cf0SJason Zhu if (rk_bootloader_rollback_index_read(TRUST_RB_INDEX_OFFSET,
456c3230cf0SJason Zhu sizeof(uint32_t), &rb_index)) {
457647502d6SJason Zhu printf("Can not read trust rollback index");
458c3230cf0SJason Zhu return -1;
459c3230cf0SJason Zhu }
460c3230cf0SJason Zhu
461c3230cf0SJason Zhu snprintf(temp, sizeof(int) + 1, "%d", 1);
462c3230cf0SJason Zhu strncat(buffer, temp, ROLLBACK_MAX_SIZE);
463c3230cf0SJason Zhu strncat(buffer, ":", 1);
464c3230cf0SJason Zhu snprintf(temp, sizeof(uint32_t) + 1, "%d", rb_index);
465c3230cf0SJason Zhu strncat(buffer, temp, ROLLBACK_MAX_SIZE);
466c3230cf0SJason Zhu
467c3230cf0SJason Zhu return 0;
468c3230cf0SJason Zhu }
469c3230cf0SJason Zhu #endif
470c3230cf0SJason Zhu
rk_avb_get_at_vboot_state(char * buf)47137a7bc39SJason Zhu void rk_avb_get_at_vboot_state(char *buf)
47237a7bc39SJason Zhu {
47337a7bc39SJason Zhu char temp_flag = 0;
47437a7bc39SJason Zhu char *lock_val = NULL;
475615e0cdeSJason Zhu char *unlock_dis_val = NULL;
47637a7bc39SJason Zhu char *perm_attr_flag = NULL;
47737a7bc39SJason Zhu char *bootloader_locked_flag = NULL;
478615e0cdeSJason Zhu char *rollback_indices;
479615e0cdeSJason Zhu char min_versions[ROLLBACK_MAX_SIZE + 1] = {0};
480615e0cdeSJason Zhu int n;
48137a7bc39SJason Zhu
48237a7bc39SJason Zhu if (rk_avb_read_perm_attr_flag((uint8_t *)&temp_flag)) {
483647502d6SJason Zhu printf("Can not read perm_attr_flag!");
48437a7bc39SJason Zhu perm_attr_flag = "";
48537a7bc39SJason Zhu } else {
48637a7bc39SJason Zhu perm_attr_flag = temp_flag ? "1" : "0";
48737a7bc39SJason Zhu }
48837a7bc39SJason Zhu
489da980a52SJason Zhu temp_flag = 0;
49037a7bc39SJason Zhu if (rk_avb_read_lock_state((uint8_t *)&temp_flag)) {
491647502d6SJason Zhu printf("Can not read lock state!");
49237a7bc39SJason Zhu lock_val = "";
493615e0cdeSJason Zhu unlock_dis_val = "";
49437a7bc39SJason Zhu } else {
49537a7bc39SJason Zhu lock_val = (temp_flag & LOCK_MASK) ? "0" : "1";
496615e0cdeSJason Zhu unlock_dis_val = (temp_flag & UNLOCK_DISABLE_MASK) ? "1" : "0";
49737a7bc39SJason Zhu }
49837a7bc39SJason Zhu
499da980a52SJason Zhu temp_flag = 0;
50037a7bc39SJason Zhu if (rk_avb_read_bootloader_locked_flag((uint8_t *)&temp_flag)) {
501647502d6SJason Zhu printf("Can not read bootloader locked flag!");
50237a7bc39SJason Zhu bootloader_locked_flag = "";
50337a7bc39SJason Zhu } else {
50437a7bc39SJason Zhu bootloader_locked_flag = temp_flag ? "1" : "0";
50537a7bc39SJason Zhu }
50637a7bc39SJason Zhu
507615e0cdeSJason Zhu rollback_indices = malloc(VBOOT_STATE_SIZE);
508615e0cdeSJason Zhu if (!rollback_indices) {
509647502d6SJason Zhu printf("No buff to malloc!");
510615e0cdeSJason Zhu return;
511615e0cdeSJason Zhu }
512615e0cdeSJason Zhu
513615e0cdeSJason Zhu memset(rollback_indices, 0, VBOOT_STATE_SIZE);
514615e0cdeSJason Zhu if (rk_avb_read_all_rollback_index(rollback_indices))
515647502d6SJason Zhu printf("Can not read avb_min_ver!");
516a2b78998SJason Zhu #ifdef CONFIG_SUPPORT_EMMC_RPMB
517c3230cf0SJason Zhu /* bootloader-min-versions */
518615e0cdeSJason Zhu if (rk_avb_get_bootloader_min_version(min_versions))
519647502d6SJason Zhu printf("Call rk_avb_get_bootloader_min_version error!");
520a2b78998SJason Zhu #endif
521615e0cdeSJason Zhu n = snprintf(buf, VBOOT_STATE_SIZE - 1,
522615e0cdeSJason Zhu "avb-perm-attr-set=%s\n"
523615e0cdeSJason Zhu "avb-locked=%s\n"
524615e0cdeSJason Zhu "avb-unlock-disabled=%s\n"
525615e0cdeSJason Zhu "bootloader-locked=%s\n"
526615e0cdeSJason Zhu "avb-min-versions=%s\n"
527615e0cdeSJason Zhu "bootloader-min-versions=%s\n",
528615e0cdeSJason Zhu perm_attr_flag,
529615e0cdeSJason Zhu lock_val,
530615e0cdeSJason Zhu unlock_dis_val,
531615e0cdeSJason Zhu bootloader_locked_flag,
532615e0cdeSJason Zhu rollback_indices,
533615e0cdeSJason Zhu min_versions);
534615e0cdeSJason Zhu if (n >= VBOOT_STATE_SIZE) {
535647502d6SJason Zhu printf("The VBOOT_STATE buf is truncated\n");
536615e0cdeSJason Zhu buf[VBOOT_STATE_SIZE - 1] = 0;
537615e0cdeSJason Zhu }
538615e0cdeSJason Zhu debug("The vboot state buf is %s\n", buf);
539615e0cdeSJason Zhu free(rollback_indices);
54037a7bc39SJason Zhu }
54137a7bc39SJason Zhu
rk_avb_get_ab_info(AvbABData * ab_data)54237a7bc39SJason Zhu int rk_avb_get_ab_info(AvbABData* ab_data)
54337a7bc39SJason Zhu {
54437a7bc39SJason Zhu AvbOps* ops;
54537a7bc39SJason Zhu AvbIOResult io_ret = AVB_IO_RESULT_OK;
54637a7bc39SJason Zhu int ret = 0;
54737a7bc39SJason Zhu
54837a7bc39SJason Zhu ops = avb_ops_user_new();
54937a7bc39SJason Zhu if (ops == NULL) {
55037a7bc39SJason Zhu printf("%s: avb_ops_user_new() failed!\n", __FILE__);
55137a7bc39SJason Zhu return -1;
55237a7bc39SJason Zhu }
55337a7bc39SJason Zhu
55437a7bc39SJason Zhu io_ret = ops->ab_ops->read_ab_metadata(ops->ab_ops, ab_data);
55537a7bc39SJason Zhu if (io_ret != AVB_IO_RESULT_OK) {
556647502d6SJason Zhu printf("I/O error while loading A/B metadata.\n");
55737a7bc39SJason Zhu ret = -1;
55837a7bc39SJason Zhu }
55937a7bc39SJason Zhu
56037a7bc39SJason Zhu avb_ops_user_free(ops);
56137a7bc39SJason Zhu
56237a7bc39SJason Zhu return ret;
56337a7bc39SJason Zhu }
56437a7bc39SJason Zhu
rk_avb_get_part_has_slot_info(const char * base_name)56537a7bc39SJason Zhu int rk_avb_get_part_has_slot_info(const char *base_name)
56637a7bc39SJason Zhu {
56737a7bc39SJason Zhu char *part_name;
56837a7bc39SJason Zhu int part_num;
56937a7bc39SJason Zhu size_t part_name_len;
57037a7bc39SJason Zhu disk_partition_t part_info;
57137a7bc39SJason Zhu struct blk_desc *dev_desc;
57237a7bc39SJason Zhu const char *slot_suffix = "_a";
57337a7bc39SJason Zhu
574459bc933SJason Zhu dev_desc = rockchip_get_bootdev();
57537a7bc39SJason Zhu if (!dev_desc) {
576459bc933SJason Zhu printf("%s: Could not find device!\n", __func__);
57737a7bc39SJason Zhu return -1;
57837a7bc39SJason Zhu }
57937a7bc39SJason Zhu
58037a7bc39SJason Zhu if (base_name == NULL) {
58137a7bc39SJason Zhu printf("The base_name is NULL!\n");
58237a7bc39SJason Zhu return -1;
58337a7bc39SJason Zhu }
58437a7bc39SJason Zhu
58537a7bc39SJason Zhu part_name_len = strlen(base_name) + 1;
58637a7bc39SJason Zhu part_name_len += strlen(slot_suffix);
58737a7bc39SJason Zhu part_name = malloc(part_name_len);
58837a7bc39SJason Zhu if (!part_name) {
58937a7bc39SJason Zhu printf("%s can not malloc a buffer!\n", __FILE__);
59037a7bc39SJason Zhu return -1;
59137a7bc39SJason Zhu }
59237a7bc39SJason Zhu
59337a7bc39SJason Zhu memset(part_name, 0, part_name_len);
59437a7bc39SJason Zhu snprintf(part_name, part_name_len, "%s%s", base_name, slot_suffix);
59537a7bc39SJason Zhu part_num = part_get_info_by_name(dev_desc, part_name, &part_info);
59637a7bc39SJason Zhu if (part_num < 0) {
59737a7bc39SJason Zhu printf("Could not find partition \"%s\"\n", part_name);
59837a7bc39SJason Zhu part_num = -1;
59937a7bc39SJason Zhu }
60037a7bc39SJason Zhu
60137a7bc39SJason Zhu free(part_name);
60237a7bc39SJason Zhu return part_num;
60337a7bc39SJason Zhu }
60483ab7b49SJason Zhu
rk_auth_unlock(void * buffer,char * out_is_trusted)60583ab7b49SJason Zhu int rk_auth_unlock(void *buffer, char *out_is_trusted)
60683ab7b49SJason Zhu {
60783ab7b49SJason Zhu AvbOps* ops;
60883ab7b49SJason Zhu
60983ab7b49SJason Zhu ops = avb_ops_user_new();
61083ab7b49SJason Zhu if (ops == NULL) {
611647502d6SJason Zhu printf("avb_ops_user_new() failed!");
61283ab7b49SJason Zhu return -1;
61383ab7b49SJason Zhu }
61483ab7b49SJason Zhu
61583ab7b49SJason Zhu if (avb_atx_validate_unlock_credential(ops->atx_ops,
61683ab7b49SJason Zhu (AvbAtxUnlockCredential*)buffer,
61783ab7b49SJason Zhu (bool*)out_is_trusted)) {
61883ab7b49SJason Zhu avb_ops_user_free(ops);
61983ab7b49SJason Zhu return -1;
62083ab7b49SJason Zhu }
62183ab7b49SJason Zhu avb_ops_user_free(ops);
62283ab7b49SJason Zhu if (*out_is_trusted == true)
62383ab7b49SJason Zhu return 0;
62483ab7b49SJason Zhu else
62583ab7b49SJason Zhu return -1;
62683ab7b49SJason Zhu }
62757c7f8feSJason Zhu
rk_generate_unlock_challenge(void * buffer,uint32_t * challenge_len)62857c7f8feSJason Zhu int rk_generate_unlock_challenge(void *buffer, uint32_t *challenge_len)
62957c7f8feSJason Zhu {
63057c7f8feSJason Zhu AvbOps* ops;
63157c7f8feSJason Zhu AvbIOResult result = AVB_IO_RESULT_OK;
63257c7f8feSJason Zhu
63357c7f8feSJason Zhu ops = avb_ops_user_new();
63457c7f8feSJason Zhu if (ops == NULL) {
635647502d6SJason Zhu printf("avb_ops_user_new() failed!");
63657c7f8feSJason Zhu return -1;
63757c7f8feSJason Zhu }
63857c7f8feSJason Zhu
63957c7f8feSJason Zhu result = avb_atx_generate_unlock_challenge(ops->atx_ops,
64057c7f8feSJason Zhu (AvbAtxUnlockChallenge *)buffer);
64157c7f8feSJason Zhu avb_ops_user_free(ops);
64257c7f8feSJason Zhu *challenge_len = sizeof(AvbAtxUnlockChallenge);
64357c7f8feSJason Zhu if (result == AVB_IO_RESULT_OK)
64457c7f8feSJason Zhu return 0;
64557c7f8feSJason Zhu else
64657c7f8feSJason Zhu return -1;
64757c7f8feSJason Zhu }
6487cca3dd4SJason Zhu
rk_avb_init_ab_metadata(void)649813227adSJason Zhu int rk_avb_init_ab_metadata(void)
650813227adSJason Zhu {
651813227adSJason Zhu AvbOps *ops;
652813227adSJason Zhu AvbABData ab_data;
653813227adSJason Zhu
654813227adSJason Zhu memset(&ab_data, 0, sizeof(AvbABData));
655813227adSJason Zhu debug("sizeof(AvbABData) = %d\n", (int)(size_t)sizeof(AvbABData));
656813227adSJason Zhu
657813227adSJason Zhu ops = avb_ops_user_new();
658813227adSJason Zhu if (ops == NULL) {
659813227adSJason Zhu printf("avb_ops_user_new() failed!\n");
660813227adSJason Zhu return -1;
661813227adSJason Zhu }
662813227adSJason Zhu
663813227adSJason Zhu avb_ab_data_init(&ab_data);
664813227adSJason Zhu if (ops->ab_ops->write_ab_metadata(ops->ab_ops, &ab_data) != 0) {
665813227adSJason Zhu printf("do_avb_init_ab_metadata error!\n");
666813227adSJason Zhu avb_ops_user_free(ops);
667813227adSJason Zhu return -1;
668813227adSJason Zhu }
669813227adSJason Zhu
670813227adSJason Zhu printf("Initialize ab data to misc partition success.\n");
671813227adSJason Zhu avb_ops_user_free(ops);
672813227adSJason Zhu
673813227adSJason Zhu return 0;
674813227adSJason Zhu }
6756e2db7c2SWu Liangqing
6766e2db7c2SWu Liangqing #define AT_PERM_ATTR_FUSE 1
6776e2db7c2SWu Liangqing #define AT_PERM_ATTR_CER_FUSE 2
6786e2db7c2SWu Liangqing #define AT_LOCK_VBOOT 3
6796e2db7c2SWu Liangqing
rk_avb_write_perm_attr(u16 id,void * pbuf,u16 size)6806e2db7c2SWu Liangqing int rk_avb_write_perm_attr(u16 id, void *pbuf, u16 size)
6816e2db7c2SWu Liangqing {
6826e2db7c2SWu Liangqing uint8_t lock_state;
6836e2db7c2SWu Liangqing #ifndef CONFIG_ROCKCHIP_PRELOADER_PUB_KEY
6846e2db7c2SWu Liangqing sha256_context ctx;
6856e2db7c2SWu Liangqing uint8_t digest[SHA256_SUM_LEN] = {0};
6866e2db7c2SWu Liangqing uint8_t digest_temp[SHA256_SUM_LEN] = {0};
6876e2db7c2SWu Liangqing uint8_t perm_attr_temp[PERM_ATTR_TOTAL_SIZE] = {0};
6886e2db7c2SWu Liangqing uint8_t flag = 0;
6896e2db7c2SWu Liangqing #endif
6906e2db7c2SWu Liangqing
6916e2db7c2SWu Liangqing switch (id) {
6926e2db7c2SWu Liangqing case AT_PERM_ATTR_FUSE:
6936e2db7c2SWu Liangqing if (size != PERM_ATTR_TOTAL_SIZE) {
6946e2db7c2SWu Liangqing debug("%s Permanent attribute size is not equal!\n", __func__);
6956e2db7c2SWu Liangqing return -EINVAL;
6966e2db7c2SWu Liangqing }
6976e2db7c2SWu Liangqing
6986e2db7c2SWu Liangqing #ifndef CONFIG_ROCKCHIP_PRELOADER_PUB_KEY
6996e2db7c2SWu Liangqing if (rk_avb_read_perm_attr_flag(&flag)) {
7006e2db7c2SWu Liangqing debug("%s rk_avb_read_perm_attr_flag error!\n", __func__);
7016e2db7c2SWu Liangqing return -EIO;
7026e2db7c2SWu Liangqing }
7036e2db7c2SWu Liangqing
7046e2db7c2SWu Liangqing if (flag == PERM_ATTR_SUCCESS_FLAG) {
7056e2db7c2SWu Liangqing if (rk_avb_read_attribute_hash(digest_temp,
7066e2db7c2SWu Liangqing SHA256_SUM_LEN)) {
7076e2db7c2SWu Liangqing debug("%s The efuse IO can not be used!\n", __func__);
7086e2db7c2SWu Liangqing return -EIO;
7096e2db7c2SWu Liangqing }
7106e2db7c2SWu Liangqing
7116e2db7c2SWu Liangqing if (memcmp(digest, digest_temp, SHA256_SUM_LEN) != 0) {
7126e2db7c2SWu Liangqing if (rk_avb_read_permanent_attributes(perm_attr_temp,
7136e2db7c2SWu Liangqing PERM_ATTR_TOTAL_SIZE)) {
7146e2db7c2SWu Liangqing debug("%s rk_avb_write_permanent_attributes error!\n", __func__);
7156e2db7c2SWu Liangqing return -EIO;
7166e2db7c2SWu Liangqing }
7176e2db7c2SWu Liangqing
7186e2db7c2SWu Liangqing sha256_starts(&ctx);
7196e2db7c2SWu Liangqing sha256_update(&ctx,
7206e2db7c2SWu Liangqing (const uint8_t *)perm_attr_temp,
7216e2db7c2SWu Liangqing PERM_ATTR_TOTAL_SIZE);
7226e2db7c2SWu Liangqing sha256_finish(&ctx, digest);
7236e2db7c2SWu Liangqing if (memcmp(digest, digest_temp, SHA256_SUM_LEN) == 0) {
7246e2db7c2SWu Liangqing debug("%s The hash has been written!\n", __func__);
7256e2db7c2SWu Liangqing return 0;
7266e2db7c2SWu Liangqing }
7276e2db7c2SWu Liangqing }
7286e2db7c2SWu Liangqing
7296e2db7c2SWu Liangqing if (rk_avb_write_perm_attr_flag(0)) {
7306e2db7c2SWu Liangqing debug("%s Perm attr flag write failure\n", __func__);
7316e2db7c2SWu Liangqing return -EIO;
7326e2db7c2SWu Liangqing }
7336e2db7c2SWu Liangqing }
7346e2db7c2SWu Liangqing #endif
7356e2db7c2SWu Liangqing if (rk_avb_write_permanent_attributes((uint8_t *)
7366e2db7c2SWu Liangqing pbuf,
7376e2db7c2SWu Liangqing size)) {
7386e2db7c2SWu Liangqing if (rk_avb_write_perm_attr_flag(0)) {
7396e2db7c2SWu Liangqing debug("%s Perm attr flag write failure\n", __func__);
7406e2db7c2SWu Liangqing return -EIO;
7416e2db7c2SWu Liangqing }
7426e2db7c2SWu Liangqing
7436e2db7c2SWu Liangqing debug("%s Perm attr write failed\n", __func__);
7446e2db7c2SWu Liangqing return -EIO;
7456e2db7c2SWu Liangqing }
7466e2db7c2SWu Liangqing #ifndef CONFIG_ROCKCHIP_PRELOADER_PUB_KEY
7476e2db7c2SWu Liangqing memset(digest, 0, SHA256_SUM_LEN);
7486e2db7c2SWu Liangqing sha256_starts(&ctx);
7496e2db7c2SWu Liangqing sha256_update(&ctx, (const uint8_t *)pbuf,
7506e2db7c2SWu Liangqing PERM_ATTR_TOTAL_SIZE);
7516e2db7c2SWu Liangqing sha256_finish(&ctx, digest);
7526e2db7c2SWu Liangqing
7536e2db7c2SWu Liangqing if (rk_avb_write_attribute_hash((uint8_t *)digest,
7546e2db7c2SWu Liangqing SHA256_SUM_LEN)) {
7556e2db7c2SWu Liangqing if (rk_avb_read_attribute_hash(digest_temp,
7566e2db7c2SWu Liangqing SHA256_SUM_LEN)) {
7576e2db7c2SWu Liangqing debug("%s The efuse IO can not be used!\n", __func__);
7586e2db7c2SWu Liangqing return -EIO;
7596e2db7c2SWu Liangqing }
7606e2db7c2SWu Liangqing
7616e2db7c2SWu Liangqing if (memcmp(digest, digest_temp, SHA256_SUM_LEN) != 0) {
7626e2db7c2SWu Liangqing if (rk_avb_write_perm_attr_flag(0)) {
7636e2db7c2SWu Liangqing debug("%s Perm attr flag write failure\n", __func__);
7646e2db7c2SWu Liangqing return -EIO;
7656e2db7c2SWu Liangqing }
7666e2db7c2SWu Liangqing debug("%s The hash has been written, but is different!\n", __func__);
7676e2db7c2SWu Liangqing return -EIO;
7686e2db7c2SWu Liangqing }
7696e2db7c2SWu Liangqing }
7706e2db7c2SWu Liangqing #endif
7716e2db7c2SWu Liangqing if (rk_avb_write_perm_attr_flag(PERM_ATTR_SUCCESS_FLAG)) {
7726e2db7c2SWu Liangqing debug("%s, Perm attr flag write failure\n", __func__);
7736e2db7c2SWu Liangqing return -EIO;
7746e2db7c2SWu Liangqing }
7756e2db7c2SWu Liangqing
7766e2db7c2SWu Liangqing break;
7776e2db7c2SWu Liangqing case AT_PERM_ATTR_CER_FUSE:
7786e2db7c2SWu Liangqing if (size != 256) {
7796e2db7c2SWu Liangqing debug("%s Permanent attribute rsahash size is not equal!\n",
7806e2db7c2SWu Liangqing __func__);
7816e2db7c2SWu Liangqing return -EINVAL;
7826e2db7c2SWu Liangqing }
7836e2db7c2SWu Liangqing if (rk_avb_set_perm_attr_cer((uint8_t *)pbuf, size)) {
7846e2db7c2SWu Liangqing debug("%s FAILSet perm attr cer fail!\n", __func__);
7856e2db7c2SWu Liangqing return -EIO;
7866e2db7c2SWu Liangqing }
7876e2db7c2SWu Liangqing break;
7886e2db7c2SWu Liangqing case AT_LOCK_VBOOT:
7896e2db7c2SWu Liangqing lock_state = 0;
7906e2db7c2SWu Liangqing if (rk_avb_write_lock_state(lock_state)) {
7916e2db7c2SWu Liangqing debug("%s FAILwrite lock state failed\n", __func__);
7926e2db7c2SWu Liangqing return -EIO;
7936e2db7c2SWu Liangqing } else {
7946e2db7c2SWu Liangqing debug("%s OKAY\n", __func__);
7956e2db7c2SWu Liangqing }
7966e2db7c2SWu Liangqing break;
7976e2db7c2SWu Liangqing }
7986e2db7c2SWu Liangqing return 0;
7996e2db7c2SWu Liangqing }
8006e2db7c2SWu Liangqing
rk_avb_read_perm_attr(u16 id,void * pbuf,u16 size)8016e2db7c2SWu Liangqing int rk_avb_read_perm_attr(u16 id, void *pbuf, u16 size)
8026e2db7c2SWu Liangqing {
8036e2db7c2SWu Liangqing int ret = 0;
8046e2db7c2SWu Liangqing debug("%s %d\n", __func__, size);
8056e2db7c2SWu Liangqing
8066e2db7c2SWu Liangqing switch (id) {
8076e2db7c2SWu Liangqing case AT_PERM_ATTR_FUSE:
8086e2db7c2SWu Liangqing size = PERM_ATTR_TOTAL_SIZE;
8096e2db7c2SWu Liangqing ret = rk_avb_read_permanent_attributes((uint8_t *)pbuf, PERM_ATTR_TOTAL_SIZE);
8106e2db7c2SWu Liangqing break;
8116e2db7c2SWu Liangqing case AT_PERM_ATTR_CER_FUSE:
8126e2db7c2SWu Liangqing size = PERM_ATTR_TOTAL_SIZE;
8136e2db7c2SWu Liangqing ret = rk_avb_get_perm_attr_cer((uint8_t *)pbuf, 256);
8146e2db7c2SWu Liangqing break;
8156e2db7c2SWu Liangqing case AT_LOCK_VBOOT:
8166e2db7c2SWu Liangqing break;
8176e2db7c2SWu Liangqing }
8186e2db7c2SWu Liangqing
8196e2db7c2SWu Liangqing return ret;
8206e2db7c2SWu Liangqing }
8216e2db7c2SWu Liangqing
rk_avb_update_stored_rollback_indexes_for_slot(AvbOps * ops,AvbSlotVerifyData * slot_data)8222d62cca0SJason Zhu int rk_avb_update_stored_rollback_indexes_for_slot(AvbOps* ops, AvbSlotVerifyData* slot_data)
8232d62cca0SJason Zhu {
8242d62cca0SJason Zhu uint64_t rollback_index = slot_data->rollback_indexes[0];
8252d62cca0SJason Zhu uint64_t current_stored_rollback_index;
8262d62cca0SJason Zhu AvbIOResult io_ret;
8272d62cca0SJason Zhu
8282d62cca0SJason Zhu if (rollback_index > 0) {
8292d62cca0SJason Zhu io_ret = ops->read_rollback_index(ops, 0, ¤t_stored_rollback_index);
8302d62cca0SJason Zhu if (io_ret != AVB_IO_RESULT_OK)
8312d62cca0SJason Zhu return -1;
8322d62cca0SJason Zhu
8332d62cca0SJason Zhu if (rollback_index > current_stored_rollback_index) {
8342d62cca0SJason Zhu io_ret = ops->write_rollback_index(ops, 0, rollback_index);
8352d62cca0SJason Zhu if (io_ret != AVB_IO_RESULT_OK)
8362d62cca0SJason Zhu return -1;
8372d62cca0SJason Zhu }
8382d62cca0SJason Zhu }
8392d62cca0SJason Zhu
8402d62cca0SJason Zhu return 0;
8412d62cca0SJason Zhu }
842