aspeed/spl: Remove OVERLAY from linker script
[platform/kernel/u-boot.git] / boot / image-pre-load.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2021 Philippe Reynes <philippe.reynes@softathome.com>
4  */
5
6 #include <common.h>
7 #include <asm/global_data.h>
8 DECLARE_GLOBAL_DATA_PTR;
9 #include <image.h>
10 #include <mapmem.h>
11
12 #include <u-boot/sha256.h>
13
14 #define IMAGE_PRE_LOAD_SIG_MAGIC                0x55425348
15 #define IMAGE_PRE_LOAD_SIG_OFFSET_MAGIC         0
16 #define IMAGE_PRE_LOAD_SIG_OFFSET_IMG_LEN       4
17 #define IMAGE_PRE_LOAD_SIG_OFFSET_SIG           8
18
19 #define IMAGE_PRE_LOAD_PATH                     "/image/pre-load/sig"
20 #define IMAGE_PRE_LOAD_PROP_ALGO_NAME           "algo-name"
21 #define IMAGE_PRE_LOAD_PROP_PADDING_NAME        "padding-name"
22 #define IMAGE_PRE_LOAD_PROP_SIG_SIZE            "signature-size"
23 #define IMAGE_PRE_LOAD_PROP_PUBLIC_KEY          "public-key"
24 #define IMAGE_PRE_LOAD_PROP_MANDATORY           "mandatory"
25
26 /*
27  * Information in the device-tree about the signature in the header
28  */
29 struct image_sig_info {
30         char *algo_name;        /* Name of the algo (eg: sha256,rsa2048) */
31         char *padding_name;     /* Name of the padding */
32         u8 *key;                /* Public signature key */
33         int key_len;            /* Length of the public key */
34         u32 sig_size;           /* size of the signature (in the header) */
35         int mandatory;          /* Set if the signature is mandatory */
36
37         struct image_sign_info sig_info; /* Signature info */
38 };
39
40 /*
41  * Header of the signature header
42  */
43 struct sig_header_s {
44         u32 magic;
45         u32 version;
46         u32 header_size;
47         u32 image_size;
48         u32 offset_img_sig;
49         u32 flags;
50         u32 reserved0;
51         u32 reserved1;
52         u8 sha256_img_sig[SHA256_SUM_LEN];
53 };
54
55 #define SIG_HEADER_LEN                  (sizeof(struct sig_header_s))
56
57 /*
58  * Offset of the image
59  *
60  * This value is used to skip the header before really launching the image
61  */
62 ulong image_load_offset;
63
64 /*
65  * This function gathers information about the signature check
66  * that could be done before launching the image.
67  *
68  * return:
69  * < 0 => an error has occurred
70  *   0 => OK
71  *   1 => no setup
72  */
73 static int image_pre_load_sig_setup(struct image_sig_info *info)
74 {
75         const void *algo_name, *padding_name, *key, *mandatory;
76         const u32 *sig_size;
77         int key_len;
78         int node, ret = 0;
79
80         if (!info) {
81                 log_err("ERROR: info is NULL for image pre-load sig check\n");
82                 ret = -EINVAL;
83                 goto out;
84         }
85
86         memset(info, 0, sizeof(*info));
87
88         node = fdt_path_offset(gd_fdt_blob(), IMAGE_PRE_LOAD_PATH);
89         if (node < 0) {
90                 log_info("INFO: no info for image pre-load sig check\n");
91                 ret = 1;
92                 goto out;
93         }
94
95         algo_name = fdt_getprop(gd_fdt_blob(), node,
96                                 IMAGE_PRE_LOAD_PROP_ALGO_NAME, NULL);
97         if (!algo_name) {
98                 printf("ERROR: no algo_name for image pre-load sig check\n");
99                 ret = -EINVAL;
100                 goto out;
101         }
102
103         padding_name = fdt_getprop(gd_fdt_blob(), node,
104                                    IMAGE_PRE_LOAD_PROP_PADDING_NAME, NULL);
105         if (!padding_name) {
106                 log_info("INFO: no padding_name provided, so using pkcs-1.5\n");
107                 padding_name = "pkcs-1.5";
108         }
109
110         sig_size = fdt_getprop(gd_fdt_blob(), node,
111                                IMAGE_PRE_LOAD_PROP_SIG_SIZE, NULL);
112         if (!sig_size) {
113                 log_err("ERROR: no signature-size for image pre-load sig check\n");
114                 ret = -EINVAL;
115                 goto out;
116         }
117
118         key = fdt_getprop(gd_fdt_blob(), node,
119                           IMAGE_PRE_LOAD_PROP_PUBLIC_KEY, &key_len);
120         if (!key) {
121                 log_err("ERROR: no key for image pre-load sig check\n");
122                 ret = -EINVAL;
123                 goto out;
124         }
125
126         info->algo_name         = (char *)algo_name;
127         info->padding_name      = (char *)padding_name;
128         info->key               = (uint8_t *)key;
129         info->key_len           = key_len;
130         info->sig_size          = fdt32_to_cpu(*sig_size);
131
132         mandatory = fdt_getprop(gd_fdt_blob(), node,
133                                 IMAGE_PRE_LOAD_PROP_MANDATORY, NULL);
134         if (mandatory && !strcmp((char *)mandatory, "yes"))
135                 info->mandatory = 1;
136
137         /* Compute signature information */
138         info->sig_info.name     = info->algo_name;
139         info->sig_info.padding  = image_get_padding_algo(info->padding_name);
140         info->sig_info.checksum = image_get_checksum_algo(info->sig_info.name);
141         info->sig_info.crypto   = image_get_crypto_algo(info->sig_info.name);
142         info->sig_info.key      = info->key;
143         info->sig_info.keylen   = info->key_len;
144
145  out:
146         return ret;
147 }
148
149 static int image_pre_load_sig_get_magic(ulong addr, u32 *magic)
150 {
151         struct sig_header_s *sig_header;
152         int ret = 0;
153
154         sig_header = (struct sig_header_s *)map_sysmem(addr, SIG_HEADER_LEN);
155         if (!sig_header) {
156                 log_err("ERROR: can't map first header\n");
157                 ret = -EFAULT;
158                 goto out;
159         }
160
161         *magic = fdt32_to_cpu(sig_header->magic);
162
163         unmap_sysmem(sig_header);
164
165  out:
166         return ret;
167 }
168
169 static int image_pre_load_sig_get_header_size(ulong addr, u32 *header_size)
170 {
171         struct sig_header_s *sig_header;
172         int ret = 0;
173
174         sig_header = (struct sig_header_s *)map_sysmem(addr, SIG_HEADER_LEN);
175         if (!sig_header) {
176                 log_err("ERROR: can't map first header\n");
177                 ret = -EFAULT;
178                 goto out;
179         }
180
181         *header_size = fdt32_to_cpu(sig_header->header_size);
182
183         unmap_sysmem(sig_header);
184
185  out:
186         return ret;
187 }
188
189 /*
190  * return:
191  * < 0 => no magic and magic mandatory (or error when reading magic)
192  *   0 => magic found
193  *   1 => magic NOT found
194  */
195 static int image_pre_load_sig_check_magic(struct image_sig_info *info, ulong addr)
196 {
197         u32 magic;
198         int ret = 1;
199
200         ret = image_pre_load_sig_get_magic(addr, &magic);
201         if (ret < 0)
202                 goto out;
203
204         if (magic != IMAGE_PRE_LOAD_SIG_MAGIC) {
205                 if (info->mandatory) {
206                         log_err("ERROR: signature is mandatory\n");
207                         ret = -EINVAL;
208                         goto out;
209                 }
210                 ret = 1;
211                 goto out;
212         }
213
214         ret = 0; /* magic found */
215
216  out:
217         return ret;
218 }
219
220 static int image_pre_load_sig_check_header_sig(struct image_sig_info *info, ulong addr)
221 {
222         void *header;
223         struct image_region reg;
224         u32 sig_len;
225         u8 *sig;
226         int ret = 0;
227
228         /* Only map header of the header and its signature */
229         header = (void *)map_sysmem(addr, SIG_HEADER_LEN + info->sig_size);
230         if (!header) {
231                 log_err("ERROR: can't map header\n");
232                 ret = -EFAULT;
233                 goto out;
234         }
235
236         reg.data = header;
237         reg.size = SIG_HEADER_LEN;
238
239         sig = (uint8_t *)header + SIG_HEADER_LEN;
240         sig_len = info->sig_size;
241
242         ret = info->sig_info.crypto->verify(&info->sig_info, &reg, 1, sig, sig_len);
243         if (ret) {
244                 log_err("ERROR: header signature check has failed (err=%d)\n", ret);
245                 ret = -EINVAL;
246                 goto out_unmap;
247         }
248
249  out_unmap:
250         unmap_sysmem(header);
251
252  out:
253         return ret;
254 }
255
256 static int image_pre_load_sig_check_img_sig_sha256(struct image_sig_info *info, ulong addr)
257 {
258         struct sig_header_s *sig_header;
259         u32 header_size, offset_img_sig;
260         void *header;
261         u8 sha256_img_sig[SHA256_SUM_LEN];
262         int ret = 0;
263
264         sig_header = (struct sig_header_s *)map_sysmem(addr, SIG_HEADER_LEN);
265         if (!sig_header) {
266                 log_err("ERROR: can't map first header\n");
267                 ret = -EFAULT;
268                 goto out;
269         }
270
271         header_size = fdt32_to_cpu(sig_header->header_size);
272         offset_img_sig = fdt32_to_cpu(sig_header->offset_img_sig);
273
274         header = (void *)map_sysmem(addr, header_size);
275         if (!header) {
276                 log_err("ERROR: can't map header\n");
277                 ret = -EFAULT;
278                 goto out_sig_header;
279         }
280
281         sha256_csum_wd(header + offset_img_sig, info->sig_size,
282                        sha256_img_sig, CHUNKSZ_SHA256);
283
284         ret = memcmp(sig_header->sha256_img_sig, sha256_img_sig, SHA256_SUM_LEN);
285         if (ret) {
286                 log_err("ERROR: sha256 of image signature is invalid\n");
287                 ret = -EFAULT;
288                 goto out_header;
289         }
290
291  out_header:
292         unmap_sysmem(header);
293  out_sig_header:
294         unmap_sysmem(sig_header);
295  out:
296         return ret;
297 }
298
299 static int image_pre_load_sig_check_img_sig(struct image_sig_info *info, ulong addr)
300 {
301         struct sig_header_s *sig_header;
302         u32 header_size, image_size, offset_img_sig;
303         void *image;
304         struct image_region reg;
305         u32 sig_len;
306         u8 *sig;
307         int ret = 0;
308
309         sig_header = (struct sig_header_s *)map_sysmem(addr, SIG_HEADER_LEN);
310         if (!sig_header) {
311                 log_err("ERROR: can't map first header\n");
312                 ret = -EFAULT;
313                 goto out;
314         }
315
316         header_size = fdt32_to_cpu(sig_header->header_size);
317         image_size = fdt32_to_cpu(sig_header->image_size);
318         offset_img_sig = fdt32_to_cpu(sig_header->offset_img_sig);
319
320         unmap_sysmem(sig_header);
321
322         image = (void *)map_sysmem(addr, header_size + image_size);
323         if (!image) {
324                 log_err("ERROR: can't map full image\n");
325                 ret = -EFAULT;
326                 goto out;
327         }
328
329         reg.data = image + header_size;
330         reg.size = image_size;
331
332         sig = (uint8_t *)image + offset_img_sig;
333         sig_len = info->sig_size;
334
335         ret = info->sig_info.crypto->verify(&info->sig_info, &reg, 1, sig, sig_len);
336         if (ret) {
337                 log_err("ERROR: signature check has failed (err=%d)\n", ret);
338                 ret = -EINVAL;
339                 goto out_unmap_image;
340         }
341
342         log_info("INFO: signature check has succeed\n");
343
344  out_unmap_image:
345         unmap_sysmem(image);
346
347  out:
348         return ret;
349 }
350
351 int image_pre_load_sig(ulong addr)
352 {
353         struct image_sig_info info;
354         int ret;
355
356         ret = image_pre_load_sig_setup(&info);
357         if (ret < 0)
358                 goto out;
359         if (ret > 0) {
360                 ret = 0;
361                 goto out;
362         }
363
364         ret = image_pre_load_sig_check_magic(&info, addr);
365         if (ret < 0)
366                 goto out;
367         if (ret > 0) {
368                 ret = 0;
369                 goto out;
370         }
371
372         /* Check the signature of the signature header */
373         ret = image_pre_load_sig_check_header_sig(&info, addr);
374         if (ret < 0)
375                 goto out;
376
377         /* Check sha256 of the image signature */
378         ret = image_pre_load_sig_check_img_sig_sha256(&info, addr);
379         if (ret < 0)
380                 goto out;
381
382         /* Check the image signature */
383         ret = image_pre_load_sig_check_img_sig(&info, addr);
384         if (!ret) {
385                 u32 header_size;
386
387                 ret = image_pre_load_sig_get_header_size(addr, &header_size);
388                 if (ret) {
389                         log_err("%s: can't get header size\n", __func__);
390                         ret = -EINVAL;
391                         goto out;
392                 }
393
394                 image_load_offset += header_size;
395         }
396
397  out:
398         return ret;
399 }
400
401 int image_pre_load(ulong addr)
402 {
403         int ret = 0;
404
405         image_load_offset = 0;
406
407         if (CONFIG_IS_ENABLED(IMAGE_PRE_LOAD_SIG))
408                 ret = image_pre_load_sig(addr);
409
410         return ret;
411 }