xref: /rk3399_rockchip-uboot/lib/avb/libavb_user/avb_ops_user.c (revision 37a7bc39c0a3beca986e8c1c85d1dd6b9921e313)
1*37a7bc39SJason Zhu /*
2*37a7bc39SJason Zhu  * Copyright (C) 2017 The Android Open Source Project
3*37a7bc39SJason Zhu  *
4*37a7bc39SJason Zhu  * Permission is hereby granted, free of charge, to any person
5*37a7bc39SJason Zhu  * obtaining a copy of this software and associated documentation
6*37a7bc39SJason Zhu  * files (the "Software"), to deal in the Software without
7*37a7bc39SJason Zhu  * restriction, including without limitation the rights to use, copy,
8*37a7bc39SJason Zhu  * modify, merge, publish, distribute, sublicense, and/or sell copies
9*37a7bc39SJason Zhu  * of the Software, and to permit persons to whom the Software is
10*37a7bc39SJason Zhu  * furnished to do so, subject to the following conditions:
11*37a7bc39SJason Zhu  *
12*37a7bc39SJason Zhu  * The above copyright notice and this permission notice shall be
13*37a7bc39SJason Zhu  * included in all copies or substantial portions of the Software.
14*37a7bc39SJason Zhu  *
15*37a7bc39SJason Zhu  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*37a7bc39SJason Zhu  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*37a7bc39SJason Zhu  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18*37a7bc39SJason Zhu  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19*37a7bc39SJason Zhu  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20*37a7bc39SJason Zhu  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21*37a7bc39SJason Zhu  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*37a7bc39SJason Zhu  * SOFTWARE.
23*37a7bc39SJason Zhu  */
24*37a7bc39SJason Zhu 
25*37a7bc39SJason Zhu #include <common.h>
26*37a7bc39SJason Zhu #include <image.h>
27*37a7bc39SJason Zhu #include <android_image.h>
28*37a7bc39SJason Zhu #include <malloc.h>
29*37a7bc39SJason Zhu #include <mapmem.h>
30*37a7bc39SJason Zhu #include <errno.h>
31*37a7bc39SJason Zhu #include <command.h>
32*37a7bc39SJason Zhu #include <mmc.h>
33*37a7bc39SJason Zhu #include <blk.h>
34*37a7bc39SJason Zhu #include <part.h>
35*37a7bc39SJason Zhu #include <android_avb/avb_ops_user.h>
36*37a7bc39SJason Zhu #include <android_avb/libavb_ab.h>
37*37a7bc39SJason Zhu #include <android_avb/avb_atx_validate.h>
38*37a7bc39SJason Zhu #include <android_avb/avb_atx_types.h>
39*37a7bc39SJason Zhu #include <optee_include/OpteeClientInterface.h>
40*37a7bc39SJason Zhu #include <optee_include/tee_api_defines.h>
41*37a7bc39SJason Zhu #include <android_avb/avb_vbmeta_image.h>
42*37a7bc39SJason Zhu #include <android_avb/avb_atx_validate.h>
43*37a7bc39SJason Zhu 
44*37a7bc39SJason Zhu static void byte_to_block(int64_t *offset,
45*37a7bc39SJason Zhu 			  size_t *num_bytes,
46*37a7bc39SJason Zhu 			  lbaint_t *offset_blk,
47*37a7bc39SJason Zhu 			  lbaint_t *blkcnt)
48*37a7bc39SJason Zhu {
49*37a7bc39SJason Zhu 	*offset_blk = (lbaint_t)(*offset / 512);
50*37a7bc39SJason Zhu 	if (*num_bytes % 512 == 0) {
51*37a7bc39SJason Zhu 		if (*offset % 512 == 0) {
52*37a7bc39SJason Zhu 			*blkcnt = (lbaint_t)(*num_bytes / 512);
53*37a7bc39SJason Zhu 		} else {
54*37a7bc39SJason Zhu 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
55*37a7bc39SJason Zhu 		}
56*37a7bc39SJason Zhu 	} else {
57*37a7bc39SJason Zhu 		if (*offset % 512 == 0) {
58*37a7bc39SJason Zhu 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
59*37a7bc39SJason Zhu 		} else {
60*37a7bc39SJason Zhu 			if ((*offset % 512) + (*num_bytes % 512) < 512 ||
61*37a7bc39SJason Zhu 			    (*offset % 512) + (*num_bytes % 512) == 512) {
62*37a7bc39SJason Zhu 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
63*37a7bc39SJason Zhu 			} else {
64*37a7bc39SJason Zhu 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 2;
65*37a7bc39SJason Zhu 			}
66*37a7bc39SJason Zhu 		}
67*37a7bc39SJason Zhu 	}
68*37a7bc39SJason Zhu }
69*37a7bc39SJason Zhu 
70*37a7bc39SJason Zhu static AvbIOResult read_from_partition(AvbOps* ops,
71*37a7bc39SJason Zhu                                        const char* partition,
72*37a7bc39SJason Zhu                                        int64_t offset,
73*37a7bc39SJason Zhu                                        size_t num_bytes,
74*37a7bc39SJason Zhu                                        void* buffer,
75*37a7bc39SJason Zhu                                        size_t* out_num_read)
76*37a7bc39SJason Zhu {
77*37a7bc39SJason Zhu 	char *dev_iface = "mmc";
78*37a7bc39SJason Zhu 	int dev_num = 0;
79*37a7bc39SJason Zhu 	struct blk_desc *dev_desc;
80*37a7bc39SJason Zhu 	lbaint_t offset_blk, blkcnt;
81*37a7bc39SJason Zhu 	disk_partition_t part_info;
82*37a7bc39SJason Zhu 
83*37a7bc39SJason Zhu 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
84*37a7bc39SJason Zhu 	dev_desc = blk_get_dev(dev_iface, dev_num);
85*37a7bc39SJason Zhu 	if (!dev_desc) {
86*37a7bc39SJason Zhu 		printf("Could not find %s %d\n", dev_iface, dev_num);
87*37a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
88*37a7bc39SJason Zhu 	}
89*37a7bc39SJason Zhu 
90*37a7bc39SJason Zhu 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
91*37a7bc39SJason Zhu 		printf("Could not find \"%s\" partition\n", partition);
92*37a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
93*37a7bc39SJason Zhu 	}
94*37a7bc39SJason Zhu 
95*37a7bc39SJason Zhu 	if((offset % 512 == 0) && (num_bytes % 512 == 0)) {
96*37a7bc39SJason Zhu 		blk_dread(dev_desc, part_info.start + offset_blk, blkcnt, buffer);
97*37a7bc39SJason Zhu 		*out_num_read = blkcnt * 512;
98*37a7bc39SJason Zhu 	} else {
99*37a7bc39SJason Zhu 		char *buffer_temp;
100*37a7bc39SJason Zhu 		buffer_temp = malloc(512 * blkcnt);
101*37a7bc39SJason Zhu 		if (buffer_temp == NULL) {
102*37a7bc39SJason Zhu 			printf("malloc error!\n");
103*37a7bc39SJason Zhu 			return AVB_IO_RESULT_ERROR_OOM;
104*37a7bc39SJason Zhu 		}
105*37a7bc39SJason Zhu 		blk_dread(dev_desc, part_info.start + offset_blk, blkcnt, buffer_temp);
106*37a7bc39SJason Zhu 		memcpy(buffer, buffer_temp + (offset % 512), num_bytes);
107*37a7bc39SJason Zhu 		*out_num_read = num_bytes;
108*37a7bc39SJason Zhu 		free(buffer_temp);
109*37a7bc39SJason Zhu 	}
110*37a7bc39SJason Zhu 
111*37a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
112*37a7bc39SJason Zhu }
113*37a7bc39SJason Zhu 
114*37a7bc39SJason Zhu static AvbIOResult write_to_partition(AvbOps* ops,
115*37a7bc39SJason Zhu                                       const char* partition,
116*37a7bc39SJason Zhu                                       int64_t offset,
117*37a7bc39SJason Zhu                                       size_t num_bytes,
118*37a7bc39SJason Zhu                                       const void* buffer)
119*37a7bc39SJason Zhu {
120*37a7bc39SJason Zhu 	const char *dev_iface = "mmc";
121*37a7bc39SJason Zhu 	int dev_num = 0;
122*37a7bc39SJason Zhu 	struct blk_desc *dev_desc;
123*37a7bc39SJason Zhu 	char *buffer_temp;
124*37a7bc39SJason Zhu 	disk_partition_t part_info;
125*37a7bc39SJason Zhu 	lbaint_t offset_blk, blkcnt;
126*37a7bc39SJason Zhu 
127*37a7bc39SJason Zhu 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
128*37a7bc39SJason Zhu 	buffer_temp = malloc(512 * blkcnt);
129*37a7bc39SJason Zhu 	if (buffer_temp == NULL) {
130*37a7bc39SJason Zhu 		printf("malloc error!\n");
131*37a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_OOM;
132*37a7bc39SJason Zhu 	}
133*37a7bc39SJason Zhu 	memset(buffer_temp, 0, 512 * blkcnt);
134*37a7bc39SJason Zhu 	dev_desc = blk_get_dev(dev_iface, dev_num);
135*37a7bc39SJason Zhu 	if (!dev_desc) {
136*37a7bc39SJason Zhu 		printf("Could not find %s %d\n", dev_iface, dev_num);
137*37a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
138*37a7bc39SJason Zhu 	}
139*37a7bc39SJason Zhu 
140*37a7bc39SJason Zhu 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
141*37a7bc39SJason Zhu 		printf("Could not find \"%s\" partition\n", partition);
142*37a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
143*37a7bc39SJason Zhu 	}
144*37a7bc39SJason Zhu 
145*37a7bc39SJason Zhu 	if ((offset % 512 != 0) && (num_bytes % 512) != 0) {
146*37a7bc39SJason Zhu 		blk_dread(dev_desc, part_info.start + offset_blk, blkcnt, buffer_temp);
147*37a7bc39SJason Zhu 	}
148*37a7bc39SJason Zhu 
149*37a7bc39SJason Zhu 	memcpy(buffer_temp, buffer + (offset % 512), num_bytes);
150*37a7bc39SJason Zhu 	blk_dwrite(dev_desc, part_info.start + offset_blk, blkcnt, buffer);
151*37a7bc39SJason Zhu 	free(buffer_temp);
152*37a7bc39SJason Zhu 
153*37a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
154*37a7bc39SJason Zhu }
155*37a7bc39SJason Zhu 
156*37a7bc39SJason Zhu static AvbIOResult validate_vbmeta_public_key(
157*37a7bc39SJason Zhu 	AvbOps *ops,
158*37a7bc39SJason Zhu 	const uint8_t *public_key_data,
159*37a7bc39SJason Zhu 	size_t public_key_length,
160*37a7bc39SJason Zhu 	const uint8_t *public_key_metadata,
161*37a7bc39SJason Zhu 	size_t public_key_metadata_length,
162*37a7bc39SJason Zhu 	bool *out_is_trusted)
163*37a7bc39SJason Zhu {
164*37a7bc39SJason Zhu #ifdef AVB_VBMETA_PUBLIC_KEY_VALIDATE
165*37a7bc39SJason Zhu 	if (out_is_trusted != NULL) {
166*37a7bc39SJason Zhu 		avb_atx_validate_vbmeta_public_key(ops,
167*37a7bc39SJason Zhu 						   public_key_data,
168*37a7bc39SJason Zhu 						   public_key_length,
169*37a7bc39SJason Zhu 						   public_key_metadata,
170*37a7bc39SJason Zhu 						   public_key_metadata_length,
171*37a7bc39SJason Zhu 						   out_is_trusted);
172*37a7bc39SJason Zhu 	}
173*37a7bc39SJason Zhu #else
174*37a7bc39SJason Zhu 	if (out_is_trusted != NULL) {
175*37a7bc39SJason Zhu 		*out_is_trusted = true;
176*37a7bc39SJason Zhu 	}
177*37a7bc39SJason Zhu #endif
178*37a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
179*37a7bc39SJason Zhu }
180*37a7bc39SJason Zhu 
181*37a7bc39SJason Zhu static AvbIOResult read_rollback_index(AvbOps *ops,
182*37a7bc39SJason Zhu                                        size_t rollback_index_location,
183*37a7bc39SJason Zhu                                        uint64_t *out_rollback_index)
184*37a7bc39SJason Zhu {
185*37a7bc39SJason Zhu 	if (out_rollback_index != NULL) {
186*37a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
187*37a7bc39SJason Zhu 		int ret;
188*37a7bc39SJason Zhu 		ret = trusty_read_rollback_index(rollback_index_location,
189*37a7bc39SJason Zhu 						 out_rollback_index);
190*37a7bc39SJason Zhu 		if (ret == TEE_ERROR_GENERIC) {
191*37a7bc39SJason Zhu 			*out_rollback_index = 0;
192*37a7bc39SJason Zhu 			ret = trusty_write_rollback_index(rollback_index_location,
193*37a7bc39SJason Zhu 							  *out_rollback_index);
194*37a7bc39SJason Zhu 			if (ret != 0) {
195*37a7bc39SJason Zhu 				printf("%s: init rollback index error\n", __FILE__);
196*37a7bc39SJason Zhu 				return AVB_IO_RESULT_ERROR_IO;
197*37a7bc39SJason Zhu 			}
198*37a7bc39SJason Zhu 			ret = trusty_read_rollback_index(rollback_index_location,
199*37a7bc39SJason Zhu 							 out_rollback_index);
200*37a7bc39SJason Zhu 			if (ret == 0)
201*37a7bc39SJason Zhu 				return AVB_IO_RESULT_OK;
202*37a7bc39SJason Zhu 		} else if (ret == 0) {
203*37a7bc39SJason Zhu 			return AVB_IO_RESULT_OK;
204*37a7bc39SJason Zhu 		} else {
205*37a7bc39SJason Zhu 			printf("trusty_read_rollback_index ret = %x\n", ret);
206*37a7bc39SJason Zhu 			return AVB_IO_RESULT_ERROR_IO;
207*37a7bc39SJason Zhu 		}
208*37a7bc39SJason Zhu #endif
209*37a7bc39SJason Zhu 	}
210*37a7bc39SJason Zhu 	return AVB_IO_RESULT_ERROR_IO;
211*37a7bc39SJason Zhu }
212*37a7bc39SJason Zhu 
213*37a7bc39SJason Zhu static AvbIOResult write_rollback_index(AvbOps *ops,
214*37a7bc39SJason Zhu                                         size_t rollback_index_location,
215*37a7bc39SJason Zhu                                         uint64_t rollback_index)
216*37a7bc39SJason Zhu {
217*37a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
218*37a7bc39SJason Zhu 	if (trusty_write_rollback_index(rollback_index_location, rollback_index)) {
219*37a7bc39SJason Zhu 		printf("%s: Fail to write rollback index\n", __FILE__);
220*37a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_IO;
221*37a7bc39SJason Zhu 	}
222*37a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
223*37a7bc39SJason Zhu #endif
224*37a7bc39SJason Zhu 	return AVB_IO_RESULT_ERROR_IO;
225*37a7bc39SJason Zhu }
226*37a7bc39SJason Zhu 
227*37a7bc39SJason Zhu static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
228*37a7bc39SJason Zhu {
229*37a7bc39SJason Zhu 	if (out_is_unlocked != NULL) {
230*37a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
231*37a7bc39SJason Zhu 		int ret;
232*37a7bc39SJason Zhu 
233*37a7bc39SJason Zhu 		ret = trusty_read_lock_state((uint8_t *)out_is_unlocked);
234*37a7bc39SJason Zhu 		if (ret == TEE_ERROR_GENERIC) {
235*37a7bc39SJason Zhu 			*out_is_unlocked = 1;
236*37a7bc39SJason Zhu 			if (trusty_write_lock_state(*out_is_unlocked)) {
237*37a7bc39SJason Zhu 				printf("%s: init lock state error\n", __FILE__);
238*37a7bc39SJason Zhu 				return AVB_IO_RESULT_ERROR_IO;
239*37a7bc39SJason Zhu 			}
240*37a7bc39SJason Zhu 
241*37a7bc39SJason Zhu 			ret = trusty_read_lock_state((uint8_t *)out_is_unlocked);
242*37a7bc39SJason Zhu 			if(ret == 0)
243*37a7bc39SJason Zhu 				return 0;
244*37a7bc39SJason Zhu 		} else if (ret == 0) {
245*37a7bc39SJason Zhu 			return AVB_IO_RESULT_OK;
246*37a7bc39SJason Zhu 		} else {
247*37a7bc39SJason Zhu 			printf("read_is_device_unlocked ret = %x\n", ret);
248*37a7bc39SJason Zhu 			return AVB_IO_RESULT_ERROR_IO;
249*37a7bc39SJason Zhu 		}
250*37a7bc39SJason Zhu #endif
251*37a7bc39SJason Zhu 	}
252*37a7bc39SJason Zhu 	return AVB_IO_RESULT_ERROR_IO;
253*37a7bc39SJason Zhu }
254*37a7bc39SJason Zhu 
255*37a7bc39SJason Zhu static AvbIOResult write_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
256*37a7bc39SJason Zhu {
257*37a7bc39SJason Zhu 	if (out_is_unlocked != NULL) {
258*37a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
259*37a7bc39SJason Zhu 		if (trusty_write_lock_state(*out_is_unlocked)) {
260*37a7bc39SJason Zhu 			printf("%s: Fail to write lock state\n", __FILE__);
261*37a7bc39SJason Zhu 			return AVB_IO_RESULT_ERROR_IO;
262*37a7bc39SJason Zhu 		}
263*37a7bc39SJason Zhu 		return AVB_IO_RESULT_OK;
264*37a7bc39SJason Zhu #endif
265*37a7bc39SJason Zhu 	}
266*37a7bc39SJason Zhu 	return AVB_IO_RESULT_ERROR_IO;
267*37a7bc39SJason Zhu }
268*37a7bc39SJason Zhu 
269*37a7bc39SJason Zhu static AvbIOResult get_size_of_partition(AvbOps *ops,
270*37a7bc39SJason Zhu                                          const char *partition,
271*37a7bc39SJason Zhu                                          uint64_t *out_size_in_bytes)
272*37a7bc39SJason Zhu {
273*37a7bc39SJason Zhu 	const char *dev_iface = "mmc";
274*37a7bc39SJason Zhu 	int dev_num = 0;
275*37a7bc39SJason Zhu 	struct blk_desc *dev_desc;
276*37a7bc39SJason Zhu 	disk_partition_t part_info;
277*37a7bc39SJason Zhu 
278*37a7bc39SJason Zhu 	dev_desc = blk_get_dev(dev_iface, dev_num);
279*37a7bc39SJason Zhu 	if (!dev_desc) {
280*37a7bc39SJason Zhu 		printf("Could not find %s %d\n", dev_iface, dev_num);
281*37a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
282*37a7bc39SJason Zhu 	}
283*37a7bc39SJason Zhu 
284*37a7bc39SJason Zhu 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
285*37a7bc39SJason Zhu 		printf("Could not find \"%s\" partition\n", partition);
286*37a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
287*37a7bc39SJason Zhu 	}
288*37a7bc39SJason Zhu 	*out_size_in_bytes = (part_info.size) * 512;
289*37a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
290*37a7bc39SJason Zhu }
291*37a7bc39SJason Zhu 
292*37a7bc39SJason Zhu static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
293*37a7bc39SJason Zhu                                                  const char *partition,
294*37a7bc39SJason Zhu                                                  char *guid_buf,
295*37a7bc39SJason Zhu                                                  size_t guid_buf_size)
296*37a7bc39SJason Zhu {
297*37a7bc39SJason Zhu 	const char *dev_iface = "mmc";
298*37a7bc39SJason Zhu 	int dev_num = 0;
299*37a7bc39SJason Zhu 	struct blk_desc *dev_desc;
300*37a7bc39SJason Zhu 	disk_partition_t part_info;
301*37a7bc39SJason Zhu 	dev_desc = blk_get_dev(dev_iface, dev_num);
302*37a7bc39SJason Zhu 	if (!dev_desc) {
303*37a7bc39SJason Zhu 		printf("Could not find %s %d\n", dev_iface, dev_num);
304*37a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
305*37a7bc39SJason Zhu 	}
306*37a7bc39SJason Zhu 
307*37a7bc39SJason Zhu 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
308*37a7bc39SJason Zhu 		printf("Could not find \"%s\" partition\n", partition);
309*37a7bc39SJason Zhu 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
310*37a7bc39SJason Zhu 	}
311*37a7bc39SJason Zhu 	if (guid_buf != NULL && guid_buf_size > 0) {
312*37a7bc39SJason Zhu 		memcpy(guid_buf, part_info.uuid, guid_buf_size);
313*37a7bc39SJason Zhu 	}
314*37a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
315*37a7bc39SJason Zhu }
316*37a7bc39SJason Zhu 
317*37a7bc39SJason Zhu /* read permanent attributes from rpmb */
318*37a7bc39SJason Zhu AvbIOResult avb_read_perm_attr(AvbAtxOps* atx_ops,
319*37a7bc39SJason Zhu 			       AvbAtxPermanentAttributes* attributes)
320*37a7bc39SJason Zhu {
321*37a7bc39SJason Zhu 	if (attributes != NULL) {
322*37a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
323*37a7bc39SJason Zhu 		trusty_read_permanent_attributes((uint8_t *)attributes,
324*37a7bc39SJason Zhu 						 sizeof(struct AvbAtxPermanentAttributes));
325*37a7bc39SJason Zhu 		return AVB_IO_RESULT_OK;
326*37a7bc39SJason Zhu #endif
327*37a7bc39SJason Zhu 	}
328*37a7bc39SJason Zhu 
329*37a7bc39SJason Zhu 	return -1;
330*37a7bc39SJason Zhu }
331*37a7bc39SJason Zhu 
332*37a7bc39SJason Zhu /*read permanent attributes hash from efuse */
333*37a7bc39SJason Zhu AvbIOResult avb_read_perm_attr_hash(AvbAtxOps* atx_ops,
334*37a7bc39SJason Zhu 				    uint8_t hash[AVB_SHA256_DIGEST_SIZE])
335*37a7bc39SJason Zhu {
336*37a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT
337*37a7bc39SJason Zhu 	if (trusty_read_attribute_hash((uint32_t *)hash, AVB_SHA256_DIGEST_SIZE / 4))
338*37a7bc39SJason Zhu 		return -1;
339*37a7bc39SJason Zhu #else
340*37a7bc39SJason Zhu 	avb_error("Please open the macro!\n");
341*37a7bc39SJason Zhu 	return -1;
342*37a7bc39SJason Zhu #endif
343*37a7bc39SJason Zhu 	return AVB_IO_RESULT_OK;
344*37a7bc39SJason Zhu }
345*37a7bc39SJason Zhu 
346*37a7bc39SJason Zhu AvbOps* avb_ops_user_new(void) {
347*37a7bc39SJason Zhu   AvbOps* ops;
348*37a7bc39SJason Zhu 
349*37a7bc39SJason Zhu   ops = calloc(1, sizeof(AvbOps));
350*37a7bc39SJason Zhu   if (ops == NULL) {
351*37a7bc39SJason Zhu     avb_error("Error allocating memory for AvbOps.\n");
352*37a7bc39SJason Zhu     goto out;
353*37a7bc39SJason Zhu   }
354*37a7bc39SJason Zhu 
355*37a7bc39SJason Zhu   ops->ab_ops = calloc(1, sizeof(AvbABOps));
356*37a7bc39SJason Zhu   if (ops->ab_ops == NULL) {
357*37a7bc39SJason Zhu     avb_error("Error allocating memory for AvbABOps.\n");
358*37a7bc39SJason Zhu     free(ops);
359*37a7bc39SJason Zhu     goto out;
360*37a7bc39SJason Zhu   }
361*37a7bc39SJason Zhu 
362*37a7bc39SJason Zhu   ops->atx_ops = calloc(1, sizeof(AvbAtxOps));
363*37a7bc39SJason Zhu   if (ops->atx_ops == NULL) {
364*37a7bc39SJason Zhu     avb_error("Error allocating memory for AvbAtxOps.\n");
365*37a7bc39SJason Zhu     free(ops->ab_ops);
366*37a7bc39SJason Zhu     free(ops);
367*37a7bc39SJason Zhu     goto out;
368*37a7bc39SJason Zhu   }
369*37a7bc39SJason Zhu   ops->ab_ops->ops = ops;
370*37a7bc39SJason Zhu   ops->atx_ops->ops = ops;
371*37a7bc39SJason Zhu 
372*37a7bc39SJason Zhu   ops->read_from_partition = read_from_partition;
373*37a7bc39SJason Zhu   ops->write_to_partition = write_to_partition;
374*37a7bc39SJason Zhu   ops->validate_vbmeta_public_key = validate_vbmeta_public_key;
375*37a7bc39SJason Zhu   ops->read_rollback_index = read_rollback_index;
376*37a7bc39SJason Zhu   ops->write_rollback_index = write_rollback_index;
377*37a7bc39SJason Zhu   ops->read_is_device_unlocked = read_is_device_unlocked;
378*37a7bc39SJason Zhu   ops->write_is_device_unlocked = write_is_device_unlocked;
379*37a7bc39SJason Zhu   ops->get_unique_guid_for_partition = get_unique_guid_for_partition;
380*37a7bc39SJason Zhu   ops->get_size_of_partition = get_size_of_partition;
381*37a7bc39SJason Zhu   ops->ab_ops->read_ab_metadata = avb_ab_data_read;
382*37a7bc39SJason Zhu   ops->ab_ops->write_ab_metadata = avb_ab_data_write;
383*37a7bc39SJason Zhu   ops->atx_ops->read_permanent_attributes = avb_read_perm_attr;
384*37a7bc39SJason Zhu   ops->atx_ops->read_permanent_attributes_hash = avb_read_perm_attr_hash;
385*37a7bc39SJason Zhu 
386*37a7bc39SJason Zhu out:
387*37a7bc39SJason Zhu   return ops;
388*37a7bc39SJason Zhu }
389*37a7bc39SJason Zhu 
390*37a7bc39SJason Zhu 
391*37a7bc39SJason Zhu void avb_ops_user_free(AvbOps* ops) {
392*37a7bc39SJason Zhu   free(ops->ab_ops);
393*37a7bc39SJason Zhu   free(ops->atx_ops);
394*37a7bc39SJason Zhu   free(ops);
395*37a7bc39SJason Zhu }
396