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 <optee_include/OpteeClientInterface.h> 14 #include <optee_include/tee_api_defines.h> 15 16 DECLARE_GLOBAL_DATA_PTR; 17 18 #if CONFIG_IS_ENABLED(FIT) 19 20 /* 21 * Override __weak board_fit_image_post_process() for SPL & U-Boot proper. 22 */ 23 #if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS) 24 25 #define FIT_UNCOMP_HASH_NODENAME "digest" 26 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS) || CONFIG_IS_ENABLED(GZIP) 27 static int fit_image_check_uncomp_hash(const void *fit, int parent_noffset, 28 const void *data, size_t size) 29 { 30 const char *name; 31 char *err_msgp; 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 fit_image_check_hash(fit, noffset, data, 39 size, &err_msgp); 40 } 41 } 42 43 return 0; 44 } 45 46 static int fit_gunzip_image(void *fit, int node, ulong *load_addr, 47 ulong **src_addr, size_t *src_len) 48 { 49 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS) 50 const void *prop; 51 #endif 52 u64 len = *src_len; 53 int ret; 54 u8 comp; 55 56 if (fit_image_get_comp(fit, node, &comp)) 57 return 0; 58 59 if (comp != IH_COMP_GZIP) 60 return 0; 61 62 #ifndef CONFIG_SPL_BUILD 63 /* handled late in bootm_decomp_image() */ 64 if (fit_image_check_type(fit, node, IH_TYPE_KERNEL)) 65 return 0; 66 #endif 67 /* 68 * For smaller spl size, we don't use misc_decompress_process() 69 * inside the gunzip(). 70 */ 71 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS) 72 ret = misc_decompress_process((ulong)(*load_addr), 73 (ulong)(*src_addr), (ulong)(*src_len), 74 DECOM_GZIP, false, &len); 75 #else 76 ret = gunzip((void *)(*load_addr), ALIGN(len, FIT_MAX_SPL_IMAGE_SZ), 77 (void *)(*src_addr), (void *)(&len)); 78 #endif 79 if (ret) { 80 printf("%s: decompress error, ret=%d\n", 81 fdt_get_name(fit, node, NULL), ret); 82 return ret; 83 } 84 85 /* check uncompressed data hash */ 86 ret = fit_image_check_uncomp_hash(fit, node, (void *)(*load_addr), len); 87 if (!ret) 88 puts("+ "); 89 else 90 return ret; 91 92 *src_addr = (ulong *)*load_addr; 93 *src_len = len; 94 95 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS) 96 /* mark for misc_decompress_cleanup() */ 97 prop = fdt_getprop(fit, node, "decomp-async", NULL); 98 if (prop) 99 misc_decompress_async(comp); 100 else 101 misc_decompress_sync(comp); 102 #endif 103 104 return 0; 105 } 106 #endif 107 108 void board_fit_image_post_process(void *fit, int node, ulong *load_addr, 109 ulong **src_addr, size_t *src_len) 110 { 111 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS) || CONFIG_IS_ENABLED(GZIP) 112 fit_gunzip_image(fit, node, load_addr, src_addr, src_len); 113 #endif 114 115 #if CONFIG_IS_ENABLED(USING_KERNEL_DTB) 116 /* Avoid overriding processed(overlay, hw-dtb, ...) kernel dtb */ 117 if (fit_image_check_type(fit, node, IH_TYPE_FLATDT)) { 118 if ((gd->flags & GD_FLG_KDTB_READY) && !gd->fdt_blob_kern) { 119 *src_addr = (void *)gd->fdt_blob; 120 *src_len = (size_t)fdt_totalsize(gd->fdt_blob); 121 } else { 122 printf(" Using fdt from load-in fdt\n"); 123 } 124 } 125 #endif 126 } 127 #endif /* FIT_IMAGE_POST_PROCESS */ 128 129 /* 130 * Override __weak fit_rollback_index_verify() for SPL & U-Boot proper. 131 */ 132 #if CONFIG_IS_ENABLED(FIT_ROLLBACK_PROTECT) 133 int fit_rollback_index_verify(const void *fit, uint32_t rollback_fd, 134 uint32_t *fit_index, uint32_t *otp_index) 135 { 136 int conf_noffset, ret; 137 138 conf_noffset = fit_conf_get_node(fit, NULL); /* NULL for default conf */ 139 if (conf_noffset < 0) 140 return conf_noffset; 141 142 ret = fit_image_get_rollback_index(fit, conf_noffset, fit_index); 143 if (ret) { 144 printf("Failed to get rollback-index from FIT, ret=%d\n", ret); 145 return ret; 146 } 147 148 ret = fit_read_otp_rollback_index(*fit_index, otp_index); 149 if (ret) { 150 printf("Failed to get rollback-index from otp, ret=%d\n", ret); 151 return ret; 152 } 153 154 /* Should update rollback index to otp ! */ 155 if (*otp_index < *fit_index) 156 gd->rollback_index = *fit_index; 157 158 return 0; 159 } 160 #endif 161 162 /* 163 * Override __weak fit_board_verify_required_sigs() for SPL & U-Boot proper. 164 */ 165 int fit_board_verify_required_sigs(void) 166 { 167 uint8_t vboot = 0; 168 169 #ifdef CONFIG_SPL_BUILD 170 #if defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP_V1) || \ 171 defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP_V2) 172 struct udevice *dev; 173 174 dev = misc_otp_get_device(OTP_S); 175 if (!dev) 176 return 1; 177 178 if (misc_otp_read(dev, OTP_SECURE_BOOT_ENABLE_ADDR, &vboot, 1)) { 179 printf("Can't read verified-boot flag\n"); 180 return 1; 181 } 182 183 vboot = (vboot == 0xff); 184 #endif 185 #else /* !CONFIG_SPL_BUILD */ 186 #ifdef CONFIG_OPTEE_CLIENT 187 int ret; 188 189 ret = trusty_read_vbootkey_enable_flag(&vboot); 190 if (ret) { 191 printf("Can't read verified-boot flag, ret=%d\n", ret); 192 return 1; 193 } 194 #endif 195 #endif /* CONFIG_SPL_BUILD*/ 196 197 printf("## Verified-boot: %d\n", vboot); 198 199 return vboot; 200 } 201 202 #endif /* CONFIG_IS_ENABLED(FIT) */ 203