1 /* 2 * (C) Copyright 2020 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <boot_rkimg.h> 9 #include <misc.h> 10 #ifdef CONFIG_SPL_BUILD 11 #include <spl.h> 12 #endif 13 #include <lzma/LzmaTools.h> 14 #include <optee_include/OpteeClientInterface.h> 15 #include <optee_include/tee_api_defines.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 #if CONFIG_IS_ENABLED(FIT) 20 21 /* 22 * Override __weak board_fit_image_post_process() for SPL & U-Boot proper. 23 */ 24 #if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS) 25 26 #define FIT_UNCOMP_HASH_NODENAME "digest" 27 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS) || CONFIG_IS_ENABLED(GZIP) 28 static int fit_image_check_uncomp_hash(const void *fit, int parent_noffset, 29 const void *data, size_t size) 30 { 31 const char *name; 32 char *err_msgp; 33 int noffset; 34 35 fdt_for_each_subnode(noffset, fit, parent_noffset) { 36 name = fit_get_name(fit, noffset, NULL); 37 if (!strncmp(name, FIT_UNCOMP_HASH_NODENAME, 38 strlen(FIT_UNCOMP_HASH_NODENAME))) { 39 return fit_image_check_hash(fit, noffset, data, 40 size, &err_msgp); 41 } 42 } 43 44 return 0; 45 } 46 47 static int fit_decomp_image(void *fit, int node, ulong *load_addr, 48 ulong **src_addr, size_t *src_len, void *spec) 49 { 50 u64 len = *src_len; 51 int ret = -ENOSYS; 52 u8 comp; 53 54 if (fit_image_get_comp(fit, node, &comp)) 55 return 0; 56 57 if (comp != IH_COMP_GZIP && comp != IH_COMP_LZMA) 58 return 0; 59 60 #ifndef CONFIG_SPL_BUILD 61 /* 62 * U-Boot: 63 * handled late in bootm_decomp_image() 64 */ 65 if (fit_image_check_type(fit, node, IH_TYPE_KERNEL)) 66 return 0; 67 #elif defined(CONFIG_SPL_MTD_SUPPORT) && defined(CONFIG_SPL_MISC_DECOMPRESS) && \ 68 defined(CONFIG_SPL_KERNEL_BOOT) 69 /* 70 * SPL Thunder-boot policty on spi-nand: 71 * enable and use interrupt status as a sync signal for 72 * kernel to poll that whether ramdisk decompress is done. 73 */ 74 struct spl_load_info *info = spec; 75 struct blk_desc *desc; 76 77 if (info && info->dev) { 78 desc = info->dev; 79 if ((desc->if_type == IF_TYPE_MTD) && 80 (desc->devnum == BLK_MTD_SPI_NAND) && 81 fit_image_check_type(fit, node, IH_TYPE_RAMDISK)) { 82 flags |= DCOMP_FLG_IRQ_ONESHOT; 83 } 84 } 85 #endif 86 if (comp == IH_COMP_LZMA) { 87 #if CONFIG_IS_ENABLED(LZMA) 88 SizeT lzma_len = ALIGN(len, FIT_MAX_SPL_IMAGE_SZ); 89 SizeT src_lenp; 90 const fdt32_t *val; 91 92 val = fdt_getprop(fit, node, "raw-size", NULL); 93 if (!val) 94 return -ENOENT; 95 src_lenp = fdt32_to_cpu(*val); 96 ret = lzmaBuffToBuffDecompress((uchar *)(*load_addr), &lzma_len, 97 (uchar *)(*src_addr), src_lenp); 98 len = lzma_len; 99 #endif 100 } else if (comp == IH_COMP_GZIP) { 101 /* 102 * For smaller spl size, we don't use misc_decompress_process() 103 * inside the gunzip(). 104 */ 105 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS) 106 const void *prop; 107 u32 flags = 0; 108 109 ret = misc_decompress_process((ulong)(*load_addr), 110 (ulong)(*src_addr), (ulong)(*src_len), 111 DECOM_GZIP, true, &len, flags); 112 /* mark for misc_decompress_cleanup() */ 113 prop = fdt_getprop(fit, node, "decomp-async", NULL); 114 if (prop) 115 misc_decompress_async(comp); 116 else 117 misc_decompress_sync(comp); 118 #else 119 ret = gunzip((void *)(*load_addr), ALIGN(len, FIT_MAX_SPL_IMAGE_SZ), 120 (void *)(*src_addr), (void *)(&len)); 121 #endif 122 } 123 124 if (ret) { 125 printf("%s: decompress error, ret=%d\n", 126 fdt_get_name(fit, node, NULL), ret); 127 return ret; 128 } 129 130 /* check uncompressed data hash */ 131 ret = fit_image_check_uncomp_hash(fit, node, (void *)(*load_addr), len); 132 if (!ret) 133 puts("+ "); 134 else 135 return ret; 136 137 *src_addr = (ulong *)*load_addr; 138 *src_len = len; 139 140 return 0; 141 } 142 #endif 143 144 void board_fit_image_post_process(void *fit, int node, ulong *load_addr, 145 ulong **src_addr, size_t *src_len, void *spec) 146 { 147 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS) || CONFIG_IS_ENABLED(GZIP) 148 fit_decomp_image(fit, node, load_addr, src_addr, src_len, spec); 149 #endif 150 151 #if CONFIG_IS_ENABLED(USING_KERNEL_DTB) 152 /* Avoid overriding processed(overlay, hw-dtb, ...) kernel dtb */ 153 if (fit_image_check_type(fit, node, IH_TYPE_FLATDT)) { 154 if ((gd->flags & GD_FLG_KDTB_READY) && !gd->fdt_blob_kern) { 155 *src_addr = (void *)gd->fdt_blob; 156 *src_len = (size_t)fdt_totalsize(gd->fdt_blob); 157 } else { 158 printf(" Using fdt from load-in fdt\n"); 159 } 160 } 161 #endif 162 } 163 #endif /* FIT_IMAGE_POST_PROCESS */ 164 /* 165 * Override __weak fit_rollback_index_verify() for SPL & U-Boot proper. 166 */ 167 #if CONFIG_IS_ENABLED(FIT_ROLLBACK_PROTECT) 168 int fit_rollback_index_verify(const void *fit, uint32_t rollback_fd, 169 uint32_t *fit_index, uint32_t *otp_index) 170 { 171 int conf_noffset, ret; 172 173 conf_noffset = fit_conf_get_node(fit, NULL); /* NULL for default conf */ 174 if (conf_noffset < 0) 175 return conf_noffset; 176 177 ret = fit_image_get_rollback_index(fit, conf_noffset, fit_index); 178 if (ret) { 179 printf("Failed to get rollback-index from FIT, ret=%d\n", ret); 180 return ret; 181 } 182 183 ret = fit_read_otp_rollback_index(*fit_index, otp_index); 184 if (ret) { 185 printf("Failed to get rollback-index from otp, ret=%d\n", ret); 186 return ret; 187 } 188 189 /* Should update rollback index to otp ! */ 190 if (*otp_index < *fit_index) 191 gd->rollback_index = *fit_index; 192 193 return 0; 194 } 195 #endif 196 197 /* 198 * Override __weak fit_board_verify_required_sigs() for SPL & U-Boot proper. 199 */ 200 int fit_board_verify_required_sigs(void) 201 { 202 uint8_t vboot = 0; 203 204 #ifdef CONFIG_SPL_BUILD 205 #if defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP) 206 struct udevice *dev; 207 208 dev = misc_otp_get_device(OTP_S); 209 if (!dev) 210 return 1; 211 212 if (misc_otp_read(dev, OTP_SECURE_BOOT_ENABLE_ADDR, &vboot, 1)) { 213 printf("Can't read verified-boot flag\n"); 214 return 1; 215 } 216 217 vboot = (vboot == 0xff); 218 #endif 219 #else /* !CONFIG_SPL_BUILD */ 220 #ifdef CONFIG_OPTEE_CLIENT 221 int ret; 222 223 ret = trusty_read_vbootkey_enable_flag(&vboot); 224 if (ret) { 225 printf("Can't read verified-boot flag, ret=%d\n", ret); 226 return 1; 227 } 228 #endif 229 #endif /* CONFIG_SPL_BUILD*/ 230 231 printf("## Verified-boot: %d\n", vboot); 232 233 return vboot; 234 } 235 236 #endif /* CONFIG_IS_ENABLED(FIT) */ 237