1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2 /*
3  * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4  */
5 
6 #include <image.h>
7 #include "imagetool.h"
8 
9 /* magic ='S' 'T' 'M' 0x32 */
10 #define HEADER_MAGIC be32_to_cpu(0x53544D32)
11 #define VER_MAJOR	2
12 #define VER_MINOR	1
13 #define VER_VARIANT	0
14 #define HEADER_VERSION_V1	0x1
15 #define HEADER_VERSION_V2	0x2
16 /* default option : bit0 => no signature */
17 #define HEADER_DEFAULT_OPTION	(cpu_to_le32(0x00000001))
18 /* default binary type for U-Boot */
19 #define HEADER_TYPE_UBOOT	(cpu_to_le32(0x00000000))
20 #define PADDING_HEADER_MAGIC	(cpu_to_le32(0xFFFF5453))
21 #define PADDING_HEADER_FLAG	(1ULL << 31)
22 #define PADDING_HEADER_LENGTH	0x180
23 
24 struct stm32_header_v1 {
25 	uint32_t magic_number;
26 	uint8_t image_signature[64];
27 	uint32_t image_checksum;
28 	uint8_t header_version[4];
29 	uint32_t image_length;
30 	uint32_t image_entry_point;
31 	uint32_t reserved1;
32 	uint32_t load_address;
33 	uint32_t reserved2;
34 	uint32_t version_number;
35 	/* V1.0 specific content */
36 	uint32_t option_flags;
37 	uint32_t ecdsa_algorithm;
38 	uint8_t ecdsa_public_key[64];
39 	uint8_t padding[83];
40 	uint8_t binary_type;
41 };
42 
43 struct stm32_header_v2 {
44 	uint32_t magic_number;
45 	uint8_t image_signature[64];
46 	uint32_t image_checksum;
47 	uint8_t header_version[4];
48 	uint32_t image_length;
49 	uint32_t image_entry_point;
50 	uint32_t reserved1;
51 	uint32_t load_address;
52 	uint32_t reserved2;
53 	uint32_t version_number;
54 	/* V2.0 specific content */
55 	uint32_t extension_flags;
56 	uint32_t extension_headers_length;
57 	uint32_t binary_type;
58 	uint8_t padding[16];
59 	uint32_t extension_header_type;
60 	uint32_t extension_header_length;
61 	uint8_t extension_padding[376];
62 };
63 
64 static struct stm32_header_v1 stm32image_header_v1;
65 static struct stm32_header_v2 stm32image_header_v2;
66 
stm32image_checksum(void * start,uint32_t len,uint32_t header_size)67 static uint32_t stm32image_checksum(void *start, uint32_t len,
68 				    uint32_t header_size)
69 {
70 	uint32_t csum = 0;
71 	uint8_t *p;
72 
73 	if (len < header_size) {
74 		return 0;
75 	}
76 
77 	p = (unsigned char *)start + header_size;
78 	len -= header_size;
79 
80 	while (len > 0) {
81 		csum += *p;
82 		p++;
83 		len--;
84 	}
85 
86 	return csum;
87 }
88 
stm32image_check_image_types_v1(uint8_t type)89 static int stm32image_check_image_types_v1(uint8_t type)
90 {
91 	if (type == IH_TYPE_STM32IMAGE)
92 		return EXIT_SUCCESS;
93 	return EXIT_FAILURE;
94 }
95 
stm32image_check_image_types_v2(uint8_t type)96 static int stm32image_check_image_types_v2(uint8_t type)
97 {
98 	if (type == IH_TYPE_STM32IMAGE_V2)
99 		return EXIT_SUCCESS;
100 	return EXIT_FAILURE;
101 }
102 
stm32image_verify_header_v1(unsigned char * ptr,int image_size,struct image_tool_params * params)103 static int stm32image_verify_header_v1(unsigned char *ptr, int image_size,
104 				       struct image_tool_params *params)
105 {
106 	struct stm32_header_v1 *stm32hdr = (struct stm32_header_v1 *)ptr;
107 	int i;
108 
109 	if (image_size < sizeof(struct stm32_header_v1))
110 		return -1;
111 	if (stm32hdr->magic_number != HEADER_MAGIC)
112 		return -1;
113 	if (stm32hdr->header_version[VER_MAJOR] != HEADER_VERSION_V1)
114 		return -1;
115 	if (stm32hdr->reserved1 || stm32hdr->reserved2)
116 		return -1;
117 	for (i = 0; i < (sizeof(stm32hdr->padding) / 4); i++) {
118 		if (stm32hdr->padding[i] != 0)
119 			return -1;
120 	}
121 
122 	return 0;
123 }
124 
stm32image_verify_header_v2(unsigned char * ptr,int image_size,struct image_tool_params * params)125 static int stm32image_verify_header_v2(unsigned char *ptr, int image_size,
126 				       struct image_tool_params *params)
127 {
128 	struct stm32_header_v2 *stm32hdr = (struct stm32_header_v2 *)ptr;
129 	int i;
130 
131 	if (image_size < sizeof(struct stm32_header_v2))
132 		return -1;
133 	if (stm32hdr->magic_number != HEADER_MAGIC)
134 		return -1;
135 	if (stm32hdr->header_version[VER_MAJOR] != HEADER_VERSION_V2)
136 		return -1;
137 	if (stm32hdr->reserved1 || stm32hdr->reserved2)
138 		return -1;
139 	for (i = 0; i < (sizeof(stm32hdr->padding) / 4); i++) {
140 		if (stm32hdr->padding[i] != 0)
141 			return -1;
142 	}
143 
144 	return 0;
145 }
146 
stm32image_print_header(const void * ptr,struct image_tool_params * params)147 static void stm32image_print_header(const void *ptr, struct image_tool_params *params)
148 {
149 	struct stm32_header_v1 *stm32hdr_v1 = (struct stm32_header_v1 *)ptr;
150 	struct stm32_header_v2 *stm32hdr_v2 = (struct stm32_header_v2 *)ptr;
151 
152 	printf("Image Type   : STMicroelectronics STM32 V%d.%d\n",
153 	       stm32hdr_v1->header_version[VER_MAJOR],
154 	       stm32hdr_v1->header_version[VER_MINOR]);
155 	printf("Image Size   : %lu bytes\n",
156 	       (unsigned long)le32_to_cpu(stm32hdr_v1->image_length));
157 	printf("Image Load   : 0x%08x\n",
158 	       le32_to_cpu(stm32hdr_v1->load_address));
159 	printf("Entry Point  : 0x%08x\n",
160 	       le32_to_cpu(stm32hdr_v1->image_entry_point));
161 	printf("Checksum     : 0x%08x\n",
162 	       le32_to_cpu(stm32hdr_v1->image_checksum));
163 	switch (stm32hdr_v1->header_version[VER_MAJOR]) {
164 	case HEADER_VERSION_V1:
165 		printf("Option     : 0x%08x\n",
166 		       le32_to_cpu(stm32hdr_v1->option_flags));
167 		printf("BinaryType : 0x%08x\n",
168 		       le32_to_cpu(stm32hdr_v1->binary_type));
169 		break;
170 
171 	case HEADER_VERSION_V2:
172 		printf("Extension    : 0x%08x\n",
173 		       le32_to_cpu(stm32hdr_v2->extension_flags));
174 		break;
175 
176 	default:
177 		printf("Incorrect header version\n");
178 	}
179 }
180 
stm32image_set_header_v1(void * ptr,struct stat * sbuf,int ifd,struct image_tool_params * params)181 static void stm32image_set_header_v1(void *ptr, struct stat *sbuf, int ifd,
182 				     struct image_tool_params *params)
183 {
184 	struct stm32_header_v1 *stm32hdr = (struct stm32_header_v1 *)ptr;
185 
186 	stm32hdr->magic_number = HEADER_MAGIC;
187 	stm32hdr->version_number = cpu_to_le32(0);
188 
189 	stm32hdr->header_version[VER_MAJOR] = HEADER_VERSION_V1;
190 	stm32hdr->option_flags = HEADER_DEFAULT_OPTION;
191 	stm32hdr->ecdsa_algorithm = cpu_to_le32(1);
192 	stm32hdr->binary_type = HEADER_TYPE_UBOOT;
193 
194 	stm32hdr->load_address = cpu_to_le32(params->addr);
195 	stm32hdr->image_entry_point = cpu_to_le32(params->ep);
196 	stm32hdr->image_length = cpu_to_le32((uint32_t)sbuf->st_size -
197 					     sizeof(*stm32hdr));
198 	stm32hdr->image_checksum =
199 		cpu_to_le32(stm32image_checksum(ptr, sbuf->st_size,
200 						sizeof(*stm32hdr)));
201 }
202 
stm32image_set_header_v2(void * ptr,struct stat * sbuf,int ifd,struct image_tool_params * params)203 static void stm32image_set_header_v2(void *ptr, struct stat *sbuf, int ifd,
204 				     struct image_tool_params *params)
205 {
206 	struct stm32_header_v2 *stm32hdr = (struct stm32_header_v2 *)ptr;
207 
208 	stm32hdr->magic_number = HEADER_MAGIC;
209 	stm32hdr->version_number = cpu_to_le32(0);
210 
211 	stm32hdr->header_version[VER_MAJOR] = HEADER_VERSION_V2;
212 	stm32hdr->extension_flags =
213 		cpu_to_le32(PADDING_HEADER_FLAG);
214 	stm32hdr->extension_headers_length =
215 		cpu_to_le32(PADDING_HEADER_LENGTH);
216 	stm32hdr->extension_header_type =
217 		cpu_to_le32(PADDING_HEADER_MAGIC);
218 	stm32hdr->extension_header_length =
219 		cpu_to_le32(PADDING_HEADER_LENGTH);
220 
221 	stm32hdr->load_address = cpu_to_le32(params->addr);
222 	stm32hdr->image_entry_point = cpu_to_le32(params->ep);
223 	stm32hdr->image_length = cpu_to_le32((uint32_t)sbuf->st_size -
224 					     sizeof(*stm32hdr));
225 	stm32hdr->image_checksum =
226 		cpu_to_le32(stm32image_checksum(ptr, sbuf->st_size,
227 						sizeof(*stm32hdr)));
228 }
229 
230 /*
231  * stm32image parameters
232  */
233 U_BOOT_IMAGE_TYPE(
234 	stm32image,
235 	"STMicroelectronics STM32MP Image support",
236 	sizeof(struct stm32_header_v1),
237 	(void *)&stm32image_header_v1,
238 	NULL,
239 	stm32image_verify_header_v1,
240 	stm32image_print_header,
241 	stm32image_set_header_v1,
242 	NULL,
243 	stm32image_check_image_types_v1,
244 	NULL,
245 	NULL
246 );
247 
248 U_BOOT_IMAGE_TYPE(
249 	stm32imagev2,
250 	"STMicroelectronics STM32MP Image V2.0 support",
251 	sizeof(struct stm32_header_v2),
252 	(void *)&stm32image_header_v2,
253 	NULL,
254 	stm32image_verify_header_v2,
255 	stm32image_print_header,
256 	stm32image_set_header_v2,
257 	NULL,
258 	stm32image_check_image_types_v2,
259 	NULL,
260 	NULL
261 );
262