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_hash_end[];
51 
52 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) || ARM_CRYPTOCELL_INTEG
53 static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
54 #endif
55 
56 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
57 /*
58  * Return the ROTPK hash stored in dedicated registers.
59  */
arm_get_rotpk_info_regs(void ** key_ptr,unsigned int * key_len,unsigned int * flags)60 int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
61 			unsigned int *flags)
62 {
63 	uint8_t *dst;
64 	uint32_t *src, tmp;
65 	unsigned int words, i;
66 
67 	assert(key_ptr != NULL);
68 	assert(key_len != NULL);
69 	assert(flags != NULL);
70 
71 	/* Copy the DER header */
72 
73 	memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
74 	dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
75 
76 	words = ARM_ROTPK_HASH_LEN >> 2;
77 
78 	src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
79 	for (i = 0 ; i < words ; i++) {
80 		tmp = src[words - 1 - i];
81 		/* Words are read in little endian */
82 		*dst++ = (uint8_t)(tmp & 0xFF);
83 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
84 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
85 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
86 	}
87 
88 	*key_ptr = (void *)rotpk_hash_der;
89 	*key_len = (unsigned int)sizeof(rotpk_hash_der);
90 	*flags = ROTPK_IS_HASH;
91 	return 0;
92 }
93 #endif
94 
95 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
96     (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
97 /*
98  * Return development ROTPK hash generated from ROT_KEY.
99  */
arm_get_rotpk_info_dev(void ** key_ptr,unsigned int * key_len,unsigned int * flags)100 int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
101 			unsigned int *flags)
102 {
103 	*key_ptr = arm_rotpk_header;
104 	*key_len = arm_rotpk_hash_end - arm_rotpk_header;
105 	*flags = ROTPK_IS_HASH;
106 	return 0;
107 }
108 #endif
109 
110 #if ARM_CRYPTOCELL_INTEG
111 /*
112  * Return ROTPK hash from CryptoCell.
113  */
arm_get_rotpk_info_cc(void ** key_ptr,unsigned int * key_len,unsigned int * flags)114 int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len,
115 			unsigned int *flags)
116 {
117 	unsigned char *dst;
118 
119 	assert(key_ptr != NULL);
120 	assert(key_len != NULL);
121 	assert(flags != NULL);
122 
123 	/* Copy the DER header */
124 	memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
125 	dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
126 	*key_ptr = rotpk_hash_der;
127 	*key_len = sizeof(rotpk_hash_der);
128 	return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags);
129 }
130 #endif
131 
132 /*
133  * Wrapper function for most Arm platforms to get ROTPK hash.
134  */
get_rotpk_info(void ** key_ptr,unsigned int * key_len,unsigned int * flags)135 static int get_rotpk_info(void **key_ptr, unsigned int *key_len,
136 				unsigned int *flags)
137 {
138 #if ARM_CRYPTOCELL_INTEG
139 	return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
140 #else
141 
142 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
143     (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
144 	return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
145 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
146 	return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
147 #else
148 	return 1;
149 #endif
150 #endif /* ARM_CRYPTOCELL_INTEG */
151 }
152 
153 #if defined(ARM_COT_tbbr)
154 
arm_get_rotpk_info(void * cookie __unused,void ** key_ptr,unsigned int * key_len,unsigned int * flags)155 int arm_get_rotpk_info(void *cookie __unused, void **key_ptr,
156 		       unsigned int *key_len, unsigned int *flags)
157 {
158 	return get_rotpk_info(key_ptr, key_len, flags);
159 }
160 
161 #elif defined(ARM_COT_dualroot)
162 
arm_get_rotpk_info(void * cookie,void ** key_ptr,unsigned int * key_len,unsigned int * flags)163 int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
164 		       unsigned int *flags)
165 {
166 	/*
167 	 * Return the right root of trust key hash based on the cookie value:
168 	 *  - NULL means the primary ROTPK.
169 	 *  - Otherwise, interpret cookie as the OID of the certificate
170 	 *    extension containing the key.
171 	 */
172 	if (cookie == NULL) {
173 		return get_rotpk_info(key_ptr, key_len, flags);
174 	} else if (strcmp(cookie, PROT_PK_OID) == 0) {
175 		extern unsigned char arm_protpk_hash[];
176 		extern unsigned char arm_protpk_hash_end[];
177 		*key_ptr = arm_protpk_hash;
178 		*key_len = arm_protpk_hash_end - arm_protpk_hash;
179 		*flags = ROTPK_IS_HASH;
180 		return 0;
181 	} else {
182 		/* Invalid key ID. */
183 		return 1;
184 	}
185 }
186 
187 #elif defined(ARM_COT_cca)
188 
arm_get_rotpk_info(void * cookie,void ** key_ptr,unsigned int * key_len,unsigned int * flags)189 int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
190 		       unsigned int *flags)
191 {
192 	/*
193 	 * Return the right root of trust key hash based on the cookie value:
194 	 *  - NULL means the primary ROTPK.
195 	 *  - Otherwise, interpret cookie as the OID of the certificate
196 	 *    extension containing the key.
197 	 */
198 	if (cookie == NULL) {
199 		return get_rotpk_info(key_ptr, key_len, flags);
200 	} else if (strcmp(cookie, PROT_PK_OID) == 0) {
201 		extern unsigned char arm_protpk_hash[];
202 		extern unsigned char arm_protpk_hash_end[];
203 		*key_ptr = arm_protpk_hash;
204 		*key_len = arm_protpk_hash_end - arm_protpk_hash;
205 		*flags = ROTPK_IS_HASH;
206 		return 0;
207 	} else if (strcmp(cookie, SWD_ROT_PK_OID) == 0) {
208 		extern unsigned char arm_swd_rotpk_hash[];
209 		extern unsigned char arm_swd_rotpk_hash_end[];
210 		*key_ptr = arm_swd_rotpk_hash;
211 		*key_len = arm_swd_rotpk_hash_end - arm_swd_rotpk_hash;
212 		*flags = ROTPK_IS_HASH;
213 		return 0;
214 	} else {
215 		/* Invalid key ID. */
216 		return 1;
217 	}
218 }
219 
220 #endif
221 
222 /*
223  * Return the non-volatile counter value stored in the platform. The cookie
224  * will contain the OID of the counter in the certificate.
225  *
226  * Return: 0 = success, Otherwise = error
227  */
plat_get_nv_ctr(void * cookie,unsigned int * nv_ctr)228 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
229 {
230 	const char *oid;
231 	uint32_t *nv_ctr_addr;
232 
233 	assert(cookie != NULL);
234 	assert(nv_ctr != NULL);
235 
236 	oid = (const char *)cookie;
237 	if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
238 		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
239 							TRUSTED_NV_CTR_ID);
240 	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
241 		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
242 							NON_TRUSTED_NV_CTR_ID);
243 	} else {
244 		return 1;
245 	}
246 
247 	*nv_ctr = (unsigned int)(*nv_ctr_addr);
248 
249 	return 0;
250 }
251 
252 /*
253  * Store a new non-volatile counter value. By default on ARM development
254  * platforms, the non-volatile counters are RO and cannot be modified. We expect
255  * the values in the certificates to always match the RO values so that this
256  * function is never called.
257  *
258  * Return: 0 = success, Otherwise = error
259  */
plat_set_nv_ctr(void * cookie,unsigned int nv_ctr)260 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
261 {
262 	return 1;
263 }
264