xref: /rk3399_rockchip-uboot/lib/avb/libavb_user/avb_ops_user.c (revision 647502d6f747bc2f4db31c4d5855ffd2b34bd7f2)
137a7bc39SJason Zhu /*
237a7bc39SJason Zhu  * Copyright (C) 2017 The Android Open Source Project
337a7bc39SJason Zhu  *
437a7bc39SJason Zhu  * Permission is hereby granted, free of charge, to any person
537a7bc39SJason Zhu  * obtaining a copy of this software and associated documentation
637a7bc39SJason Zhu  * files (the "Software"), to deal in the Software without
737a7bc39SJason Zhu  * restriction, including without limitation the rights to use, copy,
837a7bc39SJason Zhu  * modify, merge, publish, distribute, sublicense, and/or sell copies
937a7bc39SJason Zhu  * of the Software, and to permit persons to whom the Software is
1037a7bc39SJason Zhu  * furnished to do so, subject to the following conditions:
1137a7bc39SJason Zhu  *
1237a7bc39SJason Zhu  * The above copyright notice and this permission notice shall be
1337a7bc39SJason Zhu  * included in all copies or substantial portions of the Software.
1437a7bc39SJason Zhu  *
1537a7bc39SJason Zhu  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1637a7bc39SJason Zhu  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1737a7bc39SJason Zhu  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1837a7bc39SJason Zhu  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
1937a7bc39SJason Zhu  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2037a7bc39SJason Zhu  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2137a7bc39SJason Zhu  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2237a7bc39SJason Zhu  * SOFTWARE.
2337a7bc39SJason Zhu  */
2437a7bc39SJason Zhu 
2537a7bc39SJason Zhu #include <common.h>
2637a7bc39SJason Zhu #include <image.h>
2737a7bc39SJason Zhu #include <android_image.h>
2837a7bc39SJason Zhu #include <malloc.h>
2937a7bc39SJason Zhu #include <mapmem.h>
3037a7bc39SJason Zhu #include <errno.h>
3137a7bc39SJason Zhu #include <command.h>
3237a7bc39SJason Zhu #include <mmc.h>
3337a7bc39SJason Zhu #include <blk.h>
3437a7bc39SJason Zhu #include <part.h>
3516a62313SJason Zhu #include <stdio.h>
3637a7bc39SJason Zhu #include <android_avb/avb_ops_user.h>
3737a7bc39SJason Zhu #include <android_avb/libavb_ab.h>
3837a7bc39SJason Zhu #include <android_avb/avb_atx_validate.h>
3937a7bc39SJason Zhu #include <android_avb/avb_atx_types.h>
4037a7bc39SJason Zhu #include <optee_include/OpteeClientInterface.h>
4137a7bc39SJason Zhu #include <optee_include/tee_api_defines.h>
4237a7bc39SJason Zhu #include <android_avb/avb_vbmeta_image.h>
4337a7bc39SJason Zhu #include <android_avb/avb_atx_validate.h>
44459bc933SJason Zhu #include <boot_rkimg.h>
4537a7bc39SJason Zhu 
4637a7bc39SJason Zhu static void byte_to_block(int64_t *offset,
4737a7bc39SJason Zhu 			  size_t *num_bytes,
4837a7bc39SJason Zhu 			  lbaint_t *offset_blk,
4937a7bc39SJason Zhu 			  lbaint_t *blkcnt)
5037a7bc39SJason Zhu {
5137a7bc39SJason Zhu 	*offset_blk = (lbaint_t)(*offset / 512);
5237a7bc39SJason Zhu 	if (*num_bytes % 512 == 0) {
537c1937d6SJason Zhu 		if (*offset % 512 == 0)
5437a7bc39SJason Zhu 			*blkcnt = (lbaint_t)(*num_bytes / 512);
557c1937d6SJason Zhu 		else
5637a7bc39SJason Zhu 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
5737a7bc39SJason Zhu 	} else {
5837a7bc39SJason Zhu 		if (*offset % 512 == 0) {
5937a7bc39SJason Zhu 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
6037a7bc39SJason Zhu 		} else {
6137a7bc39SJason Zhu 			if ((*offset % 512) + (*num_bytes % 512) < 512 ||
6237a7bc39SJason Zhu 			    (*offset % 512) + (*num_bytes % 512) == 512) {
6337a7bc39SJason Zhu 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
6437a7bc39SJason Zhu 			} else {
6537a7bc39SJason Zhu 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 2;
6637a7bc39SJason Zhu 			}
6737a7bc39SJason Zhu 		}
6837a7bc39SJason Zhu 	}
6937a7bc39SJason Zhu }
7037a7bc39SJason Zhu 
7116a62313SJason Zhu static AvbIOResult get_size_of_partition(AvbOps *ops,
7216a62313SJason Zhu 					 const char *partition,
7316a62313SJason Zhu 					 uint64_t *out_size_in_bytes)
7416a62313SJason Zhu {
7516a62313SJason Zhu 	struct blk_desc *dev_desc;
7616a62313SJason Zhu 	disk_partition_t part_info;
7716a62313SJason Zhu 
7816a62313SJason Zhu 	dev_desc = rockchip_get_bootdev();
7916a62313SJason Zhu 	if (!dev_desc) {
8016a62313SJason Zhu 		printf("%s: Could not find device\n", __func__);
8116a62313SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
8216a62313SJason Zhu 	}
8316a62313SJason Zhu 
8416a62313SJason Zhu 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
8516a62313SJason Zhu 		printf("Could not find \"%s\" partition\n", partition);
8616a62313SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
8716a62313SJason Zhu 	}
8816a62313SJason Zhu 	*out_size_in_bytes = (part_info.size) * 512;
8916a62313SJason Zhu 	return AVB_IO_RESULT_OK;
9016a62313SJason Zhu }
9116a62313SJason Zhu 
9237a7bc39SJason Zhu static AvbIOResult read_from_partition(AvbOps *ops,
9337a7bc39SJason Zhu 				       const char *partition,
9437a7bc39SJason Zhu 				       int64_t offset,
9537a7bc39SJason Zhu 				       size_t num_bytes,
9637a7bc39SJason Zhu 				       void *buffer,
9737a7bc39SJason Zhu 				       size_t *out_num_read)
9837a7bc39SJason Zhu {
9937a7bc39SJason Zhu 	struct blk_desc *dev_desc;
10037a7bc39SJason Zhu 	lbaint_t offset_blk, blkcnt;
10137a7bc39SJason Zhu 	disk_partition_t part_info;
10216a62313SJason Zhu 	uint64_t partition_size;
10316a62313SJason Zhu 
10416a62313SJason Zhu 	if (offset < 0) {
10516a62313SJason Zhu 		if (get_size_of_partition(ops, partition, &partition_size))
10616a62313SJason Zhu 			return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
10716a62313SJason Zhu 
10816a62313SJason Zhu 		if (-offset > partition_size)
10916a62313SJason Zhu 			return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
11016a62313SJason Zhu 
11116a62313SJason Zhu 		offset = partition_size - (-offset);
11216a62313SJason Zhu 	}
11337a7bc39SJason Zhu 
11437a7bc39SJason Zhu 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
115459bc933SJason Zhu 	dev_desc = rockchip_get_bootdev();
11637a7bc39SJason Zhu 	if (!dev_desc) {
117459bc933SJason Zhu 		printf("%s: Could not find device\n", __func__);
11837a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
11937a7bc39SJason Zhu 	}
12037a7bc39SJason Zhu 
12137a7bc39SJason Zhu 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
12237a7bc39SJason Zhu 		printf("Could not find \"%s\" partition\n", partition);
12337a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
12437a7bc39SJason Zhu 	}
12537a7bc39SJason Zhu 
12637a7bc39SJason Zhu 	if ((offset % 512 == 0) && (num_bytes % 512 == 0)) {
1277c1937d6SJason Zhu 		blk_dread(dev_desc, part_info.start + offset_blk,
1287c1937d6SJason Zhu 			  blkcnt, buffer);
12937a7bc39SJason Zhu 		*out_num_read = blkcnt * 512;
13037a7bc39SJason Zhu 	} else {
13137a7bc39SJason Zhu 		char *buffer_temp;
1327c1937d6SJason Zhu 
13337a7bc39SJason Zhu 		buffer_temp = malloc(512 * blkcnt);
1347c1937d6SJason Zhu 		if (!buffer_temp) {
13537a7bc39SJason Zhu 			printf("malloc error!\n");
13637a7bc39SJason Zhu 			return AVB_IO_RESULT_ERROR_OOM;
13737a7bc39SJason Zhu 		}
1387c1937d6SJason Zhu 		blk_dread(dev_desc, part_info.start + offset_blk,
1397c1937d6SJason Zhu 			  blkcnt, buffer_temp);
14037a7bc39SJason Zhu 		memcpy(buffer, buffer_temp + (offset % 512), num_bytes);
14137a7bc39SJason Zhu 		*out_num_read = num_bytes;
14237a7bc39SJason Zhu 		free(buffer_temp);
14337a7bc39SJason Zhu 	}
14437a7bc39SJason Zhu 
14537a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
14637a7bc39SJason Zhu }
14737a7bc39SJason Zhu 
14837a7bc39SJason Zhu static AvbIOResult write_to_partition(AvbOps *ops,
14937a7bc39SJason Zhu 				      const char *partition,
15037a7bc39SJason Zhu 				      int64_t offset,
15137a7bc39SJason Zhu 				      size_t num_bytes,
15237a7bc39SJason Zhu 				      const void *buffer)
15337a7bc39SJason Zhu {
15437a7bc39SJason Zhu 	struct blk_desc *dev_desc;
15537a7bc39SJason Zhu 	char *buffer_temp;
15637a7bc39SJason Zhu 	disk_partition_t part_info;
15737a7bc39SJason Zhu 	lbaint_t offset_blk, blkcnt;
15837a7bc39SJason Zhu 
15937a7bc39SJason Zhu 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
16037a7bc39SJason Zhu 	buffer_temp = malloc(512 * blkcnt);
1617c1937d6SJason Zhu 	if (!buffer_temp) {
16237a7bc39SJason Zhu 		printf("malloc error!\n");
16337a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_OOM;
16437a7bc39SJason Zhu 	}
16537a7bc39SJason Zhu 	memset(buffer_temp, 0, 512 * blkcnt);
166459bc933SJason Zhu 	dev_desc = rockchip_get_bootdev();
16737a7bc39SJason Zhu 	if (!dev_desc) {
168459bc933SJason Zhu 		printf("%s: Could not find device\n", __func__);
16937a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
17037a7bc39SJason Zhu 	}
17137a7bc39SJason Zhu 
17237a7bc39SJason Zhu 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
17337a7bc39SJason Zhu 		printf("Could not find \"%s\" partition\n", partition);
17437a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
17537a7bc39SJason Zhu 	}
17637a7bc39SJason Zhu 
1777c1937d6SJason Zhu 	if ((offset % 512 != 0) && (num_bytes % 512) != 0)
1787c1937d6SJason Zhu 		blk_dread(dev_desc, part_info.start + offset_blk,
1797c1937d6SJason Zhu 			  blkcnt, buffer_temp);
18037a7bc39SJason Zhu 
18137a7bc39SJason Zhu 	memcpy(buffer_temp, buffer + (offset % 512), num_bytes);
18237a7bc39SJason Zhu 	blk_dwrite(dev_desc, part_info.start + offset_blk, blkcnt, buffer);
18337a7bc39SJason Zhu 	free(buffer_temp);
18437a7bc39SJason Zhu 
18537a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
18637a7bc39SJason Zhu }
18737a7bc39SJason Zhu 
1887c1937d6SJason Zhu static AvbIOResult
1897c1937d6SJason Zhu validate_vbmeta_public_key(AvbOps *ops,
19037a7bc39SJason Zhu 			   const uint8_t *public_key_data,
19137a7bc39SJason Zhu 			   size_t public_key_length,
19237a7bc39SJason Zhu 			   const uint8_t *public_key_metadata,
19337a7bc39SJason Zhu 			   size_t public_key_metadata_length,
19437a7bc39SJason Zhu 			   bool *out_is_trusted)
19537a7bc39SJason Zhu {
196caed6b4fSJoseph Chen /* remain AVB_VBMETA_PUBLIC_KEY_VALIDATE to compatible legacy code */
197caed6b4fSJoseph Chen #if defined(CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE) || \
198caed6b4fSJoseph Chen     defined(AVB_VBMETA_PUBLIC_KEY_VALIDATE)
1997c1937d6SJason Zhu 	if (out_is_trusted) {
20037a7bc39SJason Zhu 		avb_atx_validate_vbmeta_public_key(ops,
20137a7bc39SJason Zhu 						   public_key_data,
20237a7bc39SJason Zhu 						   public_key_length,
20337a7bc39SJason Zhu 						   public_key_metadata,
20437a7bc39SJason Zhu 						   public_key_metadata_length,
20537a7bc39SJason Zhu 						   out_is_trusted);
20637a7bc39SJason Zhu 	}
20737a7bc39SJason Zhu #else
2087c1937d6SJason Zhu 	if (out_is_trusted)
20937a7bc39SJason Zhu 		*out_is_trusted = true;
21037a7bc39SJason Zhu #endif
21137a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
21237a7bc39SJason Zhu }
21337a7bc39SJason Zhu 
21437a7bc39SJason Zhu static AvbIOResult read_rollback_index(AvbOps *ops,
21537a7bc39SJason Zhu 				       size_t rollback_index_location,
21637a7bc39SJason Zhu 				       uint64_t *out_rollback_index)
21737a7bc39SJason Zhu {
2187c1937d6SJason Zhu 	if (out_rollback_index) {
21937a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
22037a7bc39SJason Zhu 		int ret;
2217c1937d6SJason Zhu 
22237a7bc39SJason Zhu 		ret = trusty_read_rollback_index(rollback_index_location,
22337a7bc39SJason Zhu 						 out_rollback_index);
2247c1937d6SJason Zhu 		switch (ret) {
2257c1937d6SJason Zhu 		case TEE_SUCCESS:
2267c1937d6SJason Zhu 			ret = AVB_IO_RESULT_OK;
2277c1937d6SJason Zhu 			break;
2287c1937d6SJason Zhu 		case TEE_ERROR_GENERIC:
2297c1937d6SJason Zhu 		case TEE_ERROR_NO_DATA:
2307c1937d6SJason Zhu 		case TEE_ERROR_ITEM_NOT_FOUND:
23137a7bc39SJason Zhu 			*out_rollback_index = 0;
23237a7bc39SJason Zhu 			ret = trusty_write_rollback_index(rollback_index_location,
23337a7bc39SJason Zhu 							  *out_rollback_index);
2347c1937d6SJason Zhu 			if (ret) {
2357c1937d6SJason Zhu 				printf("%s: init rollback index error\n",
2367c1937d6SJason Zhu 				       __FILE__);
2377c1937d6SJason Zhu 				ret = AVB_IO_RESULT_ERROR_IO;
23837a7bc39SJason Zhu 			} else {
2397c1937d6SJason Zhu 				ret =
2407c1937d6SJason Zhu 				trusty_read_rollback_index(rollback_index_location,
2417c1937d6SJason Zhu 							   out_rollback_index);
2427c1937d6SJason Zhu 				if (ret)
2437c1937d6SJason Zhu 					ret = AVB_IO_RESULT_ERROR_IO;
2447c1937d6SJason Zhu 				else
2457c1937d6SJason Zhu 					ret = AVB_IO_RESULT_OK;
24637a7bc39SJason Zhu 			}
2477c1937d6SJason Zhu 			break;
2487c1937d6SJason Zhu 		default:
2497c1937d6SJason Zhu 			ret = AVB_IO_RESULT_ERROR_IO;
2507c1937d6SJason Zhu 			printf("%s: trusty_read_rollback_index failed",
2517c1937d6SJason Zhu 			       __FILE__);
2527c1937d6SJason Zhu 		}
2537c1937d6SJason Zhu 
2547c1937d6SJason Zhu 		return ret;
255ae205b95SJoseph Chen #else
256ae205b95SJoseph Chen 		*out_rollback_index = 0;
257ae205b95SJoseph Chen 
258ae205b95SJoseph Chen 		return AVB_IO_RESULT_OK;
25937a7bc39SJason Zhu #endif
26037a7bc39SJason Zhu 	}
261ae205b95SJoseph Chen 
26237a7bc39SJason Zhu 	return AVB_IO_RESULT_ERROR_IO;
26337a7bc39SJason Zhu }
26437a7bc39SJason Zhu 
26537a7bc39SJason Zhu static AvbIOResult write_rollback_index(AvbOps *ops,
26637a7bc39SJason Zhu 					size_t rollback_index_location,
26737a7bc39SJason Zhu 					uint64_t rollback_index)
26837a7bc39SJason Zhu {
26937a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
2707c1937d6SJason Zhu 	if (trusty_write_rollback_index(rollback_index_location,
2717c1937d6SJason Zhu 					rollback_index)) {
27237a7bc39SJason Zhu 		printf("%s: Fail to write rollback index\n", __FILE__);
27337a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_IO;
27437a7bc39SJason Zhu 	}
27537a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
27637a7bc39SJason Zhu #endif
27737a7bc39SJason Zhu 	return AVB_IO_RESULT_ERROR_IO;
27837a7bc39SJason Zhu }
27937a7bc39SJason Zhu 
28037a7bc39SJason Zhu static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
28137a7bc39SJason Zhu {
2827c1937d6SJason Zhu 	if (out_is_unlocked) {
28337a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
28437a7bc39SJason Zhu 		int ret;
28537a7bc39SJason Zhu 
28637a7bc39SJason Zhu 		ret = trusty_read_lock_state((uint8_t *)out_is_unlocked);
2877c1937d6SJason Zhu 		switch (ret) {
2887c1937d6SJason Zhu 		case TEE_SUCCESS:
2897c1937d6SJason Zhu 			ret = AVB_IO_RESULT_OK;
2907c1937d6SJason Zhu 			break;
2917c1937d6SJason Zhu 		case TEE_ERROR_GENERIC:
2927c1937d6SJason Zhu 		case TEE_ERROR_NO_DATA:
2937c1937d6SJason Zhu 		case TEE_ERROR_ITEM_NOT_FOUND:
29437a7bc39SJason Zhu 			*out_is_unlocked = 1;
29537a7bc39SJason Zhu 			if (trusty_write_lock_state(*out_is_unlocked)) {
29637a7bc39SJason Zhu 				printf("%s: init lock state error\n", __FILE__);
2977c1937d6SJason Zhu 				ret = AVB_IO_RESULT_ERROR_IO;
29837a7bc39SJason Zhu 			} else {
2997c1937d6SJason Zhu 				ret =
3007c1937d6SJason Zhu 				trusty_read_lock_state((uint8_t *)out_is_unlocked);
3017c1937d6SJason Zhu 				if (ret == 0)
3027c1937d6SJason Zhu 					ret = AVB_IO_RESULT_OK;
3037c1937d6SJason Zhu 				else
3047c1937d6SJason Zhu 					ret = AVB_IO_RESULT_ERROR_IO;
30537a7bc39SJason Zhu 			}
3067c1937d6SJason Zhu 			break;
3077c1937d6SJason Zhu 		default:
3087c1937d6SJason Zhu 			ret = AVB_IO_RESULT_ERROR_IO;
3097c1937d6SJason Zhu 			printf("%s: trusty_read_lock_state failed\n", __FILE__);
3107c1937d6SJason Zhu 		}
3117c1937d6SJason Zhu 		return ret;
312ae205b95SJoseph Chen #else
313ae205b95SJoseph Chen 		*out_is_unlocked = 1;
314ae205b95SJoseph Chen 
315ae205b95SJoseph Chen 		return AVB_IO_RESULT_OK;
31637a7bc39SJason Zhu #endif
31737a7bc39SJason Zhu 	}
31837a7bc39SJason Zhu 	return AVB_IO_RESULT_ERROR_IO;
31937a7bc39SJason Zhu }
32037a7bc39SJason Zhu 
32137a7bc39SJason Zhu static AvbIOResult write_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
32237a7bc39SJason Zhu {
3237c1937d6SJason Zhu 	if (out_is_unlocked) {
32437a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
32537a7bc39SJason Zhu 		if (trusty_write_lock_state(*out_is_unlocked)) {
32637a7bc39SJason Zhu 			printf("%s: Fail to write lock state\n", __FILE__);
32737a7bc39SJason Zhu 			return AVB_IO_RESULT_ERROR_IO;
32837a7bc39SJason Zhu 		}
32937a7bc39SJason Zhu 		return AVB_IO_RESULT_OK;
33037a7bc39SJason Zhu #endif
33137a7bc39SJason Zhu 	}
33237a7bc39SJason Zhu 	return AVB_IO_RESULT_ERROR_IO;
33337a7bc39SJason Zhu }
33437a7bc39SJason Zhu 
33537a7bc39SJason Zhu static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
33637a7bc39SJason Zhu 						 const char *partition,
33737a7bc39SJason Zhu 						 char *guid_buf,
33837a7bc39SJason Zhu 						 size_t guid_buf_size)
33937a7bc39SJason Zhu {
34037a7bc39SJason Zhu 	struct blk_desc *dev_desc;
34137a7bc39SJason Zhu 	disk_partition_t part_info;
3427c1937d6SJason Zhu 
343459bc933SJason Zhu 	dev_desc = rockchip_get_bootdev();
34437a7bc39SJason Zhu 	if (!dev_desc) {
345459bc933SJason Zhu 		printf("%s: Could not find device\n", __func__);
34637a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
34737a7bc39SJason Zhu 	}
34837a7bc39SJason Zhu 
34937a7bc39SJason Zhu 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
35037a7bc39SJason Zhu 		printf("Could not find \"%s\" partition\n", partition);
35137a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
35237a7bc39SJason Zhu 	}
3537c1937d6SJason Zhu 	if (guid_buf && guid_buf_size > 0)
35437a7bc39SJason Zhu 		memcpy(guid_buf, part_info.uuid, guid_buf_size);
3557c1937d6SJason Zhu 
35637a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
35737a7bc39SJason Zhu }
35837a7bc39SJason Zhu 
35937a7bc39SJason Zhu /* read permanent attributes from rpmb */
36037a7bc39SJason Zhu AvbIOResult avb_read_perm_attr(AvbAtxOps *atx_ops,
36137a7bc39SJason Zhu 			       AvbAtxPermanentAttributes *attributes)
36237a7bc39SJason Zhu {
3637c1937d6SJason Zhu 	if (attributes) {
36437a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
36537a7bc39SJason Zhu 		trusty_read_permanent_attributes((uint8_t *)attributes,
36637a7bc39SJason Zhu 						 sizeof(struct AvbAtxPermanentAttributes));
36737a7bc39SJason Zhu 		return AVB_IO_RESULT_OK;
36837a7bc39SJason Zhu #endif
36937a7bc39SJason Zhu 	}
37037a7bc39SJason Zhu 
37137a7bc39SJason Zhu 	return -1;
37237a7bc39SJason Zhu }
37337a7bc39SJason Zhu 
37437a7bc39SJason Zhu /*read permanent attributes hash from efuse */
37537a7bc39SJason Zhu AvbIOResult avb_read_perm_attr_hash(AvbAtxOps *atx_ops,
37637a7bc39SJason Zhu 				    uint8_t hash[AVB_SHA256_DIGEST_SIZE])
37737a7bc39SJason Zhu {
37874b485fbSJason Zhu #ifndef CONFIG_ROCKCHIP_PRELOADER_PUB_KEY
37937a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
3807c1937d6SJason Zhu 	if (trusty_read_attribute_hash((uint32_t *)hash,
3817c1937d6SJason Zhu 				       AVB_SHA256_DIGEST_SIZE / 4))
38237a7bc39SJason Zhu 		return -1;
38337a7bc39SJason Zhu #else
384*647502d6SJason Zhu 	printf("Please open the macro!\n");
38537a7bc39SJason Zhu 	return -1;
38637a7bc39SJason Zhu #endif
38765f0143bSJason Zhu #endif
38837a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
38937a7bc39SJason Zhu }
39037a7bc39SJason Zhu 
39182e713e1SJason Zhu static void avb_set_key_version(AvbAtxOps *atx_ops,
39282e713e1SJason Zhu 				size_t rollback_index_location,
39382e713e1SJason Zhu 				uint64_t key_version)
39482e713e1SJason Zhu {
39582e713e1SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
396ee9d3433SJason Zhu 	uint64_t key_version_temp = 0;
397ee9d3433SJason Zhu 
398ee9d3433SJason Zhu 	if (trusty_read_rollback_index(rollback_index_location, &key_version_temp))
399ee9d3433SJason Zhu 		printf("%s: Fail to read rollback index\n", __FILE__);
400ee9d3433SJason Zhu 	if (key_version_temp == key_version)
401ee9d3433SJason Zhu 		return;
4027c1937d6SJason Zhu 	if (trusty_write_rollback_index(rollback_index_location, key_version))
40382e713e1SJason Zhu 		printf("%s: Fail to write rollback index\n", __FILE__);
40482e713e1SJason Zhu #endif
40582e713e1SJason Zhu }
40682e713e1SJason Zhu 
4078d0db1d9SJason Zhu AvbIOResult rk_get_random(AvbAtxOps *atx_ops,
4088d0db1d9SJason Zhu 			  size_t num_bytes,
4098d0db1d9SJason Zhu 			  uint8_t *output)
4108d0db1d9SJason Zhu {
4118d0db1d9SJason Zhu 	int i;
4128d0db1d9SJason Zhu 	unsigned int seed;
4138d0db1d9SJason Zhu 
4148d0db1d9SJason Zhu 	seed = (unsigned int)get_timer(0);
4158d0db1d9SJason Zhu 	for (i = 0; i < num_bytes; i++) {
4168d0db1d9SJason Zhu 		srand(seed);
4178d0db1d9SJason Zhu 		output[i] = (uint8_t)(rand());
4188d0db1d9SJason Zhu 		seed = (unsigned int)(output[i]);
4198d0db1d9SJason Zhu 	}
4208d0db1d9SJason Zhu 
4218d0db1d9SJason Zhu 	return 0;
4228d0db1d9SJason Zhu }
4238d0db1d9SJason Zhu 
42427e62cd7SJoseph Chen #ifdef CONFIG_ANDROID_BOOT_IMAGE
42527e62cd7SJoseph Chen static AvbIOResult get_preloaded_partition(AvbOps* ops,
42627e62cd7SJoseph Chen 					   const char* partition,
42727e62cd7SJoseph Chen 					   size_t num_bytes,
42827e62cd7SJoseph Chen 					   uint8_t** out_pointer,
42927e62cd7SJoseph Chen 					   size_t* out_num_bytes_preloaded,
43027e62cd7SJoseph Chen 					   int allow_verification_error)
43127e62cd7SJoseph Chen {
43227e62cd7SJoseph Chen 	struct blk_desc *dev_desc;
43327e62cd7SJoseph Chen 	ulong load_addr;
43427e62cd7SJoseph Chen 	int ret;
43527e62cd7SJoseph Chen 
43627e62cd7SJoseph Chen 	/* no need go further */
43727e62cd7SJoseph Chen 	if (!allow_verification_error)
43827e62cd7SJoseph Chen 		return AVB_IO_RESULT_OK;
43927e62cd7SJoseph Chen 
44027e62cd7SJoseph Chen 	printf("get image from preloaded partition...\n");
44127e62cd7SJoseph Chen 	dev_desc = rockchip_get_bootdev();
44227e62cd7SJoseph Chen 	if (!dev_desc)
4431e9494b5SJoseph Chen 	    return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
44427e62cd7SJoseph Chen 
44527e62cd7SJoseph Chen 	load_addr = env_get_ulong("kernel_addr_r", 16, 0);
44627e62cd7SJoseph Chen 	if (!load_addr)
4471e9494b5SJoseph Chen 		return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE;
44827e62cd7SJoseph Chen 
44927e62cd7SJoseph Chen 	ret = android_image_load_by_partname(dev_desc, partition, &load_addr);
45027e62cd7SJoseph Chen 	if (!ret) {
45127e62cd7SJoseph Chen 		*out_pointer = (u8 *)load_addr;
45227e62cd7SJoseph Chen 		*out_num_bytes_preloaded = num_bytes; /* return what it expects */
4531e9494b5SJoseph Chen 		ret = AVB_IO_RESULT_OK;
45427e62cd7SJoseph Chen 	} else {
4551e9494b5SJoseph Chen 		ret = AVB_IO_RESULT_ERROR_IO;
45627e62cd7SJoseph Chen 	}
45727e62cd7SJoseph Chen 
45827e62cd7SJoseph Chen 	return ret;
45927e62cd7SJoseph Chen }
46027e62cd7SJoseph Chen #endif
46127e62cd7SJoseph Chen 
46216a62313SJason Zhu AvbIOResult validate_public_key_for_partition(AvbOps *ops,
46316a62313SJason Zhu 					      const char *partition,
46416a62313SJason Zhu 					      const uint8_t *public_key_data,
46516a62313SJason Zhu 					      size_t public_key_length,
46616a62313SJason Zhu 					      const uint8_t *public_key_metadata,
46716a62313SJason Zhu 					      size_t public_key_metadata_length,
46816a62313SJason Zhu 					      bool *out_is_trusted,
46916a62313SJason Zhu 					      uint32_t *out_rollback_index_location)
47016a62313SJason Zhu {
47116a62313SJason Zhu /* remain AVB_VBMETA_PUBLIC_KEY_VALIDATE to compatible legacy code */
47216a62313SJason Zhu #if defined(CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE) || \
47316a62313SJason Zhu     defined(AVB_VBMETA_PUBLIC_KEY_VALIDATE)
47416a62313SJason Zhu 	if (out_is_trusted) {
47516a62313SJason Zhu 		avb_atx_validate_vbmeta_public_key(ops,
47616a62313SJason Zhu 						   public_key_data,
47716a62313SJason Zhu 						   public_key_length,
47816a62313SJason Zhu 						   public_key_metadata,
47916a62313SJason Zhu 						   public_key_metadata_length,
48016a62313SJason Zhu 						   out_is_trusted);
48116a62313SJason Zhu 	}
48216a62313SJason Zhu #else
48316a62313SJason Zhu 	if (out_is_trusted)
48416a62313SJason Zhu 		*out_is_trusted = true;
48516a62313SJason Zhu #endif
48616a62313SJason Zhu 	*out_rollback_index_location = 0;
48716a62313SJason Zhu 	return AVB_IO_RESULT_OK;
48816a62313SJason Zhu }
48916a62313SJason Zhu 
4907c1937d6SJason Zhu AvbOps *avb_ops_user_new(void)
4917c1937d6SJason Zhu {
49237a7bc39SJason Zhu 	AvbOps *ops;
49337a7bc39SJason Zhu 
49437a7bc39SJason Zhu 	ops = calloc(1, sizeof(AvbOps));
4957c1937d6SJason Zhu 	if (!ops) {
49608f7f19aSJason Zhu 		printf("Error allocating memory for AvbOps.\n");
49737a7bc39SJason Zhu 		goto out;
49837a7bc39SJason Zhu 	}
49937a7bc39SJason Zhu 	ops->ab_ops = calloc(1, sizeof(AvbABOps));
5007c1937d6SJason Zhu 	if (!ops->ab_ops) {
50108f7f19aSJason Zhu 		printf("Error allocating memory for AvbABOps.\n");
50237a7bc39SJason Zhu 		free(ops);
50337a7bc39SJason Zhu 		goto out;
50437a7bc39SJason Zhu 	}
50537a7bc39SJason Zhu 
50637a7bc39SJason Zhu 	ops->atx_ops = calloc(1, sizeof(AvbAtxOps));
5077c1937d6SJason Zhu 	if (!ops->atx_ops) {
50808f7f19aSJason Zhu 		printf("Error allocating memory for AvbAtxOps.\n");
50937a7bc39SJason Zhu 		free(ops->ab_ops);
51037a7bc39SJason Zhu 		free(ops);
51137a7bc39SJason Zhu 		goto out;
51237a7bc39SJason Zhu 	}
51337a7bc39SJason Zhu 	ops->ab_ops->ops = ops;
51437a7bc39SJason Zhu 	ops->atx_ops->ops = ops;
51537a7bc39SJason Zhu 
51637a7bc39SJason Zhu 	ops->read_from_partition = read_from_partition;
51737a7bc39SJason Zhu 	ops->write_to_partition = write_to_partition;
51837a7bc39SJason Zhu 	ops->validate_vbmeta_public_key = validate_vbmeta_public_key;
51937a7bc39SJason Zhu 	ops->read_rollback_index = read_rollback_index;
52037a7bc39SJason Zhu 	ops->write_rollback_index = write_rollback_index;
52137a7bc39SJason Zhu 	ops->read_is_device_unlocked = read_is_device_unlocked;
52237a7bc39SJason Zhu 	ops->write_is_device_unlocked = write_is_device_unlocked;
52337a7bc39SJason Zhu 	ops->get_unique_guid_for_partition = get_unique_guid_for_partition;
52437a7bc39SJason Zhu 	ops->get_size_of_partition = get_size_of_partition;
52527e62cd7SJoseph Chen #ifdef CONFIG_ANDROID_BOOT_IMAGE
52627e62cd7SJoseph Chen 	ops->get_preloaded_partition = get_preloaded_partition;
52727e62cd7SJoseph Chen #endif
52816a62313SJason Zhu 	ops->validate_public_key_for_partition = validate_public_key_for_partition;
52937a7bc39SJason Zhu 	ops->ab_ops->read_ab_metadata = avb_ab_data_read;
53037a7bc39SJason Zhu 	ops->ab_ops->write_ab_metadata = avb_ab_data_write;
53137a7bc39SJason Zhu 	ops->atx_ops->read_permanent_attributes = avb_read_perm_attr;
53237a7bc39SJason Zhu 	ops->atx_ops->read_permanent_attributes_hash = avb_read_perm_attr_hash;
53382e713e1SJason Zhu 	ops->atx_ops->set_key_version = avb_set_key_version;
5348d0db1d9SJason Zhu 	ops->atx_ops->get_random = rk_get_random;
53537a7bc39SJason Zhu 
53637a7bc39SJason Zhu out:
53737a7bc39SJason Zhu 	return ops;
53837a7bc39SJason Zhu }
53937a7bc39SJason Zhu 
5407c1937d6SJason Zhu void avb_ops_user_free(AvbOps *ops)
5417c1937d6SJason Zhu {
54237a7bc39SJason Zhu 	free(ops->ab_ops);
54337a7bc39SJason Zhu 	free(ops->atx_ops);
54437a7bc39SJason Zhu 	free(ops);
54537a7bc39SJason Zhu }
546