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