1 /*
2  * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <errno.h>
8 
9 #include <platform_def.h>
10 
11 #include <common/debug.h>
12 #include <drivers/io/io_storage.h>
13 #include <drivers/st/bsec.h>
14 #include <drivers/st/stm32_hash.h>
15 #include <lib/xlat_tables/xlat_tables_v2.h>
16 #include <plat/common/platform.h>
17 
18 static const struct stm32mp_auth_ops *auth_ops;
19 
stm32mp_init_auth(struct stm32mp_auth_ops * init_ptr)20 void stm32mp_init_auth(struct stm32mp_auth_ops *init_ptr)
21 {
22 	if ((init_ptr == NULL) ||
23 	    (init_ptr->check_key == NULL) ||
24 	    (init_ptr->verify_signature == NULL) ||
25 	    (stm32_hash_register() != 0)) {
26 		panic();
27 	}
28 
29 	auth_ops = init_ptr;
30 }
31 
stm32mp_auth_image(boot_api_image_header_t * header,uintptr_t buffer)32 int stm32mp_auth_image(boot_api_image_header_t *header, uintptr_t buffer)
33 {
34 	int ret;
35 	uint8_t image_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES];
36 	uint32_t header_skip_cksum = sizeof(header->magic) +
37 				     sizeof(header->image_signature) +
38 				     sizeof(header->payload_checksum);
39 
40 	/* Check Security Status */
41 	if (!stm32mp_is_closed_device()) {
42 		if (header->option_flags != 0U) {
43 			WARN("Skip signature check (header option)\n");
44 			return 0;
45 		}
46 		INFO("Check signature on Open device\n");
47 	}
48 
49 	ret = mmap_add_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_BASE,
50 				      STM32MP_ROM_SIZE, MT_CODE | MT_SECURE);
51 	if (ret != 0) {
52 		return ret;
53 	}
54 
55 	/* Check Public Key */
56 	if (auth_ops->check_key(header->ecc_pubk, NULL) != BOOT_API_RETURN_OK) {
57 		ret = -EINVAL;
58 		goto err;
59 	}
60 
61 	/* Compute end of header hash and payload hash */
62 	stm32_hash_init(HASH_SHA256);
63 
64 	ret = stm32_hash_update((uint8_t *)&header->header_version,
65 				sizeof(boot_api_image_header_t) -
66 				header_skip_cksum);
67 	if (ret != 0) {
68 		ERROR("Hash of header failed, %i\n", ret);
69 		goto err;
70 	}
71 
72 	ret = stm32_hash_final_update((uint8_t *)buffer,
73 			       header->image_length, image_hash);
74 	if (ret != 0) {
75 		ERROR("Hash of payload failed\n");
76 		goto err;
77 	}
78 
79 	/* Verify signature */
80 	if (auth_ops->verify_signature(image_hash, header->ecc_pubk,
81 				       header->image_signature,
82 				       header->ecc_algo_type) !=
83 	    BOOT_API_RETURN_OK) {
84 		ret = -EINVAL;
85 	}
86 
87 err:
88 	mmap_remove_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_SIZE);
89 	return ret;
90 }
91