1 /*
2  * Copyright (c) 2022, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include <assert.h>
7 #include <stdint.h>
8 #include <string.h>
9 
10 #include <common/debug.h>
11 #include <drivers/auth/crypto_mod.h>
12 #include <drivers/measured_boot/rss/rss_measured_boot.h>
13 #include <lib/psa/measured_boot.h>
14 #include <psa/crypto_types.h>
15 #include <psa/crypto_values.h>
16 #include <psa/error.h>
17 
18 #define MBOOT_ALG_SHA512 0
19 #define MBOOT_ALG_SHA384 1
20 #define MBOOT_ALG_SHA256 2
21 
22 #if MBOOT_ALG_ID == MBOOT_ALG_SHA512
23 #define	CRYPTO_MD_ID		CRYPTO_MD_SHA512
24 #define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_512
25 #elif MBOOT_ALG_ID == MBOOT_ALG_SHA384
26 #define	CRYPTO_MD_ID		CRYPTO_MD_SHA384
27 #define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_384
28 #elif MBOOT_ALG_ID == MBOOT_ALG_SHA256
29 #define	CRYPTO_MD_ID		CRYPTO_MD_SHA256
30 #define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_256
31 #else
32 #  error Invalid Measured Boot algorithm.
33 #endif /* MBOOT_ALG_ID */
34 
35 /* Pointer to struct rss_mboot_metadata */
36 static struct rss_mboot_metadata *plat_metadata_ptr;
37 
38 /* Functions' declarations */
rss_measured_boot_init(void)39 void rss_measured_boot_init(void)
40 {
41 	/* At this point it is expected that communication channel over MHU
42 	 * is already initialised by platform init.
43 	 */
44 	struct rss_mboot_metadata *metadata_ptr;
45 
46 	/* Get pointer to platform's struct rss_mboot_metadata structure */
47 	plat_metadata_ptr = plat_rss_mboot_get_metadata();
48 	assert(plat_metadata_ptr != NULL);
49 
50 	/* Use a local variable to preserve the value of the global pointer */
51 	metadata_ptr = plat_metadata_ptr;
52 
53 	/* Init the non-const members of the metadata structure */
54 	while (metadata_ptr->id != RSS_MBOOT_INVALID_ID) {
55 		metadata_ptr->sw_type_size =
56 			strlen((const char *)&metadata_ptr->sw_type) + 1;
57 		metadata_ptr++;
58 	}
59 }
60 
rss_mboot_measure_and_record(uintptr_t data_base,uint32_t data_size,uint32_t data_id)61 int rss_mboot_measure_and_record(uintptr_t data_base, uint32_t data_size,
62 				 uint32_t data_id)
63 {
64 	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
65 	int rc;
66 	psa_status_t ret;
67 	const struct rss_mboot_metadata *metadata_ptr = plat_metadata_ptr;
68 
69 	/* Get the metadata associated with this image. */
70 	while ((metadata_ptr->id != RSS_MBOOT_INVALID_ID) &&
71 		(metadata_ptr->id != data_id)) {
72 		metadata_ptr++;
73 	}
74 
75 	/* If image is not present in metadata array then skip */
76 	if (metadata_ptr->id == RSS_MBOOT_INVALID_ID) {
77 		return 0;
78 	}
79 
80 	/* Calculate hash */
81 	rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
82 				  (void *)data_base, data_size, hash_data);
83 	if (rc != 0) {
84 		return rc;
85 	}
86 
87 	ret = rss_measured_boot_extend_measurement(
88 						metadata_ptr->slot,
89 						metadata_ptr->signer_id,
90 						metadata_ptr->signer_id_size,
91 						metadata_ptr->version,
92 						metadata_ptr->version_size,
93 						PSA_CRYPTO_MD_ID,
94 						metadata_ptr->sw_type,
95 						metadata_ptr->sw_type_size,
96 						hash_data,
97 						MBOOT_DIGEST_SIZE,
98 						metadata_ptr->lock_measurement);
99 	if (ret != PSA_SUCCESS) {
100 		return ret;
101 	}
102 
103 	return 0;
104 }
105 
rss_mboot_set_signer_id(unsigned int img_id,const void * pk_ptr,size_t pk_len)106 int rss_mboot_set_signer_id(unsigned int img_id,
107 			    const void *pk_ptr,
108 			    size_t pk_len)
109 {
110 	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
111 	struct rss_mboot_metadata *metadata_ptr = plat_metadata_ptr;
112 	int rc;
113 
114 	/* Get the metadata associated with this image. */
115 	while ((metadata_ptr->id != RSS_MBOOT_INVALID_ID) &&
116 		(metadata_ptr->id != img_id)) {
117 		metadata_ptr++;
118 	}
119 
120 	/* If image is not present in metadata array then skip */
121 	if (metadata_ptr->id == RSS_MBOOT_INVALID_ID) {
122 		return 0;
123 	}
124 
125 	/* Calculate public key hash */
126 	rc = crypto_mod_calc_hash(CRYPTO_MD_ID, (void *)pk_ptr,
127 				  pk_len, hash_data);
128 	if (rc != 0) {
129 		return rc;
130 	}
131 
132 	/* Update metadata struct with the received signer_id */
133 	(void)memcpy(metadata_ptr->signer_id, hash_data, MBOOT_DIGEST_SIZE);
134 	metadata_ptr->signer_id_size = MBOOT_DIGEST_SIZE;
135 
136 	return 0;
137 }
138