xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/fit_misc.c (revision f36ea2f6e17621c4d9dd97c4dbfab62d03d061df)
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 	    !fdt_check_header(gd->fdt_blob)) {
119 		*src_addr = (void *)gd->fdt_blob;
120 		*src_len = (size_t)fdt_totalsize(gd->fdt_blob);
121 	}
122 #endif
123 }
124 #endif /* FIT_IMAGE_POST_PROCESS */
125 
126 /*
127  * Override __weak fit_rollback_index_verify() for SPL & U-Boot proper.
128  */
129 #if CONFIG_IS_ENABLED(FIT_ROLLBACK_PROTECT)
130 int fit_rollback_index_verify(const void *fit, uint32_t rollback_fd,
131 			      uint32_t *fit_index, uint32_t *otp_index)
132 {
133 	int conf_noffset, ret;
134 
135 	conf_noffset = fit_conf_get_node(fit, NULL); /* NULL for default conf */
136 	if (conf_noffset < 0)
137 		return conf_noffset;
138 
139 	ret = fit_image_get_rollback_index(fit, conf_noffset, fit_index);
140 	if (ret) {
141 		printf("Failed to get rollback-index from FIT, ret=%d\n", ret);
142 		return ret;
143 	}
144 
145 	ret = fit_read_otp_rollback_index(*fit_index, otp_index);
146 	if (ret) {
147 		printf("Failed to get rollback-index from otp, ret=%d\n", ret);
148 		return ret;
149 	}
150 
151 	/* Should update rollback index to otp ! */
152 	if (*otp_index < *fit_index)
153 		gd->rollback_index = *fit_index;
154 
155 	return 0;
156 }
157 #endif
158 
159 /*
160  * Override __weak fit_board_verify_required_sigs() for SPL & U-Boot proper.
161  */
162 int fit_board_verify_required_sigs(void)
163 {
164 	uint8_t vboot = 0;
165 
166 #ifdef CONFIG_SPL_BUILD
167 #if defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP_V1) || \
168     defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP_V2)
169 	struct udevice *dev;
170 
171 	dev = misc_otp_get_device(OTP_S);
172 	if (!dev)
173 		return 1;
174 
175 	if (misc_otp_read(dev, OTP_SECURE_BOOT_ENABLE_ADDR, &vboot, 1)) {
176 		printf("Can't read verified-boot flag\n");
177 		return 1;
178 	}
179 
180 	vboot = (vboot == 0xff);
181 #endif
182 #else /* !CONFIG_SPL_BUILD */
183 #ifdef CONFIG_OPTEE_CLIENT
184 	int ret;
185 
186 	ret = trusty_read_vbootkey_enable_flag(&vboot);
187 	if (ret) {
188 		printf("Can't read verified-boot flag, ret=%d\n", ret);
189 		return 1;
190 	}
191 #endif
192 #endif /* CONFIG_SPL_BUILD*/
193 
194 	printf("## Verified-boot: %d\n", vboot);
195 
196 	return vboot;
197 }
198 
199 #endif /* CONFIG_IS_ENABLED(FIT) */
200