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