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