xref: /rk3399_rockchip-uboot/lib/avb/libavb_user/avb_ops_user.c (revision 7c1937d6d1c7daf8e59b4760f8adc7ee42bd7bea)
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>
3537a7bc39SJason Zhu #include <android_avb/avb_ops_user.h>
3637a7bc39SJason Zhu #include <android_avb/libavb_ab.h>
3737a7bc39SJason Zhu #include <android_avb/avb_atx_validate.h>
3837a7bc39SJason Zhu #include <android_avb/avb_atx_types.h>
3937a7bc39SJason Zhu #include <optee_include/OpteeClientInterface.h>
4037a7bc39SJason Zhu #include <optee_include/tee_api_defines.h>
4137a7bc39SJason Zhu #include <android_avb/avb_vbmeta_image.h>
4237a7bc39SJason Zhu #include <android_avb/avb_atx_validate.h>
43459bc933SJason Zhu #include <boot_rkimg.h>
4437a7bc39SJason Zhu 
4537a7bc39SJason Zhu static void byte_to_block(int64_t *offset,
4637a7bc39SJason Zhu 			  size_t *num_bytes,
4737a7bc39SJason Zhu 			  lbaint_t *offset_blk,
4837a7bc39SJason Zhu 			  lbaint_t *blkcnt)
4937a7bc39SJason Zhu {
5037a7bc39SJason Zhu 	*offset_blk = (lbaint_t)(*offset / 512);
5137a7bc39SJason Zhu 	if (*num_bytes % 512 == 0) {
52*7c1937d6SJason Zhu 		if (*offset % 512 == 0)
5337a7bc39SJason Zhu 			*blkcnt = (lbaint_t)(*num_bytes / 512);
54*7c1937d6SJason Zhu 		else
5537a7bc39SJason Zhu 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
5637a7bc39SJason Zhu 	} else {
5737a7bc39SJason Zhu 		if (*offset % 512 == 0) {
5837a7bc39SJason Zhu 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
5937a7bc39SJason Zhu 		} else {
6037a7bc39SJason Zhu 			if ((*offset % 512) + (*num_bytes % 512) < 512 ||
6137a7bc39SJason Zhu 			    (*offset % 512) + (*num_bytes % 512) == 512) {
6237a7bc39SJason Zhu 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
6337a7bc39SJason Zhu 			} else {
6437a7bc39SJason Zhu 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 2;
6537a7bc39SJason Zhu 			}
6637a7bc39SJason Zhu 		}
6737a7bc39SJason Zhu 	}
6837a7bc39SJason Zhu }
6937a7bc39SJason Zhu 
7037a7bc39SJason Zhu static AvbIOResult read_from_partition(AvbOps *ops,
7137a7bc39SJason Zhu 				       const char *partition,
7237a7bc39SJason Zhu 				       int64_t offset,
7337a7bc39SJason Zhu 				       size_t num_bytes,
7437a7bc39SJason Zhu 				       void *buffer,
7537a7bc39SJason Zhu 				       size_t *out_num_read)
7637a7bc39SJason Zhu {
7737a7bc39SJason Zhu 	struct blk_desc *dev_desc;
7837a7bc39SJason Zhu 	lbaint_t offset_blk, blkcnt;
7937a7bc39SJason Zhu 	disk_partition_t part_info;
8037a7bc39SJason Zhu 
8137a7bc39SJason Zhu 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
82459bc933SJason Zhu 	dev_desc = rockchip_get_bootdev();
8337a7bc39SJason Zhu 	if (!dev_desc) {
84459bc933SJason Zhu 		printf("%s: Could not find device\n", __func__);
8537a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
8637a7bc39SJason Zhu 	}
8737a7bc39SJason Zhu 
8837a7bc39SJason Zhu 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
8937a7bc39SJason Zhu 		printf("Could not find \"%s\" partition\n", partition);
9037a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
9137a7bc39SJason Zhu 	}
9237a7bc39SJason Zhu 
9337a7bc39SJason Zhu 	if ((offset % 512 == 0) && (num_bytes % 512 == 0)) {
94*7c1937d6SJason Zhu 		blk_dread(dev_desc, part_info.start + offset_blk,
95*7c1937d6SJason Zhu 			  blkcnt, buffer);
9637a7bc39SJason Zhu 		*out_num_read = blkcnt * 512;
9737a7bc39SJason Zhu 	} else {
9837a7bc39SJason Zhu 		char *buffer_temp;
99*7c1937d6SJason Zhu 
10037a7bc39SJason Zhu 		buffer_temp = malloc(512 * blkcnt);
101*7c1937d6SJason Zhu 		if (!buffer_temp) {
10237a7bc39SJason Zhu 			printf("malloc error!\n");
10337a7bc39SJason Zhu 			return AVB_IO_RESULT_ERROR_OOM;
10437a7bc39SJason Zhu 		}
105*7c1937d6SJason Zhu 		blk_dread(dev_desc, part_info.start + offset_blk,
106*7c1937d6SJason Zhu 			  blkcnt, buffer_temp);
10737a7bc39SJason Zhu 		memcpy(buffer, buffer_temp + (offset % 512), num_bytes);
10837a7bc39SJason Zhu 		*out_num_read = num_bytes;
10937a7bc39SJason Zhu 		free(buffer_temp);
11037a7bc39SJason Zhu 	}
11137a7bc39SJason Zhu 
11237a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
11337a7bc39SJason Zhu }
11437a7bc39SJason Zhu 
11537a7bc39SJason Zhu static AvbIOResult write_to_partition(AvbOps *ops,
11637a7bc39SJason Zhu 				      const char *partition,
11737a7bc39SJason Zhu 				      int64_t offset,
11837a7bc39SJason Zhu 				      size_t num_bytes,
11937a7bc39SJason Zhu 				      const void *buffer)
12037a7bc39SJason Zhu {
12137a7bc39SJason Zhu 	struct blk_desc *dev_desc;
12237a7bc39SJason Zhu 	char *buffer_temp;
12337a7bc39SJason Zhu 	disk_partition_t part_info;
12437a7bc39SJason Zhu 	lbaint_t offset_blk, blkcnt;
12537a7bc39SJason Zhu 
12637a7bc39SJason Zhu 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
12737a7bc39SJason Zhu 	buffer_temp = malloc(512 * blkcnt);
128*7c1937d6SJason Zhu 	if (!buffer_temp) {
12937a7bc39SJason Zhu 		printf("malloc error!\n");
13037a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_OOM;
13137a7bc39SJason Zhu 	}
13237a7bc39SJason Zhu 	memset(buffer_temp, 0, 512 * blkcnt);
133459bc933SJason Zhu 	dev_desc = rockchip_get_bootdev();
13437a7bc39SJason Zhu 	if (!dev_desc) {
135459bc933SJason Zhu 		printf("%s: Could not find device\n", __func__);
13637a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
13737a7bc39SJason Zhu 	}
13837a7bc39SJason Zhu 
13937a7bc39SJason Zhu 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
14037a7bc39SJason Zhu 		printf("Could not find \"%s\" partition\n", partition);
14137a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
14237a7bc39SJason Zhu 	}
14337a7bc39SJason Zhu 
144*7c1937d6SJason Zhu 	if ((offset % 512 != 0) && (num_bytes % 512) != 0)
145*7c1937d6SJason Zhu 		blk_dread(dev_desc, part_info.start + offset_blk,
146*7c1937d6SJason Zhu 			  blkcnt, buffer_temp);
14737a7bc39SJason Zhu 
14837a7bc39SJason Zhu 	memcpy(buffer_temp, buffer + (offset % 512), num_bytes);
14937a7bc39SJason Zhu 	blk_dwrite(dev_desc, part_info.start + offset_blk, blkcnt, buffer);
15037a7bc39SJason Zhu 	free(buffer_temp);
15137a7bc39SJason Zhu 
15237a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
15337a7bc39SJason Zhu }
15437a7bc39SJason Zhu 
155*7c1937d6SJason Zhu static AvbIOResult
156*7c1937d6SJason Zhu validate_vbmeta_public_key(AvbOps *ops,
15737a7bc39SJason Zhu 			   const uint8_t *public_key_data,
15837a7bc39SJason Zhu 			   size_t public_key_length,
15937a7bc39SJason Zhu 			   const uint8_t *public_key_metadata,
16037a7bc39SJason Zhu 			   size_t public_key_metadata_length,
16137a7bc39SJason Zhu 			   bool *out_is_trusted)
16237a7bc39SJason Zhu {
16337a7bc39SJason Zhu #ifdef AVB_VBMETA_PUBLIC_KEY_VALIDATE
164*7c1937d6SJason Zhu 	if (out_is_trusted) {
16537a7bc39SJason Zhu 		avb_atx_validate_vbmeta_public_key(ops,
16637a7bc39SJason Zhu 						   public_key_data,
16737a7bc39SJason Zhu 						   public_key_length,
16837a7bc39SJason Zhu 						   public_key_metadata,
16937a7bc39SJason Zhu 						   public_key_metadata_length,
17037a7bc39SJason Zhu 						   out_is_trusted);
17137a7bc39SJason Zhu 	}
17237a7bc39SJason Zhu #else
173*7c1937d6SJason Zhu 	if (out_is_trusted)
17437a7bc39SJason Zhu 		*out_is_trusted = true;
17537a7bc39SJason Zhu #endif
17637a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
17737a7bc39SJason Zhu }
17837a7bc39SJason Zhu 
17937a7bc39SJason Zhu static AvbIOResult read_rollback_index(AvbOps *ops,
18037a7bc39SJason Zhu 				       size_t rollback_index_location,
18137a7bc39SJason Zhu 				       uint64_t *out_rollback_index)
18237a7bc39SJason Zhu {
183*7c1937d6SJason Zhu 	if (out_rollback_index) {
18437a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
18537a7bc39SJason Zhu 		int ret;
186*7c1937d6SJason Zhu 
18737a7bc39SJason Zhu 		ret = trusty_read_rollback_index(rollback_index_location,
18837a7bc39SJason Zhu 						 out_rollback_index);
189*7c1937d6SJason Zhu 		switch (ret) {
190*7c1937d6SJason Zhu 		case TEE_SUCCESS:
191*7c1937d6SJason Zhu 			ret = AVB_IO_RESULT_OK;
192*7c1937d6SJason Zhu 			break;
193*7c1937d6SJason Zhu 		case TEE_ERROR_GENERIC:
194*7c1937d6SJason Zhu 		case TEE_ERROR_NO_DATA:
195*7c1937d6SJason Zhu 		case TEE_ERROR_ITEM_NOT_FOUND:
19637a7bc39SJason Zhu 			*out_rollback_index = 0;
19737a7bc39SJason Zhu 			ret = trusty_write_rollback_index(rollback_index_location,
19837a7bc39SJason Zhu 							  *out_rollback_index);
199*7c1937d6SJason Zhu 			if (ret) {
200*7c1937d6SJason Zhu 				printf("%s: init rollback index error\n",
201*7c1937d6SJason Zhu 				       __FILE__);
202*7c1937d6SJason Zhu 				ret = AVB_IO_RESULT_ERROR_IO;
20337a7bc39SJason Zhu 			} else {
204*7c1937d6SJason Zhu 				ret =
205*7c1937d6SJason Zhu 				trusty_read_rollback_index(rollback_index_location,
206*7c1937d6SJason Zhu 							   out_rollback_index);
207*7c1937d6SJason Zhu 				if (ret)
208*7c1937d6SJason Zhu 					ret = AVB_IO_RESULT_ERROR_IO;
209*7c1937d6SJason Zhu 				else
210*7c1937d6SJason Zhu 					ret = AVB_IO_RESULT_OK;
21137a7bc39SJason Zhu 			}
212*7c1937d6SJason Zhu 			break;
213*7c1937d6SJason Zhu 		default:
214*7c1937d6SJason Zhu 			ret = AVB_IO_RESULT_ERROR_IO;
215*7c1937d6SJason Zhu 			printf("%s: trusty_read_rollback_index failed",
216*7c1937d6SJason Zhu 			       __FILE__);
217*7c1937d6SJason Zhu 		}
218*7c1937d6SJason Zhu 
219*7c1937d6SJason Zhu 		return ret;
22037a7bc39SJason Zhu #endif
22137a7bc39SJason Zhu 	}
22237a7bc39SJason Zhu 	return AVB_IO_RESULT_ERROR_IO;
22337a7bc39SJason Zhu }
22437a7bc39SJason Zhu 
22537a7bc39SJason Zhu static AvbIOResult write_rollback_index(AvbOps *ops,
22637a7bc39SJason Zhu 					size_t rollback_index_location,
22737a7bc39SJason Zhu 					uint64_t rollback_index)
22837a7bc39SJason Zhu {
22937a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
230*7c1937d6SJason Zhu 	if (trusty_write_rollback_index(rollback_index_location,
231*7c1937d6SJason Zhu 					rollback_index)) {
23237a7bc39SJason Zhu 		printf("%s: Fail to write rollback index\n", __FILE__);
23337a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_IO;
23437a7bc39SJason Zhu 	}
23537a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
23637a7bc39SJason Zhu #endif
23737a7bc39SJason Zhu 	return AVB_IO_RESULT_ERROR_IO;
23837a7bc39SJason Zhu }
23937a7bc39SJason Zhu 
24037a7bc39SJason Zhu static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
24137a7bc39SJason Zhu {
242*7c1937d6SJason Zhu 	if (out_is_unlocked) {
24337a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
24437a7bc39SJason Zhu 		int ret;
24537a7bc39SJason Zhu 
24637a7bc39SJason Zhu 		ret = trusty_read_lock_state((uint8_t *)out_is_unlocked);
247*7c1937d6SJason Zhu 		switch (ret) {
248*7c1937d6SJason Zhu 		case TEE_SUCCESS:
249*7c1937d6SJason Zhu 			ret = AVB_IO_RESULT_OK;
250*7c1937d6SJason Zhu 			break;
251*7c1937d6SJason Zhu 		case TEE_ERROR_GENERIC:
252*7c1937d6SJason Zhu 		case TEE_ERROR_NO_DATA:
253*7c1937d6SJason Zhu 		case TEE_ERROR_ITEM_NOT_FOUND:
25437a7bc39SJason Zhu 			*out_is_unlocked = 1;
25537a7bc39SJason Zhu 			if (trusty_write_lock_state(*out_is_unlocked)) {
25637a7bc39SJason Zhu 				printf("%s: init lock state error\n", __FILE__);
257*7c1937d6SJason Zhu 				ret = AVB_IO_RESULT_ERROR_IO;
25837a7bc39SJason Zhu 			} else {
259*7c1937d6SJason Zhu 				ret =
260*7c1937d6SJason Zhu 				trusty_read_lock_state((uint8_t *)out_is_unlocked);
261*7c1937d6SJason Zhu 				if (ret == 0)
262*7c1937d6SJason Zhu 					ret = AVB_IO_RESULT_OK;
263*7c1937d6SJason Zhu 				else
264*7c1937d6SJason Zhu 					ret = AVB_IO_RESULT_ERROR_IO;
26537a7bc39SJason Zhu 			}
266*7c1937d6SJason Zhu 			break;
267*7c1937d6SJason Zhu 		default:
268*7c1937d6SJason Zhu 			ret = AVB_IO_RESULT_ERROR_IO;
269*7c1937d6SJason Zhu 			printf("%s: trusty_read_lock_state failed\n", __FILE__);
270*7c1937d6SJason Zhu 		}
271*7c1937d6SJason Zhu 		return ret;
27237a7bc39SJason Zhu #endif
27337a7bc39SJason Zhu 	}
27437a7bc39SJason Zhu 	return AVB_IO_RESULT_ERROR_IO;
27537a7bc39SJason Zhu }
27637a7bc39SJason Zhu 
27737a7bc39SJason Zhu static AvbIOResult write_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
27837a7bc39SJason Zhu {
279*7c1937d6SJason Zhu 	if (out_is_unlocked) {
28037a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
28137a7bc39SJason Zhu 		if (trusty_write_lock_state(*out_is_unlocked)) {
28237a7bc39SJason Zhu 			printf("%s: Fail to write lock state\n", __FILE__);
28337a7bc39SJason Zhu 			return AVB_IO_RESULT_ERROR_IO;
28437a7bc39SJason Zhu 		}
28537a7bc39SJason Zhu 		return AVB_IO_RESULT_OK;
28637a7bc39SJason Zhu #endif
28737a7bc39SJason Zhu 	}
28837a7bc39SJason Zhu 	return AVB_IO_RESULT_ERROR_IO;
28937a7bc39SJason Zhu }
29037a7bc39SJason Zhu 
29137a7bc39SJason Zhu static AvbIOResult get_size_of_partition(AvbOps *ops,
29237a7bc39SJason Zhu 					 const char *partition,
29337a7bc39SJason Zhu 					 uint64_t *out_size_in_bytes)
29437a7bc39SJason Zhu {
29537a7bc39SJason Zhu 	struct blk_desc *dev_desc;
29637a7bc39SJason Zhu 	disk_partition_t part_info;
29737a7bc39SJason Zhu 
298459bc933SJason Zhu 	dev_desc = rockchip_get_bootdev();
29937a7bc39SJason Zhu 	if (!dev_desc) {
300459bc933SJason Zhu 		printf("%s: Could not find device\n", __func__);
30137a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
30237a7bc39SJason Zhu 	}
30337a7bc39SJason Zhu 
30437a7bc39SJason Zhu 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
30537a7bc39SJason Zhu 		printf("Could not find \"%s\" partition\n", partition);
30637a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
30737a7bc39SJason Zhu 	}
30837a7bc39SJason Zhu 	*out_size_in_bytes = (part_info.size) * 512;
30937a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
31037a7bc39SJason Zhu }
31137a7bc39SJason Zhu 
31237a7bc39SJason Zhu static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
31337a7bc39SJason Zhu 						 const char *partition,
31437a7bc39SJason Zhu 						 char *guid_buf,
31537a7bc39SJason Zhu 						 size_t guid_buf_size)
31637a7bc39SJason Zhu {
31737a7bc39SJason Zhu 	struct blk_desc *dev_desc;
31837a7bc39SJason Zhu 	disk_partition_t part_info;
319*7c1937d6SJason Zhu 
320459bc933SJason Zhu 	dev_desc = rockchip_get_bootdev();
32137a7bc39SJason Zhu 	if (!dev_desc) {
322459bc933SJason Zhu 		printf("%s: Could not find device\n", __func__);
32337a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
32437a7bc39SJason Zhu 	}
32537a7bc39SJason Zhu 
32637a7bc39SJason Zhu 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
32737a7bc39SJason Zhu 		printf("Could not find \"%s\" partition\n", partition);
32837a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
32937a7bc39SJason Zhu 	}
330*7c1937d6SJason Zhu 	if (guid_buf && guid_buf_size > 0)
33137a7bc39SJason Zhu 		memcpy(guid_buf, part_info.uuid, guid_buf_size);
332*7c1937d6SJason Zhu 
33337a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
33437a7bc39SJason Zhu }
33537a7bc39SJason Zhu 
33637a7bc39SJason Zhu /* read permanent attributes from rpmb */
33737a7bc39SJason Zhu AvbIOResult avb_read_perm_attr(AvbAtxOps *atx_ops,
33837a7bc39SJason Zhu 			       AvbAtxPermanentAttributes *attributes)
33937a7bc39SJason Zhu {
340*7c1937d6SJason Zhu 	if (attributes) {
34137a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
34237a7bc39SJason Zhu 		trusty_read_permanent_attributes((uint8_t *)attributes,
34337a7bc39SJason Zhu 						 sizeof(struct AvbAtxPermanentAttributes));
34437a7bc39SJason Zhu 		return AVB_IO_RESULT_OK;
34537a7bc39SJason Zhu #endif
34637a7bc39SJason Zhu 	}
34737a7bc39SJason Zhu 
34837a7bc39SJason Zhu 	return -1;
34937a7bc39SJason Zhu }
35037a7bc39SJason Zhu 
35137a7bc39SJason Zhu /*read permanent attributes hash from efuse */
35237a7bc39SJason Zhu AvbIOResult avb_read_perm_attr_hash(AvbAtxOps *atx_ops,
35337a7bc39SJason Zhu 				    uint8_t hash[AVB_SHA256_DIGEST_SIZE])
35437a7bc39SJason Zhu {
35537a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
356*7c1937d6SJason Zhu 	if (trusty_read_attribute_hash((uint32_t *)hash,
357*7c1937d6SJason Zhu 				       AVB_SHA256_DIGEST_SIZE / 4))
35837a7bc39SJason Zhu 		return -1;
35937a7bc39SJason Zhu #else
36037a7bc39SJason Zhu 	avb_error("Please open the macro!\n");
36137a7bc39SJason Zhu 	return -1;
36237a7bc39SJason Zhu #endif
36337a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
36437a7bc39SJason Zhu }
36537a7bc39SJason Zhu 
36682e713e1SJason Zhu static void avb_set_key_version(AvbAtxOps *atx_ops,
36782e713e1SJason Zhu 				size_t rollback_index_location,
36882e713e1SJason Zhu 				uint64_t key_version)
36982e713e1SJason Zhu {
37082e713e1SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
371*7c1937d6SJason Zhu 	if (trusty_write_rollback_index(rollback_index_location, key_version))
37282e713e1SJason Zhu 		printf("%s: Fail to write rollback index\n", __FILE__);
37382e713e1SJason Zhu #endif
37482e713e1SJason Zhu }
37582e713e1SJason Zhu 
3768d0db1d9SJason Zhu AvbIOResult rk_get_random(AvbAtxOps *atx_ops,
3778d0db1d9SJason Zhu 			  size_t num_bytes,
3788d0db1d9SJason Zhu 			  uint8_t *output)
3798d0db1d9SJason Zhu {
3808d0db1d9SJason Zhu 	int i;
3818d0db1d9SJason Zhu 	unsigned int seed;
3828d0db1d9SJason Zhu 
3838d0db1d9SJason Zhu 	seed = (unsigned int)get_timer(0);
3848d0db1d9SJason Zhu 	for (i = 0; i < num_bytes; i++) {
3858d0db1d9SJason Zhu 		srand(seed);
3868d0db1d9SJason Zhu 		output[i] = (uint8_t)(rand());
3878d0db1d9SJason Zhu 		seed = (unsigned int)(output[i]);
3888d0db1d9SJason Zhu 	}
3898d0db1d9SJason Zhu 
3908d0db1d9SJason Zhu 	return 0;
3918d0db1d9SJason Zhu }
3928d0db1d9SJason Zhu 
393*7c1937d6SJason Zhu AvbOps *avb_ops_user_new(void)
394*7c1937d6SJason Zhu {
39537a7bc39SJason Zhu 	AvbOps *ops;
39637a7bc39SJason Zhu 
39737a7bc39SJason Zhu 	ops = calloc(1, sizeof(AvbOps));
398*7c1937d6SJason Zhu 	if (!ops) {
39937a7bc39SJason Zhu 		avb_error("Error allocating memory for AvbOps.\n");
40037a7bc39SJason Zhu 		goto out;
40137a7bc39SJason Zhu 	}
40237a7bc39SJason Zhu 	ops->ab_ops = calloc(1, sizeof(AvbABOps));
403*7c1937d6SJason Zhu 	if (!ops->ab_ops) {
40437a7bc39SJason Zhu 		avb_error("Error allocating memory for AvbABOps.\n");
40537a7bc39SJason Zhu 		free(ops);
40637a7bc39SJason Zhu 		goto out;
40737a7bc39SJason Zhu 	}
40837a7bc39SJason Zhu 
40937a7bc39SJason Zhu 	ops->atx_ops = calloc(1, sizeof(AvbAtxOps));
410*7c1937d6SJason Zhu 	if (!ops->atx_ops) {
41137a7bc39SJason Zhu 		avb_error("Error allocating memory for AvbAtxOps.\n");
41237a7bc39SJason Zhu 		free(ops->ab_ops);
41337a7bc39SJason Zhu 		free(ops);
41437a7bc39SJason Zhu 		goto out;
41537a7bc39SJason Zhu 	}
41637a7bc39SJason Zhu 	ops->ab_ops->ops = ops;
41737a7bc39SJason Zhu 	ops->atx_ops->ops = ops;
41837a7bc39SJason Zhu 
41937a7bc39SJason Zhu 	ops->read_from_partition = read_from_partition;
42037a7bc39SJason Zhu 	ops->write_to_partition = write_to_partition;
42137a7bc39SJason Zhu 	ops->validate_vbmeta_public_key = validate_vbmeta_public_key;
42237a7bc39SJason Zhu 	ops->read_rollback_index = read_rollback_index;
42337a7bc39SJason Zhu 	ops->write_rollback_index = write_rollback_index;
42437a7bc39SJason Zhu 	ops->read_is_device_unlocked = read_is_device_unlocked;
42537a7bc39SJason Zhu 	ops->write_is_device_unlocked = write_is_device_unlocked;
42637a7bc39SJason Zhu 	ops->get_unique_guid_for_partition = get_unique_guid_for_partition;
42737a7bc39SJason Zhu 	ops->get_size_of_partition = get_size_of_partition;
42837a7bc39SJason Zhu 	ops->ab_ops->read_ab_metadata = avb_ab_data_read;
42937a7bc39SJason Zhu 	ops->ab_ops->write_ab_metadata = avb_ab_data_write;
43037a7bc39SJason Zhu 	ops->atx_ops->read_permanent_attributes = avb_read_perm_attr;
43137a7bc39SJason Zhu 	ops->atx_ops->read_permanent_attributes_hash = avb_read_perm_attr_hash;
43282e713e1SJason Zhu 	ops->atx_ops->set_key_version = avb_set_key_version;
4338d0db1d9SJason Zhu 	ops->atx_ops->get_random = rk_get_random;
43437a7bc39SJason Zhu 
43537a7bc39SJason Zhu out:
43637a7bc39SJason Zhu 	return ops;
43737a7bc39SJason Zhu }
43837a7bc39SJason Zhu 
439*7c1937d6SJason Zhu void avb_ops_user_free(AvbOps *ops)
440*7c1937d6SJason Zhu {
44137a7bc39SJason Zhu 	free(ops->ab_ops);
44237a7bc39SJason Zhu 	free(ops->atx_ops);
44337a7bc39SJason Zhu 	free(ops);
44437a7bc39SJason Zhu }
445