xref: /arm-trusted-firmware/plat/arm/board/common/board_arm_trusted_boot.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu #include <stdint.h>
9*91f16700Schasinglulu #include <string.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu #include <common/debug.h>
12*91f16700Schasinglulu #include <drivers/delay_timer.h>
13*91f16700Schasinglulu #include <lib/cassert.h>
14*91f16700Schasinglulu #include <lib/fconf/fconf.h>
15*91f16700Schasinglulu #include <plat/common/common_def.h>
16*91f16700Schasinglulu #include <plat/common/platform.h>
17*91f16700Schasinglulu #if defined(ARM_COT_cca)
18*91f16700Schasinglulu #include <tools_share/cca_oid.h>
19*91f16700Schasinglulu #elif defined(ARM_COT_dualroot)
20*91f16700Schasinglulu #include <tools_share/dualroot_oid.h>
21*91f16700Schasinglulu #elif defined(ARM_COT_tbbr)
22*91f16700Schasinglulu #include <tools_share/tbbr_oid.h>
23*91f16700Schasinglulu #endif
24*91f16700Schasinglulu 
25*91f16700Schasinglulu #include <plat/arm/common/fconf_nv_cntr_getter.h>
26*91f16700Schasinglulu #include <plat/arm/common/plat_arm.h>
27*91f16700Schasinglulu #include <platform_def.h>
28*91f16700Schasinglulu 
29*91f16700Schasinglulu #if !ARM_ROTPK_LOCATION_ID
30*91f16700Schasinglulu   #error "ARM_ROTPK_LOCATION_ID not defined"
31*91f16700Schasinglulu #endif
32*91f16700Schasinglulu 
33*91f16700Schasinglulu #if COT_DESC_IN_DTB && defined(IMAGE_BL2)
34*91f16700Schasinglulu uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS];
35*91f16700Schasinglulu #else
36*91f16700Schasinglulu uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS] = {
37*91f16700Schasinglulu 	TFW_NVCTR_BASE,
38*91f16700Schasinglulu 	NTFW_CTR_BASE
39*91f16700Schasinglulu };
40*91f16700Schasinglulu #endif
41*91f16700Schasinglulu 
42*91f16700Schasinglulu 
43*91f16700Schasinglulu /* Weak definition may be overridden in specific platform */
44*91f16700Schasinglulu #pragma weak plat_get_nv_ctr
45*91f16700Schasinglulu #pragma weak plat_set_nv_ctr
46*91f16700Schasinglulu 
47*91f16700Schasinglulu extern unsigned char arm_rotpk_header[], arm_rotpk_key[], arm_rotpk_hash_end[],
48*91f16700Schasinglulu        arm_rotpk_key_end[];
49*91f16700Schasinglulu 
50*91f16700Schasinglulu #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
51*91f16700Schasinglulu static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
52*91f16700Schasinglulu #endif
53*91f16700Schasinglulu 
54*91f16700Schasinglulu #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
55*91f16700Schasinglulu /*
56*91f16700Schasinglulu  * Return the ROTPK hash stored in dedicated registers.
57*91f16700Schasinglulu  */
58*91f16700Schasinglulu int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
59*91f16700Schasinglulu 			unsigned int *flags)
60*91f16700Schasinglulu {
61*91f16700Schasinglulu 	uint8_t *dst;
62*91f16700Schasinglulu 	uint32_t *src, tmp;
63*91f16700Schasinglulu 	unsigned int words, i;
64*91f16700Schasinglulu 
65*91f16700Schasinglulu 	assert(key_ptr != NULL);
66*91f16700Schasinglulu 	assert(key_len != NULL);
67*91f16700Schasinglulu 	assert(flags != NULL);
68*91f16700Schasinglulu 
69*91f16700Schasinglulu 	/* Copy the DER header */
70*91f16700Schasinglulu 
71*91f16700Schasinglulu 	memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
72*91f16700Schasinglulu 	dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
73*91f16700Schasinglulu 
74*91f16700Schasinglulu 	words = ARM_ROTPK_HASH_LEN >> 2;
75*91f16700Schasinglulu 
76*91f16700Schasinglulu 	src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
77*91f16700Schasinglulu 	for (i = 0 ; i < words ; i++) {
78*91f16700Schasinglulu 		tmp = src[words - 1 - i];
79*91f16700Schasinglulu 		/* Words are read in little endian */
80*91f16700Schasinglulu 		*dst++ = (uint8_t)(tmp & 0xFF);
81*91f16700Schasinglulu 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
82*91f16700Schasinglulu 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
83*91f16700Schasinglulu 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
84*91f16700Schasinglulu 	}
85*91f16700Schasinglulu 
86*91f16700Schasinglulu 	*key_ptr = (void *)rotpk_hash_der;
87*91f16700Schasinglulu 	*key_len = (unsigned int)sizeof(rotpk_hash_der);
88*91f16700Schasinglulu 	*flags = ROTPK_IS_HASH;
89*91f16700Schasinglulu 	return 0;
90*91f16700Schasinglulu }
91*91f16700Schasinglulu #endif
92*91f16700Schasinglulu 
93*91f16700Schasinglulu #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
94*91f16700Schasinglulu     (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
95*91f16700Schasinglulu int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
96*91f16700Schasinglulu 			unsigned int *flags)
97*91f16700Schasinglulu {
98*91f16700Schasinglulu 	*key_ptr = arm_rotpk_header;
99*91f16700Schasinglulu 	*key_len = arm_rotpk_hash_end - arm_rotpk_header;
100*91f16700Schasinglulu 	*flags = ROTPK_IS_HASH;
101*91f16700Schasinglulu 	return 0;
102*91f16700Schasinglulu }
103*91f16700Schasinglulu #endif
104*91f16700Schasinglulu 
105*91f16700Schasinglulu #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID) || \
106*91f16700Schasinglulu     (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_ECDSA_KEY_ID)
107*91f16700Schasinglulu int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
108*91f16700Schasinglulu 			unsigned int *flags)
109*91f16700Schasinglulu {
110*91f16700Schasinglulu 	*key_ptr = arm_rotpk_key;
111*91f16700Schasinglulu 	*key_len = arm_rotpk_key_end - arm_rotpk_key;
112*91f16700Schasinglulu 	*flags = 0;
113*91f16700Schasinglulu 	return 0;
114*91f16700Schasinglulu }
115*91f16700Schasinglulu #endif
116*91f16700Schasinglulu 
117*91f16700Schasinglulu /*
118*91f16700Schasinglulu  * Wrapper function for most Arm platforms to get ROTPK info.
119*91f16700Schasinglulu  */
120*91f16700Schasinglulu static int get_rotpk_info(void **key_ptr, unsigned int *key_len,
121*91f16700Schasinglulu 				unsigned int *flags)
122*91f16700Schasinglulu {
123*91f16700Schasinglulu #if ARM_USE_DEVEL_ROTPK
124*91f16700Schasinglulu 	return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
125*91f16700Schasinglulu #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
126*91f16700Schasinglulu 	return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
127*91f16700Schasinglulu #else
128*91f16700Schasinglulu 	return 1;
129*91f16700Schasinglulu #endif
130*91f16700Schasinglulu }
131*91f16700Schasinglulu 
132*91f16700Schasinglulu #if defined(ARM_COT_tbbr)
133*91f16700Schasinglulu 
134*91f16700Schasinglulu int arm_get_rotpk_info(void *cookie __unused, void **key_ptr,
135*91f16700Schasinglulu 		       unsigned int *key_len, unsigned int *flags)
136*91f16700Schasinglulu {
137*91f16700Schasinglulu 	return get_rotpk_info(key_ptr, key_len, flags);
138*91f16700Schasinglulu }
139*91f16700Schasinglulu 
140*91f16700Schasinglulu #elif defined(ARM_COT_dualroot)
141*91f16700Schasinglulu 
142*91f16700Schasinglulu int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
143*91f16700Schasinglulu 		       unsigned int *flags)
144*91f16700Schasinglulu {
145*91f16700Schasinglulu 	/*
146*91f16700Schasinglulu 	 * Return the right root of trust key hash based on the cookie value:
147*91f16700Schasinglulu 	 *  - NULL means the primary ROTPK.
148*91f16700Schasinglulu 	 *  - Otherwise, interpret cookie as the OID of the certificate
149*91f16700Schasinglulu 	 *    extension containing the key.
150*91f16700Schasinglulu 	 */
151*91f16700Schasinglulu 	if (cookie == NULL) {
152*91f16700Schasinglulu 		return get_rotpk_info(key_ptr, key_len, flags);
153*91f16700Schasinglulu 	} else if (strcmp(cookie, PROT_PK_OID) == 0) {
154*91f16700Schasinglulu 		extern unsigned char arm_protpk_hash[];
155*91f16700Schasinglulu 		extern unsigned char arm_protpk_hash_end[];
156*91f16700Schasinglulu 		*key_ptr = arm_protpk_hash;
157*91f16700Schasinglulu 		*key_len = arm_protpk_hash_end - arm_protpk_hash;
158*91f16700Schasinglulu 		*flags = ROTPK_IS_HASH;
159*91f16700Schasinglulu 		return 0;
160*91f16700Schasinglulu 	} else {
161*91f16700Schasinglulu 		/* Invalid key ID. */
162*91f16700Schasinglulu 		return 1;
163*91f16700Schasinglulu 	}
164*91f16700Schasinglulu }
165*91f16700Schasinglulu 
166*91f16700Schasinglulu #elif defined(ARM_COT_cca)
167*91f16700Schasinglulu 
168*91f16700Schasinglulu int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
169*91f16700Schasinglulu 		       unsigned int *flags)
170*91f16700Schasinglulu {
171*91f16700Schasinglulu 	/*
172*91f16700Schasinglulu 	 * Return the right root of trust key hash based on the cookie value:
173*91f16700Schasinglulu 	 *  - NULL means the primary ROTPK.
174*91f16700Schasinglulu 	 *  - Otherwise, interpret cookie as the OID of the certificate
175*91f16700Schasinglulu 	 *    extension containing the key.
176*91f16700Schasinglulu 	 */
177*91f16700Schasinglulu 	if (cookie == NULL) {
178*91f16700Schasinglulu 		return get_rotpk_info(key_ptr, key_len, flags);
179*91f16700Schasinglulu 	} else if (strcmp(cookie, PROT_PK_OID) == 0) {
180*91f16700Schasinglulu 		extern unsigned char arm_protpk_hash[];
181*91f16700Schasinglulu 		extern unsigned char arm_protpk_hash_end[];
182*91f16700Schasinglulu 		*key_ptr = arm_protpk_hash;
183*91f16700Schasinglulu 		*key_len = arm_protpk_hash_end - arm_protpk_hash;
184*91f16700Schasinglulu 		*flags = ROTPK_IS_HASH;
185*91f16700Schasinglulu 		return 0;
186*91f16700Schasinglulu 	} else if (strcmp(cookie, SWD_ROT_PK_OID) == 0) {
187*91f16700Schasinglulu 		extern unsigned char arm_swd_rotpk_hash[];
188*91f16700Schasinglulu 		extern unsigned char arm_swd_rotpk_hash_end[];
189*91f16700Schasinglulu 		*key_ptr = arm_swd_rotpk_hash;
190*91f16700Schasinglulu 		*key_len = arm_swd_rotpk_hash_end - arm_swd_rotpk_hash;
191*91f16700Schasinglulu 		*flags = ROTPK_IS_HASH;
192*91f16700Schasinglulu 		return 0;
193*91f16700Schasinglulu 	} else {
194*91f16700Schasinglulu 		/* Invalid key ID. */
195*91f16700Schasinglulu 		return 1;
196*91f16700Schasinglulu 	}
197*91f16700Schasinglulu }
198*91f16700Schasinglulu 
199*91f16700Schasinglulu #endif
200*91f16700Schasinglulu 
201*91f16700Schasinglulu /*
202*91f16700Schasinglulu  * Return the non-volatile counter value stored in the platform. The cookie
203*91f16700Schasinglulu  * will contain the OID of the counter in the certificate.
204*91f16700Schasinglulu  *
205*91f16700Schasinglulu  * Return: 0 = success, Otherwise = error
206*91f16700Schasinglulu  */
207*91f16700Schasinglulu int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
208*91f16700Schasinglulu {
209*91f16700Schasinglulu 	const char *oid;
210*91f16700Schasinglulu 	uint32_t *nv_ctr_addr;
211*91f16700Schasinglulu 
212*91f16700Schasinglulu 	assert(cookie != NULL);
213*91f16700Schasinglulu 	assert(nv_ctr != NULL);
214*91f16700Schasinglulu 
215*91f16700Schasinglulu 	oid = (const char *)cookie;
216*91f16700Schasinglulu 	if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
217*91f16700Schasinglulu 		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
218*91f16700Schasinglulu 							TRUSTED_NV_CTR_ID);
219*91f16700Schasinglulu 	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
220*91f16700Schasinglulu 		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
221*91f16700Schasinglulu 							NON_TRUSTED_NV_CTR_ID);
222*91f16700Schasinglulu 	} else {
223*91f16700Schasinglulu 		return 1;
224*91f16700Schasinglulu 	}
225*91f16700Schasinglulu 
226*91f16700Schasinglulu 	*nv_ctr = (unsigned int)(*nv_ctr_addr);
227*91f16700Schasinglulu 
228*91f16700Schasinglulu 	return 0;
229*91f16700Schasinglulu }
230*91f16700Schasinglulu 
231*91f16700Schasinglulu /*
232*91f16700Schasinglulu  * Store a new non-volatile counter value. By default on ARM development
233*91f16700Schasinglulu  * platforms, the non-volatile counters are RO and cannot be modified. We expect
234*91f16700Schasinglulu  * the values in the certificates to always match the RO values so that this
235*91f16700Schasinglulu  * function is never called.
236*91f16700Schasinglulu  *
237*91f16700Schasinglulu  * Return: 0 = success, Otherwise = error
238*91f16700Schasinglulu  */
239*91f16700Schasinglulu int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
240*91f16700Schasinglulu {
241*91f16700Schasinglulu 	return 1;
242*91f16700Schasinglulu }
243