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