xref: /rk3399_ARM-atf/plat/arm/board/common/board_arm_trusted_boot.c (revision 09d40e0e08283a249e7dce0e106c07c5141f9b7e)
1 /*
2  * Copyright (c) 2015-2017, 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 <lib/cassert.h>
12 #include <plat/common/platform.h>
13 #include <tools_share/tbbr_oid.h>
14 
15 #include <arm_def.h>
16 
17 /* SHA256 algorithm */
18 #define SHA256_BYTES			32
19 
20 /* ROTPK locations */
21 #define ARM_ROTPK_REGS_ID		1
22 #define ARM_ROTPK_DEVEL_RSA_ID		2
23 #define ARM_ROTPK_DEVEL_ECDSA_ID	3
24 
25 static const unsigned char rotpk_hash_hdr[] =		\
26 		"\x30\x31\x30\x0D\x06\x09\x60\x86\x48"	\
27 		"\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
28 static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1;
29 static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES];
30 
31 /* Use the cryptocell variants if Cryptocell is present */
32 #if !ARM_CRYPTOCELL_INTEG
33 #if !ARM_ROTPK_LOCATION_ID
34   #error "ARM_ROTPK_LOCATION_ID not defined"
35 #endif
36 
37 /* Weak definition may be overridden in specific platform */
38 #pragma weak plat_get_nv_ctr
39 #pragma weak plat_set_nv_ctr
40 
41 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
42 static const unsigned char arm_devel_rotpk_hash[] =	\
43 		"\xB0\xF3\x82\x09\x12\x97\xD8\x3A"	\
44 		"\x37\x7A\x72\x47\x1B\xEC\x32\x73"	\
45 		"\xE9\x92\x32\xE2\x49\x59\xF6\x5E"	\
46 		"\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA";
47 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
48 static const unsigned char arm_devel_rotpk_hash[] =	\
49 		"\x2E\x40\xBF\x6E\xF9\x12\xBB\x98"	\
50 		"\x31\x71\x09\x0E\x1E\x15\x3D\x0B"	\
51 		"\xFD\xD1\xCC\x69\x4A\x98\xEB\x8B"	\
52 		"\xA0\xB0\x20\x86\x4E\x6C\x07\x17";
53 #endif
54 
55 /*
56  * Return the ROTPK hash in the following ASN.1 structure in DER format:
57  *
58  * AlgorithmIdentifier  ::=  SEQUENCE  {
59  *     algorithm         OBJECT IDENTIFIER,
60  *     parameters        ANY DEFINED BY algorithm OPTIONAL
61  * }
62  *
63  * DigestInfo ::= SEQUENCE {
64  *     digestAlgorithm   AlgorithmIdentifier,
65  *     digest            OCTET STRING
66  * }
67  */
68 int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
69 			unsigned int *flags)
70 {
71 	uint8_t *dst;
72 
73 	assert(key_ptr != NULL);
74 	assert(key_len != NULL);
75 	assert(flags != NULL);
76 
77 	/* Copy the DER header */
78 	memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
79 	dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len];
80 
81 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
82 	|| (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
83 	memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES);
84 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
85 	uint32_t *src, tmp;
86 	unsigned int words, i;
87 
88 	/*
89 	 * Append the hash from Trusted Root-Key Storage registers. The hash has
90 	 * not been written linearly into the registers, so we have to do a bit
91 	 * of byte swapping:
92 	 *
93 	 *     0x00    0x04    0x08    0x0C    0x10    0x14    0x18    0x1C
94 	 * +---------------------------------------------------------------+
95 	 * | Reg0  | Reg1  | Reg2  | Reg3  | Reg4  | Reg5  | Reg6  | Reg7  |
96 	 * +---------------------------------------------------------------+
97 	 *  | ...                    ... |   | ...                   ...  |
98 	 *  |       +--------------------+   |                    +-------+
99 	 *  |       |                        |                    |
100 	 *  +----------------------------+   +----------------------------+
101 	 *          |                    |                        |       |
102 	 *  +-------+                    |   +--------------------+       |
103 	 *  |                            |   |                            |
104 	 *  v                            v   v                            v
105 	 * +---------------------------------------------------------------+
106 	 * |                               |                               |
107 	 * +---------------------------------------------------------------+
108 	 *  0                           15  16                           31
109 	 *
110 	 * Additionally, we have to access the registers in 32-bit words
111 	 */
112 	words = SHA256_BYTES >> 3;
113 
114 	/* Swap bytes 0-15 (first four registers) */
115 	src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
116 	for (i = 0 ; i < words ; i++) {
117 		tmp = src[words - 1 - i];
118 		/* Words are read in little endian */
119 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
120 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
121 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
122 		*dst++ = (uint8_t)(tmp & 0xFF);
123 	}
124 
125 	/* Swap bytes 16-31 (last four registers) */
126 	src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2);
127 	for (i = 0 ; i < words ; i++) {
128 		tmp = src[words - 1 - i];
129 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
130 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
131 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
132 		*dst++ = (uint8_t)(tmp & 0xFF);
133 	}
134 #endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
135 		  || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) */
136 
137 	*key_ptr = (void *)rotpk_hash_der;
138 	*key_len = (unsigned int)sizeof(rotpk_hash_der);
139 	*flags = ROTPK_IS_HASH;
140 	return 0;
141 }
142 
143 /*
144  * Return the non-volatile counter value stored in the platform. The cookie
145  * will contain the OID of the counter in the certificate.
146  *
147  * Return: 0 = success, Otherwise = error
148  */
149 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
150 {
151 	const char *oid;
152 	uint32_t *nv_ctr_addr;
153 
154 	assert(cookie != NULL);
155 	assert(nv_ctr != NULL);
156 
157 	oid = (const char *)cookie;
158 	if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
159 		nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE;
160 	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
161 		nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE;
162 	} else {
163 		return 1;
164 	}
165 
166 	*nv_ctr = (unsigned int)(*nv_ctr_addr);
167 
168 	return 0;
169 }
170 
171 /*
172  * Store a new non-volatile counter value. By default on ARM development
173  * platforms, the non-volatile counters are RO and cannot be modified. We expect
174  * the values in the certificates to always match the RO values so that this
175  * function is never called.
176  *
177  * Return: 0 = success, Otherwise = error
178  */
179 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
180 {
181 	return 1;
182 }
183 #else /* ARM_CRYPTOCELL_INTEG */
184 
185 #include <drivers/arm/cryptocell/nvm.h>
186 #include <drivers/arm/cryptocell/nvm_otp.h>
187 #include <drivers/arm/cryptocell/sbrom_bsv_api.h>
188 
189 CASSERT(HASH_RESULT_SIZE_IN_BYTES == SHA256_BYTES,
190 		assert_mismatch_in_hash_result_size);
191 
192 /*
193  * Return the ROTPK hash in the following ASN.1 structure in DER format:
194  *
195  * AlgorithmIdentifier  ::=  SEQUENCE  {
196  *     algorithm         OBJECT IDENTIFIER,
197  *     parameters        ANY DEFINED BY algorithm OPTIONAL
198  * }
199  *
200  * DigestInfo ::= SEQUENCE {
201  *     digestAlgorithm   AlgorithmIdentifier,
202  *     digest            OCTET STRING
203  * }
204  */
205 int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
206 			unsigned int *flags)
207 {
208 	unsigned char *dst;
209 	CCError_t error;
210 	uint32_t lcs;
211 
212 	assert(key_ptr != NULL);
213 	assert(key_len != NULL);
214 	assert(flags != NULL);
215 
216 	error = NVM_GetLCS(PLAT_CRYPTOCELL_BASE, &lcs);
217 	if (error != CC_OK)
218 		return 1;
219 
220 	/* If the lifecycle state is `SD`, return failure */
221 	if (lcs == CC_BSV_SECURITY_DISABLED_LCS)
222 		return 1;
223 
224 	/*
225 	 * If the lifecycle state is `CM` or `DM`, ROTPK shouldn't be verified.
226 	 * Return success after setting ROTPK_NOT_DEPLOYED flag
227 	 */
228 	if ((lcs == CC_BSV_CHIP_MANUFACTURE_LCS) ||
229 			(lcs == CC_BSV_DEVICE_MANUFACTURE_LCS)) {
230 		*key_len = 0;
231 		*flags = ROTPK_NOT_DEPLOYED;
232 		return 0;
233 	}
234 
235 	/* Copy the DER header */
236 	memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
237 	dst = &rotpk_hash_der[rotpk_hash_hdr_len];
238 	error = NVM_ReadHASHPubKey(PLAT_CRYPTOCELL_BASE,
239 			CC_SB_HASH_BOOT_KEY_256B,
240 			(uint32_t *)dst, HASH_RESULT_SIZE_IN_WORDS);
241 	if (error != CC_OK)
242 		return 1;
243 
244 	*key_ptr = rotpk_hash_der;
245 	*key_len = sizeof(rotpk_hash_der);
246 	*flags = ROTPK_IS_HASH;
247 	return 0;
248 }
249 
250 /*
251  * Return the non-volatile counter value stored in the platform. The cookie
252  * specifies the OID of the counter in the certificate.
253  *
254  * Return: 0 = success, Otherwise = error
255  */
256 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
257 {
258 	CCError_t error = CC_FAIL;
259 
260 	if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) {
261 		error = NVM_GetSwVersion(PLAT_CRYPTOCELL_BASE,
262 				CC_SW_VERSION_COUNTER1, nv_ctr);
263 	} else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
264 		error = NVM_GetSwVersion(PLAT_CRYPTOCELL_BASE,
265 				CC_SW_VERSION_COUNTER2, nv_ctr);
266 	}
267 
268 	return (error != CC_OK);
269 }
270 
271 /*
272  * Store a new non-volatile counter value in the counter specified by the OID
273  * in the cookie. This function is not expected to be called if the Lifecycle
274  * state is RMA as the values in the certificate are expected to always match
275  * the nvcounter values. But if called when the LCS is RMA, the underlying
276  * helper functions will return success but without updating the counter.
277  *
278  * Return: 0 = success, Otherwise = error
279  */
280 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
281 {
282 	CCError_t error = CC_FAIL;
283 
284 	if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) {
285 		error = NVM_SetSwVersion(PLAT_CRYPTOCELL_BASE,
286 				CC_SW_VERSION_COUNTER1, nv_ctr);
287 	} else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
288 		error = NVM_SetSwVersion(PLAT_CRYPTOCELL_BASE,
289 				CC_SW_VERSION_COUNTER2, nv_ctr);
290 	}
291 
292 	return (error != CC_OK);
293 }
294 
295 #endif /* ARM_CRYPTOCELL_INTEG */
296