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