1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2021 Philippe Reynes <philippe.reynes@softathome.com>
6 #include <asm/global_data.h>
7 DECLARE_GLOBAL_DATA_PTR
;
11 #include <u-boot/sha256.h>
16 * This value is used to skip the header before really launching the image
18 ulong image_load_offset
;
21 * This function gathers information about the signature check
22 * that could be done before launching the image.
25 * < 0 => an error has occurred
29 static int image_pre_load_sig_setup(struct image_sig_info
*info
)
31 const void *algo_name
, *padding_name
, *key
, *mandatory
;
35 char *sig_info_path
= NULL
;
38 log_err("ERROR: info is NULL for image pre-load sig check\n");
43 memset(info
, 0, sizeof(*info
));
45 sig_info_path
= env_get("pre_load_sig_info_path");
47 sig_info_path
= IMAGE_PRE_LOAD_PATH
;
49 node
= fdt_path_offset(gd_fdt_blob(), sig_info_path
);
51 log_info("INFO: no info for image pre-load sig check\n");
56 algo_name
= fdt_getprop(gd_fdt_blob(), node
,
57 IMAGE_PRE_LOAD_PROP_ALGO_NAME
, NULL
);
59 printf("ERROR: no algo_name for image pre-load sig check\n");
64 padding_name
= fdt_getprop(gd_fdt_blob(), node
,
65 IMAGE_PRE_LOAD_PROP_PADDING_NAME
, NULL
);
67 log_info("INFO: no padding_name provided, so using pkcs-1.5\n");
68 padding_name
= "pkcs-1.5";
71 sig_size
= fdt_getprop(gd_fdt_blob(), node
,
72 IMAGE_PRE_LOAD_PROP_SIG_SIZE
, NULL
);
74 log_err("ERROR: no signature-size for image pre-load sig check\n");
79 key
= fdt_getprop(gd_fdt_blob(), node
,
80 IMAGE_PRE_LOAD_PROP_PUBLIC_KEY
, &key_len
);
82 log_err("ERROR: no key for image pre-load sig check\n");
87 info
->algo_name
= (char *)algo_name
;
88 info
->padding_name
= (char *)padding_name
;
89 info
->key
= (uint8_t *)key
;
90 info
->key_len
= key_len
;
91 info
->sig_size
= fdt32_to_cpu(*sig_size
);
93 mandatory
= fdt_getprop(gd_fdt_blob(), node
,
94 IMAGE_PRE_LOAD_PROP_MANDATORY
, NULL
);
95 if (mandatory
&& !strcmp((char *)mandatory
, "yes"))
98 /* Compute signature information */
99 info
->sig_info
.name
= info
->algo_name
;
100 info
->sig_info
.padding
= image_get_padding_algo(info
->padding_name
);
101 info
->sig_info
.checksum
= image_get_checksum_algo(info
->sig_info
.name
);
102 info
->sig_info
.crypto
= image_get_crypto_algo(info
->sig_info
.name
);
103 info
->sig_info
.key
= info
->key
;
104 info
->sig_info
.keylen
= info
->key_len
;
110 static int image_pre_load_sig_get_magic(ulong addr
, u32
*magic
)
112 struct sig_header_s
*sig_header
;
115 sig_header
= (struct sig_header_s
*)map_sysmem(addr
, SIG_HEADER_LEN
);
117 log_err("ERROR: can't map first header\n");
122 *magic
= fdt32_to_cpu(sig_header
->magic
);
124 unmap_sysmem(sig_header
);
130 static int image_pre_load_sig_get_header_size(ulong addr
, u32
*header_size
)
132 struct sig_header_s
*sig_header
;
135 sig_header
= (struct sig_header_s
*)map_sysmem(addr
, SIG_HEADER_LEN
);
137 log_err("ERROR: can't map first header\n");
142 *header_size
= fdt32_to_cpu(sig_header
->header_size
);
144 unmap_sysmem(sig_header
);
152 * < 0 => no magic and magic mandatory (or error when reading magic)
154 * 1 => magic NOT found
156 static int image_pre_load_sig_check_magic(struct image_sig_info
*info
, ulong addr
)
161 ret
= image_pre_load_sig_get_magic(addr
, &magic
);
165 if (magic
!= IMAGE_PRE_LOAD_SIG_MAGIC
) {
166 if (info
->mandatory
) {
167 log_err("ERROR: signature is mandatory\n");
175 ret
= 0; /* magic found */
181 static int image_pre_load_sig_check_header_sig(struct image_sig_info
*info
, ulong addr
)
184 struct image_region reg
;
189 /* Only map header of the header and its signature */
190 header
= (void *)map_sysmem(addr
, SIG_HEADER_LEN
+ info
->sig_size
);
192 log_err("ERROR: can't map header\n");
198 reg
.size
= SIG_HEADER_LEN
;
200 sig
= (uint8_t *)header
+ SIG_HEADER_LEN
;
201 sig_len
= info
->sig_size
;
203 ret
= info
->sig_info
.crypto
->verify(&info
->sig_info
, ®
, 1, sig
, sig_len
);
205 log_err("ERROR: header signature check has failed (err=%d)\n", ret
);
211 unmap_sysmem(header
);
217 static int image_pre_load_sig_check_img_sig_sha256(struct image_sig_info
*info
, ulong addr
)
219 struct sig_header_s
*sig_header
;
220 u32 header_size
, offset_img_sig
;
222 u8 sha256_img_sig
[SHA256_SUM_LEN
];
225 sig_header
= (struct sig_header_s
*)map_sysmem(addr
, SIG_HEADER_LEN
);
227 log_err("ERROR: can't map first header\n");
232 header_size
= fdt32_to_cpu(sig_header
->header_size
);
233 offset_img_sig
= fdt32_to_cpu(sig_header
->offset_img_sig
);
235 header
= (void *)map_sysmem(addr
, header_size
);
237 log_err("ERROR: can't map header\n");
242 sha256_csum_wd(header
+ offset_img_sig
, info
->sig_size
,
243 sha256_img_sig
, CHUNKSZ_SHA256
);
245 ret
= memcmp(sig_header
->sha256_img_sig
, sha256_img_sig
, SHA256_SUM_LEN
);
247 log_err("ERROR: sha256 of image signature is invalid\n");
253 unmap_sysmem(header
);
255 unmap_sysmem(sig_header
);
260 static int image_pre_load_sig_check_img_sig(struct image_sig_info
*info
, ulong addr
)
262 struct sig_header_s
*sig_header
;
263 u32 header_size
, image_size
, offset_img_sig
;
265 struct image_region reg
;
270 sig_header
= (struct sig_header_s
*)map_sysmem(addr
, SIG_HEADER_LEN
);
272 log_err("ERROR: can't map first header\n");
277 header_size
= fdt32_to_cpu(sig_header
->header_size
);
278 image_size
= fdt32_to_cpu(sig_header
->image_size
);
279 offset_img_sig
= fdt32_to_cpu(sig_header
->offset_img_sig
);
281 unmap_sysmem(sig_header
);
283 image
= (void *)map_sysmem(addr
, header_size
+ image_size
);
285 log_err("ERROR: can't map full image\n");
290 reg
.data
= image
+ header_size
;
291 reg
.size
= image_size
;
293 sig
= (uint8_t *)image
+ offset_img_sig
;
294 sig_len
= info
->sig_size
;
296 ret
= info
->sig_info
.crypto
->verify(&info
->sig_info
, ®
, 1, sig
, sig_len
);
298 log_err("ERROR: signature check has failed (err=%d)\n", ret
);
300 goto out_unmap_image
;
303 log_info("INFO: signature check has succeed\n");
312 int image_pre_load_sig(ulong addr
)
314 struct image_sig_info info
;
317 ret
= image_pre_load_sig_setup(&info
);
325 ret
= image_pre_load_sig_check_magic(&info
, addr
);
333 /* Check the signature of the signature header */
334 ret
= image_pre_load_sig_check_header_sig(&info
, addr
);
338 /* Check sha256 of the image signature */
339 ret
= image_pre_load_sig_check_img_sig_sha256(&info
, addr
);
343 /* Check the image signature */
344 ret
= image_pre_load_sig_check_img_sig(&info
, addr
);
348 ret
= image_pre_load_sig_get_header_size(addr
, &header_size
);
350 log_err("%s: can't get header size\n", __func__
);
355 image_load_offset
+= header_size
;
362 int image_pre_load(ulong addr
)
366 image_load_offset
= 0;
368 if (CONFIG_IS_ENABLED(IMAGE_PRE_LOAD_SIG
))
369 ret
= image_pre_load_sig(addr
);