xref: /OK3568_Linux_fs/u-boot/lib/avb/libavb_user/avb_ops_user.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2017 The Android Open Source Project
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person
5*4882a593Smuzhiyun  * obtaining a copy of this software and associated documentation
6*4882a593Smuzhiyun  * files (the "Software"), to deal in the Software without
7*4882a593Smuzhiyun  * restriction, including without limitation the rights to use, copy,
8*4882a593Smuzhiyun  * modify, merge, publish, distribute, sublicense, and/or sell copies
9*4882a593Smuzhiyun  * of the Software, and to permit persons to whom the Software is
10*4882a593Smuzhiyun  * furnished to do so, subject to the following conditions:
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  * The above copyright notice and this permission notice shall be
13*4882a593Smuzhiyun  * included in all copies or substantial portions of the Software.
14*4882a593Smuzhiyun  *
15*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*4882a593Smuzhiyun  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*4882a593Smuzhiyun  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18*4882a593Smuzhiyun  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19*4882a593Smuzhiyun  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20*4882a593Smuzhiyun  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21*4882a593Smuzhiyun  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*4882a593Smuzhiyun  * SOFTWARE.
23*4882a593Smuzhiyun  */
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #include <common.h>
26*4882a593Smuzhiyun #include <image.h>
27*4882a593Smuzhiyun #include <android_image.h>
28*4882a593Smuzhiyun #include <malloc.h>
29*4882a593Smuzhiyun #include <mapmem.h>
30*4882a593Smuzhiyun #include <errno.h>
31*4882a593Smuzhiyun #include <command.h>
32*4882a593Smuzhiyun #include <mmc.h>
33*4882a593Smuzhiyun #include <blk.h>
34*4882a593Smuzhiyun #include <part.h>
35*4882a593Smuzhiyun #include <stdio.h>
36*4882a593Smuzhiyun #include <android_avb/avb_ops_user.h>
37*4882a593Smuzhiyun #include <android_avb/libavb_ab.h>
38*4882a593Smuzhiyun #include <android_avb/avb_atx_validate.h>
39*4882a593Smuzhiyun #include <android_avb/avb_atx_types.h>
40*4882a593Smuzhiyun #include <optee_include/OpteeClientInterface.h>
41*4882a593Smuzhiyun #include <optee_include/tee_api_defines.h>
42*4882a593Smuzhiyun #include <android_avb/avb_vbmeta_image.h>
43*4882a593Smuzhiyun #include <android_avb/avb_atx_validate.h>
44*4882a593Smuzhiyun #include <boot_rkimg.h>
45*4882a593Smuzhiyun 
byte_to_block(int64_t * offset,size_t * num_bytes,lbaint_t * offset_blk,lbaint_t * blkcnt)46*4882a593Smuzhiyun static void byte_to_block(int64_t *offset,
47*4882a593Smuzhiyun 			  size_t *num_bytes,
48*4882a593Smuzhiyun 			  lbaint_t *offset_blk,
49*4882a593Smuzhiyun 			  lbaint_t *blkcnt)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun 	*offset_blk = (lbaint_t)(*offset / 512);
52*4882a593Smuzhiyun 	if (*num_bytes % 512 == 0) {
53*4882a593Smuzhiyun 		if (*offset % 512 == 0)
54*4882a593Smuzhiyun 			*blkcnt = (lbaint_t)(*num_bytes / 512);
55*4882a593Smuzhiyun 		else
56*4882a593Smuzhiyun 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
57*4882a593Smuzhiyun 	} else {
58*4882a593Smuzhiyun 		if (*offset % 512 == 0) {
59*4882a593Smuzhiyun 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
60*4882a593Smuzhiyun 		} else {
61*4882a593Smuzhiyun 			if ((*offset % 512) + (*num_bytes % 512) < 512 ||
62*4882a593Smuzhiyun 			    (*offset % 512) + (*num_bytes % 512) == 512) {
63*4882a593Smuzhiyun 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
64*4882a593Smuzhiyun 			} else {
65*4882a593Smuzhiyun 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 2;
66*4882a593Smuzhiyun 			}
67*4882a593Smuzhiyun 		}
68*4882a593Smuzhiyun 	}
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
get_size_of_partition(AvbOps * ops,const char * partition,uint64_t * out_size_in_bytes)71*4882a593Smuzhiyun static AvbIOResult get_size_of_partition(AvbOps *ops,
72*4882a593Smuzhiyun 					 const char *partition,
73*4882a593Smuzhiyun 					 uint64_t *out_size_in_bytes)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun 	struct blk_desc *dev_desc;
76*4882a593Smuzhiyun 	disk_partition_t part_info;
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	dev_desc = rockchip_get_bootdev();
79*4882a593Smuzhiyun 	if (!dev_desc) {
80*4882a593Smuzhiyun 		printf("%s: Could not find device\n", __func__);
81*4882a593Smuzhiyun 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
82*4882a593Smuzhiyun 	}
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0)
85*4882a593Smuzhiyun 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	*out_size_in_bytes = (part_info.size) * 512;
88*4882a593Smuzhiyun 	return AVB_IO_RESULT_OK;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun 
read_from_partition(AvbOps * ops,const char * partition,int64_t offset,size_t num_bytes,void * buffer,size_t * out_num_read)91*4882a593Smuzhiyun static AvbIOResult read_from_partition(AvbOps *ops,
92*4882a593Smuzhiyun 				       const char *partition,
93*4882a593Smuzhiyun 				       int64_t offset,
94*4882a593Smuzhiyun 				       size_t num_bytes,
95*4882a593Smuzhiyun 				       void *buffer,
96*4882a593Smuzhiyun 				       size_t *out_num_read)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	struct blk_desc *dev_desc;
99*4882a593Smuzhiyun 	lbaint_t offset_blk, blkcnt;
100*4882a593Smuzhiyun 	disk_partition_t part_info;
101*4882a593Smuzhiyun 	uint64_t partition_size;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	if (offset < 0) {
104*4882a593Smuzhiyun 		if (get_size_of_partition(ops, partition, &partition_size))
105*4882a593Smuzhiyun 			return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 		if (-offset > partition_size)
108*4882a593Smuzhiyun 			return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 		offset = partition_size - (-offset);
111*4882a593Smuzhiyun 	}
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
114*4882a593Smuzhiyun 	dev_desc = rockchip_get_bootdev();
115*4882a593Smuzhiyun 	if (!dev_desc) {
116*4882a593Smuzhiyun 		printf("%s: Could not find device\n", __func__);
117*4882a593Smuzhiyun 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
118*4882a593Smuzhiyun 	}
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
121*4882a593Smuzhiyun 		printf("Could not find \"%s\" partition\n", partition);
122*4882a593Smuzhiyun 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
123*4882a593Smuzhiyun 	}
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	if ((offset % 512 == 0) && (num_bytes % 512 == 0)) {
126*4882a593Smuzhiyun 		blk_dread(dev_desc, part_info.start + offset_blk,
127*4882a593Smuzhiyun 			  blkcnt, buffer);
128*4882a593Smuzhiyun 		*out_num_read = blkcnt * 512;
129*4882a593Smuzhiyun 	} else {
130*4882a593Smuzhiyun 		char *buffer_temp;
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 		buffer_temp = malloc(512 * blkcnt);
133*4882a593Smuzhiyun 		if (!buffer_temp) {
134*4882a593Smuzhiyun 			printf("malloc error!\n");
135*4882a593Smuzhiyun 			return AVB_IO_RESULT_ERROR_OOM;
136*4882a593Smuzhiyun 		}
137*4882a593Smuzhiyun 		blk_dread(dev_desc, part_info.start + offset_blk,
138*4882a593Smuzhiyun 			  blkcnt, buffer_temp);
139*4882a593Smuzhiyun 		memcpy(buffer, buffer_temp + (offset % 512), num_bytes);
140*4882a593Smuzhiyun 		*out_num_read = num_bytes;
141*4882a593Smuzhiyun 		free(buffer_temp);
142*4882a593Smuzhiyun 	}
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	return AVB_IO_RESULT_OK;
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun 
write_to_partition(AvbOps * ops,const char * partition,int64_t offset,size_t num_bytes,const void * buffer)147*4882a593Smuzhiyun static AvbIOResult write_to_partition(AvbOps *ops,
148*4882a593Smuzhiyun 				      const char *partition,
149*4882a593Smuzhiyun 				      int64_t offset,
150*4882a593Smuzhiyun 				      size_t num_bytes,
151*4882a593Smuzhiyun 				      const void *buffer)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun 	struct blk_desc *dev_desc;
154*4882a593Smuzhiyun 	char *buffer_temp;
155*4882a593Smuzhiyun 	disk_partition_t part_info;
156*4882a593Smuzhiyun 	lbaint_t offset_blk, blkcnt;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
159*4882a593Smuzhiyun 	buffer_temp = malloc(512 * blkcnt);
160*4882a593Smuzhiyun 	if (!buffer_temp) {
161*4882a593Smuzhiyun 		printf("malloc error!\n");
162*4882a593Smuzhiyun 		return AVB_IO_RESULT_ERROR_OOM;
163*4882a593Smuzhiyun 	}
164*4882a593Smuzhiyun 	memset(buffer_temp, 0, 512 * blkcnt);
165*4882a593Smuzhiyun 	dev_desc = rockchip_get_bootdev();
166*4882a593Smuzhiyun 	if (!dev_desc) {
167*4882a593Smuzhiyun 		printf("%s: Could not find device\n", __func__);
168*4882a593Smuzhiyun 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
169*4882a593Smuzhiyun 	}
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
172*4882a593Smuzhiyun 		printf("Could not find \"%s\" partition\n", partition);
173*4882a593Smuzhiyun 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
174*4882a593Smuzhiyun 	}
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	if ((offset % 512 != 0) && (num_bytes % 512) != 0)
177*4882a593Smuzhiyun 		blk_dread(dev_desc, part_info.start + offset_blk,
178*4882a593Smuzhiyun 			  blkcnt, buffer_temp);
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	memcpy(buffer_temp, buffer + (offset % 512), num_bytes);
181*4882a593Smuzhiyun 	blk_dwrite(dev_desc, part_info.start + offset_blk, blkcnt, buffer);
182*4882a593Smuzhiyun 	free(buffer_temp);
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	return AVB_IO_RESULT_OK;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun static AvbIOResult
validate_vbmeta_public_key(AvbOps * ops,const uint8_t * public_key_data,size_t public_key_length,const uint8_t * public_key_metadata,size_t public_key_metadata_length,bool * out_is_trusted)188*4882a593Smuzhiyun validate_vbmeta_public_key(AvbOps *ops,
189*4882a593Smuzhiyun 			   const uint8_t *public_key_data,
190*4882a593Smuzhiyun 			   size_t public_key_length,
191*4882a593Smuzhiyun 			   const uint8_t *public_key_metadata,
192*4882a593Smuzhiyun 			   size_t public_key_metadata_length,
193*4882a593Smuzhiyun 			   bool *out_is_trusted)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun /* remain AVB_VBMETA_PUBLIC_KEY_VALIDATE to compatible legacy code */
196*4882a593Smuzhiyun #if defined(CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE) || \
197*4882a593Smuzhiyun     defined(AVB_VBMETA_PUBLIC_KEY_VALIDATE)
198*4882a593Smuzhiyun 	if (out_is_trusted) {
199*4882a593Smuzhiyun 		avb_atx_validate_vbmeta_public_key(ops,
200*4882a593Smuzhiyun 						   public_key_data,
201*4882a593Smuzhiyun 						   public_key_length,
202*4882a593Smuzhiyun 						   public_key_metadata,
203*4882a593Smuzhiyun 						   public_key_metadata_length,
204*4882a593Smuzhiyun 						   out_is_trusted);
205*4882a593Smuzhiyun 	}
206*4882a593Smuzhiyun #else
207*4882a593Smuzhiyun 	if (out_is_trusted)
208*4882a593Smuzhiyun 		*out_is_trusted = true;
209*4882a593Smuzhiyun #endif
210*4882a593Smuzhiyun 	return AVB_IO_RESULT_OK;
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun 
read_rollback_index(AvbOps * ops,size_t rollback_index_location,uint64_t * out_rollback_index)213*4882a593Smuzhiyun static AvbIOResult read_rollback_index(AvbOps *ops,
214*4882a593Smuzhiyun 				       size_t rollback_index_location,
215*4882a593Smuzhiyun 				       uint64_t *out_rollback_index)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun 	if (out_rollback_index) {
218*4882a593Smuzhiyun #ifdef CONFIG_OPTEE_CLIENT
219*4882a593Smuzhiyun 		int ret;
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun 		ret = trusty_read_rollback_index(rollback_index_location,
222*4882a593Smuzhiyun 						 out_rollback_index);
223*4882a593Smuzhiyun 		switch (ret) {
224*4882a593Smuzhiyun 		case TEE_SUCCESS:
225*4882a593Smuzhiyun 			ret = AVB_IO_RESULT_OK;
226*4882a593Smuzhiyun 			break;
227*4882a593Smuzhiyun 		case TEE_ERROR_GENERIC:
228*4882a593Smuzhiyun 		case TEE_ERROR_NO_DATA:
229*4882a593Smuzhiyun 		case TEE_ERROR_ITEM_NOT_FOUND:
230*4882a593Smuzhiyun 			*out_rollback_index = 0;
231*4882a593Smuzhiyun 			ret = trusty_write_rollback_index(rollback_index_location,
232*4882a593Smuzhiyun 							  *out_rollback_index);
233*4882a593Smuzhiyun 			if (ret) {
234*4882a593Smuzhiyun 				printf("%s: init rollback index error\n",
235*4882a593Smuzhiyun 				       __FILE__);
236*4882a593Smuzhiyun 				ret = AVB_IO_RESULT_ERROR_IO;
237*4882a593Smuzhiyun 			} else {
238*4882a593Smuzhiyun 				ret =
239*4882a593Smuzhiyun 				trusty_read_rollback_index(rollback_index_location,
240*4882a593Smuzhiyun 							   out_rollback_index);
241*4882a593Smuzhiyun 				if (ret)
242*4882a593Smuzhiyun 					ret = AVB_IO_RESULT_ERROR_IO;
243*4882a593Smuzhiyun 				else
244*4882a593Smuzhiyun 					ret = AVB_IO_RESULT_OK;
245*4882a593Smuzhiyun 			}
246*4882a593Smuzhiyun 			break;
247*4882a593Smuzhiyun 		default:
248*4882a593Smuzhiyun 			ret = AVB_IO_RESULT_ERROR_IO;
249*4882a593Smuzhiyun 			printf("%s: trusty_read_rollback_index failed",
250*4882a593Smuzhiyun 			       __FILE__);
251*4882a593Smuzhiyun 		}
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 		return ret;
254*4882a593Smuzhiyun #else
255*4882a593Smuzhiyun 		*out_rollback_index = 0;
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 		return AVB_IO_RESULT_OK;
258*4882a593Smuzhiyun #endif
259*4882a593Smuzhiyun 	}
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	return AVB_IO_RESULT_ERROR_IO;
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun 
write_rollback_index(AvbOps * ops,size_t rollback_index_location,uint64_t rollback_index)264*4882a593Smuzhiyun static AvbIOResult write_rollback_index(AvbOps *ops,
265*4882a593Smuzhiyun 					size_t rollback_index_location,
266*4882a593Smuzhiyun 					uint64_t rollback_index)
267*4882a593Smuzhiyun {
268*4882a593Smuzhiyun #ifdef CONFIG_OPTEE_CLIENT
269*4882a593Smuzhiyun 	if (trusty_write_rollback_index(rollback_index_location,
270*4882a593Smuzhiyun 					rollback_index)) {
271*4882a593Smuzhiyun 		printf("%s: Fail to write rollback index\n", __FILE__);
272*4882a593Smuzhiyun 		return AVB_IO_RESULT_ERROR_IO;
273*4882a593Smuzhiyun 	}
274*4882a593Smuzhiyun 	return AVB_IO_RESULT_OK;
275*4882a593Smuzhiyun #endif
276*4882a593Smuzhiyun 	return AVB_IO_RESULT_ERROR_IO;
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun 
read_is_device_unlocked(AvbOps * ops,bool * out_is_unlocked)279*4882a593Smuzhiyun static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun 	if (out_is_unlocked) {
282*4882a593Smuzhiyun #ifdef CONFIG_OPTEE_CLIENT
283*4882a593Smuzhiyun 		uint8_t vboot_flag = 0;
284*4882a593Smuzhiyun 		int ret;
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 		ret = trusty_read_lock_state((uint8_t *)out_is_unlocked);
287*4882a593Smuzhiyun 		switch (ret) {
288*4882a593Smuzhiyun 		case TEE_SUCCESS:
289*4882a593Smuzhiyun 			ret = AVB_IO_RESULT_OK;
290*4882a593Smuzhiyun 			break;
291*4882a593Smuzhiyun 		case TEE_ERROR_GENERIC:
292*4882a593Smuzhiyun 		case TEE_ERROR_NO_DATA:
293*4882a593Smuzhiyun 		case TEE_ERROR_ITEM_NOT_FOUND:
294*4882a593Smuzhiyun 			if (trusty_read_vbootkey_enable_flag(&vboot_flag)) {
295*4882a593Smuzhiyun 				printf("Can't read vboot flag\n");
296*4882a593Smuzhiyun 				return AVB_IO_RESULT_ERROR_IO;
297*4882a593Smuzhiyun 			}
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 			if (vboot_flag)
300*4882a593Smuzhiyun 				*out_is_unlocked = 0;
301*4882a593Smuzhiyun 			else
302*4882a593Smuzhiyun 				*out_is_unlocked = 1;
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 			if (trusty_write_lock_state(*out_is_unlocked)) {
305*4882a593Smuzhiyun 				printf("%s: init lock state error\n", __FILE__);
306*4882a593Smuzhiyun 				ret = AVB_IO_RESULT_ERROR_IO;
307*4882a593Smuzhiyun 			} else {
308*4882a593Smuzhiyun 				ret =
309*4882a593Smuzhiyun 				trusty_read_lock_state((uint8_t *)out_is_unlocked);
310*4882a593Smuzhiyun 				if (ret == 0)
311*4882a593Smuzhiyun 					ret = AVB_IO_RESULT_OK;
312*4882a593Smuzhiyun 				else
313*4882a593Smuzhiyun 					ret = AVB_IO_RESULT_ERROR_IO;
314*4882a593Smuzhiyun 			}
315*4882a593Smuzhiyun 			break;
316*4882a593Smuzhiyun 		default:
317*4882a593Smuzhiyun 			ret = AVB_IO_RESULT_ERROR_IO;
318*4882a593Smuzhiyun 			printf("%s: trusty_read_lock_state failed\n", __FILE__);
319*4882a593Smuzhiyun 		}
320*4882a593Smuzhiyun 		return ret;
321*4882a593Smuzhiyun #else
322*4882a593Smuzhiyun 		*out_is_unlocked = 1;
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 		return AVB_IO_RESULT_OK;
325*4882a593Smuzhiyun #endif
326*4882a593Smuzhiyun 	}
327*4882a593Smuzhiyun 	return AVB_IO_RESULT_ERROR_IO;
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun 
write_is_device_unlocked(AvbOps * ops,bool * out_is_unlocked)330*4882a593Smuzhiyun static AvbIOResult write_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
331*4882a593Smuzhiyun {
332*4882a593Smuzhiyun 	if (out_is_unlocked) {
333*4882a593Smuzhiyun #ifdef CONFIG_OPTEE_CLIENT
334*4882a593Smuzhiyun 		if (trusty_write_lock_state(*out_is_unlocked)) {
335*4882a593Smuzhiyun 			printf("%s: Fail to write lock state\n", __FILE__);
336*4882a593Smuzhiyun 			return AVB_IO_RESULT_ERROR_IO;
337*4882a593Smuzhiyun 		}
338*4882a593Smuzhiyun 		return AVB_IO_RESULT_OK;
339*4882a593Smuzhiyun #endif
340*4882a593Smuzhiyun 	}
341*4882a593Smuzhiyun 	return AVB_IO_RESULT_ERROR_IO;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun 
get_unique_guid_for_partition(AvbOps * ops,const char * partition,char * guid_buf,size_t guid_buf_size)344*4882a593Smuzhiyun static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
345*4882a593Smuzhiyun 						 const char *partition,
346*4882a593Smuzhiyun 						 char *guid_buf,
347*4882a593Smuzhiyun 						 size_t guid_buf_size)
348*4882a593Smuzhiyun {
349*4882a593Smuzhiyun 	struct blk_desc *dev_desc;
350*4882a593Smuzhiyun 	disk_partition_t part_info;
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	dev_desc = rockchip_get_bootdev();
353*4882a593Smuzhiyun 	if (!dev_desc) {
354*4882a593Smuzhiyun 		printf("%s: Could not find device\n", __func__);
355*4882a593Smuzhiyun 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
356*4882a593Smuzhiyun 	}
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
359*4882a593Smuzhiyun 		printf("Could not find \"%s\" partition\n", partition);
360*4882a593Smuzhiyun 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
361*4882a593Smuzhiyun 	}
362*4882a593Smuzhiyun 	if (guid_buf && guid_buf_size > 0)
363*4882a593Smuzhiyun 		memcpy(guid_buf, part_info.uuid, guid_buf_size);
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 	return AVB_IO_RESULT_OK;
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun /* read permanent attributes from rpmb */
avb_read_perm_attr(AvbAtxOps * atx_ops,AvbAtxPermanentAttributes * attributes)369*4882a593Smuzhiyun AvbIOResult avb_read_perm_attr(AvbAtxOps *atx_ops,
370*4882a593Smuzhiyun 			       AvbAtxPermanentAttributes *attributes)
371*4882a593Smuzhiyun {
372*4882a593Smuzhiyun 	if (attributes) {
373*4882a593Smuzhiyun #ifdef CONFIG_OPTEE_CLIENT
374*4882a593Smuzhiyun 		trusty_read_permanent_attributes((uint8_t *)attributes,
375*4882a593Smuzhiyun 						 sizeof(struct AvbAtxPermanentAttributes));
376*4882a593Smuzhiyun 		return AVB_IO_RESULT_OK;
377*4882a593Smuzhiyun #endif
378*4882a593Smuzhiyun 	}
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	return -1;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun /*read permanent attributes hash from efuse */
avb_read_perm_attr_hash(AvbAtxOps * atx_ops,uint8_t hash[AVB_SHA256_DIGEST_SIZE])384*4882a593Smuzhiyun AvbIOResult avb_read_perm_attr_hash(AvbAtxOps *atx_ops,
385*4882a593Smuzhiyun 				    uint8_t hash[AVB_SHA256_DIGEST_SIZE])
386*4882a593Smuzhiyun {
387*4882a593Smuzhiyun #ifndef CONFIG_ROCKCHIP_PRELOADER_PUB_KEY
388*4882a593Smuzhiyun #ifdef CONFIG_OPTEE_CLIENT
389*4882a593Smuzhiyun 	if (trusty_read_attribute_hash((uint32_t *)hash,
390*4882a593Smuzhiyun 				       AVB_SHA256_DIGEST_SIZE / 4))
391*4882a593Smuzhiyun 		return -1;
392*4882a593Smuzhiyun #else
393*4882a593Smuzhiyun 	printf("Please open the macro!\n");
394*4882a593Smuzhiyun 	return -1;
395*4882a593Smuzhiyun #endif
396*4882a593Smuzhiyun #endif
397*4882a593Smuzhiyun 	return AVB_IO_RESULT_OK;
398*4882a593Smuzhiyun }
399*4882a593Smuzhiyun 
avb_set_key_version(AvbAtxOps * atx_ops,size_t rollback_index_location,uint64_t key_version)400*4882a593Smuzhiyun static void avb_set_key_version(AvbAtxOps *atx_ops,
401*4882a593Smuzhiyun 				size_t rollback_index_location,
402*4882a593Smuzhiyun 				uint64_t key_version)
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun #ifdef CONFIG_OPTEE_CLIENT
405*4882a593Smuzhiyun 	uint64_t key_version_temp = 0;
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	if (trusty_read_rollback_index(rollback_index_location, &key_version_temp))
408*4882a593Smuzhiyun 		printf("%s: Fail to read rollback index\n", __FILE__);
409*4882a593Smuzhiyun 	if (key_version_temp == key_version)
410*4882a593Smuzhiyun 		return;
411*4882a593Smuzhiyun 	if (trusty_write_rollback_index(rollback_index_location, key_version))
412*4882a593Smuzhiyun 		printf("%s: Fail to write rollback index\n", __FILE__);
413*4882a593Smuzhiyun #endif
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun 
rk_get_random(AvbAtxOps * atx_ops,size_t num_bytes,uint8_t * output)416*4882a593Smuzhiyun AvbIOResult rk_get_random(AvbAtxOps *atx_ops,
417*4882a593Smuzhiyun 			  size_t num_bytes,
418*4882a593Smuzhiyun 			  uint8_t *output)
419*4882a593Smuzhiyun {
420*4882a593Smuzhiyun 	int i;
421*4882a593Smuzhiyun 	unsigned int seed;
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun 	seed = (unsigned int)get_timer(0);
424*4882a593Smuzhiyun 	for (i = 0; i < num_bytes; i++) {
425*4882a593Smuzhiyun 		srand(seed);
426*4882a593Smuzhiyun 		output[i] = (uint8_t)(rand());
427*4882a593Smuzhiyun 		seed = (unsigned int)(output[i]);
428*4882a593Smuzhiyun 	}
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 	return 0;
431*4882a593Smuzhiyun }
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun #ifdef CONFIG_ANDROID_BOOT_IMAGE
get_preloaded_partition(AvbOps * ops,const char * partition,size_t num_bytes,uint8_t ** out_pointer,size_t * out_num_bytes_preloaded,int allow_verification_error)434*4882a593Smuzhiyun static AvbIOResult get_preloaded_partition(AvbOps* ops,
435*4882a593Smuzhiyun 					   const char* partition,
436*4882a593Smuzhiyun 					   size_t num_bytes,
437*4882a593Smuzhiyun 					   uint8_t** out_pointer,
438*4882a593Smuzhiyun 					   size_t* out_num_bytes_preloaded,
439*4882a593Smuzhiyun 					   int allow_verification_error)
440*4882a593Smuzhiyun {
441*4882a593Smuzhiyun 	struct preloaded_partition *preload_info = NULL;
442*4882a593Smuzhiyun 	struct AvbOpsData *data = ops->user_data;
443*4882a593Smuzhiyun 	struct blk_desc *dev_desc;
444*4882a593Smuzhiyun 	disk_partition_t part_info;
445*4882a593Smuzhiyun 	ulong load_addr;
446*4882a593Smuzhiyun 	AvbIOResult ret;
447*4882a593Smuzhiyun 	int full_preload = 0;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	dev_desc = rockchip_get_bootdev();
450*4882a593Smuzhiyun 	if (!dev_desc)
451*4882a593Smuzhiyun 		return AVB_IO_RESULT_ERROR_IO;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
454*4882a593Smuzhiyun 		printf("Could not find \"%s\" partition\n", partition);
455*4882a593Smuzhiyun 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
456*4882a593Smuzhiyun 	}
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 	if (!allow_verification_error) {
459*4882a593Smuzhiyun 		if (!strncmp(partition, ANDROID_PARTITION_BOOT, 4) ||
460*4882a593Smuzhiyun 		    !strncmp(partition, ANDROID_PARTITION_RECOVERY, 8))
461*4882a593Smuzhiyun 			preload_info = &data->boot;
462*4882a593Smuzhiyun 		else if (!strncmp(partition, ANDROID_PARTITION_VENDOR_BOOT, 11))
463*4882a593Smuzhiyun 			preload_info = &data->vendor_boot;
464*4882a593Smuzhiyun 		else if (!strncmp(partition, ANDROID_PARTITION_INIT_BOOT, 9))
465*4882a593Smuzhiyun 			preload_info = &data->init_boot;
466*4882a593Smuzhiyun 		else if (!strncmp(partition, ANDROID_PARTITION_RESOURCE, 8))
467*4882a593Smuzhiyun 			preload_info = &data->resource;
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun 		if (!preload_info) {
470*4882a593Smuzhiyun 			printf("Error: unknown full load partition '%s'\n", partition);
471*4882a593Smuzhiyun 			return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
472*4882a593Smuzhiyun 		}
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 		printf("preloaded(s): %sfull image from '%s' at 0x%08lx - 0x%08lx\n",
475*4882a593Smuzhiyun 		       preload_info->size ? "pre-" : "", partition,
476*4882a593Smuzhiyun 		       (ulong)preload_info->addr,
477*4882a593Smuzhiyun 		       (ulong)preload_info->addr + num_bytes);
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun 		/* If the partition hasn't yet been preloaded, do it now.*/
480*4882a593Smuzhiyun 		if (preload_info->size == 0) {
481*4882a593Smuzhiyun 			ret = ops->read_from_partition(ops, partition,
482*4882a593Smuzhiyun 						       0, num_bytes,
483*4882a593Smuzhiyun 						       preload_info->addr,
484*4882a593Smuzhiyun 						       &preload_info->size);
485*4882a593Smuzhiyun 			if (ret != AVB_IO_RESULT_OK)
486*4882a593Smuzhiyun 				return ret;
487*4882a593Smuzhiyun 		}
488*4882a593Smuzhiyun 		*out_pointer = preload_info->addr;
489*4882a593Smuzhiyun 		*out_num_bytes_preloaded = preload_info->size;
490*4882a593Smuzhiyun 		ret = AVB_IO_RESULT_OK;
491*4882a593Smuzhiyun 	} else {
492*4882a593Smuzhiyun 		if (!strncmp(partition, ANDROID_PARTITION_INIT_BOOT, 9) ||
493*4882a593Smuzhiyun 		    !strncmp(partition, ANDROID_PARTITION_VENDOR_BOOT, 11) ||
494*4882a593Smuzhiyun 		    !strncmp(partition, ANDROID_PARTITION_BOOT, 4) ||
495*4882a593Smuzhiyun 		    !strncmp(partition, ANDROID_PARTITION_RECOVERY, 8) ||
496*4882a593Smuzhiyun 		    !strncmp(partition, ANDROID_PARTITION_RESOURCE, 8)) {
497*4882a593Smuzhiyun 			/* If already full preloaded, just use it */
498*4882a593Smuzhiyun 			if (!strncmp(partition, ANDROID_PARTITION_BOOT, 4) ||
499*4882a593Smuzhiyun 			    !strncmp(partition, ANDROID_PARTITION_RECOVERY, 8)) {
500*4882a593Smuzhiyun 				preload_info = &data->boot;
501*4882a593Smuzhiyun 				if (preload_info->size) {
502*4882a593Smuzhiyun 					*out_pointer = preload_info->addr;
503*4882a593Smuzhiyun 					*out_num_bytes_preloaded = num_bytes;
504*4882a593Smuzhiyun 					full_preload = 1;
505*4882a593Smuzhiyun 				}
506*4882a593Smuzhiyun 			}
507*4882a593Smuzhiyun 			printf("preloaded: %s image from '%s\n",
508*4882a593Smuzhiyun 			       full_preload ? "pre-full" : "distribute", partition);
509*4882a593Smuzhiyun 		} else {
510*4882a593Smuzhiyun 			printf("Error: unknown preloaded partition '%s'\n", partition);
511*4882a593Smuzhiyun 			return AVB_IO_RESULT_ERROR_OOM;
512*4882a593Smuzhiyun 		}
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 		/*
515*4882a593Smuzhiyun 		 * Already preloaded during boot/recovery loading,
516*4882a593Smuzhiyun 		 * here we just return a dummy buffer.
517*4882a593Smuzhiyun 		 */
518*4882a593Smuzhiyun 		if (!strncmp(partition, ANDROID_PARTITION_INIT_BOOT, 9) ||
519*4882a593Smuzhiyun 		    !strncmp(partition, ANDROID_PARTITION_VENDOR_BOOT, 11) ||
520*4882a593Smuzhiyun 		    !strncmp(partition, ANDROID_PARTITION_RESOURCE, 8)) {
521*4882a593Smuzhiyun 			*out_pointer = (u8 *)avb_malloc(ARCH_DMA_MINALIGN);
522*4882a593Smuzhiyun 			*out_num_bytes_preloaded = num_bytes; /* return what it expects */
523*4882a593Smuzhiyun 			return AVB_IO_RESULT_OK;
524*4882a593Smuzhiyun 		}
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 		/* If already full preloaded, there is nothing to do and just return */
527*4882a593Smuzhiyun 		if (full_preload)
528*4882a593Smuzhiyun 			return AVB_IO_RESULT_OK;
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 		/*
531*4882a593Smuzhiyun 		 * only boot/recovery partition can reach here
532*4882a593Smuzhiyun 		 * and init/vendor_boot are loaded at this round.
533*4882a593Smuzhiyun 		 */
534*4882a593Smuzhiyun 		load_addr = env_get_ulong("kernel_addr_r", 16, 0);
535*4882a593Smuzhiyun 		if (!load_addr)
536*4882a593Smuzhiyun 			return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE;
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 		ret = android_image_load_by_partname(dev_desc, partition, &load_addr);
539*4882a593Smuzhiyun 		if (!ret) {
540*4882a593Smuzhiyun 			*out_pointer = (u8 *)load_addr;
541*4882a593Smuzhiyun 			*out_num_bytes_preloaded = num_bytes; /* return what it expects */
542*4882a593Smuzhiyun 			ret = AVB_IO_RESULT_OK;
543*4882a593Smuzhiyun 		} else {
544*4882a593Smuzhiyun 			ret = AVB_IO_RESULT_ERROR_IO;
545*4882a593Smuzhiyun 		}
546*4882a593Smuzhiyun 	}
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 	return ret;
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun #endif
551*4882a593Smuzhiyun 
validate_public_key_for_partition(AvbOps * ops,const char * partition,const uint8_t * public_key_data,size_t public_key_length,const uint8_t * public_key_metadata,size_t public_key_metadata_length,bool * out_is_trusted,uint32_t * out_rollback_index_location)552*4882a593Smuzhiyun AvbIOResult validate_public_key_for_partition(AvbOps *ops,
553*4882a593Smuzhiyun 					      const char *partition,
554*4882a593Smuzhiyun 					      const uint8_t *public_key_data,
555*4882a593Smuzhiyun 					      size_t public_key_length,
556*4882a593Smuzhiyun 					      const uint8_t *public_key_metadata,
557*4882a593Smuzhiyun 					      size_t public_key_metadata_length,
558*4882a593Smuzhiyun 					      bool *out_is_trusted,
559*4882a593Smuzhiyun 					      uint32_t *out_rollback_index_location)
560*4882a593Smuzhiyun {
561*4882a593Smuzhiyun /* remain AVB_VBMETA_PUBLIC_KEY_VALIDATE to compatible legacy code */
562*4882a593Smuzhiyun #if defined(CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE) || \
563*4882a593Smuzhiyun     defined(AVB_VBMETA_PUBLIC_KEY_VALIDATE)
564*4882a593Smuzhiyun 	if (out_is_trusted) {
565*4882a593Smuzhiyun 		avb_atx_validate_vbmeta_public_key(ops,
566*4882a593Smuzhiyun 						   public_key_data,
567*4882a593Smuzhiyun 						   public_key_length,
568*4882a593Smuzhiyun 						   public_key_metadata,
569*4882a593Smuzhiyun 						   public_key_metadata_length,
570*4882a593Smuzhiyun 						   out_is_trusted);
571*4882a593Smuzhiyun 	}
572*4882a593Smuzhiyun #else
573*4882a593Smuzhiyun 	if (out_is_trusted)
574*4882a593Smuzhiyun 		*out_is_trusted = true;
575*4882a593Smuzhiyun #endif
576*4882a593Smuzhiyun 	*out_rollback_index_location = 0;
577*4882a593Smuzhiyun 	return AVB_IO_RESULT_OK;
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun 
avb_ops_user_new(void)580*4882a593Smuzhiyun AvbOps *avb_ops_user_new(void)
581*4882a593Smuzhiyun {
582*4882a593Smuzhiyun 	AvbOps *ops = NULL;
583*4882a593Smuzhiyun 	struct AvbOpsData *ops_data = NULL;
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 	ops = calloc(1, sizeof(AvbOps));
586*4882a593Smuzhiyun 	if (!ops) {
587*4882a593Smuzhiyun 		printf("Error allocating memory for AvbOps.\n");
588*4882a593Smuzhiyun 		goto out;
589*4882a593Smuzhiyun 	}
590*4882a593Smuzhiyun 	ops->ab_ops = calloc(1, sizeof(AvbABOps));
591*4882a593Smuzhiyun 	if (!ops->ab_ops) {
592*4882a593Smuzhiyun 		printf("Error allocating memory for AvbABOps.\n");
593*4882a593Smuzhiyun 		free(ops);
594*4882a593Smuzhiyun 		goto out;
595*4882a593Smuzhiyun 	}
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun 	ops->atx_ops = calloc(1, sizeof(AvbAtxOps));
598*4882a593Smuzhiyun 	if (!ops->atx_ops) {
599*4882a593Smuzhiyun 		printf("Error allocating memory for AvbAtxOps.\n");
600*4882a593Smuzhiyun 		free(ops->ab_ops);
601*4882a593Smuzhiyun 		free(ops);
602*4882a593Smuzhiyun 		goto out;
603*4882a593Smuzhiyun 	}
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 	ops_data = calloc(1, sizeof(struct AvbOpsData));
606*4882a593Smuzhiyun 	if (!ops_data) {
607*4882a593Smuzhiyun 		printf("Error allocating memory for AvbOpsData.\n");
608*4882a593Smuzhiyun 		free(ops->atx_ops);
609*4882a593Smuzhiyun 		free(ops->ab_ops);
610*4882a593Smuzhiyun 		free(ops);
611*4882a593Smuzhiyun 		goto out;
612*4882a593Smuzhiyun 	}
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 	ops->ab_ops->ops = ops;
615*4882a593Smuzhiyun 	ops->atx_ops->ops = ops;
616*4882a593Smuzhiyun 	ops_data->ops = ops;
617*4882a593Smuzhiyun 	ops->user_data = ops_data;
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun 	ops->read_from_partition = read_from_partition;
620*4882a593Smuzhiyun 	ops->write_to_partition = write_to_partition;
621*4882a593Smuzhiyun 	ops->validate_vbmeta_public_key = validate_vbmeta_public_key;
622*4882a593Smuzhiyun 	ops->read_rollback_index = read_rollback_index;
623*4882a593Smuzhiyun 	ops->write_rollback_index = write_rollback_index;
624*4882a593Smuzhiyun 	ops->read_is_device_unlocked = read_is_device_unlocked;
625*4882a593Smuzhiyun 	ops->write_is_device_unlocked = write_is_device_unlocked;
626*4882a593Smuzhiyun 	ops->get_unique_guid_for_partition = get_unique_guid_for_partition;
627*4882a593Smuzhiyun 	ops->get_size_of_partition = get_size_of_partition;
628*4882a593Smuzhiyun #ifdef CONFIG_ANDROID_BOOT_IMAGE
629*4882a593Smuzhiyun 	ops->get_preloaded_partition = get_preloaded_partition;
630*4882a593Smuzhiyun #endif
631*4882a593Smuzhiyun 	ops->validate_public_key_for_partition = validate_public_key_for_partition;
632*4882a593Smuzhiyun 	ops->ab_ops->read_ab_metadata = avb_ab_data_read;
633*4882a593Smuzhiyun 	ops->ab_ops->write_ab_metadata = avb_ab_data_write;
634*4882a593Smuzhiyun 	ops->atx_ops->read_permanent_attributes = avb_read_perm_attr;
635*4882a593Smuzhiyun 	ops->atx_ops->read_permanent_attributes_hash = avb_read_perm_attr_hash;
636*4882a593Smuzhiyun 	ops->atx_ops->set_key_version = avb_set_key_version;
637*4882a593Smuzhiyun 	ops->atx_ops->get_random = rk_get_random;
638*4882a593Smuzhiyun 
639*4882a593Smuzhiyun 	return ops;
640*4882a593Smuzhiyun out:
641*4882a593Smuzhiyun 	return NULL;
642*4882a593Smuzhiyun }
643*4882a593Smuzhiyun 
avb_ops_user_free(AvbOps * ops)644*4882a593Smuzhiyun void avb_ops_user_free(AvbOps *ops)
645*4882a593Smuzhiyun {
646*4882a593Smuzhiyun 	free(ops->user_data);
647*4882a593Smuzhiyun 	free(ops->ab_ops);
648*4882a593Smuzhiyun 	free(ops->atx_ops);
649*4882a593Smuzhiyun 	free(ops);
650*4882a593Smuzhiyun }
651