xref: /arm-trusted-firmware/lib/psa/measured_boot.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2022, Arm Limited. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  *
6*91f16700Schasinglulu  */
7*91f16700Schasinglulu 
8*91f16700Schasinglulu #include <string.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <common/debug.h>
11*91f16700Schasinglulu #include <measured_boot.h>
12*91f16700Schasinglulu #include <psa/client.h>
13*91f16700Schasinglulu #include <psa_manifest/sid.h>
14*91f16700Schasinglulu 
15*91f16700Schasinglulu #include "measured_boot_private.h"
16*91f16700Schasinglulu 
17*91f16700Schasinglulu static void print_byte_array(const uint8_t *array __unused, size_t len __unused)
18*91f16700Schasinglulu {
19*91f16700Schasinglulu #if LOG_LEVEL >= LOG_LEVEL_INFO
20*91f16700Schasinglulu 	size_t i;
21*91f16700Schasinglulu 
22*91f16700Schasinglulu 	if (array == NULL || len == 0U) {
23*91f16700Schasinglulu 		(void)printf("\n");
24*91f16700Schasinglulu 	} else {
25*91f16700Schasinglulu 		for (i = 0U; i < len; ++i) {
26*91f16700Schasinglulu 			(void)printf(" %02x", array[i]);
27*91f16700Schasinglulu 			if ((i & U(0xF)) == U(0xF)) {
28*91f16700Schasinglulu 				(void)printf("\n");
29*91f16700Schasinglulu 				if (i < (len - 1U)) {
30*91f16700Schasinglulu 					INFO("\t\t:");
31*91f16700Schasinglulu 				}
32*91f16700Schasinglulu 			}
33*91f16700Schasinglulu 		}
34*91f16700Schasinglulu 	}
35*91f16700Schasinglulu #endif
36*91f16700Schasinglulu }
37*91f16700Schasinglulu 
38*91f16700Schasinglulu static void log_measurement(uint8_t index,
39*91f16700Schasinglulu 			    const uint8_t *signer_id,
40*91f16700Schasinglulu 			    size_t signer_id_size,
41*91f16700Schasinglulu 			    const uint8_t *version,     /* string */
42*91f16700Schasinglulu 			    size_t version_size,
43*91f16700Schasinglulu 			    const uint8_t *sw_type,     /* string */
44*91f16700Schasinglulu 			    size_t sw_type_size,
45*91f16700Schasinglulu 			    uint32_t measurement_algo,
46*91f16700Schasinglulu 			    const uint8_t *measurement_value,
47*91f16700Schasinglulu 			    size_t measurement_value_size,
48*91f16700Schasinglulu 			    bool lock_measurement)
49*91f16700Schasinglulu {
50*91f16700Schasinglulu 	INFO("Measured boot extend measurement:\n");
51*91f16700Schasinglulu 	INFO(" - slot        : %u\n", index);
52*91f16700Schasinglulu 	INFO(" - signer_id   :");
53*91f16700Schasinglulu 	print_byte_array(signer_id, signer_id_size);
54*91f16700Schasinglulu 	INFO(" - version     : %s\n",  version);
55*91f16700Schasinglulu 	INFO(" - version_size: %zu\n", version_size);
56*91f16700Schasinglulu 	INFO(" - sw_type     : %s\n",  sw_type);
57*91f16700Schasinglulu 	INFO(" - sw_type_size: %zu\n", sw_type_size);
58*91f16700Schasinglulu 	INFO(" - algorithm   : %x\n", measurement_algo);
59*91f16700Schasinglulu 	INFO(" - measurement :");
60*91f16700Schasinglulu 	print_byte_array(measurement_value, measurement_value_size);
61*91f16700Schasinglulu 	INFO(" - locking     : %s\n", lock_measurement ? "true" : "false");
62*91f16700Schasinglulu }
63*91f16700Schasinglulu 
64*91f16700Schasinglulu #if !PLAT_RSS_NOT_SUPPORTED
65*91f16700Schasinglulu psa_status_t
66*91f16700Schasinglulu rss_measured_boot_extend_measurement(uint8_t index,
67*91f16700Schasinglulu 				     const uint8_t *signer_id,
68*91f16700Schasinglulu 				     size_t signer_id_size,
69*91f16700Schasinglulu 				     const uint8_t *version,
70*91f16700Schasinglulu 				     size_t version_size,
71*91f16700Schasinglulu 				     uint32_t measurement_algo,
72*91f16700Schasinglulu 				     const uint8_t *sw_type,
73*91f16700Schasinglulu 				     size_t sw_type_size,
74*91f16700Schasinglulu 				     const uint8_t *measurement_value,
75*91f16700Schasinglulu 				     size_t measurement_value_size,
76*91f16700Schasinglulu 				     bool lock_measurement)
77*91f16700Schasinglulu {
78*91f16700Schasinglulu 	struct measured_boot_extend_iovec_t extend_iov = {
79*91f16700Schasinglulu 		.index = index,
80*91f16700Schasinglulu 		.lock_measurement = lock_measurement,
81*91f16700Schasinglulu 		.measurement_algo = measurement_algo,
82*91f16700Schasinglulu 		.sw_type = {0},
83*91f16700Schasinglulu 		.sw_type_size = sw_type_size,
84*91f16700Schasinglulu 	};
85*91f16700Schasinglulu 
86*91f16700Schasinglulu 	if (version_size > VERSION_MAX_SIZE) {
87*91f16700Schasinglulu 		return PSA_ERROR_INVALID_ARGUMENT;
88*91f16700Schasinglulu 	}
89*91f16700Schasinglulu 
90*91f16700Schasinglulu 
91*91f16700Schasinglulu 	if (version_size > 0 && version[version_size - 1] == '\0') {
92*91f16700Schasinglulu 		version_size--;
93*91f16700Schasinglulu 	}
94*91f16700Schasinglulu 
95*91f16700Schasinglulu 	psa_invec in_vec[] = {
96*91f16700Schasinglulu 		{.base = &extend_iov,
97*91f16700Schasinglulu 			.len = sizeof(struct measured_boot_extend_iovec_t)},
98*91f16700Schasinglulu 		{.base = signer_id, .len = signer_id_size},
99*91f16700Schasinglulu 		{.base = version, .len = version_size },
100*91f16700Schasinglulu 		{.base = measurement_value, .len = measurement_value_size}
101*91f16700Schasinglulu 	};
102*91f16700Schasinglulu 
103*91f16700Schasinglulu 	if (sw_type != NULL) {
104*91f16700Schasinglulu 		if (extend_iov.sw_type_size > SW_TYPE_MAX_SIZE) {
105*91f16700Schasinglulu 			return PSA_ERROR_INVALID_ARGUMENT;
106*91f16700Schasinglulu 		}
107*91f16700Schasinglulu 		if (sw_type_size > 0 && sw_type[sw_type_size - 1] == '\0') {
108*91f16700Schasinglulu 			extend_iov.sw_type_size--;
109*91f16700Schasinglulu 		}
110*91f16700Schasinglulu 		memcpy(extend_iov.sw_type, sw_type, extend_iov.sw_type_size);
111*91f16700Schasinglulu 	}
112*91f16700Schasinglulu 
113*91f16700Schasinglulu 	log_measurement(index, signer_id, signer_id_size,
114*91f16700Schasinglulu 			version, version_size, sw_type, sw_type_size,
115*91f16700Schasinglulu 			measurement_algo, measurement_value,
116*91f16700Schasinglulu 			measurement_value_size, lock_measurement);
117*91f16700Schasinglulu 
118*91f16700Schasinglulu 	return psa_call(RSS_MEASURED_BOOT_HANDLE,
119*91f16700Schasinglulu 			RSS_MEASURED_BOOT_EXTEND,
120*91f16700Schasinglulu 			in_vec, IOVEC_LEN(in_vec),
121*91f16700Schasinglulu 			NULL, 0);
122*91f16700Schasinglulu }
123*91f16700Schasinglulu 
124*91f16700Schasinglulu psa_status_t rss_measured_boot_read_measurement(uint8_t index,
125*91f16700Schasinglulu 					uint8_t *signer_id,
126*91f16700Schasinglulu 					size_t signer_id_size,
127*91f16700Schasinglulu 					size_t *signer_id_len,
128*91f16700Schasinglulu 					uint8_t *version,
129*91f16700Schasinglulu 					size_t version_size,
130*91f16700Schasinglulu 					size_t *version_len,
131*91f16700Schasinglulu 					uint32_t *measurement_algo,
132*91f16700Schasinglulu 					uint8_t *sw_type,
133*91f16700Schasinglulu 					size_t sw_type_size,
134*91f16700Schasinglulu 					size_t *sw_type_len,
135*91f16700Schasinglulu 					uint8_t *measurement_value,
136*91f16700Schasinglulu 					size_t measurement_value_size,
137*91f16700Schasinglulu 					size_t *measurement_value_len,
138*91f16700Schasinglulu 					bool *is_locked)
139*91f16700Schasinglulu {
140*91f16700Schasinglulu 	psa_status_t status;
141*91f16700Schasinglulu 	struct measured_boot_read_iovec_in_t read_iov_in = {
142*91f16700Schasinglulu 		.index = index,
143*91f16700Schasinglulu 		.sw_type_size = sw_type_size,
144*91f16700Schasinglulu 		.version_size = version_size,
145*91f16700Schasinglulu 	};
146*91f16700Schasinglulu 
147*91f16700Schasinglulu 	struct measured_boot_read_iovec_out_t read_iov_out;
148*91f16700Schasinglulu 
149*91f16700Schasinglulu 	psa_invec in_vec[] = {
150*91f16700Schasinglulu 		{.base = &read_iov_in,
151*91f16700Schasinglulu 		 .len = sizeof(struct measured_boot_read_iovec_in_t)},
152*91f16700Schasinglulu 	};
153*91f16700Schasinglulu 
154*91f16700Schasinglulu 	psa_outvec out_vec[] = {
155*91f16700Schasinglulu 		{.base = &read_iov_out,
156*91f16700Schasinglulu 		 .len = sizeof(struct measured_boot_read_iovec_out_t)},
157*91f16700Schasinglulu 		{.base = signer_id, .len = signer_id_size},
158*91f16700Schasinglulu 		{.base = measurement_value, .len = measurement_value_size}
159*91f16700Schasinglulu 	};
160*91f16700Schasinglulu 
161*91f16700Schasinglulu 	status = psa_call(RSS_MEASURED_BOOT_HANDLE, RSS_MEASURED_BOOT_READ,
162*91f16700Schasinglulu 					  in_vec, IOVEC_LEN(in_vec),
163*91f16700Schasinglulu 					  out_vec, IOVEC_LEN(out_vec));
164*91f16700Schasinglulu 
165*91f16700Schasinglulu 	if (status == PSA_SUCCESS) {
166*91f16700Schasinglulu 		*is_locked = read_iov_out.is_locked;
167*91f16700Schasinglulu 		*measurement_algo = read_iov_out.measurement_algo;
168*91f16700Schasinglulu 		*sw_type_len = read_iov_out.sw_type_len;
169*91f16700Schasinglulu 		*version_len = read_iov_out.version_len;
170*91f16700Schasinglulu 		memcpy(sw_type, read_iov_out.sw_type, read_iov_out.sw_type_len);
171*91f16700Schasinglulu 		memcpy(version, read_iov_out.version, read_iov_out.version_len);
172*91f16700Schasinglulu 		*signer_id_len = out_vec[1].len;
173*91f16700Schasinglulu 		*measurement_value_len = out_vec[2].len;
174*91f16700Schasinglulu 	}
175*91f16700Schasinglulu 
176*91f16700Schasinglulu 	return status;
177*91f16700Schasinglulu }
178*91f16700Schasinglulu 
179*91f16700Schasinglulu #else /* !PLAT_RSS_NOT_SUPPORTED */
180*91f16700Schasinglulu 
181*91f16700Schasinglulu psa_status_t
182*91f16700Schasinglulu rss_measured_boot_extend_measurement(uint8_t index,
183*91f16700Schasinglulu 				     const uint8_t *signer_id,
184*91f16700Schasinglulu 				     size_t signer_id_size,
185*91f16700Schasinglulu 				     const uint8_t *version,
186*91f16700Schasinglulu 				     size_t version_size,
187*91f16700Schasinglulu 				     uint32_t measurement_algo,
188*91f16700Schasinglulu 				     const uint8_t *sw_type,
189*91f16700Schasinglulu 				     size_t sw_type_size,
190*91f16700Schasinglulu 				     const uint8_t *measurement_value,
191*91f16700Schasinglulu 				     size_t measurement_value_size,
192*91f16700Schasinglulu 				     bool lock_measurement)
193*91f16700Schasinglulu {
194*91f16700Schasinglulu 	log_measurement(index, signer_id, signer_id_size,
195*91f16700Schasinglulu 			version, version_size, sw_type, sw_type_size,
196*91f16700Schasinglulu 			measurement_algo, measurement_value,
197*91f16700Schasinglulu 			measurement_value_size, lock_measurement);
198*91f16700Schasinglulu 
199*91f16700Schasinglulu 	return PSA_SUCCESS;
200*91f16700Schasinglulu }
201*91f16700Schasinglulu 
202*91f16700Schasinglulu psa_status_t rss_measured_boot_read_measurement(uint8_t index,
203*91f16700Schasinglulu 					uint8_t *signer_id,
204*91f16700Schasinglulu 					size_t signer_id_size,
205*91f16700Schasinglulu 					size_t *signer_id_len,
206*91f16700Schasinglulu 					uint8_t *version,
207*91f16700Schasinglulu 					size_t version_size,
208*91f16700Schasinglulu 					size_t *version_len,
209*91f16700Schasinglulu 					uint32_t *measurement_algo,
210*91f16700Schasinglulu 					uint8_t *sw_type,
211*91f16700Schasinglulu 					size_t sw_type_size,
212*91f16700Schasinglulu 					size_t *sw_type_len,
213*91f16700Schasinglulu 					uint8_t *measurement_value,
214*91f16700Schasinglulu 					size_t measurement_value_size,
215*91f16700Schasinglulu 					size_t *measurement_value_len,
216*91f16700Schasinglulu 					bool *is_locked)
217*91f16700Schasinglulu {
218*91f16700Schasinglulu 	return PSA_SUCCESS;
219*91f16700Schasinglulu }
220*91f16700Schasinglulu 
221*91f16700Schasinglulu #endif /* !PLAT_RSS_NOT_SUPPORTED */
222