1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2021 Philippe Reynes <philippe.reynes@softathome.com>
7 #include <asm/global_data.h>
8 DECLARE_GLOBAL_DATA_PTR;
12 #include <u-boot/sha256.h>
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
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"
27 * Information in the device-tree about the signature in the header
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 */
37 struct image_sign_info sig_info; /* Signature info */
41 * Header of the signature header
52 u8 sha256_img_sig[SHA256_SUM_LEN];
55 #define SIG_HEADER_LEN (sizeof(struct sig_header_s))
60 * This value is used to skip the header before really launching the image
62 ulong image_load_offset;
65 * This function gathers information about the signature check
66 * that could be done before launching the image.
69 * < 0 => an error has occurred
73 static int image_pre_load_sig_setup(struct image_sig_info *info)
75 const void *algo_name, *padding_name, *key, *mandatory;
81 log_err("ERROR: info is NULL for image pre-load sig check\n");
86 memset(info, 0, sizeof(*info));
88 node = fdt_path_offset(gd_fdt_blob(), IMAGE_PRE_LOAD_PATH);
90 log_info("INFO: no info for image pre-load sig check\n");
95 algo_name = fdt_getprop(gd_fdt_blob(), node,
96 IMAGE_PRE_LOAD_PROP_ALGO_NAME, NULL);
98 printf("ERROR: no algo_name for image pre-load sig check\n");
103 padding_name = fdt_getprop(gd_fdt_blob(), node,
104 IMAGE_PRE_LOAD_PROP_PADDING_NAME, NULL);
106 log_info("INFO: no padding_name provided, so using pkcs-1.5\n");
107 padding_name = "pkcs-1.5";
110 sig_size = fdt_getprop(gd_fdt_blob(), node,
111 IMAGE_PRE_LOAD_PROP_SIG_SIZE, NULL);
113 log_err("ERROR: no signature-size for image pre-load sig check\n");
118 key = fdt_getprop(gd_fdt_blob(), node,
119 IMAGE_PRE_LOAD_PROP_PUBLIC_KEY, &key_len);
121 log_err("ERROR: no key for image pre-load sig check\n");
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);
132 mandatory = fdt_getprop(gd_fdt_blob(), node,
133 IMAGE_PRE_LOAD_PROP_MANDATORY, NULL);
134 if (mandatory && !strcmp((char *)mandatory, "yes"))
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;
149 static int image_pre_load_sig_get_magic(ulong addr, u32 *magic)
151 struct sig_header_s *sig_header;
154 sig_header = (struct sig_header_s *)map_sysmem(addr, SIG_HEADER_LEN);
156 log_err("ERROR: can't map first header\n");
161 *magic = fdt32_to_cpu(sig_header->magic);
163 unmap_sysmem(sig_header);
169 static int image_pre_load_sig_get_header_size(ulong addr, u32 *header_size)
171 struct sig_header_s *sig_header;
174 sig_header = (struct sig_header_s *)map_sysmem(addr, SIG_HEADER_LEN);
176 log_err("ERROR: can't map first header\n");
181 *header_size = fdt32_to_cpu(sig_header->header_size);
183 unmap_sysmem(sig_header);
191 * < 0 => no magic and magic mandatory (or error when reading magic)
193 * 1 => magic NOT found
195 static int image_pre_load_sig_check_magic(struct image_sig_info *info, ulong addr)
200 ret = image_pre_load_sig_get_magic(addr, &magic);
204 if (magic != IMAGE_PRE_LOAD_SIG_MAGIC) {
205 if (info->mandatory) {
206 log_err("ERROR: signature is mandatory\n");
214 ret = 0; /* magic found */
220 static int image_pre_load_sig_check_header_sig(struct image_sig_info *info, ulong addr)
223 struct image_region reg;
228 /* Only map header of the header and its signature */
229 header = (void *)map_sysmem(addr, SIG_HEADER_LEN + info->sig_size);
231 log_err("ERROR: can't map header\n");
237 reg.size = SIG_HEADER_LEN;
239 sig = (uint8_t *)header + SIG_HEADER_LEN;
240 sig_len = info->sig_size;
242 ret = info->sig_info.crypto->verify(&info->sig_info, ®, 1, sig, sig_len);
244 log_err("ERROR: header signature check has failed (err=%d)\n", ret);
250 unmap_sysmem(header);
256 static int image_pre_load_sig_check_img_sig_sha256(struct image_sig_info *info, ulong addr)
258 struct sig_header_s *sig_header;
259 u32 header_size, offset_img_sig;
261 u8 sha256_img_sig[SHA256_SUM_LEN];
264 sig_header = (struct sig_header_s *)map_sysmem(addr, SIG_HEADER_LEN);
266 log_err("ERROR: can't map first header\n");
271 header_size = fdt32_to_cpu(sig_header->header_size);
272 offset_img_sig = fdt32_to_cpu(sig_header->offset_img_sig);
274 header = (void *)map_sysmem(addr, header_size);
276 log_err("ERROR: can't map header\n");
281 sha256_csum_wd(header + offset_img_sig, info->sig_size,
282 sha256_img_sig, CHUNKSZ_SHA256);
284 ret = memcmp(sig_header->sha256_img_sig, sha256_img_sig, SHA256_SUM_LEN);
286 log_err("ERROR: sha256 of image signature is invalid\n");
292 unmap_sysmem(header);
294 unmap_sysmem(sig_header);
299 static int image_pre_load_sig_check_img_sig(struct image_sig_info *info, ulong addr)
301 struct sig_header_s *sig_header;
302 u32 header_size, image_size, offset_img_sig;
304 struct image_region reg;
309 sig_header = (struct sig_header_s *)map_sysmem(addr, SIG_HEADER_LEN);
311 log_err("ERROR: can't map first header\n");
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);
320 unmap_sysmem(sig_header);
322 image = (void *)map_sysmem(addr, header_size + image_size);
324 log_err("ERROR: can't map full image\n");
329 reg.data = image + header_size;
330 reg.size = image_size;
332 sig = (uint8_t *)image + offset_img_sig;
333 sig_len = info->sig_size;
335 ret = info->sig_info.crypto->verify(&info->sig_info, ®, 1, sig, sig_len);
337 log_err("ERROR: signature check has failed (err=%d)\n", ret);
339 goto out_unmap_image;
342 log_info("INFO: signature check has succeed\n");
351 int image_pre_load_sig(ulong addr)
353 struct image_sig_info info;
356 ret = image_pre_load_sig_setup(&info);
364 ret = image_pre_load_sig_check_magic(&info, addr);
372 /* Check the signature of the signature header */
373 ret = image_pre_load_sig_check_header_sig(&info, addr);
377 /* Check sha256 of the image signature */
378 ret = image_pre_load_sig_check_img_sig_sha256(&info, addr);
382 /* Check the image signature */
383 ret = image_pre_load_sig_check_img_sig(&info, addr);
387 ret = image_pre_load_sig_get_header_size(addr, &header_size);
389 log_err("%s: can't get header size\n", __func__);
394 image_load_offset += header_size;
401 int image_pre_load(ulong addr)
405 image_load_offset = 0;
407 if (CONFIG_IS_ENABLED(IMAGE_PRE_LOAD_SIG))
408 ret = image_pre_load_sig(addr);