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