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