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