Commit 3fc3f521957677b1f363624494ed866985a25505
1 parent
6c1087c030
Exists in
smarc_8mm-imx_v2019.04_4.19.35_1.1.0
and in
1 other branch
MA-15151 Limit some hwcrypto commands within bootloader
It can be dangerous to export some hwcrypto commands to Linux, add commands to limit some commands within bootloader. Test: hwcrypto commands can't be used after locking boot state. Change-Id: Ib0a96a87f661778c133178840d8dccf49f151c22 Signed-off-by: Ji Luo <ji.luo@nxp.com>
Showing 4 changed files with 15 additions and 0 deletions Inline Diff
drivers/fastboot/fb_fsl/fb_fsl_boot.c
1 | // SPDX-License-Identifier: GPL-2.0+ | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | 2 | /* |
3 | * Copyright 2019 NXP | 3 | * Copyright 2019 NXP |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <asm/mach-imx/sys_proto.h> | 6 | #include <asm/mach-imx/sys_proto.h> |
7 | #include <fb_fsl.h> | 7 | #include <fb_fsl.h> |
8 | #include <fastboot.h> | 8 | #include <fastboot.h> |
9 | #include <mmc.h> | 9 | #include <mmc.h> |
10 | #include <android_image.h> | 10 | #include <android_image.h> |
11 | #include <asm/bootm.h> | 11 | #include <asm/bootm.h> |
12 | #include <nand.h> | 12 | #include <nand.h> |
13 | #include <part.h> | 13 | #include <part.h> |
14 | #include <sparse_format.h> | 14 | #include <sparse_format.h> |
15 | #include <image-sparse.h> | 15 | #include <image-sparse.h> |
16 | #include <image.h> | 16 | #include <image.h> |
17 | #include <asm/mach-imx/boot_mode.h> | 17 | #include <asm/mach-imx/boot_mode.h> |
18 | #include <asm/arch/sys_proto.h> | 18 | #include <asm/arch/sys_proto.h> |
19 | #include <asm/setup.h> | 19 | #include <asm/setup.h> |
20 | #include <environment.h> | 20 | #include <environment.h> |
21 | #include "../lib/avb/fsl/utils.h" | 21 | #include "../lib/avb/fsl/utils.h" |
22 | 22 | ||
23 | #ifdef CONFIG_AVB_SUPPORT | 23 | #ifdef CONFIG_AVB_SUPPORT |
24 | #include <dt_table.h> | 24 | #include <dt_table.h> |
25 | #include <fsl_avb.h> | 25 | #include <fsl_avb.h> |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT | 28 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT |
29 | #include <asm-generic/gpio.h> | 29 | #include <asm-generic/gpio.h> |
30 | #include <asm/mach-imx/gpio.h> | 30 | #include <asm/mach-imx/gpio.h> |
31 | #include "../lib/avb/fsl/fsl_avbkey.h" | 31 | #include "../lib/avb/fsl/fsl_avbkey.h" |
32 | #include "../arch/arm/include/asm/mach-imx/hab.h" | 32 | #include "../arch/arm/include/asm/mach-imx/hab.h" |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | #if defined(CONFIG_FASTBOOT_LOCK) | 35 | #if defined(CONFIG_FASTBOOT_LOCK) |
36 | #include "fastboot_lock_unlock.h" | 36 | #include "fastboot_lock_unlock.h" |
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | #ifdef CONFIG_IMX_TRUSTY_OS | 39 | #ifdef CONFIG_IMX_TRUSTY_OS |
40 | #include "u-boot/sha256.h" | 40 | #include "u-boot/sha256.h" |
41 | #include <trusty/libtipc.h> | 41 | #include <trusty/libtipc.h> |
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | #include "fb_fsl_common.h" | 44 | #include "fb_fsl_common.h" |
45 | 45 | ||
46 | #if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M) | 46 | #if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M) |
47 | #define DST_DECOMPRESS_LEN 1024*1024*32 | 47 | #define DST_DECOMPRESS_LEN 1024*1024*32 |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT | 50 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT |
51 | #define FDT_PART_NAME "oem_bootloader" | 51 | #define FDT_PART_NAME "oem_bootloader" |
52 | #else | 52 | #else |
53 | #define FDT_PART_NAME "dtbo" | 53 | #define FDT_PART_NAME "dtbo" |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | /* Offset (in u32's) of start and end fields in the zImage header. */ | 56 | /* Offset (in u32's) of start and end fields in the zImage header. */ |
57 | #define ZIMAGE_START_ADDR 10 | 57 | #define ZIMAGE_START_ADDR 10 |
58 | #define ZIMAGE_END_ADDR 11 | 58 | #define ZIMAGE_END_ADDR 11 |
59 | 59 | ||
60 | /* Boot metric variables */ | 60 | /* Boot metric variables */ |
61 | boot_metric metrics = { | 61 | boot_metric metrics = { |
62 | .bll_1 = 0, | 62 | .bll_1 = 0, |
63 | .ble_1 = 0, | 63 | .ble_1 = 0, |
64 | .kl = 0, | 64 | .kl = 0, |
65 | .kd = 0, | 65 | .kd = 0, |
66 | .avb = 0, | 66 | .avb = 0, |
67 | .odt = 0, | 67 | .odt = 0, |
68 | .sw = 0 | 68 | .sw = 0 |
69 | }; | 69 | }; |
70 | 70 | ||
71 | int read_from_partition_multi(const char* partition, | 71 | int read_from_partition_multi(const char* partition, |
72 | int64_t offset, size_t num_bytes, void* buffer, size_t* out_num_read) | 72 | int64_t offset, size_t num_bytes, void* buffer, size_t* out_num_read) |
73 | { | 73 | { |
74 | struct fastboot_ptentry *pte; | 74 | struct fastboot_ptentry *pte; |
75 | unsigned char *bdata; | 75 | unsigned char *bdata; |
76 | unsigned char *out_buf = (unsigned char *)buffer; | 76 | unsigned char *out_buf = (unsigned char *)buffer; |
77 | unsigned char *dst, *dst64 = NULL; | 77 | unsigned char *dst, *dst64 = NULL; |
78 | unsigned long blksz; | 78 | unsigned long blksz; |
79 | unsigned long s, cnt; | 79 | unsigned long s, cnt; |
80 | size_t num_read = 0; | 80 | size_t num_read = 0; |
81 | lbaint_t part_start, part_end, bs, be, bm, blk_num; | 81 | lbaint_t part_start, part_end, bs, be, bm, blk_num; |
82 | margin_pos_t margin; | 82 | margin_pos_t margin; |
83 | struct blk_desc *fs_dev_desc = NULL; | 83 | struct blk_desc *fs_dev_desc = NULL; |
84 | int dev_no; | 84 | int dev_no; |
85 | int ret; | 85 | int ret; |
86 | 86 | ||
87 | assert(buffer != NULL && out_num_read != NULL); | 87 | assert(buffer != NULL && out_num_read != NULL); |
88 | 88 | ||
89 | dev_no = mmc_get_env_dev(); | 89 | dev_no = mmc_get_env_dev(); |
90 | if ((fs_dev_desc = blk_get_dev("mmc", dev_no)) == NULL) { | 90 | if ((fs_dev_desc = blk_get_dev("mmc", dev_no)) == NULL) { |
91 | printf("mmc device not found\n"); | 91 | printf("mmc device not found\n"); |
92 | return -1; | 92 | return -1; |
93 | } | 93 | } |
94 | 94 | ||
95 | pte = fastboot_flash_find_ptn(partition); | 95 | pte = fastboot_flash_find_ptn(partition); |
96 | if (!pte) { | 96 | if (!pte) { |
97 | printf("no %s partition\n", partition); | 97 | printf("no %s partition\n", partition); |
98 | fastboot_flash_dump_ptn(); | 98 | fastboot_flash_dump_ptn(); |
99 | return -1; | 99 | return -1; |
100 | } | 100 | } |
101 | 101 | ||
102 | blksz = fs_dev_desc->blksz; | 102 | blksz = fs_dev_desc->blksz; |
103 | part_start = pte->start; | 103 | part_start = pte->start; |
104 | part_end = pte->start + pte->length - 1; | 104 | part_end = pte->start + pte->length - 1; |
105 | 105 | ||
106 | if (get_margin_pos((uint64_t)part_start, (uint64_t)part_end, blksz, | 106 | if (get_margin_pos((uint64_t)part_start, (uint64_t)part_end, blksz, |
107 | &margin, offset, num_bytes, true)) | 107 | &margin, offset, num_bytes, true)) |
108 | return -1; | 108 | return -1; |
109 | 109 | ||
110 | bs = (lbaint_t)margin.blk_start; | 110 | bs = (lbaint_t)margin.blk_start; |
111 | be = (lbaint_t)margin.blk_end; | 111 | be = (lbaint_t)margin.blk_end; |
112 | s = margin.start; | 112 | s = margin.start; |
113 | bm = margin.multi; | 113 | bm = margin.multi; |
114 | 114 | ||
115 | /* alloc a blksz mem */ | 115 | /* alloc a blksz mem */ |
116 | bdata = (unsigned char *)memalign(ALIGN_BYTES, blksz); | 116 | bdata = (unsigned char *)memalign(ALIGN_BYTES, blksz); |
117 | if (bdata == NULL) { | 117 | if (bdata == NULL) { |
118 | printf("Failed to allocate memory!\n"); | 118 | printf("Failed to allocate memory!\n"); |
119 | return -1; | 119 | return -1; |
120 | } | 120 | } |
121 | 121 | ||
122 | /* support multi blk read */ | 122 | /* support multi blk read */ |
123 | while (bs <= be) { | 123 | while (bs <= be) { |
124 | if (!s && bm > 1) { | 124 | if (!s && bm > 1) { |
125 | dst = out_buf; | 125 | dst = out_buf; |
126 | dst64 = PTR_ALIGN(out_buf, 64); /* for mmc blk read alignment */ | 126 | dst64 = PTR_ALIGN(out_buf, 64); /* for mmc blk read alignment */ |
127 | if (dst64 != dst) { | 127 | if (dst64 != dst) { |
128 | dst = dst64; | 128 | dst = dst64; |
129 | bm--; | 129 | bm--; |
130 | } | 130 | } |
131 | blk_num = bm; | 131 | blk_num = bm; |
132 | cnt = bm * blksz; | 132 | cnt = bm * blksz; |
133 | bm = 0; /* no more multi blk */ | 133 | bm = 0; /* no more multi blk */ |
134 | } else { | 134 | } else { |
135 | blk_num = 1; | 135 | blk_num = 1; |
136 | cnt = blksz - s; | 136 | cnt = blksz - s; |
137 | if (num_read + cnt > num_bytes) | 137 | if (num_read + cnt > num_bytes) |
138 | cnt = num_bytes - num_read; | 138 | cnt = num_bytes - num_read; |
139 | dst = bdata; | 139 | dst = bdata; |
140 | } | 140 | } |
141 | if (blk_dread(fs_dev_desc, bs, blk_num, dst) != blk_num) { | 141 | if (blk_dread(fs_dev_desc, bs, blk_num, dst) != blk_num) { |
142 | ret = -1; | 142 | ret = -1; |
143 | goto fail; | 143 | goto fail; |
144 | } | 144 | } |
145 | 145 | ||
146 | if (dst == bdata) | 146 | if (dst == bdata) |
147 | memcpy(out_buf, bdata + s, cnt); | 147 | memcpy(out_buf, bdata + s, cnt); |
148 | else if (dst == dst64) | 148 | else if (dst == dst64) |
149 | memcpy(out_buf, dst, cnt); /* internal copy */ | 149 | memcpy(out_buf, dst, cnt); /* internal copy */ |
150 | 150 | ||
151 | s = 0; | 151 | s = 0; |
152 | bs += blk_num; | 152 | bs += blk_num; |
153 | num_read += cnt; | 153 | num_read += cnt; |
154 | out_buf += cnt; | 154 | out_buf += cnt; |
155 | } | 155 | } |
156 | *out_num_read = num_read; | 156 | *out_num_read = num_read; |
157 | ret = 0; | 157 | ret = 0; |
158 | 158 | ||
159 | fail: | 159 | fail: |
160 | free(bdata); | 160 | free(bdata); |
161 | return ret; | 161 | return ret; |
162 | } | 162 | } |
163 | 163 | ||
164 | 164 | ||
165 | #if defined(CONFIG_FASTBOOT_LOCK) | 165 | #if defined(CONFIG_FASTBOOT_LOCK) |
166 | int do_lock_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { | 166 | int do_lock_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { |
167 | FbLockState status = fastboot_get_lock_stat(); | 167 | FbLockState status = fastboot_get_lock_stat(); |
168 | if (status != FASTBOOT_LOCK_ERROR) { | 168 | if (status != FASTBOOT_LOCK_ERROR) { |
169 | if (status == FASTBOOT_LOCK) | 169 | if (status == FASTBOOT_LOCK) |
170 | printf("fastboot lock status: locked.\n"); | 170 | printf("fastboot lock status: locked.\n"); |
171 | else | 171 | else |
172 | printf("fastboot lock status: unlocked.\n"); | 172 | printf("fastboot lock status: unlocked.\n"); |
173 | } else | 173 | } else |
174 | printf("fastboot lock status error!\n"); | 174 | printf("fastboot lock status error!\n"); |
175 | 175 | ||
176 | display_lock(status, -1); | 176 | display_lock(status, -1); |
177 | 177 | ||
178 | return 0; | 178 | return 0; |
179 | 179 | ||
180 | } | 180 | } |
181 | 181 | ||
182 | U_BOOT_CMD( | 182 | U_BOOT_CMD( |
183 | lock_status, 2, 1, do_lock_status, | 183 | lock_status, 2, 1, do_lock_status, |
184 | "lock_status", | 184 | "lock_status", |
185 | "lock_status"); | 185 | "lock_status"); |
186 | #endif | 186 | #endif |
187 | 187 | ||
188 | #if defined(CONFIG_FLASH_MCUFIRMWARE_SUPPORT) && defined(CONFIG_ARCH_IMX8M) | 188 | #if defined(CONFIG_FLASH_MCUFIRMWARE_SUPPORT) && defined(CONFIG_ARCH_IMX8M) |
189 | static int do_bootmcu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | 189 | static int do_bootmcu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
190 | { | 190 | { |
191 | int ret; | 191 | int ret; |
192 | size_t out_num_read; | 192 | size_t out_num_read; |
193 | void *mcu_base_addr = (void *)MCU_BOOTROM_BASE_ADDR; | 193 | void *mcu_base_addr = (void *)MCU_BOOTROM_BASE_ADDR; |
194 | char command[32]; | 194 | char command[32]; |
195 | 195 | ||
196 | ret = read_from_partition_multi(FASTBOOT_MCU_FIRMWARE_PARTITION, | 196 | ret = read_from_partition_multi(FASTBOOT_MCU_FIRMWARE_PARTITION, |
197 | 0, ANDROID_MCU_FIRMWARE_SIZE, (void *)mcu_base_addr, &out_num_read); | 197 | 0, ANDROID_MCU_FIRMWARE_SIZE, (void *)mcu_base_addr, &out_num_read); |
198 | if ((ret != 0) || (out_num_read != ANDROID_MCU_FIRMWARE_SIZE)) { | 198 | if ((ret != 0) || (out_num_read != ANDROID_MCU_FIRMWARE_SIZE)) { |
199 | printf("Read MCU images failed!\n"); | 199 | printf("Read MCU images failed!\n"); |
200 | return 1; | 200 | return 1; |
201 | } else { | 201 | } else { |
202 | printf("run command: 'bootaux 0x%x'\n",(unsigned int)(ulong)mcu_base_addr); | 202 | printf("run command: 'bootaux 0x%x'\n",(unsigned int)(ulong)mcu_base_addr); |
203 | 203 | ||
204 | sprintf(command, "bootaux 0x%x", (unsigned int)(ulong)mcu_base_addr); | 204 | sprintf(command, "bootaux 0x%x", (unsigned int)(ulong)mcu_base_addr); |
205 | ret = run_command(command, 0); | 205 | ret = run_command(command, 0); |
206 | if (ret) { | 206 | if (ret) { |
207 | printf("run 'bootaux' command failed!\n"); | 207 | printf("run 'bootaux' command failed!\n"); |
208 | return 1; | 208 | return 1; |
209 | } | 209 | } |
210 | } | 210 | } |
211 | return 0; | 211 | return 0; |
212 | } | 212 | } |
213 | 213 | ||
214 | U_BOOT_CMD( | 214 | U_BOOT_CMD( |
215 | bootmcu, 1, 0, do_bootmcu, | 215 | bootmcu, 1, 0, do_bootmcu, |
216 | "boot mcu images\n", | 216 | "boot mcu images\n", |
217 | "boot mcu images from 'mcu_os' partition, only support images run from TCM" | 217 | "boot mcu images from 'mcu_os' partition, only support images run from TCM" |
218 | ); | 218 | ); |
219 | #endif | 219 | #endif |
220 | 220 | ||
221 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | 221 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT |
222 | /* Setup booargs for taking the system parition as ramdisk */ | 222 | /* Setup booargs for taking the system parition as ramdisk */ |
223 | static void fastboot_setup_system_boot_args(const char *slot, bool append_root) | 223 | static void fastboot_setup_system_boot_args(const char *slot, bool append_root) |
224 | { | 224 | { |
225 | const char *system_part_name = NULL; | 225 | const char *system_part_name = NULL; |
226 | #ifdef CONFIG_ANDROID_AB_SUPPORT | 226 | #ifdef CONFIG_ANDROID_AB_SUPPORT |
227 | if(slot == NULL) | 227 | if(slot == NULL) |
228 | return; | 228 | return; |
229 | if(!strncmp(slot, "_a", strlen("_a")) || !strncmp(slot, "boot_a", strlen("boot_a"))) { | 229 | if(!strncmp(slot, "_a", strlen("_a")) || !strncmp(slot, "boot_a", strlen("boot_a"))) { |
230 | system_part_name = FASTBOOT_PARTITION_SYSTEM_A; | 230 | system_part_name = FASTBOOT_PARTITION_SYSTEM_A; |
231 | } | 231 | } |
232 | else if(!strncmp(slot, "_b", strlen("_b")) || !strncmp(slot, "boot_b", strlen("boot_b"))) { | 232 | else if(!strncmp(slot, "_b", strlen("_b")) || !strncmp(slot, "boot_b", strlen("boot_b"))) { |
233 | system_part_name = FASTBOOT_PARTITION_SYSTEM_B; | 233 | system_part_name = FASTBOOT_PARTITION_SYSTEM_B; |
234 | } else { | 234 | } else { |
235 | printf("slot invalid!\n"); | 235 | printf("slot invalid!\n"); |
236 | return; | 236 | return; |
237 | } | 237 | } |
238 | #else | 238 | #else |
239 | system_part_name = FASTBOOT_PARTITION_SYSTEM; | 239 | system_part_name = FASTBOOT_PARTITION_SYSTEM; |
240 | #endif | 240 | #endif |
241 | 241 | ||
242 | struct fastboot_ptentry *ptentry = fastboot_flash_find_ptn(system_part_name); | 242 | struct fastboot_ptentry *ptentry = fastboot_flash_find_ptn(system_part_name); |
243 | if(ptentry != NULL) { | 243 | if(ptentry != NULL) { |
244 | char bootargs_3rd[ANDR_BOOT_ARGS_SIZE]; | 244 | char bootargs_3rd[ANDR_BOOT_ARGS_SIZE]; |
245 | if (append_root) { | 245 | if (append_root) { |
246 | u32 dev_no = mmc_map_to_kernel_blk(mmc_get_env_dev()); | 246 | u32 dev_no = mmc_map_to_kernel_blk(mmc_get_env_dev()); |
247 | sprintf(bootargs_3rd, "skip_initramfs root=/dev/mmcblk%dp%d", | 247 | sprintf(bootargs_3rd, "skip_initramfs root=/dev/mmcblk%dp%d", |
248 | dev_no, | 248 | dev_no, |
249 | ptentry->partition_index); | 249 | ptentry->partition_index); |
250 | } else { | 250 | } else { |
251 | sprintf(bootargs_3rd, "skip_initramfs"); | 251 | sprintf(bootargs_3rd, "skip_initramfs"); |
252 | } | 252 | } |
253 | strcat(bootargs_3rd, " rootwait"); | 253 | strcat(bootargs_3rd, " rootwait"); |
254 | env_set("bootargs_3rd", bootargs_3rd); | 254 | env_set("bootargs_3rd", bootargs_3rd); |
255 | } else { | 255 | } else { |
256 | printf("Can't find partition: %s\n", system_part_name); | 256 | printf("Can't find partition: %s\n", system_part_name); |
257 | fastboot_flash_dump_ptn(); | 257 | fastboot_flash_dump_ptn(); |
258 | } | 258 | } |
259 | } | 259 | } |
260 | #endif | 260 | #endif |
261 | 261 | ||
262 | #ifdef CONFIG_CMD_BOOTA | 262 | #ifdef CONFIG_CMD_BOOTA |
263 | 263 | ||
264 | /* Section for Android bootimage format support | 264 | /* Section for Android bootimage format support |
265 | * Refer: | 265 | * Refer: |
266 | * http://android.git.kernel.org/?p=platform/system/core.git;a=blob; | 266 | * http://android.git.kernel.org/?p=platform/system/core.git;a=blob; |
267 | * f=mkbootimg/bootimg.h | 267 | * f=mkbootimg/bootimg.h |
268 | */ | 268 | */ |
269 | 269 | ||
270 | void | 270 | void |
271 | bootimg_print_image_hdr(struct andr_img_hdr *hdr) | 271 | bootimg_print_image_hdr(struct andr_img_hdr *hdr) |
272 | { | 272 | { |
273 | #ifdef DEBUG | 273 | #ifdef DEBUG |
274 | int i; | 274 | int i; |
275 | printf(" Image magic: %s\n", hdr->magic); | 275 | printf(" Image magic: %s\n", hdr->magic); |
276 | 276 | ||
277 | printf(" kernel_size: 0x%x\n", hdr->kernel_size); | 277 | printf(" kernel_size: 0x%x\n", hdr->kernel_size); |
278 | printf(" kernel_addr: 0x%x\n", hdr->kernel_addr); | 278 | printf(" kernel_addr: 0x%x\n", hdr->kernel_addr); |
279 | 279 | ||
280 | printf(" rdisk_size: 0x%x\n", hdr->ramdisk_size); | 280 | printf(" rdisk_size: 0x%x\n", hdr->ramdisk_size); |
281 | printf(" rdisk_addr: 0x%x\n", hdr->ramdisk_addr); | 281 | printf(" rdisk_addr: 0x%x\n", hdr->ramdisk_addr); |
282 | 282 | ||
283 | printf(" second_size: 0x%x\n", hdr->second_size); | 283 | printf(" second_size: 0x%x\n", hdr->second_size); |
284 | printf(" second_addr: 0x%x\n", hdr->second_addr); | 284 | printf(" second_addr: 0x%x\n", hdr->second_addr); |
285 | 285 | ||
286 | printf(" tags_addr: 0x%x\n", hdr->tags_addr); | 286 | printf(" tags_addr: 0x%x\n", hdr->tags_addr); |
287 | printf(" page_size: 0x%x\n", hdr->page_size); | 287 | printf(" page_size: 0x%x\n", hdr->page_size); |
288 | 288 | ||
289 | printf(" name: %s\n", hdr->name); | 289 | printf(" name: %s\n", hdr->name); |
290 | printf(" cmdline: %s\n", hdr->cmdline); | 290 | printf(" cmdline: %s\n", hdr->cmdline); |
291 | 291 | ||
292 | for (i = 0; i < 8; i++) | 292 | for (i = 0; i < 8; i++) |
293 | printf(" id[%d]: 0x%x\n", i, hdr->id[i]); | 293 | printf(" id[%d]: 0x%x\n", i, hdr->id[i]); |
294 | #endif | 294 | #endif |
295 | } | 295 | } |
296 | 296 | ||
297 | #if !defined(CONFIG_AVB_SUPPORT) || !defined(CONFIG_MMC) | 297 | #if !defined(CONFIG_AVB_SUPPORT) || !defined(CONFIG_MMC) |
298 | static struct andr_img_hdr boothdr __aligned(ARCH_DMA_MINALIGN); | 298 | static struct andr_img_hdr boothdr __aligned(ARCH_DMA_MINALIGN); |
299 | #endif | 299 | #endif |
300 | 300 | ||
301 | #ifdef CONFIG_IMX_TRUSTY_OS | 301 | #ifdef CONFIG_IMX_TRUSTY_OS |
302 | #if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_AVB_ATX) | 302 | #if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_AVB_ATX) |
303 | static int sha256_concatenation(uint8_t *hash_buf, uint8_t *vbh, uint8_t *image_hash) | 303 | static int sha256_concatenation(uint8_t *hash_buf, uint8_t *vbh, uint8_t *image_hash) |
304 | { | 304 | { |
305 | if ((hash_buf == NULL) || (vbh == NULL) || (image_hash == NULL)) { | 305 | if ((hash_buf == NULL) || (vbh == NULL) || (image_hash == NULL)) { |
306 | printf("sha256_concatenation: null buffer found!\n"); | 306 | printf("sha256_concatenation: null buffer found!\n"); |
307 | return -1; | 307 | return -1; |
308 | } | 308 | } |
309 | 309 | ||
310 | memcpy(hash_buf, vbh, AVB_SHA256_DIGEST_SIZE); | 310 | memcpy(hash_buf, vbh, AVB_SHA256_DIGEST_SIZE); |
311 | memcpy(hash_buf + AVB_SHA256_DIGEST_SIZE, | 311 | memcpy(hash_buf + AVB_SHA256_DIGEST_SIZE, |
312 | image_hash, AVB_SHA256_DIGEST_SIZE); | 312 | image_hash, AVB_SHA256_DIGEST_SIZE); |
313 | sha256_csum_wd((unsigned char *)hash_buf, 2 * AVB_SHA256_DIGEST_SIZE, | 313 | sha256_csum_wd((unsigned char *)hash_buf, 2 * AVB_SHA256_DIGEST_SIZE, |
314 | (unsigned char *)vbh, CHUNKSZ_SHA256); | 314 | (unsigned char *)vbh, CHUNKSZ_SHA256); |
315 | 315 | ||
316 | return 0; | 316 | return 0; |
317 | } | 317 | } |
318 | 318 | ||
319 | /* Since we use fit format to organize the atf, tee, u-boot and u-boot dtb, | 319 | /* Since we use fit format to organize the atf, tee, u-boot and u-boot dtb, |
320 | * so calculate the hash of fit is enough. | 320 | * so calculate the hash of fit is enough. |
321 | */ | 321 | */ |
322 | static int vbh_bootloader(uint8_t *image_hash) | 322 | static int vbh_bootloader(uint8_t *image_hash) |
323 | { | 323 | { |
324 | char* slot_suffixes[2] = {"_a", "_b"}; | 324 | char* slot_suffixes[2] = {"_a", "_b"}; |
325 | char partition_name[20]; | 325 | char partition_name[20]; |
326 | AvbABData ab_data; | 326 | AvbABData ab_data; |
327 | uint8_t *image_buf = NULL; | 327 | uint8_t *image_buf = NULL; |
328 | uint32_t image_size; | 328 | uint32_t image_size; |
329 | size_t image_num_read; | 329 | size_t image_num_read; |
330 | int target_slot; | 330 | int target_slot; |
331 | int ret = 0; | 331 | int ret = 0; |
332 | 332 | ||
333 | /* Load A/B metadata and decide which slot we are going to load */ | 333 | /* Load A/B metadata and decide which slot we are going to load */ |
334 | if (fsl_avb_ab_ops.read_ab_metadata(&fsl_avb_ab_ops, &ab_data) != | 334 | if (fsl_avb_ab_ops.read_ab_metadata(&fsl_avb_ab_ops, &ab_data) != |
335 | AVB_IO_RESULT_OK) { | 335 | AVB_IO_RESULT_OK) { |
336 | ret = -1; | 336 | ret = -1; |
337 | goto fail ; | 337 | goto fail ; |
338 | } | 338 | } |
339 | target_slot = get_curr_slot(&ab_data); | 339 | target_slot = get_curr_slot(&ab_data); |
340 | sprintf(partition_name, "bootloader%s", slot_suffixes[target_slot]); | 340 | sprintf(partition_name, "bootloader%s", slot_suffixes[target_slot]); |
341 | 341 | ||
342 | /* Read image header to find the image size */ | 342 | /* Read image header to find the image size */ |
343 | image_buf = (uint8_t *)malloc(MMC_SATA_BLOCK_SIZE); | 343 | image_buf = (uint8_t *)malloc(MMC_SATA_BLOCK_SIZE); |
344 | if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, partition_name, | 344 | if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, partition_name, |
345 | 0, MMC_SATA_BLOCK_SIZE, | 345 | 0, MMC_SATA_BLOCK_SIZE, |
346 | image_buf, &image_num_read)) { | 346 | image_buf, &image_num_read)) { |
347 | printf("bootloader image load error!\n"); | 347 | printf("bootloader image load error!\n"); |
348 | ret = -1; | 348 | ret = -1; |
349 | goto fail; | 349 | goto fail; |
350 | } | 350 | } |
351 | image_size = fdt_totalsize((struct image_header *)image_buf); | 351 | image_size = fdt_totalsize((struct image_header *)image_buf); |
352 | image_size = (image_size + 3) & ~3; | 352 | image_size = (image_size + 3) & ~3; |
353 | free(image_buf); | 353 | free(image_buf); |
354 | 354 | ||
355 | /* Load full fit image */ | 355 | /* Load full fit image */ |
356 | image_buf = (uint8_t *)malloc(image_size); | 356 | image_buf = (uint8_t *)malloc(image_size); |
357 | if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, partition_name, | 357 | if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, partition_name, |
358 | 0, image_size, | 358 | 0, image_size, |
359 | image_buf, &image_num_read)) { | 359 | image_buf, &image_num_read)) { |
360 | printf("bootloader image load error!\n"); | 360 | printf("bootloader image load error!\n"); |
361 | ret = -1; | 361 | ret = -1; |
362 | goto fail; | 362 | goto fail; |
363 | } | 363 | } |
364 | /* Calculate hash */ | 364 | /* Calculate hash */ |
365 | sha256_csum_wd((unsigned char *)image_buf, image_size, | 365 | sha256_csum_wd((unsigned char *)image_buf, image_size, |
366 | (unsigned char *)image_hash, CHUNKSZ_SHA256); | 366 | (unsigned char *)image_hash, CHUNKSZ_SHA256); |
367 | 367 | ||
368 | fail: | 368 | fail: |
369 | if (image_buf != NULL) | 369 | if (image_buf != NULL) |
370 | free(image_buf); | 370 | free(image_buf); |
371 | return ret; | 371 | return ret; |
372 | } | 372 | } |
373 | 373 | ||
374 | int vbh_calculate(uint8_t *vbh, AvbSlotVerifyData *avb_out_data) | 374 | int vbh_calculate(uint8_t *vbh, AvbSlotVerifyData *avb_out_data) |
375 | { | 375 | { |
376 | uint8_t image_hash[AVB_SHA256_DIGEST_SIZE]; | 376 | uint8_t image_hash[AVB_SHA256_DIGEST_SIZE]; |
377 | uint8_t hash_buf[2 * AVB_SHA256_DIGEST_SIZE]; | 377 | uint8_t hash_buf[2 * AVB_SHA256_DIGEST_SIZE]; |
378 | uint8_t* image_buf = NULL; | 378 | uint8_t* image_buf = NULL; |
379 | uint32_t image_size; | 379 | uint32_t image_size; |
380 | size_t image_num_read; | 380 | size_t image_num_read; |
381 | int ret = 0; | 381 | int ret = 0; |
382 | 382 | ||
383 | if (vbh == NULL) | 383 | if (vbh == NULL) |
384 | return -1; | 384 | return -1; |
385 | 385 | ||
386 | /* Initial VBH (VBH0) should be 32 bytes 0 */ | 386 | /* Initial VBH (VBH0) should be 32 bytes 0 */ |
387 | memset(vbh, 0, AVB_SHA256_DIGEST_SIZE); | 387 | memset(vbh, 0, AVB_SHA256_DIGEST_SIZE); |
388 | /* Load and calculate the sha256 hash of spl.bin */ | 388 | /* Load and calculate the sha256 hash of spl.bin */ |
389 | image_size = (ANDROID_SPL_SIZE + MMC_SATA_BLOCK_SIZE -1) / | 389 | image_size = (ANDROID_SPL_SIZE + MMC_SATA_BLOCK_SIZE -1) / |
390 | MMC_SATA_BLOCK_SIZE; | 390 | MMC_SATA_BLOCK_SIZE; |
391 | image_buf = (uint8_t *)malloc(image_size); | 391 | image_buf = (uint8_t *)malloc(image_size); |
392 | if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, | 392 | if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, |
393 | FASTBOOT_PARTITION_BOOTLOADER, | 393 | FASTBOOT_PARTITION_BOOTLOADER, |
394 | 0, image_size, | 394 | 0, image_size, |
395 | image_buf, &image_num_read)) { | 395 | image_buf, &image_num_read)) { |
396 | printf("spl image load error!\n"); | 396 | printf("spl image load error!\n"); |
397 | ret = -1; | 397 | ret = -1; |
398 | goto fail; | 398 | goto fail; |
399 | } | 399 | } |
400 | sha256_csum_wd((unsigned char *)image_buf, image_size, | 400 | sha256_csum_wd((unsigned char *)image_buf, image_size, |
401 | (unsigned char *)image_hash, CHUNKSZ_SHA256); | 401 | (unsigned char *)image_hash, CHUNKSZ_SHA256); |
402 | /* Calculate VBH1 */ | 402 | /* Calculate VBH1 */ |
403 | if (sha256_concatenation(hash_buf, vbh, image_hash)) { | 403 | if (sha256_concatenation(hash_buf, vbh, image_hash)) { |
404 | ret = -1; | 404 | ret = -1; |
405 | goto fail; | 405 | goto fail; |
406 | } | 406 | } |
407 | free(image_buf); | 407 | free(image_buf); |
408 | 408 | ||
409 | /* Load and calculate hash of bootloader.img */ | 409 | /* Load and calculate hash of bootloader.img */ |
410 | if (vbh_bootloader(image_hash)) { | 410 | if (vbh_bootloader(image_hash)) { |
411 | ret = -1; | 411 | ret = -1; |
412 | goto fail; | 412 | goto fail; |
413 | } | 413 | } |
414 | /* Calculate VBH2 */ | 414 | /* Calculate VBH2 */ |
415 | if (sha256_concatenation(hash_buf, vbh, image_hash)) { | 415 | if (sha256_concatenation(hash_buf, vbh, image_hash)) { |
416 | ret = -1; | 416 | ret = -1; |
417 | goto fail; | 417 | goto fail; |
418 | } | 418 | } |
419 | 419 | ||
420 | /* Calculate the hash of vbmeta.img */ | 420 | /* Calculate the hash of vbmeta.img */ |
421 | avb_slot_verify_data_calculate_vbmeta_digest(avb_out_data, | 421 | avb_slot_verify_data_calculate_vbmeta_digest(avb_out_data, |
422 | AVB_DIGEST_TYPE_SHA256, | 422 | AVB_DIGEST_TYPE_SHA256, |
423 | image_hash); | 423 | image_hash); |
424 | /* Calculate VBH3 */ | 424 | /* Calculate VBH3 */ |
425 | if (sha256_concatenation(hash_buf, vbh, image_hash)) { | 425 | if (sha256_concatenation(hash_buf, vbh, image_hash)) { |
426 | ret = -1; | 426 | ret = -1; |
427 | goto fail; | 427 | goto fail; |
428 | } | 428 | } |
429 | 429 | ||
430 | fail: | 430 | fail: |
431 | if (image_buf != NULL) | 431 | if (image_buf != NULL) |
432 | free(image_buf); | 432 | free(image_buf); |
433 | return ret; | 433 | return ret; |
434 | } | 434 | } |
435 | #endif /* CONFIG_DUAL_BOOTLOADER && CONFIG_AVB_ATX */ | 435 | #endif /* CONFIG_DUAL_BOOTLOADER && CONFIG_AVB_ATX */ |
436 | 436 | ||
437 | int trusty_setbootparameter(struct andr_img_hdr *hdr, AvbABFlowResult avb_result, | 437 | int trusty_setbootparameter(struct andr_img_hdr *hdr, AvbABFlowResult avb_result, |
438 | AvbSlotVerifyData *avb_out_data) { | 438 | AvbSlotVerifyData *avb_out_data) { |
439 | #if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_AVB_ATX) | 439 | #if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_AVB_ATX) |
440 | uint8_t vbh[AVB_SHA256_DIGEST_SIZE]; | 440 | uint8_t vbh[AVB_SHA256_DIGEST_SIZE]; |
441 | #endif | 441 | #endif |
442 | int ret = 0; | 442 | int ret = 0; |
443 | u32 os_ver = hdr->os_version >> 11; | 443 | u32 os_ver = hdr->os_version >> 11; |
444 | u32 os_ver_km = (((os_ver >> 14) & 0x7F) * 100 + ((os_ver >> 7) & 0x7F)) * 100 | 444 | u32 os_ver_km = (((os_ver >> 14) & 0x7F) * 100 + ((os_ver >> 7) & 0x7F)) * 100 |
445 | + (os_ver & 0x7F); | 445 | + (os_ver & 0x7F); |
446 | u32 os_lvl = hdr->os_version & ((1U << 11) - 1); | 446 | u32 os_lvl = hdr->os_version & ((1U << 11) - 1); |
447 | u32 os_lvl_km = ((os_lvl >> 4) + 2000) * 100 + (os_lvl & 0x0F); | 447 | u32 os_lvl_km = ((os_lvl >> 4) + 2000) * 100 + (os_lvl & 0x0F); |
448 | keymaster_verified_boot_t vbstatus; | 448 | keymaster_verified_boot_t vbstatus; |
449 | FbLockState lock_status = fastboot_get_lock_stat(); | 449 | FbLockState lock_status = fastboot_get_lock_stat(); |
450 | 450 | ||
451 | uint8_t boot_key_hash[AVB_SHA256_DIGEST_SIZE]; | 451 | uint8_t boot_key_hash[AVB_SHA256_DIGEST_SIZE]; |
452 | #ifdef CONFIG_AVB_ATX | 452 | #ifdef CONFIG_AVB_ATX |
453 | if (fsl_read_permanent_attributes_hash(&fsl_avb_atx_ops, boot_key_hash)) { | 453 | if (fsl_read_permanent_attributes_hash(&fsl_avb_atx_ops, boot_key_hash)) { |
454 | printf("ERROR - failed to read permanent attributes hash for keymaster\n"); | 454 | printf("ERROR - failed to read permanent attributes hash for keymaster\n"); |
455 | memset(boot_key_hash, 0, AVB_SHA256_DIGEST_SIZE); | 455 | memset(boot_key_hash, 0, AVB_SHA256_DIGEST_SIZE); |
456 | } | 456 | } |
457 | #else | 457 | #else |
458 | uint8_t public_key_buf[AVB_MAX_BUFFER_LENGTH]; | 458 | uint8_t public_key_buf[AVB_MAX_BUFFER_LENGTH]; |
459 | if (trusty_read_vbmeta_public_key(public_key_buf, | 459 | if (trusty_read_vbmeta_public_key(public_key_buf, |
460 | AVB_MAX_BUFFER_LENGTH) != 0) { | 460 | AVB_MAX_BUFFER_LENGTH) != 0) { |
461 | printf("ERROR - failed to read public key for keymaster\n"); | 461 | printf("ERROR - failed to read public key for keymaster\n"); |
462 | memset(boot_key_hash, 0, AVB_SHA256_DIGEST_SIZE); | 462 | memset(boot_key_hash, 0, AVB_SHA256_DIGEST_SIZE); |
463 | } else | 463 | } else |
464 | sha256_csum_wd((unsigned char *)public_key_buf, AVB_SHA256_DIGEST_SIZE, | 464 | sha256_csum_wd((unsigned char *)public_key_buf, AVB_SHA256_DIGEST_SIZE, |
465 | (unsigned char *)boot_key_hash, CHUNKSZ_SHA256); | 465 | (unsigned char *)boot_key_hash, CHUNKSZ_SHA256); |
466 | #endif | 466 | #endif |
467 | 467 | ||
468 | bool lock = (lock_status == FASTBOOT_LOCK)? true: false; | 468 | bool lock = (lock_status == FASTBOOT_LOCK)? true: false; |
469 | if (avb_result == AVB_AB_FLOW_RESULT_OK) | 469 | if (avb_result == AVB_AB_FLOW_RESULT_OK) |
470 | vbstatus = KM_VERIFIED_BOOT_VERIFIED; | 470 | vbstatus = KM_VERIFIED_BOOT_VERIFIED; |
471 | else | 471 | else |
472 | vbstatus = KM_VERIFIED_BOOT_FAILED; | 472 | vbstatus = KM_VERIFIED_BOOT_FAILED; |
473 | 473 | ||
474 | /* Calculate VBH */ | 474 | /* Calculate VBH */ |
475 | #if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_AVB_ATX) | 475 | #if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_AVB_ATX) |
476 | if (vbh_calculate(vbh, avb_out_data)) { | 476 | if (vbh_calculate(vbh, avb_out_data)) { |
477 | ret = -1; | 477 | ret = -1; |
478 | goto fail; | 478 | goto fail; |
479 | } | 479 | } |
480 | 480 | ||
481 | trusty_set_boot_params(os_ver_km, os_lvl_km, vbstatus, lock, | 481 | trusty_set_boot_params(os_ver_km, os_lvl_km, vbstatus, lock, |
482 | boot_key_hash, AVB_SHA256_DIGEST_SIZE, | 482 | boot_key_hash, AVB_SHA256_DIGEST_SIZE, |
483 | vbh, AVB_SHA256_DIGEST_SIZE); | 483 | vbh, AVB_SHA256_DIGEST_SIZE); |
484 | #else | 484 | #else |
485 | trusty_set_boot_params(os_ver_km, os_lvl_km, vbstatus, lock, | 485 | trusty_set_boot_params(os_ver_km, os_lvl_km, vbstatus, lock, |
486 | boot_key_hash, AVB_SHA256_DIGEST_SIZE, | 486 | boot_key_hash, AVB_SHA256_DIGEST_SIZE, |
487 | NULL, 0); | 487 | NULL, 0); |
488 | #endif | 488 | #endif |
489 | 489 | ||
490 | fail: | 490 | fail: |
491 | return ret; | 491 | return ret; |
492 | } | 492 | } |
493 | #endif | 493 | #endif |
494 | 494 | ||
495 | #if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC) | 495 | #if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC) |
496 | /* we can use avb to verify Trusty if we want */ | 496 | /* we can use avb to verify Trusty if we want */ |
497 | const char *requested_partitions_boot[] = {"boot", FDT_PART_NAME, NULL}; | 497 | const char *requested_partitions_boot[] = {"boot", FDT_PART_NAME, NULL}; |
498 | const char *requested_partitions_recovery[] = {"recovery", FDT_PART_NAME, NULL}; | 498 | const char *requested_partitions_recovery[] = {"recovery", FDT_PART_NAME, NULL}; |
499 | 499 | ||
500 | static bool is_load_fdt_from_part(void) | 500 | static bool is_load_fdt_from_part(void) |
501 | { | 501 | { |
502 | bool ptn_find; | 502 | bool ptn_find; |
503 | 503 | ||
504 | #if defined(CONFIG_ANDROID_THINGS_SUPPORT) | 504 | #if defined(CONFIG_ANDROID_THINGS_SUPPORT) |
505 | ptn_find = fastboot_flash_find_ptn("oem_bootloader_a") && | 505 | ptn_find = fastboot_flash_find_ptn("oem_bootloader_a") && |
506 | fastboot_flash_find_ptn("oem_bootloader_b"); | 506 | fastboot_flash_find_ptn("oem_bootloader_b"); |
507 | #elif defined(CONFIG_ANDROID_AB_SUPPORT) | 507 | #elif defined(CONFIG_ANDROID_AB_SUPPORT) |
508 | ptn_find = fastboot_flash_find_ptn("dtbo_a") && | 508 | ptn_find = fastboot_flash_find_ptn("dtbo_a") && |
509 | fastboot_flash_find_ptn("dtbo_b"); | 509 | fastboot_flash_find_ptn("dtbo_b"); |
510 | #else | 510 | #else |
511 | ptn_find = fastboot_flash_find_ptn("dtbo"); | 511 | ptn_find = fastboot_flash_find_ptn("dtbo"); |
512 | #endif | 512 | #endif |
513 | 513 | ||
514 | if (ptn_find) | 514 | if (ptn_find) |
515 | return true; | 515 | return true; |
516 | else | 516 | else |
517 | return false; | 517 | return false; |
518 | } | 518 | } |
519 | 519 | ||
520 | static int find_partition_data_by_name(char* part_name, | 520 | static int find_partition_data_by_name(char* part_name, |
521 | AvbSlotVerifyData* avb_out_data, AvbPartitionData** avb_loadpart) | 521 | AvbSlotVerifyData* avb_out_data, AvbPartitionData** avb_loadpart) |
522 | { | 522 | { |
523 | int num = 0; | 523 | int num = 0; |
524 | AvbPartitionData* loadpart = NULL; | 524 | AvbPartitionData* loadpart = NULL; |
525 | 525 | ||
526 | for (num = 0; num < avb_out_data->num_loaded_partitions; num++) { | 526 | for (num = 0; num < avb_out_data->num_loaded_partitions; num++) { |
527 | loadpart = &(avb_out_data->loaded_partitions[num]); | 527 | loadpart = &(avb_out_data->loaded_partitions[num]); |
528 | if (!(strncmp(loadpart->partition_name, | 528 | if (!(strncmp(loadpart->partition_name, |
529 | part_name, strlen(part_name)))) { | 529 | part_name, strlen(part_name)))) { |
530 | *avb_loadpart = loadpart; | 530 | *avb_loadpart = loadpart; |
531 | break; | 531 | break; |
532 | } | 532 | } |
533 | } | 533 | } |
534 | if (num == avb_out_data->num_loaded_partitions) { | 534 | if (num == avb_out_data->num_loaded_partitions) { |
535 | printf("Error! Can't find %s partition from avb partition data!\n", | 535 | printf("Error! Can't find %s partition from avb partition data!\n", |
536 | part_name); | 536 | part_name); |
537 | return -1; | 537 | return -1; |
538 | } | 538 | } |
539 | else | 539 | else |
540 | return 0; | 540 | return 0; |
541 | } | 541 | } |
542 | 542 | ||
543 | int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { | 543 | int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { |
544 | 544 | ||
545 | ulong addr = 0; | 545 | ulong addr = 0; |
546 | struct andr_img_hdr *hdr = NULL; | 546 | struct andr_img_hdr *hdr = NULL; |
547 | void *boot_buf = NULL; | 547 | void *boot_buf = NULL; |
548 | ulong image_size; | 548 | ulong image_size; |
549 | u32 avb_metric; | 549 | u32 avb_metric; |
550 | bool check_image_arm64 = false; | 550 | bool check_image_arm64 = false; |
551 | bool is_recovery_mode = false; | 551 | bool is_recovery_mode = false; |
552 | 552 | ||
553 | AvbABFlowResult avb_result; | 553 | AvbABFlowResult avb_result; |
554 | AvbSlotVerifyData *avb_out_data = NULL; | 554 | AvbSlotVerifyData *avb_out_data = NULL; |
555 | AvbPartitionData *avb_loadpart = NULL; | 555 | AvbPartitionData *avb_loadpart = NULL; |
556 | 556 | ||
557 | /* get bootmode, default to boot "boot" */ | 557 | /* get bootmode, default to boot "boot" */ |
558 | if (argc > 1) { | 558 | if (argc > 1) { |
559 | is_recovery_mode = | 559 | is_recovery_mode = |
560 | (strncmp(argv[1], "recovery", sizeof("recovery")) != 0) ? false: true; | 560 | (strncmp(argv[1], "recovery", sizeof("recovery")) != 0) ? false: true; |
561 | if (is_recovery_mode) | 561 | if (is_recovery_mode) |
562 | printf("Will boot from recovery!\n"); | 562 | printf("Will boot from recovery!\n"); |
563 | } | 563 | } |
564 | 564 | ||
565 | /* check lock state */ | 565 | /* check lock state */ |
566 | FbLockState lock_status = fastboot_get_lock_stat(); | 566 | FbLockState lock_status = fastboot_get_lock_stat(); |
567 | if (lock_status == FASTBOOT_LOCK_ERROR) { | 567 | if (lock_status == FASTBOOT_LOCK_ERROR) { |
568 | #ifdef CONFIG_AVB_ATX | 568 | #ifdef CONFIG_AVB_ATX |
569 | printf("In boota get fastboot lock status error, enter fastboot mode.\n"); | 569 | printf("In boota get fastboot lock status error, enter fastboot mode.\n"); |
570 | goto fail; | 570 | goto fail; |
571 | #else | 571 | #else |
572 | printf("In boota get fastboot lock status error. Set lock status\n"); | 572 | printf("In boota get fastboot lock status error. Set lock status\n"); |
573 | fastboot_set_lock_stat(FASTBOOT_LOCK); | 573 | fastboot_set_lock_stat(FASTBOOT_LOCK); |
574 | lock_status = FASTBOOT_LOCK; | 574 | lock_status = FASTBOOT_LOCK; |
575 | #endif | 575 | #endif |
576 | } | 576 | } |
577 | bool allow_fail = (lock_status == FASTBOOT_UNLOCK ? true : false); | 577 | bool allow_fail = (lock_status == FASTBOOT_UNLOCK ? true : false); |
578 | avb_metric = get_timer(0); | 578 | avb_metric = get_timer(0); |
579 | /* we don't need to verify fdt partition if we don't have it. */ | 579 | /* we don't need to verify fdt partition if we don't have it. */ |
580 | if (!is_load_fdt_from_part()) { | 580 | if (!is_load_fdt_from_part()) { |
581 | requested_partitions_boot[1] = NULL; | 581 | requested_partitions_boot[1] = NULL; |
582 | requested_partitions_recovery[1] = NULL; | 582 | requested_partitions_recovery[1] = NULL; |
583 | } | 583 | } |
584 | #ifndef CONFIG_SYSTEM_RAMDISK_SUPPORT | 584 | #ifndef CONFIG_SYSTEM_RAMDISK_SUPPORT |
585 | else if (is_recovery_mode){ | 585 | else if (is_recovery_mode){ |
586 | requested_partitions_recovery[1] = NULL; | 586 | requested_partitions_recovery[1] = NULL; |
587 | } | 587 | } |
588 | #endif | 588 | #endif |
589 | 589 | ||
590 | /* if in lock state, do avb verify */ | 590 | /* if in lock state, do avb verify */ |
591 | #ifndef CONFIG_DUAL_BOOTLOADER | 591 | #ifndef CONFIG_DUAL_BOOTLOADER |
592 | /* For imx6 on Android, we don't have a/b slot and we want to verify | 592 | /* For imx6 on Android, we don't have a/b slot and we want to verify |
593 | * boot/recovery with AVB. For imx8 and Android Things we don't have | 593 | * boot/recovery with AVB. For imx8 and Android Things we don't have |
594 | * recovery and support a/b slot for boot */ | 594 | * recovery and support a/b slot for boot */ |
595 | #ifdef CONFIG_ANDROID_AB_SUPPORT | 595 | #ifdef CONFIG_ANDROID_AB_SUPPORT |
596 | /* we can use avb to verify Trusty if we want */ | 596 | /* we can use avb to verify Trusty if we want */ |
597 | avb_result = avb_ab_flow_fast(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, | 597 | avb_result = avb_ab_flow_fast(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, |
598 | AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &avb_out_data); | 598 | AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &avb_out_data); |
599 | #else | 599 | #else |
600 | #ifndef CONFIG_SYSTEM_RAMDISK_SUPPORT | 600 | #ifndef CONFIG_SYSTEM_RAMDISK_SUPPORT |
601 | if (!is_recovery_mode) { | 601 | if (!is_recovery_mode) { |
602 | avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, | 602 | avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, |
603 | AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data); | 603 | AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data); |
604 | } else { | 604 | } else { |
605 | avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions_recovery, allow_fail, | 605 | avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions_recovery, allow_fail, |
606 | AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data); | 606 | AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data); |
607 | } | 607 | } |
608 | #else /* CONFIG_SYSTEM_RAMDISK_SUPPORT defined */ | 608 | #else /* CONFIG_SYSTEM_RAMDISK_SUPPORT defined */ |
609 | avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, | 609 | avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, |
610 | AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data); | 610 | AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data); |
611 | #endif /*CONFIG_SYSTEM_RAMDISK_SUPPORT*/ | 611 | #endif /*CONFIG_SYSTEM_RAMDISK_SUPPORT*/ |
612 | #endif | 612 | #endif |
613 | #else /* !CONFIG_DUAL_BOOTLOADER */ | 613 | #else /* !CONFIG_DUAL_BOOTLOADER */ |
614 | /* We will only verify single one slot which has been selected in SPL */ | 614 | /* We will only verify single one slot which has been selected in SPL */ |
615 | avb_result = avb_flow_dual_uboot(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, | 615 | avb_result = avb_flow_dual_uboot(&fsl_avb_ab_ops, requested_partitions_boot, allow_fail, |
616 | AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &avb_out_data); | 616 | AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &avb_out_data); |
617 | 617 | ||
618 | /* Reboot if current slot is not bootable. */ | 618 | /* Reboot if current slot is not bootable. */ |
619 | if (avb_result == AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS) { | 619 | if (avb_result == AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS) { |
620 | printf("boota: slot verify fail!\n"); | 620 | printf("boota: slot verify fail!\n"); |
621 | do_reset(NULL, 0, 0, NULL); | 621 | do_reset(NULL, 0, 0, NULL); |
622 | } | 622 | } |
623 | #endif /* !CONFIG_DUAL_BOOTLOADER */ | 623 | #endif /* !CONFIG_DUAL_BOOTLOADER */ |
624 | 624 | ||
625 | /* get the duration of avb */ | 625 | /* get the duration of avb */ |
626 | metrics.avb = get_timer(avb_metric); | 626 | metrics.avb = get_timer(avb_metric); |
627 | 627 | ||
628 | if ((avb_result == AVB_AB_FLOW_RESULT_OK) || | 628 | if ((avb_result == AVB_AB_FLOW_RESULT_OK) || |
629 | (avb_result == AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR)) { | 629 | (avb_result == AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR)) { |
630 | assert(avb_out_data != NULL); | 630 | assert(avb_out_data != NULL); |
631 | /* We may have more than one partition loaded by AVB, find the boot | 631 | /* We may have more than one partition loaded by AVB, find the boot |
632 | * partition first. | 632 | * partition first. |
633 | */ | 633 | */ |
634 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | 634 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT |
635 | if (find_partition_data_by_name("boot", avb_out_data, &avb_loadpart)) | 635 | if (find_partition_data_by_name("boot", avb_out_data, &avb_loadpart)) |
636 | goto fail; | 636 | goto fail; |
637 | #else | 637 | #else |
638 | if (!is_recovery_mode) { | 638 | if (!is_recovery_mode) { |
639 | if (find_partition_data_by_name("boot", avb_out_data, &avb_loadpart)) | 639 | if (find_partition_data_by_name("boot", avb_out_data, &avb_loadpart)) |
640 | goto fail; | 640 | goto fail; |
641 | } else { | 641 | } else { |
642 | if (find_partition_data_by_name("recovery", avb_out_data, &avb_loadpart)) | 642 | if (find_partition_data_by_name("recovery", avb_out_data, &avb_loadpart)) |
643 | goto fail; | 643 | goto fail; |
644 | } | 644 | } |
645 | #endif | 645 | #endif |
646 | assert(avb_loadpart != NULL); | 646 | assert(avb_loadpart != NULL); |
647 | /* we should use avb_part_data->data as boot image */ | 647 | /* we should use avb_part_data->data as boot image */ |
648 | /* boot image is already read by avb */ | 648 | /* boot image is already read by avb */ |
649 | hdr = (struct andr_img_hdr *)avb_loadpart->data; | 649 | hdr = (struct andr_img_hdr *)avb_loadpart->data; |
650 | if (android_image_check_header(hdr)) { | 650 | if (android_image_check_header(hdr)) { |
651 | printf("boota: bad boot image magic\n"); | 651 | printf("boota: bad boot image magic\n"); |
652 | goto fail; | 652 | goto fail; |
653 | } | 653 | } |
654 | if (avb_result == AVB_AB_FLOW_RESULT_OK) | 654 | if (avb_result == AVB_AB_FLOW_RESULT_OK) |
655 | printf(" verify OK, boot '%s%s'\n", | 655 | printf(" verify OK, boot '%s%s'\n", |
656 | avb_loadpart->partition_name, avb_out_data->ab_suffix); | 656 | avb_loadpart->partition_name, avb_out_data->ab_suffix); |
657 | else { | 657 | else { |
658 | printf(" verify FAIL, state: UNLOCK\n"); | 658 | printf(" verify FAIL, state: UNLOCK\n"); |
659 | printf(" boot '%s%s' still\n", | 659 | printf(" boot '%s%s' still\n", |
660 | avb_loadpart->partition_name, avb_out_data->ab_suffix); | 660 | avb_loadpart->partition_name, avb_out_data->ab_suffix); |
661 | } | 661 | } |
662 | char bootargs_sec[ANDR_BOOT_EXTRA_ARGS_SIZE]; | 662 | char bootargs_sec[ANDR_BOOT_EXTRA_ARGS_SIZE]; |
663 | if (lock_status == FASTBOOT_LOCK) { | 663 | if (lock_status == FASTBOOT_LOCK) { |
664 | snprintf(bootargs_sec, sizeof(bootargs_sec), | 664 | snprintf(bootargs_sec, sizeof(bootargs_sec), |
665 | "androidboot.verifiedbootstate=green androidboot.flash.locked=1 androidboot.slot_suffix=%s %s", | 665 | "androidboot.verifiedbootstate=green androidboot.flash.locked=1 androidboot.slot_suffix=%s %s", |
666 | avb_out_data->ab_suffix, avb_out_data->cmdline); | 666 | avb_out_data->ab_suffix, avb_out_data->cmdline); |
667 | } else { | 667 | } else { |
668 | snprintf(bootargs_sec, sizeof(bootargs_sec), | 668 | snprintf(bootargs_sec, sizeof(bootargs_sec), |
669 | "androidboot.verifiedbootstate=orange androidboot.flash.locked=0 androidboot.slot_suffix=%s %s", | 669 | "androidboot.verifiedbootstate=orange androidboot.flash.locked=0 androidboot.slot_suffix=%s %s", |
670 | avb_out_data->ab_suffix, avb_out_data->cmdline); | 670 | avb_out_data->ab_suffix, avb_out_data->cmdline); |
671 | } | 671 | } |
672 | env_set("bootargs_sec", bootargs_sec); | 672 | env_set("bootargs_sec", bootargs_sec); |
673 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | 673 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT |
674 | if(!is_recovery_mode) { | 674 | if(!is_recovery_mode) { |
675 | if(avb_out_data->cmdline != NULL && strstr(avb_out_data->cmdline, "root=")) | 675 | if(avb_out_data->cmdline != NULL && strstr(avb_out_data->cmdline, "root=")) |
676 | fastboot_setup_system_boot_args(avb_out_data->ab_suffix, false); | 676 | fastboot_setup_system_boot_args(avb_out_data->ab_suffix, false); |
677 | else | 677 | else |
678 | fastboot_setup_system_boot_args(avb_out_data->ab_suffix, true); | 678 | fastboot_setup_system_boot_args(avb_out_data->ab_suffix, true); |
679 | } | 679 | } |
680 | #endif /* CONFIG_SYSTEM_RAMDISK_SUPPORT */ | 680 | #endif /* CONFIG_SYSTEM_RAMDISK_SUPPORT */ |
681 | image_size = avb_loadpart->data_size; | 681 | image_size = avb_loadpart->data_size; |
682 | #if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M) | 682 | #if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M) |
683 | /* If we are using uncompressed kernel image, copy it directly to | 683 | /* If we are using uncompressed kernel image, copy it directly to |
684 | * hdr->kernel_addr, if we are using compressed lz4 kernel image, | 684 | * hdr->kernel_addr, if we are using compressed lz4 kernel image, |
685 | * we need to decompress the kernel image first. */ | 685 | * we need to decompress the kernel image first. */ |
686 | if (image_arm64((void *)((ulong)hdr + hdr->page_size))) { | 686 | if (image_arm64((void *)((ulong)hdr + hdr->page_size))) { |
687 | memcpy((void *)(long)hdr->kernel_addr, | 687 | memcpy((void *)(long)hdr->kernel_addr, |
688 | (void *)((ulong)hdr + hdr->page_size), hdr->kernel_size); | 688 | (void *)((ulong)hdr + hdr->page_size), hdr->kernel_size); |
689 | } else { | 689 | } else { |
690 | #ifdef CONFIG_LZ4 | 690 | #ifdef CONFIG_LZ4 |
691 | size_t lz4_len = DST_DECOMPRESS_LEN; | 691 | size_t lz4_len = DST_DECOMPRESS_LEN; |
692 | if (ulz4fn((void *)((ulong)hdr + hdr->page_size), | 692 | if (ulz4fn((void *)((ulong)hdr + hdr->page_size), |
693 | hdr->kernel_size, (void *)(ulong)hdr->kernel_addr, &lz4_len) != 0) { | 693 | hdr->kernel_size, (void *)(ulong)hdr->kernel_addr, &lz4_len) != 0) { |
694 | printf("Decompress kernel fail!\n"); | 694 | printf("Decompress kernel fail!\n"); |
695 | goto fail; | 695 | goto fail; |
696 | } | 696 | } |
697 | #else /* CONFIG_LZ4 */ | 697 | #else /* CONFIG_LZ4 */ |
698 | printf("please enable CONFIG_LZ4 if we're using compressed lz4 kernel image!\n"); | 698 | printf("please enable CONFIG_LZ4 if we're using compressed lz4 kernel image!\n"); |
699 | goto fail; | 699 | goto fail; |
700 | #endif /* CONFIG_LZ4 */ | 700 | #endif /* CONFIG_LZ4 */ |
701 | } | 701 | } |
702 | #else /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */ | 702 | #else /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */ |
703 | /* copy kernel image and boot header to hdr->kernel_addr - hdr->page_size */ | 703 | /* copy kernel image and boot header to hdr->kernel_addr - hdr->page_size */ |
704 | memcpy((void *)(ulong)(hdr->kernel_addr - hdr->page_size), (void *)hdr, | 704 | memcpy((void *)(ulong)(hdr->kernel_addr - hdr->page_size), (void *)hdr, |
705 | hdr->page_size + ALIGN(hdr->kernel_size, hdr->page_size)); | 705 | hdr->page_size + ALIGN(hdr->kernel_size, hdr->page_size)); |
706 | #endif /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */ | 706 | #endif /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */ |
707 | } else { | 707 | } else { |
708 | /* Fall into fastboot mode if get unacceptable error from avb | 708 | /* Fall into fastboot mode if get unacceptable error from avb |
709 | * or verify fail in lock state. | 709 | * or verify fail in lock state. |
710 | */ | 710 | */ |
711 | if (lock_status == FASTBOOT_LOCK) | 711 | if (lock_status == FASTBOOT_LOCK) |
712 | printf(" verify FAIL, state: LOCK\n"); | 712 | printf(" verify FAIL, state: LOCK\n"); |
713 | 713 | ||
714 | goto fail; | 714 | goto fail; |
715 | } | 715 | } |
716 | 716 | ||
717 | flush_cache((ulong)load_addr, image_size); | 717 | flush_cache((ulong)load_addr, image_size); |
718 | check_image_arm64 = image_arm64((void *)(ulong)hdr->kernel_addr); | 718 | check_image_arm64 = image_arm64((void *)(ulong)hdr->kernel_addr); |
719 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | 719 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT |
720 | if (is_recovery_mode) | 720 | if (is_recovery_mode) |
721 | memcpy((void *)(ulong)hdr->ramdisk_addr, (void *)(ulong)hdr + hdr->page_size | 721 | memcpy((void *)(ulong)hdr->ramdisk_addr, (void *)(ulong)hdr + hdr->page_size |
722 | + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); | 722 | + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); |
723 | #else | 723 | #else |
724 | memcpy((void *)(ulong)hdr->ramdisk_addr, (void *)(ulong)hdr + hdr->page_size | 724 | memcpy((void *)(ulong)hdr->ramdisk_addr, (void *)(ulong)hdr + hdr->page_size |
725 | + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); | 725 | + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); |
726 | #endif | 726 | #endif |
727 | #ifdef CONFIG_OF_LIBFDT | 727 | #ifdef CONFIG_OF_LIBFDT |
728 | /* load the dtb file */ | 728 | /* load the dtb file */ |
729 | u32 fdt_size = 0; | 729 | u32 fdt_size = 0; |
730 | struct dt_table_header *dt_img = NULL; | 730 | struct dt_table_header *dt_img = NULL; |
731 | 731 | ||
732 | if (is_load_fdt_from_part()) { | 732 | if (is_load_fdt_from_part()) { |
733 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT | 733 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT |
734 | if (find_partition_data_by_name("oem_bootloader", | 734 | if (find_partition_data_by_name("oem_bootloader", |
735 | avb_out_data, &avb_loadpart)) { | 735 | avb_out_data, &avb_loadpart)) { |
736 | goto fail; | 736 | goto fail; |
737 | } else | 737 | } else |
738 | dt_img = (struct dt_table_header *)avb_loadpart->data; | 738 | dt_img = (struct dt_table_header *)avb_loadpart->data; |
739 | #elif defined(CONFIG_SYSTEM_RAMDISK_SUPPORT) /* It means boot.img(recovery) do not include dtb, it need load dtb from partition */ | 739 | #elif defined(CONFIG_SYSTEM_RAMDISK_SUPPORT) /* It means boot.img(recovery) do not include dtb, it need load dtb from partition */ |
740 | if (find_partition_data_by_name("dtbo", | 740 | if (find_partition_data_by_name("dtbo", |
741 | avb_out_data, &avb_loadpart)) { | 741 | avb_out_data, &avb_loadpart)) { |
742 | goto fail; | 742 | goto fail; |
743 | } else | 743 | } else |
744 | dt_img = (struct dt_table_header *)avb_loadpart->data; | 744 | dt_img = (struct dt_table_header *)avb_loadpart->data; |
745 | #else /* recovery.img include dts while boot.img use dtbo */ | 745 | #else /* recovery.img include dts while boot.img use dtbo */ |
746 | if (is_recovery_mode) { | 746 | if (is_recovery_mode) { |
747 | if (hdr->header_version != 1) { | 747 | if (hdr->header_version != 1) { |
748 | printf("boota: boot image header version error!\n"); | 748 | printf("boota: boot image header version error!\n"); |
749 | goto fail; | 749 | goto fail; |
750 | } | 750 | } |
751 | 751 | ||
752 | dt_img = (struct dt_table_header *)((void *)(ulong)hdr + | 752 | dt_img = (struct dt_table_header *)((void *)(ulong)hdr + |
753 | hdr->page_size + | 753 | hdr->page_size + |
754 | ALIGN(hdr->kernel_size, hdr->page_size) + | 754 | ALIGN(hdr->kernel_size, hdr->page_size) + |
755 | ALIGN(hdr->ramdisk_size, hdr->page_size) + | 755 | ALIGN(hdr->ramdisk_size, hdr->page_size) + |
756 | ALIGN(hdr->second_size, hdr->page_size)); | 756 | ALIGN(hdr->second_size, hdr->page_size)); |
757 | } else if (find_partition_data_by_name("dtbo", | 757 | } else if (find_partition_data_by_name("dtbo", |
758 | avb_out_data, &avb_loadpart)) { | 758 | avb_out_data, &avb_loadpart)) { |
759 | goto fail; | 759 | goto fail; |
760 | } else | 760 | } else |
761 | dt_img = (struct dt_table_header *)avb_loadpart->data; | 761 | dt_img = (struct dt_table_header *)avb_loadpart->data; |
762 | #endif | 762 | #endif |
763 | 763 | ||
764 | if (be32_to_cpu(dt_img->magic) != DT_TABLE_MAGIC) { | 764 | if (be32_to_cpu(dt_img->magic) != DT_TABLE_MAGIC) { |
765 | printf("boota: bad dt table magic %08x\n", | 765 | printf("boota: bad dt table magic %08x\n", |
766 | be32_to_cpu(dt_img->magic)); | 766 | be32_to_cpu(dt_img->magic)); |
767 | goto fail; | 767 | goto fail; |
768 | } else if (!be32_to_cpu(dt_img->dt_entry_count)) { | 768 | } else if (!be32_to_cpu(dt_img->dt_entry_count)) { |
769 | printf("boota: no dt entries\n"); | 769 | printf("boota: no dt entries\n"); |
770 | goto fail; | 770 | goto fail; |
771 | } | 771 | } |
772 | 772 | ||
773 | struct dt_table_entry *dt_entry; | 773 | struct dt_table_entry *dt_entry; |
774 | dt_entry = (struct dt_table_entry *)((ulong)dt_img + | 774 | dt_entry = (struct dt_table_entry *)((ulong)dt_img + |
775 | be32_to_cpu(dt_img->dt_entries_offset)); | 775 | be32_to_cpu(dt_img->dt_entries_offset)); |
776 | fdt_size = be32_to_cpu(dt_entry->dt_size); | 776 | fdt_size = be32_to_cpu(dt_entry->dt_size); |
777 | memcpy((void *)(ulong)hdr->second_addr, (void *)((ulong)dt_img + | 777 | memcpy((void *)(ulong)hdr->second_addr, (void *)((ulong)dt_img + |
778 | be32_to_cpu(dt_entry->dt_offset)), fdt_size); | 778 | be32_to_cpu(dt_entry->dt_offset)), fdt_size); |
779 | } else { | 779 | } else { |
780 | if (hdr->second_size && hdr->second_addr) { | 780 | if (hdr->second_size && hdr->second_addr) { |
781 | memcpy((void *)(ulong)hdr->second_addr, | 781 | memcpy((void *)(ulong)hdr->second_addr, |
782 | (void *)(ulong)hdr + hdr->page_size | 782 | (void *)(ulong)hdr + hdr->page_size |
783 | + ALIGN(hdr->kernel_size, hdr->page_size) | 783 | + ALIGN(hdr->kernel_size, hdr->page_size) |
784 | + ALIGN(hdr->ramdisk_size, hdr->page_size), | 784 | + ALIGN(hdr->ramdisk_size, hdr->page_size), |
785 | hdr->second_size); | 785 | hdr->second_size); |
786 | } | 786 | } |
787 | } | 787 | } |
788 | #endif /*CONFIG_OF_LIBFDT*/ | 788 | #endif /*CONFIG_OF_LIBFDT*/ |
789 | 789 | ||
790 | if (check_image_arm64) { | 790 | if (check_image_arm64) { |
791 | android_image_get_kernel(hdr, 0, NULL, NULL); | 791 | android_image_get_kernel(hdr, 0, NULL, NULL); |
792 | addr = hdr->kernel_addr; | 792 | addr = hdr->kernel_addr; |
793 | } else { | 793 | } else { |
794 | addr = (ulong)(hdr->kernel_addr - hdr->page_size); | 794 | addr = (ulong)(hdr->kernel_addr - hdr->page_size); |
795 | } | 795 | } |
796 | printf("kernel @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size); | 796 | printf("kernel @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size); |
797 | printf("ramdisk @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size); | 797 | printf("ramdisk @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size); |
798 | #ifdef CONFIG_OF_LIBFDT | 798 | #ifdef CONFIG_OF_LIBFDT |
799 | if (is_load_fdt_from_part()) { | 799 | if (is_load_fdt_from_part()) { |
800 | if (fdt_size) | 800 | if (fdt_size) |
801 | printf("fdt @ %08x (%d)\n", hdr->second_addr, fdt_size); | 801 | printf("fdt @ %08x (%d)\n", hdr->second_addr, fdt_size); |
802 | } else { | 802 | } else { |
803 | if (hdr->second_size) | 803 | if (hdr->second_size) |
804 | printf("fdt @ %08x (%d)\n", hdr->second_addr, hdr->second_size); | 804 | printf("fdt @ %08x (%d)\n", hdr->second_addr, hdr->second_size); |
805 | } | 805 | } |
806 | #endif /*CONFIG_OF_LIBFDT*/ | 806 | #endif /*CONFIG_OF_LIBFDT*/ |
807 | 807 | ||
808 | char boot_addr_start[12]; | 808 | char boot_addr_start[12]; |
809 | char ramdisk_addr[25]; | 809 | char ramdisk_addr[25]; |
810 | char fdt_addr[12]; | 810 | char fdt_addr[12]; |
811 | 811 | ||
812 | char *boot_args[] = { NULL, boot_addr_start, ramdisk_addr, fdt_addr}; | 812 | char *boot_args[] = { NULL, boot_addr_start, ramdisk_addr, fdt_addr}; |
813 | if (check_image_arm64) | 813 | if (check_image_arm64) |
814 | boot_args[0] = "booti"; | 814 | boot_args[0] = "booti"; |
815 | else | 815 | else |
816 | boot_args[0] = "bootm"; | 816 | boot_args[0] = "bootm"; |
817 | 817 | ||
818 | sprintf(boot_addr_start, "0x%lx", addr); | 818 | sprintf(boot_addr_start, "0x%lx", addr); |
819 | sprintf(ramdisk_addr, "0x%x:0x%x", hdr->ramdisk_addr, hdr->ramdisk_size); | 819 | sprintf(ramdisk_addr, "0x%x:0x%x", hdr->ramdisk_addr, hdr->ramdisk_size); |
820 | sprintf(fdt_addr, "0x%x", hdr->second_addr); | 820 | sprintf(fdt_addr, "0x%x", hdr->second_addr); |
821 | 821 | ||
822 | /* no need to pass ramdisk addr for normal boot mode when enable CONFIG_SYSTEM_RAMDISK_SUPPORT*/ | 822 | /* no need to pass ramdisk addr for normal boot mode when enable CONFIG_SYSTEM_RAMDISK_SUPPORT*/ |
823 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT | 823 | #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT |
824 | if (!is_recovery_mode) | 824 | if (!is_recovery_mode) |
825 | boot_args[2] = NULL; | 825 | boot_args[2] = NULL; |
826 | #endif | 826 | #endif |
827 | 827 | ||
828 | #ifdef CONFIG_IMX_TRUSTY_OS | 828 | #ifdef CONFIG_IMX_TRUSTY_OS |
829 | /* Trusty keymaster needs some parameters before it work */ | 829 | /* Trusty keymaster needs some parameters before it work */ |
830 | if (trusty_setbootparameter(hdr, avb_result, avb_out_data)) | 830 | if (trusty_setbootparameter(hdr, avb_result, avb_out_data)) |
831 | goto fail; | 831 | goto fail; |
832 | /* lock the boot status and rollback_idx preventing Linux modify it */ | 832 | /* lock the boot status and rollback_idx preventing Linux modify it */ |
833 | trusty_lock_boot_state(); | 833 | trusty_lock_boot_state(); |
834 | /* lock the boot state so linux can't use some hwcrypto commands. */ | ||
835 | hwcrypto_lock_boot_state(); | ||
834 | /* put ql-tipc to release resource for Linux */ | 836 | /* put ql-tipc to release resource for Linux */ |
835 | trusty_ipc_shutdown(); | 837 | trusty_ipc_shutdown(); |
836 | #endif | 838 | #endif |
837 | 839 | ||
838 | if (avb_out_data != NULL) | 840 | if (avb_out_data != NULL) |
839 | avb_slot_verify_data_free(avb_out_data); | 841 | avb_slot_verify_data_free(avb_out_data); |
840 | if (boot_buf != NULL) | 842 | if (boot_buf != NULL) |
841 | free(boot_buf); | 843 | free(boot_buf); |
842 | 844 | ||
843 | if (check_image_arm64) { | 845 | if (check_image_arm64) { |
844 | #ifdef CONFIG_CMD_BOOTI | 846 | #ifdef CONFIG_CMD_BOOTI |
845 | do_booti(NULL, 0, 4, boot_args); | 847 | do_booti(NULL, 0, 4, boot_args); |
846 | #else | 848 | #else |
847 | debug("please enable CONFIG_CMD_BOOTI when kernel are Image"); | 849 | debug("please enable CONFIG_CMD_BOOTI when kernel are Image"); |
848 | #endif | 850 | #endif |
849 | } else { | 851 | } else { |
850 | do_bootm(NULL, 0, 4, boot_args); | 852 | do_bootm(NULL, 0, 4, boot_args); |
851 | } | 853 | } |
852 | 854 | ||
853 | /* This only happens if image is somehow faulty so we start over */ | 855 | /* This only happens if image is somehow faulty so we start over */ |
854 | do_reset(NULL, 0, 0, NULL); | 856 | do_reset(NULL, 0, 0, NULL); |
855 | 857 | ||
856 | return 1; | 858 | return 1; |
857 | 859 | ||
858 | fail: | 860 | fail: |
859 | /* avb has no recovery */ | 861 | /* avb has no recovery */ |
860 | if (avb_out_data != NULL) | 862 | if (avb_out_data != NULL) |
861 | avb_slot_verify_data_free(avb_out_data); | 863 | avb_slot_verify_data_free(avb_out_data); |
862 | 864 | ||
863 | return run_command("fastboot 0", 0); | 865 | return run_command("fastboot 0", 0); |
864 | } | 866 | } |
865 | 867 | ||
866 | U_BOOT_CMD( | 868 | U_BOOT_CMD( |
867 | boota, 2, 1, do_boota, | 869 | boota, 2, 1, do_boota, |
868 | "boota - boot android bootimg \n", | 870 | "boota - boot android bootimg \n", |
869 | "boot from current mmc with avb verify\n" | 871 | "boot from current mmc with avb verify\n" |
870 | ); | 872 | ); |
871 | 873 | ||
872 | #else /* CONFIG_AVB_SUPPORT */ | 874 | #else /* CONFIG_AVB_SUPPORT */ |
873 | /* boota <addr> [ mmc0 | mmc1 [ <partition> ] ] */ | 875 | /* boota <addr> [ mmc0 | mmc1 [ <partition> ] ] */ |
874 | int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | 876 | int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
875 | { | 877 | { |
876 | ulong addr = 0; | 878 | ulong addr = 0; |
877 | char *ptn = "boot"; | 879 | char *ptn = "boot"; |
878 | int mmcc = -1; | 880 | int mmcc = -1; |
879 | struct andr_img_hdr *hdr = &boothdr; | 881 | struct andr_img_hdr *hdr = &boothdr; |
880 | ulong image_size; | 882 | ulong image_size; |
881 | bool check_image_arm64 = false; | 883 | bool check_image_arm64 = false; |
882 | int i = 0; | 884 | int i = 0; |
883 | 885 | ||
884 | for (i = 0; i < argc; i++) | 886 | for (i = 0; i < argc; i++) |
885 | printf("%s ", argv[i]); | 887 | printf("%s ", argv[i]); |
886 | printf("\n"); | 888 | printf("\n"); |
887 | 889 | ||
888 | if (argc < 2) | 890 | if (argc < 2) |
889 | return -1; | 891 | return -1; |
890 | 892 | ||
891 | mmcc = simple_strtoul(argv[1]+3, NULL, 10); | 893 | mmcc = simple_strtoul(argv[1]+3, NULL, 10); |
892 | 894 | ||
893 | if (argc > 2) | 895 | if (argc > 2) |
894 | ptn = argv[2]; | 896 | ptn = argv[2]; |
895 | 897 | ||
896 | if (mmcc != -1) { | 898 | if (mmcc != -1) { |
897 | #ifdef CONFIG_MMC | 899 | #ifdef CONFIG_MMC |
898 | struct fastboot_ptentry *pte; | 900 | struct fastboot_ptentry *pte; |
899 | struct mmc *mmc; | 901 | struct mmc *mmc; |
900 | disk_partition_t info; | 902 | disk_partition_t info; |
901 | struct blk_desc *dev_desc = NULL; | 903 | struct blk_desc *dev_desc = NULL; |
902 | unsigned bootimg_sectors; | 904 | unsigned bootimg_sectors; |
903 | 905 | ||
904 | memset((void *)&info, 0 , sizeof(disk_partition_t)); | 906 | memset((void *)&info, 0 , sizeof(disk_partition_t)); |
905 | /* i.MX use MBR as partition table, so this will have | 907 | /* i.MX use MBR as partition table, so this will have |
906 | to find the start block and length for the | 908 | to find the start block and length for the |
907 | partition name and register the fastboot pte we | 909 | partition name and register the fastboot pte we |
908 | define the partition number of each partition in | 910 | define the partition number of each partition in |
909 | config file | 911 | config file |
910 | */ | 912 | */ |
911 | mmc = find_mmc_device(mmcc); | 913 | mmc = find_mmc_device(mmcc); |
912 | if (!mmc) { | 914 | if (!mmc) { |
913 | printf("boota: cannot find '%d' mmc device\n", mmcc); | 915 | printf("boota: cannot find '%d' mmc device\n", mmcc); |
914 | goto fail; | 916 | goto fail; |
915 | } | 917 | } |
916 | dev_desc = blk_get_dev("mmc", mmcc); | 918 | dev_desc = blk_get_dev("mmc", mmcc); |
917 | if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { | 919 | if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { |
918 | printf("** Block device MMC %d not supported\n", mmcc); | 920 | printf("** Block device MMC %d not supported\n", mmcc); |
919 | goto fail; | 921 | goto fail; |
920 | } | 922 | } |
921 | 923 | ||
922 | /* below was i.MX mmc operation code */ | 924 | /* below was i.MX mmc operation code */ |
923 | if (mmc_init(mmc)) { | 925 | if (mmc_init(mmc)) { |
924 | printf("mmc%d init failed\n", mmcc); | 926 | printf("mmc%d init failed\n", mmcc); |
925 | goto fail; | 927 | goto fail; |
926 | } | 928 | } |
927 | 929 | ||
928 | pte = fastboot_flash_find_ptn(ptn); | 930 | pte = fastboot_flash_find_ptn(ptn); |
929 | if (!pte) { | 931 | if (!pte) { |
930 | printf("boota: cannot find '%s' partition\n", ptn); | 932 | printf("boota: cannot find '%s' partition\n", ptn); |
931 | fastboot_flash_dump_ptn(); | 933 | fastboot_flash_dump_ptn(); |
932 | goto fail; | 934 | goto fail; |
933 | } | 935 | } |
934 | 936 | ||
935 | if (blk_dread(dev_desc, pte->start, | 937 | if (blk_dread(dev_desc, pte->start, |
936 | 1, (void *)hdr) < 0) { | 938 | 1, (void *)hdr) < 0) { |
937 | printf("boota: mmc failed to read bootimg header\n"); | 939 | printf("boota: mmc failed to read bootimg header\n"); |
938 | goto fail; | 940 | goto fail; |
939 | } | 941 | } |
940 | 942 | ||
941 | if (android_image_check_header(hdr)) { | 943 | if (android_image_check_header(hdr)) { |
942 | printf("boota: bad boot image magic\n"); | 944 | printf("boota: bad boot image magic\n"); |
943 | goto fail; | 945 | goto fail; |
944 | } | 946 | } |
945 | 947 | ||
946 | image_size = android_image_get_end(hdr) - (ulong)hdr; | 948 | image_size = android_image_get_end(hdr) - (ulong)hdr; |
947 | bootimg_sectors = image_size/512; | 949 | bootimg_sectors = image_size/512; |
948 | 950 | ||
949 | if (blk_dread(dev_desc, pte->start, | 951 | if (blk_dread(dev_desc, pte->start, |
950 | bootimg_sectors, | 952 | bootimg_sectors, |
951 | (void *)(hdr->kernel_addr - hdr->page_size)) < 0) { | 953 | (void *)(hdr->kernel_addr - hdr->page_size)) < 0) { |
952 | printf("boota: mmc failed to read bootimage\n"); | 954 | printf("boota: mmc failed to read bootimage\n"); |
953 | goto fail; | 955 | goto fail; |
954 | } | 956 | } |
955 | check_image_arm64 = image_arm64((void *)hdr->kernel_addr); | 957 | check_image_arm64 = image_arm64((void *)hdr->kernel_addr); |
956 | #if defined(CONFIG_FASTBOOT_LOCK) | 958 | #if defined(CONFIG_FASTBOOT_LOCK) |
957 | int verifyresult = -1; | 959 | int verifyresult = -1; |
958 | #endif | 960 | #endif |
959 | 961 | ||
960 | #if defined(CONFIG_FASTBOOT_LOCK) | 962 | #if defined(CONFIG_FASTBOOT_LOCK) |
961 | int lock_status = fastboot_get_lock_stat(); | 963 | int lock_status = fastboot_get_lock_stat(); |
962 | if (lock_status == FASTBOOT_LOCK_ERROR) { | 964 | if (lock_status == FASTBOOT_LOCK_ERROR) { |
963 | printf("In boota get fastboot lock status error. Set lock status\n"); | 965 | printf("In boota get fastboot lock status error. Set lock status\n"); |
964 | fastboot_set_lock_stat(FASTBOOT_LOCK); | 966 | fastboot_set_lock_stat(FASTBOOT_LOCK); |
965 | } | 967 | } |
966 | display_lock(fastboot_get_lock_stat(), verifyresult); | 968 | display_lock(fastboot_get_lock_stat(), verifyresult); |
967 | #endif | 969 | #endif |
968 | /* load the ramdisk file */ | 970 | /* load the ramdisk file */ |
969 | memcpy((void *)hdr->ramdisk_addr, (void *)hdr->kernel_addr | 971 | memcpy((void *)hdr->ramdisk_addr, (void *)hdr->kernel_addr |
970 | + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); | 972 | + ALIGN(hdr->kernel_size, hdr->page_size), hdr->ramdisk_size); |
971 | 973 | ||
972 | #ifdef CONFIG_OF_LIBFDT | 974 | #ifdef CONFIG_OF_LIBFDT |
973 | u32 fdt_size = 0; | 975 | u32 fdt_size = 0; |
974 | /* load the dtb file */ | 976 | /* load the dtb file */ |
975 | if (hdr->second_addr) { | 977 | if (hdr->second_addr) { |
976 | u32 zimage_size = ((u32 *)hdrload->kernel_addr)[ZIMAGE_END_ADDR] | 978 | u32 zimage_size = ((u32 *)hdrload->kernel_addr)[ZIMAGE_END_ADDR] |
977 | - ((u32 *)hdrload->kernel_addr)[ZIMAGE_START_ADDR]; | 979 | - ((u32 *)hdrload->kernel_addr)[ZIMAGE_START_ADDR]; |
978 | fdt_size = hdrload->kernel_size - zimage_size; | 980 | fdt_size = hdrload->kernel_size - zimage_size; |
979 | memcpy((void *)(ulong)hdrload->second_addr, | 981 | memcpy((void *)(ulong)hdrload->second_addr, |
980 | (void*)(ulong)hdrload->kernel_addr + zimage_size, fdt_size); | 982 | (void*)(ulong)hdrload->kernel_addr + zimage_size, fdt_size); |
981 | } | 983 | } |
982 | #endif /*CONFIG_OF_LIBFDT*/ | 984 | #endif /*CONFIG_OF_LIBFDT*/ |
983 | 985 | ||
984 | #else /*! CONFIG_MMC*/ | 986 | #else /*! CONFIG_MMC*/ |
985 | return -1; | 987 | return -1; |
986 | #endif /*! CONFIG_MMC*/ | 988 | #endif /*! CONFIG_MMC*/ |
987 | } else { | 989 | } else { |
988 | printf("boota: parameters is invalid. only support mmcX device\n"); | 990 | printf("boota: parameters is invalid. only support mmcX device\n"); |
989 | return -1; | 991 | return -1; |
990 | } | 992 | } |
991 | 993 | ||
992 | printf("kernel @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size); | 994 | printf("kernel @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size); |
993 | printf("ramdisk @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size); | 995 | printf("ramdisk @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size); |
994 | #ifdef CONFIG_OF_LIBFDT | 996 | #ifdef CONFIG_OF_LIBFDT |
995 | if (fdt_size) | 997 | if (fdt_size) |
996 | printf("fdt @ %08x (%d)\n", hdr->second_addr, fdt_size); | 998 | printf("fdt @ %08x (%d)\n", hdr->second_addr, fdt_size); |
997 | #endif /*CONFIG_OF_LIBFDT*/ | 999 | #endif /*CONFIG_OF_LIBFDT*/ |
998 | 1000 | ||
999 | 1001 | ||
1000 | char boot_addr_start[12]; | 1002 | char boot_addr_start[12]; |
1001 | char ramdisk_addr[25]; | 1003 | char ramdisk_addr[25]; |
1002 | char fdt_addr[12]; | 1004 | char fdt_addr[12]; |
1003 | char *boot_args[] = { NULL, boot_addr_start, ramdisk_addr, fdt_addr}; | 1005 | char *boot_args[] = { NULL, boot_addr_start, ramdisk_addr, fdt_addr}; |
1004 | if (check_image_arm64 ) { | 1006 | if (check_image_arm64 ) { |
1005 | addr = hdr->kernel_addr; | 1007 | addr = hdr->kernel_addr; |
1006 | boot_args[0] = "booti"; | 1008 | boot_args[0] = "booti"; |
1007 | } else { | 1009 | } else { |
1008 | addr = hdr->kernel_addr - hdr->page_size; | 1010 | addr = hdr->kernel_addr - hdr->page_size; |
1009 | boot_args[0] = "bootm"; | 1011 | boot_args[0] = "bootm"; |
1010 | } | 1012 | } |
1011 | 1013 | ||
1012 | sprintf(boot_addr_start, "0x%lx", addr); | 1014 | sprintf(boot_addr_start, "0x%lx", addr); |
1013 | sprintf(ramdisk_addr, "0x%x:0x%x", hdr->ramdisk_addr, hdr->ramdisk_size); | 1015 | sprintf(ramdisk_addr, "0x%x:0x%x", hdr->ramdisk_addr, hdr->ramdisk_size); |
1014 | sprintf(fdt_addr, "0x%x", hdr->second_addr); | 1016 | sprintf(fdt_addr, "0x%x", hdr->second_addr); |
1015 | if (check_image_arm64) { | 1017 | if (check_image_arm64) { |
1016 | android_image_get_kernel(hdr, 0, NULL, NULL); | 1018 | android_image_get_kernel(hdr, 0, NULL, NULL); |
1017 | #ifdef CONFIG_CMD_BOOTI | 1019 | #ifdef CONFIG_CMD_BOOTI |
1018 | do_booti(NULL, 0, 4, boot_args); | 1020 | do_booti(NULL, 0, 4, boot_args); |
1019 | #else | 1021 | #else |
1020 | debug("please enable CONFIG_CMD_BOOTI when kernel are Image"); | 1022 | debug("please enable CONFIG_CMD_BOOTI when kernel are Image"); |
1021 | #endif | 1023 | #endif |
1022 | } else { | 1024 | } else { |
1023 | do_bootm(NULL, 0, 4, boot_args); | 1025 | do_bootm(NULL, 0, 4, boot_args); |
1024 | } | 1026 | } |
1025 | /* This only happens if image is somehow faulty so we start over */ | 1027 | /* This only happens if image is somehow faulty so we start over */ |
1026 | do_reset(NULL, 0, 0, NULL); | 1028 | do_reset(NULL, 0, 0, NULL); |
1027 | 1029 | ||
1028 | return 1; | 1030 | return 1; |
1029 | 1031 | ||
1030 | fail: | 1032 | fail: |
1031 | #if defined(CONFIG_FSL_FASTBOOT) | 1033 | #if defined(CONFIG_FSL_FASTBOOT) |
1032 | return run_command("fastboot 0", 0); | 1034 | return run_command("fastboot 0", 0); |
1033 | #else /*! CONFIG_FSL_FASTBOOT*/ | 1035 | #else /*! CONFIG_FSL_FASTBOOT*/ |
1034 | return -1; | 1036 | return -1; |
1035 | #endif /*! CONFIG_FSL_FASTBOOT*/ | 1037 | #endif /*! CONFIG_FSL_FASTBOOT*/ |
1036 | } | 1038 | } |
1037 | 1039 | ||
1038 | U_BOOT_CMD( | 1040 | U_BOOT_CMD( |
1039 | boota, 3, 1, do_boota, | 1041 | boota, 3, 1, do_boota, |
1040 | "boota - boot android bootimg from memory\n", | 1042 | "boota - boot android bootimg from memory\n", |
1041 | "[<addr> | mmc0 | mmc1 | mmc2 | mmcX] [<partition>]\n " | 1043 | "[<addr> | mmc0 | mmc1 | mmc2 | mmcX] [<partition>]\n " |
1042 | "- boot application image stored in memory or mmc\n" | 1044 | "- boot application image stored in memory or mmc\n" |
1043 | "\t'addr' should be the address of boot image " | 1045 | "\t'addr' should be the address of boot image " |
1044 | "which is zImage+ramdisk.img\n" | 1046 | "which is zImage+ramdisk.img\n" |
1045 | "\t'mmcX' is the mmc device you store your boot.img, " | 1047 | "\t'mmcX' is the mmc device you store your boot.img, " |
1046 | "which will read the boot.img from 1M offset('/boot' partition)\n" | 1048 | "which will read the boot.img from 1M offset('/boot' partition)\n" |
1047 | "\t 'partition' (optional) is the partition id of your device, " | 1049 | "\t 'partition' (optional) is the partition id of your device, " |
1048 | "if no partition give, will going to 'boot' partition\n" | 1050 | "if no partition give, will going to 'boot' partition\n" |
1049 | ); | 1051 | ); |
1050 | #endif /* CONFIG_AVB_SUPPORT */ | 1052 | #endif /* CONFIG_AVB_SUPPORT */ |
1051 | #endif /* CONFIG_CMD_BOOTA */ | 1053 | #endif /* CONFIG_CMD_BOOTA */ |
1052 | 1054 |
include/interface/hwcrypto/hwcrypto.h
1 | /* | 1 | /* |
2 | * Copyright (C) 2016 The Android Open Source Project | 2 | * Copyright (C) 2016 The Android Open Source Project |
3 | * Copyright NXP 2018 | 3 | * Copyright NXP 2018 |
4 | * | 4 | * |
5 | * Permission is hereby granted, free of charge, to any person | 5 | * Permission is hereby granted, free of charge, to any person |
6 | * obtaining a copy of this software and associated documentation | 6 | * obtaining a copy of this software and associated documentation |
7 | * files (the "Software"), to deal in the Software without | 7 | * files (the "Software"), to deal in the Software without |
8 | * restriction, including without limitation the rights to use, copy, | 8 | * restriction, including without limitation the rights to use, copy, |
9 | * modify, merge, publish, distribute, sublicense, and/or sell copies | 9 | * modify, merge, publish, distribute, sublicense, and/or sell copies |
10 | * of the Software, and to permit persons to whom the Software is | 10 | * of the Software, and to permit persons to whom the Software is |
11 | * furnished to do so, subject to the following conditions: | 11 | * furnished to do so, subject to the following conditions: |
12 | * | 12 | * |
13 | * The above copyright notice and this permission notice shall be | 13 | * The above copyright notice and this permission notice shall be |
14 | * included in all copies or substantial portions of the Software. | 14 | * included in all copies or substantial portions of the Software. |
15 | * | 15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
20 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | 20 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
21 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | 21 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
23 | * SOFTWARE. | 23 | * SOFTWARE. |
24 | * | 24 | * |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #ifndef TRUSTY_INTERFACE_HWCRYPTO_H_ | 27 | #ifndef TRUSTY_INTERFACE_HWCRYPTO_H_ |
28 | #define TRUSTY_INTERFACE_HWCRYPTO_H_ | 28 | #define TRUSTY_INTERFACE_HWCRYPTO_H_ |
29 | 29 | ||
30 | #include <trusty/sysdeps.h> | 30 | #include <trusty/sysdeps.h> |
31 | 31 | ||
32 | #define HWCRYPTO_PORT "com.android.trusty.hwcrypto" | 32 | #define HWCRYPTO_PORT "com.android.trusty.hwcrypto" |
33 | #define HWCRYPTO_MAX_BUFFER_LENGTH 2048 | 33 | #define HWCRYPTO_MAX_BUFFER_LENGTH 2048 |
34 | 34 | ||
35 | enum hwcrypto_command { | 35 | enum hwcrypto_command { |
36 | HWCRYPTO_REQ_SHIFT = 1, | 36 | HWCRYPTO_REQ_SHIFT = 1, |
37 | HWCRYPTO_RESP_BIT = 1, | 37 | HWCRYPTO_RESP_BIT = 1, |
38 | 38 | ||
39 | HWCRYPTO_HASH = (1 << HWCRYPTO_REQ_SHIFT), | 39 | HWCRYPTO_HASH = (1 << HWCRYPTO_REQ_SHIFT), |
40 | HWCRYPTO_ENCAP_BLOB = (2 << HWCRYPTO_REQ_SHIFT), | 40 | HWCRYPTO_ENCAP_BLOB = (2 << HWCRYPTO_REQ_SHIFT), |
41 | HWCRYPTO_GEN_RNG = (3 << HWCRYPTO_REQ_SHIFT), | 41 | HWCRYPTO_GEN_RNG = (3 << HWCRYPTO_REQ_SHIFT), |
42 | HWCRYPTO_GEN_BKEK = (4 << HWCRYPTO_REQ_SHIFT), | 42 | HWCRYPTO_GEN_BKEK = (4 << HWCRYPTO_REQ_SHIFT), |
43 | HWCRYPTO_LOCK_BOOT_STATE = (5 << HWCRYPTO_REQ_SHIFT), | ||
43 | }; | 44 | }; |
44 | 45 | ||
45 | /** | 46 | /** |
46 | * enum hwcrypto_error - error codes for HWCRYPTO protocol | 47 | * enum hwcrypto_error - error codes for HWCRYPTO protocol |
47 | * @HWCRYPTO_ERROR_NONE: All OK | 48 | * @HWCRYPTO_ERROR_NONE: All OK |
48 | * @HWCRYPTO_ERROR_INVALID: Invalid input | 49 | * @HWCRYPTO_ERROR_INVALID: Invalid input |
49 | * @HWCRYPTO_ERROR_INTERNAL: Error occurred during an operation in Trusty | 50 | * @HWCRYPTO_ERROR_INTERNAL: Error occurred during an operation in Trusty |
50 | */ | 51 | */ |
51 | enum hwcrypto_error { | 52 | enum hwcrypto_error { |
52 | HWCRYPTO_ERROR_NONE = 0, | 53 | HWCRYPTO_ERROR_NONE = 0, |
53 | HWCRYPTO_ERROR_INVALID = 1, | 54 | HWCRYPTO_ERROR_INVALID = 1, |
54 | HWCRYPTO_ERROR_INTERNAL = 2, | 55 | HWCRYPTO_ERROR_INTERNAL = 2, |
55 | }; | 56 | }; |
56 | 57 | ||
57 | enum hwcrypto_hash_algo { | 58 | enum hwcrypto_hash_algo { |
58 | SHA1 = 0, | 59 | SHA1 = 0, |
59 | SHA256 | 60 | SHA256 |
60 | }; | 61 | }; |
61 | /** | 62 | /** |
62 | * hwcrypto_message - Serial header for communicating with hwcrypto server | 63 | * hwcrypto_message - Serial header for communicating with hwcrypto server |
63 | * @cmd: the command. Payload must be a serialized buffer of the | 64 | * @cmd: the command. Payload must be a serialized buffer of the |
64 | * corresponding request object. | 65 | * corresponding request object. |
65 | * @result: resulting error code for message, one of hwcrypto_error. | 66 | * @result: resulting error code for message, one of hwcrypto_error. |
66 | * @payload: start of the serialized command specific payload | 67 | * @payload: start of the serialized command specific payload |
67 | */ | 68 | */ |
68 | struct hwcrypto_message { | 69 | struct hwcrypto_message { |
69 | uint32_t cmd; | 70 | uint32_t cmd; |
70 | uint32_t result; | 71 | uint32_t result; |
71 | uint8_t payload[0]; | 72 | uint8_t payload[0]; |
72 | }; | 73 | }; |
73 | 74 | ||
74 | /** | 75 | /** |
75 | * hwcrypto_hash_msg - Serial header for communicating with hwcrypto server | 76 | * hwcrypto_hash_msg - Serial header for communicating with hwcrypto server |
76 | * @in_addr: start address of the input buf. | 77 | * @in_addr: start address of the input buf. |
77 | * @in_len: size of the input buf. | 78 | * @in_len: size of the input buf. |
78 | * @out_addr: start addrss of the output buf. | 79 | * @out_addr: start addrss of the output buf. |
79 | * @out_len: size of the output buf. | 80 | * @out_len: size of the output buf. |
80 | * @algo: hash algorithm expect to use. | 81 | * @algo: hash algorithm expect to use. |
81 | */ | 82 | */ |
82 | typedef struct hwcrypto_hash_msg { | 83 | typedef struct hwcrypto_hash_msg { |
83 | uint32_t in_addr; | 84 | uint32_t in_addr; |
84 | uint32_t in_len; | 85 | uint32_t in_len; |
85 | uint32_t out_addr; | 86 | uint32_t out_addr; |
86 | uint32_t out_len; | 87 | uint32_t out_len; |
87 | enum hwcrypto_hash_algo algo; | 88 | enum hwcrypto_hash_algo algo; |
88 | } hwcrypto_hash_msg; | 89 | } hwcrypto_hash_msg; |
89 | 90 | ||
90 | /** | 91 | /** |
91 | * @plain_pa: physical start address of the plain blob buf. | 92 | * @plain_pa: physical start address of the plain blob buf. |
92 | * @plain_size: size of the plain blob. | 93 | * @plain_size: size of the plain blob. |
93 | * @blob: physical start addrss of the output buf. | 94 | * @blob: physical start addrss of the output buf. |
94 | */ | 95 | */ |
95 | typedef struct hwcrypto_blob_msg { | 96 | typedef struct hwcrypto_blob_msg { |
96 | uint32_t plain_pa; | 97 | uint32_t plain_pa; |
97 | uint32_t plain_size; | 98 | uint32_t plain_size; |
98 | uint32_t blob_pa; | 99 | uint32_t blob_pa; |
99 | }hwcrypto_blob_msg; | 100 | }hwcrypto_blob_msg; |
100 | 101 | ||
101 | /** | 102 | /** |
102 | * @buf: physical start address of the output rng buf. | 103 | * @buf: physical start address of the output rng buf. |
103 | * @len: size of required rng. | 104 | * @len: size of required rng. |
104 | */ | 105 | */ |
105 | typedef struct hwcrypto_rng_msg { | 106 | typedef struct hwcrypto_rng_msg { |
106 | uint32_t buf; | 107 | uint32_t buf; |
107 | uint32_t len; | 108 | uint32_t len; |
108 | }hwcrypto_rng_msg; | 109 | }hwcrypto_rng_msg; |
109 | 110 | ||
110 | /** | 111 | /** |
111 | * @buf: physical start address of the output bkek buf. | 112 | * @buf: physical start address of the output bkek buf. |
112 | * @len: size of required rng. | 113 | * @len: size of required rng. |
113 | */ | 114 | */ |
114 | typedef struct hwcrypto_bkek_msg { | 115 | typedef struct hwcrypto_bkek_msg { |
115 | uint32_t buf; | 116 | uint32_t buf; |
116 | uint32_t len; | 117 | uint32_t len; |
117 | }hwcrypto_bkek_msg; | 118 | }hwcrypto_bkek_msg; |
118 | #endif /* TRUSTY_INTERFACE_HWCRYPTO_H_ */ | 119 | #endif /* TRUSTY_INTERFACE_HWCRYPTO_H_ */ |
119 | 120 |
include/trusty/hwcrypto.h
1 | /* | 1 | /* |
2 | * Copyright (C) 2016 The Android Open Source Project | 2 | * Copyright (C) 2016 The Android Open Source Project |
3 | * Copyright NXP 2018 | 3 | * Copyright NXP 2018 |
4 | * | 4 | * |
5 | * Permission is hereby granted, free of charge, to any person | 5 | * Permission is hereby granted, free of charge, to any person |
6 | * obtaining a copy of this software and associated documentation | 6 | * obtaining a copy of this software and associated documentation |
7 | * files (the "Software"), to deal in the Software without | 7 | * files (the "Software"), to deal in the Software without |
8 | * restriction, including without limitation the rights to use, copy, | 8 | * restriction, including without limitation the rights to use, copy, |
9 | * modify, merge, publish, distribute, sublicense, and/or sell copies | 9 | * modify, merge, publish, distribute, sublicense, and/or sell copies |
10 | * of the Software, and to permit persons to whom the Software is | 10 | * of the Software, and to permit persons to whom the Software is |
11 | * furnished to do so, subject to the following conditions: | 11 | * furnished to do so, subject to the following conditions: |
12 | * | 12 | * |
13 | * The above copyright notice and this permission notice shall be | 13 | * The above copyright notice and this permission notice shall be |
14 | * included in all copies or substantial portions of the Software. | 14 | * included in all copies or substantial portions of the Software. |
15 | * | 15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
20 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | 20 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
21 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | 21 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
23 | * SOFTWARE. | 23 | * SOFTWARE. |
24 | * | 24 | * |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #ifndef TRUSTY_HWCRYPTO_H_ | 27 | #ifndef TRUSTY_HWCRYPTO_H_ |
28 | #define TRUSTY_HWCRYPTO_H_ | 28 | #define TRUSTY_HWCRYPTO_H_ |
29 | 29 | ||
30 | #include <trusty/sysdeps.h> | 30 | #include <trusty/sysdeps.h> |
31 | #include <trusty/trusty_ipc.h> | 31 | #include <trusty/trusty_ipc.h> |
32 | #include <interface/hwcrypto/hwcrypto.h> | 32 | #include <interface/hwcrypto/hwcrypto.h> |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Initialize HWCRYPTO TIPC client. Returns one of trusty_err. | 35 | * Initialize HWCRYPTO TIPC client. Returns one of trusty_err. |
36 | * | 36 | * |
37 | * @dev: initialized with trusty_ipc_dev_create | 37 | * @dev: initialized with trusty_ipc_dev_create |
38 | */ | 38 | */ |
39 | int hwcrypto_tipc_init(struct trusty_ipc_dev *dev); | 39 | int hwcrypto_tipc_init(struct trusty_ipc_dev *dev); |
40 | /* | 40 | /* |
41 | * Shutdown HWCRYPTO TIPC client. | 41 | * Shutdown HWCRYPTO TIPC client. |
42 | * | 42 | * |
43 | * @dev: initialized with trusty_ipc_dev_create | 43 | * @dev: initialized with trusty_ipc_dev_create |
44 | */ | 44 | */ |
45 | void hwcrypto_tipc_shutdown(struct trusty_ipc_dev *dev); | 45 | void hwcrypto_tipc_shutdown(struct trusty_ipc_dev *dev); |
46 | /* | 46 | /* |
47 | * Send request to secure side to calculate sha256 hash with caam. | 47 | * Send request to secure side to calculate sha256 hash with caam. |
48 | * Returns one of trusty_err. | 48 | * Returns one of trusty_err. |
49 | * | 49 | * |
50 | * @in_addr: start address of the input buf | 50 | * @in_addr: start address of the input buf |
51 | * @in_len: size of the input buf | 51 | * @in_len: size of the input buf |
52 | * @out_addr: start address of the output buf | 52 | * @out_addr: start address of the output buf |
53 | * @out_len: size of the output buf | 53 | * @out_len: size of the output buf |
54 | * @algo: hash algorithm type expect to use | 54 | * @algo: hash algorithm type expect to use |
55 | */ | 55 | */ |
56 | int hwcrypto_hash(uint32_t in_addr, uint32_t in_len, uint32_t out_addr, | 56 | int hwcrypto_hash(uint32_t in_addr, uint32_t in_len, uint32_t out_addr, |
57 | uint32_t out_len, enum hwcrypto_hash_algo algo); | 57 | uint32_t out_len, enum hwcrypto_hash_algo algo); |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * Send request to secure side to generate blob with caam. | 60 | * Send request to secure side to generate blob with caam. |
61 | * Returns one of trusty_err. | 61 | * Returns one of trusty_err. |
62 | * | 62 | * |
63 | * @plain_pa: physical start address of the plain blob buffer. | 63 | * @plain_pa: physical start address of the plain blob buffer. |
64 | * @plain_size: size of the plain blob buffer. | 64 | * @plain_size: size of the plain blob buffer. |
65 | * @blob_pa: physical start address of the generated blob buffer. | 65 | * @blob_pa: physical start address of the generated blob buffer. |
66 | */ | 66 | */ |
67 | int hwcrypto_gen_blob(uint32_t plain_pa, | 67 | int hwcrypto_gen_blob(uint32_t plain_pa, |
68 | uint32_t plain_size, uint32_t blob_pa); | 68 | uint32_t plain_size, uint32_t blob_pa); |
69 | 69 | ||
70 | /* Send request to secure side to generate rng with caam. | 70 | /* Send request to secure side to generate rng with caam. |
71 | * Returns one of trusty_err. | 71 | * Returns one of trusty_err. |
72 | * | 72 | * |
73 | * @buf: physical start address of the output rng buf. | 73 | * @buf: physical start address of the output rng buf. |
74 | * @len: size of required rng. | 74 | * @len: size of required rng. |
75 | * */ | 75 | * */ |
76 | int hwcrypto_gen_rng(uint32_t buf, uint32_t len); | 76 | int hwcrypto_gen_rng(uint32_t buf, uint32_t len); |
77 | 77 | ||
78 | /* Send request to secure side to generate bkek with caam. | 78 | /* Send request to secure side to generate bkek with caam. |
79 | * Returns one of trusty_err. | 79 | * Returns one of trusty_err. |
80 | * | 80 | * |
81 | * @buf: physical start address of the output rng buf. | 81 | * @buf: physical start address of the output rng buf. |
82 | * @len: size of required rng. | 82 | * @len: size of required rng. |
83 | * */ | 83 | * */ |
84 | int hwcrypto_gen_bkek(uint32_t buf, uint32_t len); | 84 | int hwcrypto_gen_bkek(uint32_t buf, uint32_t len); |
85 | |||
86 | /* Send request to secure side to lock boot state, so some | ||
87 | * hwcrypto commands can't be used outside of bootloader. | ||
88 | * Returns one of trusty_err. | ||
89 | * */ | ||
90 | int hwcrypto_lock_boot_state(void); | ||
91 | |||
85 | #endif /* TRUSTY_HWCRYPTO_H_ */ | 92 | #endif /* TRUSTY_HWCRYPTO_H_ */ |
86 | 93 |
lib/trusty/ql-tipc/hwcrypto.c
1 | /* | 1 | /* |
2 | * Copyright (C) 2016 The Android Open Source Project | 2 | * Copyright (C) 2016 The Android Open Source Project |
3 | * Copyright NXP 2018 | 3 | * Copyright NXP 2018 |
4 | * | 4 | * |
5 | * Permission is hereby granted, free of charge, to any person | 5 | * Permission is hereby granted, free of charge, to any person |
6 | * obtaining a copy of this software and associated documentation | 6 | * obtaining a copy of this software and associated documentation |
7 | * files (the "Software"), to deal in the Software without | 7 | * files (the "Software"), to deal in the Software without |
8 | * restriction, including without limitation the rights to use, copy, | 8 | * restriction, including without limitation the rights to use, copy, |
9 | * modify, merge, publish, distribute, sublicense, and/or sell copies | 9 | * modify, merge, publish, distribute, sublicense, and/or sell copies |
10 | * of the Software, and to permit persons to whom the Software is | 10 | * of the Software, and to permit persons to whom the Software is |
11 | * furnished to do so, subject to the following conditions: | 11 | * furnished to do so, subject to the following conditions: |
12 | * | 12 | * |
13 | * The above copyright notice and this permission notice shall be | 13 | * The above copyright notice and this permission notice shall be |
14 | * included in all copies or substantial portions of the Software. | 14 | * included in all copies or substantial portions of the Software. |
15 | * | 15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
20 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | 20 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
21 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | 21 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
23 | * SOFTWARE. | 23 | * SOFTWARE. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <trusty/hwcrypto.h> | 26 | #include <trusty/hwcrypto.h> |
27 | #include <trusty/rpmb.h> | 27 | #include <trusty/rpmb.h> |
28 | #include <trusty/trusty_ipc.h> | 28 | #include <trusty/trusty_ipc.h> |
29 | #include <trusty/util.h> | 29 | #include <trusty/util.h> |
30 | #include "common.h" | 30 | #include "common.h" |
31 | 31 | ||
32 | #define LOCAL_LOG 0 | 32 | #define LOCAL_LOG 0 |
33 | #define CAAM_KB_HEADER_LEN 48 | 33 | #define CAAM_KB_HEADER_LEN 48 |
34 | 34 | ||
35 | static bool initialized; | 35 | static bool initialized; |
36 | static struct trusty_ipc_chan hwcrypto_chan; | 36 | static struct trusty_ipc_chan hwcrypto_chan; |
37 | 37 | ||
38 | static int hwcrypto_send_request(struct hwcrypto_message *msg, void *req, size_t req_len) | 38 | static int hwcrypto_send_request(struct hwcrypto_message *msg, void *req, size_t req_len) |
39 | { | 39 | { |
40 | struct trusty_ipc_iovec req_iovs[2] = { | 40 | struct trusty_ipc_iovec req_iovs[2] = { |
41 | { .base = msg, .len = sizeof(*msg) }, | 41 | { .base = msg, .len = sizeof(*msg) }, |
42 | { .base = req, .len = req_len }, | 42 | { .base = req, .len = req_len }, |
43 | }; | 43 | }; |
44 | 44 | ||
45 | return trusty_ipc_send(&hwcrypto_chan, req_iovs, req ? 2 : 1, true); | 45 | return trusty_ipc_send(&hwcrypto_chan, req_iovs, req ? 2 : 1, true); |
46 | } | 46 | } |
47 | 47 | ||
48 | static int hwcrypto_read_response(struct hwcrypto_message *msg, uint32_t cmd, void *resp, | 48 | static int hwcrypto_read_response(struct hwcrypto_message *msg, uint32_t cmd, void *resp, |
49 | size_t resp_len) | 49 | size_t resp_len) |
50 | { | 50 | { |
51 | int rc; | 51 | int rc; |
52 | struct trusty_ipc_iovec resp_iovs[2] = { | 52 | struct trusty_ipc_iovec resp_iovs[2] = { |
53 | { .base = msg, .len = sizeof(*msg) }, | 53 | { .base = msg, .len = sizeof(*msg) }, |
54 | { .base = resp, .len = resp_len }, | 54 | { .base = resp, .len = resp_len }, |
55 | }; | 55 | }; |
56 | 56 | ||
57 | rc = trusty_ipc_recv(&hwcrypto_chan, resp_iovs, resp ? 2 : 1, true); | 57 | rc = trusty_ipc_recv(&hwcrypto_chan, resp_iovs, resp ? 2 : 1, true); |
58 | if (rc < 0) { | 58 | if (rc < 0) { |
59 | trusty_error("failed (%d) to recv response\n", rc); | 59 | trusty_error("failed (%d) to recv response\n", rc); |
60 | return rc; | 60 | return rc; |
61 | } | 61 | } |
62 | if (msg->cmd != (cmd | HWCRYPTO_RESP_BIT)) { | 62 | if (msg->cmd != (cmd | HWCRYPTO_RESP_BIT)) { |
63 | trusty_error("malformed response\n"); | 63 | trusty_error("malformed response\n"); |
64 | return TRUSTY_ERR_GENERIC; | 64 | return TRUSTY_ERR_GENERIC; |
65 | } | 65 | } |
66 | /* return payload size */ | 66 | /* return payload size */ |
67 | return rc - sizeof(*msg); | 67 | return rc - sizeof(*msg); |
68 | } | 68 | } |
69 | 69 | ||
70 | /* | 70 | /* |
71 | * Convenience function to send a request to the hwcrypto service and read the | 71 | * Convenience function to send a request to the hwcrypto service and read the |
72 | * response. | 72 | * response. |
73 | * | 73 | * |
74 | * @cmd: the command | 74 | * @cmd: the command |
75 | * @req: the request buffer | 75 | * @req: the request buffer |
76 | * @req_size: size of the request buffer | 76 | * @req_size: size of the request buffer |
77 | * @resp: the response buffer | 77 | * @resp: the response buffer |
78 | * @resp_size_p: pointer to the size of the response buffer. changed to the | 78 | * @resp_size_p: pointer to the size of the response buffer. changed to the |
79 | actual size of the response read from the secure side | 79 | actual size of the response read from the secure side |
80 | * @handle_rpmb: true if the request is expected to invoke RPMB callbacks | 80 | * @handle_rpmb: true if the request is expected to invoke RPMB callbacks |
81 | */ | 81 | */ |
82 | static int hwcrypto_do_tipc(uint32_t cmd, void *req, uint32_t req_size, void *resp, | 82 | static int hwcrypto_do_tipc(uint32_t cmd, void *req, uint32_t req_size, void *resp, |
83 | uint32_t *resp_size_p, bool handle_rpmb) | 83 | uint32_t *resp_size_p, bool handle_rpmb) |
84 | { | 84 | { |
85 | int rc; | 85 | int rc; |
86 | struct hwcrypto_message msg = { .cmd = cmd }; | 86 | struct hwcrypto_message msg = { .cmd = cmd }; |
87 | 87 | ||
88 | if (!initialized) { | 88 | if (!initialized) { |
89 | trusty_error("%s: HWCRYPTO TIPC client not initialized\n", __func__); | 89 | trusty_error("%s: HWCRYPTO TIPC client not initialized\n", __func__); |
90 | return TRUSTY_ERR_GENERIC; | 90 | return TRUSTY_ERR_GENERIC; |
91 | } | 91 | } |
92 | 92 | ||
93 | rc = hwcrypto_send_request(&msg, req, req_size); | 93 | rc = hwcrypto_send_request(&msg, req, req_size); |
94 | if (rc < 0) { | 94 | if (rc < 0) { |
95 | trusty_error("%s: failed (%d) to send hwcrypto request\n", __func__, rc); | 95 | trusty_error("%s: failed (%d) to send hwcrypto request\n", __func__, rc); |
96 | return rc; | 96 | return rc; |
97 | } | 97 | } |
98 | 98 | ||
99 | if (handle_rpmb) { | 99 | if (handle_rpmb) { |
100 | /* handle any incoming RPMB requests */ | 100 | /* handle any incoming RPMB requests */ |
101 | rc = rpmb_storage_proxy_poll(); | 101 | rc = rpmb_storage_proxy_poll(); |
102 | if (rc < 0) { | 102 | if (rc < 0) { |
103 | trusty_error("%s: failed (%d) to get RPMB requests\n", __func__, | 103 | trusty_error("%s: failed (%d) to get RPMB requests\n", __func__, |
104 | rc); | 104 | rc); |
105 | return rc; | 105 | return rc; |
106 | } | 106 | } |
107 | } | 107 | } |
108 | 108 | ||
109 | uint32_t resp_size = resp_size_p ? *resp_size_p : 0; | 109 | uint32_t resp_size = resp_size_p ? *resp_size_p : 0; |
110 | rc = hwcrypto_read_response(&msg, cmd, resp, resp_size); | 110 | rc = hwcrypto_read_response(&msg, cmd, resp, resp_size); |
111 | if (rc < 0) { | 111 | if (rc < 0) { |
112 | trusty_error("%s: failed (%d) to read HWCRYPTO response\n", __func__, rc); | 112 | trusty_error("%s: failed (%d) to read HWCRYPTO response\n", __func__, rc); |
113 | return rc; | 113 | return rc; |
114 | } | 114 | } |
115 | /* change response size to actual response size */ | 115 | /* change response size to actual response size */ |
116 | if (resp_size_p && rc != *resp_size_p) { | 116 | if (resp_size_p && rc != *resp_size_p) { |
117 | *resp_size_p = rc; | 117 | *resp_size_p = rc; |
118 | } | 118 | } |
119 | if (msg.result != HWCRYPTO_ERROR_NONE) { | 119 | if (msg.result != HWCRYPTO_ERROR_NONE) { |
120 | trusty_error("%s: HWCRYPTO service returned error (%d)\n", __func__, | 120 | trusty_error("%s: HWCRYPTO service returned error (%d)\n", __func__, |
121 | msg.result); | 121 | msg.result); |
122 | return TRUSTY_ERR_GENERIC; | 122 | return TRUSTY_ERR_GENERIC; |
123 | } | 123 | } |
124 | return TRUSTY_ERR_NONE; | 124 | return TRUSTY_ERR_NONE; |
125 | } | 125 | } |
126 | 126 | ||
127 | int hwcrypto_tipc_init(struct trusty_ipc_dev *dev) | 127 | int hwcrypto_tipc_init(struct trusty_ipc_dev *dev) |
128 | { | 128 | { |
129 | int rc; | 129 | int rc; |
130 | 130 | ||
131 | trusty_assert(dev); | 131 | trusty_assert(dev); |
132 | trusty_assert(!initialized); | 132 | trusty_assert(!initialized); |
133 | 133 | ||
134 | trusty_ipc_chan_init(&hwcrypto_chan, dev); | 134 | trusty_ipc_chan_init(&hwcrypto_chan, dev); |
135 | trusty_debug("Connecting to hwcrypto service\n"); | 135 | trusty_debug("Connecting to hwcrypto service\n"); |
136 | 136 | ||
137 | /* connect to hwcrypto service and wait for connect to complete */ | 137 | /* connect to hwcrypto service and wait for connect to complete */ |
138 | rc = trusty_ipc_connect(&hwcrypto_chan, HWCRYPTO_PORT, true); | 138 | rc = trusty_ipc_connect(&hwcrypto_chan, HWCRYPTO_PORT, true); |
139 | if (rc < 0) { | 139 | if (rc < 0) { |
140 | trusty_error("failed (%d) to connect to '%s'\n", rc, HWCRYPTO_PORT); | 140 | trusty_error("failed (%d) to connect to '%s'\n", rc, HWCRYPTO_PORT); |
141 | return rc; | 141 | return rc; |
142 | } | 142 | } |
143 | 143 | ||
144 | /* mark as initialized */ | 144 | /* mark as initialized */ |
145 | initialized = true; | 145 | initialized = true; |
146 | 146 | ||
147 | return TRUSTY_ERR_NONE; | 147 | return TRUSTY_ERR_NONE; |
148 | } | 148 | } |
149 | 149 | ||
150 | void hwcrypto_tipc_shutdown(struct trusty_ipc_dev *dev) | 150 | void hwcrypto_tipc_shutdown(struct trusty_ipc_dev *dev) |
151 | { | 151 | { |
152 | if (!initialized) | 152 | if (!initialized) |
153 | return; /* nothing to do */ | 153 | return; /* nothing to do */ |
154 | 154 | ||
155 | /* close channel */ | 155 | /* close channel */ |
156 | trusty_ipc_close(&hwcrypto_chan); | 156 | trusty_ipc_close(&hwcrypto_chan); |
157 | 157 | ||
158 | initialized = false; | 158 | initialized = false; |
159 | } | 159 | } |
160 | 160 | ||
161 | int hwcrypto_hash(uint32_t in_addr, uint32_t in_len, uint32_t out_addr, | 161 | int hwcrypto_hash(uint32_t in_addr, uint32_t in_len, uint32_t out_addr, |
162 | uint32_t out_len, enum hwcrypto_hash_algo algo) | 162 | uint32_t out_len, enum hwcrypto_hash_algo algo) |
163 | { | 163 | { |
164 | hwcrypto_hash_msg req; | 164 | hwcrypto_hash_msg req; |
165 | unsigned long start, end; | 165 | unsigned long start, end; |
166 | 166 | ||
167 | /* check the address */ | 167 | /* check the address */ |
168 | if (in_addr == 0 || out_addr == 0) | 168 | if (in_addr == 0 || out_addr == 0) |
169 | return TRUSTY_ERR_INVALID_ARGS; | 169 | return TRUSTY_ERR_INVALID_ARGS; |
170 | /* fill the request buffer */ | 170 | /* fill the request buffer */ |
171 | req.in_addr = in_addr; | 171 | req.in_addr = in_addr; |
172 | req.out_addr = out_addr; | 172 | req.out_addr = out_addr; |
173 | req.in_len = in_len; | 173 | req.in_len = in_len; |
174 | req.out_len = out_len; | 174 | req.out_len = out_len; |
175 | req.algo = algo; | 175 | req.algo = algo; |
176 | 176 | ||
177 | /* flush dcache for input buffer */ | 177 | /* flush dcache for input buffer */ |
178 | start = (unsigned long)in_addr & ~(ARCH_DMA_MINALIGN - 1); | 178 | start = (unsigned long)in_addr & ~(ARCH_DMA_MINALIGN - 1); |
179 | end = ALIGN((unsigned long)in_addr + in_len, ARCH_DMA_MINALIGN); | 179 | end = ALIGN((unsigned long)in_addr + in_len, ARCH_DMA_MINALIGN); |
180 | flush_dcache_range(start, end); | 180 | flush_dcache_range(start, end); |
181 | 181 | ||
182 | /* invalidate dcache for output buffer */ | 182 | /* invalidate dcache for output buffer */ |
183 | start = (unsigned long)out_addr & ~(ARCH_DMA_MINALIGN - 1); | 183 | start = (unsigned long)out_addr & ~(ARCH_DMA_MINALIGN - 1); |
184 | end = ALIGN((unsigned long)out_addr + out_len, ARCH_DMA_MINALIGN); | 184 | end = ALIGN((unsigned long)out_addr + out_len, ARCH_DMA_MINALIGN); |
185 | invalidate_dcache_range(start, end); | 185 | invalidate_dcache_range(start, end); |
186 | 186 | ||
187 | int rc = hwcrypto_do_tipc(HWCRYPTO_HASH, (void*)&req, | 187 | int rc = hwcrypto_do_tipc(HWCRYPTO_HASH, (void*)&req, |
188 | sizeof(req), NULL, 0, false); | 188 | sizeof(req), NULL, 0, false); |
189 | return rc; | 189 | return rc; |
190 | } | 190 | } |
191 | 191 | ||
192 | int hwcrypto_gen_blob(uint32_t plain_pa, | 192 | int hwcrypto_gen_blob(uint32_t plain_pa, |
193 | uint32_t plain_size, uint32_t blob_pa) | 193 | uint32_t plain_size, uint32_t blob_pa) |
194 | { | 194 | { |
195 | hwcrypto_blob_msg req; | 195 | hwcrypto_blob_msg req; |
196 | unsigned long start, end; | 196 | unsigned long start, end; |
197 | 197 | ||
198 | /* check the address */ | 198 | /* check the address */ |
199 | if (plain_pa == 0 || blob_pa == 0) | 199 | if (plain_pa == 0 || blob_pa == 0) |
200 | return TRUSTY_ERR_INVALID_ARGS; | 200 | return TRUSTY_ERR_INVALID_ARGS; |
201 | /* fill the request buffer */ | 201 | /* fill the request buffer */ |
202 | req.plain_pa = plain_pa; | 202 | req.plain_pa = plain_pa; |
203 | req.plain_size = plain_size; | 203 | req.plain_size = plain_size; |
204 | req.blob_pa = blob_pa; | 204 | req.blob_pa = blob_pa; |
205 | 205 | ||
206 | /* flush dcache for input buffer */ | 206 | /* flush dcache for input buffer */ |
207 | start = (unsigned long)plain_pa & ~(ARCH_DMA_MINALIGN - 1); | 207 | start = (unsigned long)plain_pa & ~(ARCH_DMA_MINALIGN - 1); |
208 | end = ALIGN((unsigned long)plain_pa + plain_size, ARCH_DMA_MINALIGN); | 208 | end = ALIGN((unsigned long)plain_pa + plain_size, ARCH_DMA_MINALIGN); |
209 | flush_dcache_range(start, end); | 209 | flush_dcache_range(start, end); |
210 | 210 | ||
211 | /* invalidate dcache for output buffer */ | 211 | /* invalidate dcache for output buffer */ |
212 | start = (unsigned long)blob_pa & ~(ARCH_DMA_MINALIGN - 1); | 212 | start = (unsigned long)blob_pa & ~(ARCH_DMA_MINALIGN - 1); |
213 | end = ALIGN((unsigned long)blob_pa + plain_size + | 213 | end = ALIGN((unsigned long)blob_pa + plain_size + |
214 | CAAM_KB_HEADER_LEN, ARCH_DMA_MINALIGN); | 214 | CAAM_KB_HEADER_LEN, ARCH_DMA_MINALIGN); |
215 | invalidate_dcache_range(start, end); | 215 | invalidate_dcache_range(start, end); |
216 | 216 | ||
217 | int rc = hwcrypto_do_tipc(HWCRYPTO_ENCAP_BLOB, (void*)&req, | 217 | int rc = hwcrypto_do_tipc(HWCRYPTO_ENCAP_BLOB, (void*)&req, |
218 | sizeof(req), NULL, 0, false); | 218 | sizeof(req), NULL, 0, false); |
219 | return rc; | 219 | return rc; |
220 | } | 220 | } |
221 | 221 | ||
222 | int hwcrypto_gen_rng(uint32_t buf, uint32_t len) | 222 | int hwcrypto_gen_rng(uint32_t buf, uint32_t len) |
223 | { | 223 | { |
224 | hwcrypto_rng_msg req; | 224 | hwcrypto_rng_msg req; |
225 | unsigned long start, end; | 225 | unsigned long start, end; |
226 | 226 | ||
227 | /* check the address */ | 227 | /* check the address */ |
228 | if (buf == 0) | 228 | if (buf == 0) |
229 | return TRUSTY_ERR_INVALID_ARGS; | 229 | return TRUSTY_ERR_INVALID_ARGS; |
230 | /* fill the request buffer */ | 230 | /* fill the request buffer */ |
231 | req.buf = buf; | 231 | req.buf = buf; |
232 | req.len = len; | 232 | req.len = len; |
233 | 233 | ||
234 | /* invalidate dcache for output buffer */ | 234 | /* invalidate dcache for output buffer */ |
235 | start = (unsigned long)buf & ~(ARCH_DMA_MINALIGN - 1); | 235 | start = (unsigned long)buf & ~(ARCH_DMA_MINALIGN - 1); |
236 | end = ALIGN((unsigned long)buf + len, ARCH_DMA_MINALIGN); | 236 | end = ALIGN((unsigned long)buf + len, ARCH_DMA_MINALIGN); |
237 | invalidate_dcache_range(start, end); | 237 | invalidate_dcache_range(start, end); |
238 | 238 | ||
239 | int rc = hwcrypto_do_tipc(HWCRYPTO_GEN_RNG, (void*)&req, | 239 | int rc = hwcrypto_do_tipc(HWCRYPTO_GEN_RNG, (void*)&req, |
240 | sizeof(req), NULL, 0, false); | 240 | sizeof(req), NULL, 0, false); |
241 | return rc; | 241 | return rc; |
242 | } | 242 | } |
243 | 243 | ||
244 | int hwcrypto_gen_bkek(uint32_t buf, uint32_t len) | 244 | int hwcrypto_gen_bkek(uint32_t buf, uint32_t len) |
245 | { | 245 | { |
246 | hwcrypto_bkek_msg req; | 246 | hwcrypto_bkek_msg req; |
247 | unsigned long start, end; | 247 | unsigned long start, end; |
248 | 248 | ||
249 | /* check the address */ | 249 | /* check the address */ |
250 | if (buf == 0) | 250 | if (buf == 0) |
251 | return TRUSTY_ERR_INVALID_ARGS; | 251 | return TRUSTY_ERR_INVALID_ARGS; |
252 | /* fill the request buffer */ | 252 | /* fill the request buffer */ |
253 | req.buf = buf; | 253 | req.buf = buf; |
254 | req.len = len; | 254 | req.len = len; |
255 | 255 | ||
256 | /* invalidate dcache for output buffer */ | 256 | /* invalidate dcache for output buffer */ |
257 | start = (unsigned long)buf & ~(ARCH_DMA_MINALIGN - 1); | 257 | start = (unsigned long)buf & ~(ARCH_DMA_MINALIGN - 1); |
258 | end = ALIGN((unsigned long)buf + len, ARCH_DMA_MINALIGN); | 258 | end = ALIGN((unsigned long)buf + len, ARCH_DMA_MINALIGN); |
259 | invalidate_dcache_range(start, end); | 259 | invalidate_dcache_range(start, end); |
260 | 260 | ||
261 | int rc = hwcrypto_do_tipc(HWCRYPTO_GEN_BKEK, (void*)&req, | 261 | int rc = hwcrypto_do_tipc(HWCRYPTO_GEN_BKEK, (void*)&req, |
262 | sizeof(req), NULL, 0, false); | 262 | sizeof(req), NULL, 0, false); |
263 | return rc; | 263 | return rc; |
264 | } | 264 | } |
265 | |||
266 | int hwcrypto_lock_boot_state(void) | ||
267 | { | ||
268 | return hwcrypto_do_tipc(HWCRYPTO_LOCK_BOOT_STATE, NULL, 0, NULL, 0, false); | ||
269 | } | ||
265 | 270 |
-
mentioned in commit 1411f5
-
mentioned in commit 1411f5
-
mentioned in commit 0221ae
-
mentioned in commit 0221ae
-
mentioned in commit 38f997
-
mentioned in commit 38f997
-
mentioned in commit 0221ae
-
mentioned in commit 38f997
-
mentioned in commit 38f997
-
mentioned in commit 38f997
-
mentioned in commit 38f997
-
mentioned in commit 744668