xref: /rk3399_ARM-atf/plat/arm/board/common/board_arm_trusted_boot.c (revision 7af195e29a4213eefac0661d84e1c9c20476e166)
1 /*
2  * Copyright (c) 2015-2019, 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 #include <platform_def.h>
15 
16 /* SHA256 algorithm */
17 #define SHA256_BYTES			32
18 
19 /* ROTPK locations */
20 #define ARM_ROTPK_REGS_ID		1
21 #define ARM_ROTPK_DEVEL_RSA_ID		2
22 #define ARM_ROTPK_DEVEL_ECDSA_ID	3
23 
24 static const unsigned char rotpk_hash_hdr[] =		\
25 		"\x30\x31\x30\x0D\x06\x09\x60\x86\x48"	\
26 		"\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
27 static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1;
28 static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES];
29 
30 /* Use the cryptocell variants if Cryptocell is present */
31 #if !ARM_CRYPTOCELL_INTEG
32 #if !ARM_ROTPK_LOCATION_ID
33   #error "ARM_ROTPK_LOCATION_ID not defined"
34 #endif
35 
36 /* Weak definition may be overridden in specific platform */
37 #pragma weak plat_get_nv_ctr
38 #pragma weak plat_set_nv_ctr
39 
40 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
41 static const unsigned char arm_devel_rotpk_hash[] =	\
42 		"\xB0\xF3\x82\x09\x12\x97\xD8\x3A"	\
43 		"\x37\x7A\x72\x47\x1B\xEC\x32\x73"	\
44 		"\xE9\x92\x32\xE2\x49\x59\xF6\x5E"	\
45 		"\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA";
46 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
47 static const unsigned char arm_devel_rotpk_hash[] =	\
48 		"\x2E\x40\xBF\x6E\xF9\x12\xBB\x98"	\
49 		"\x31\x71\x09\x0E\x1E\x15\x3D\x0B"	\
50 		"\xFD\xD1\xCC\x69\x4A\x98\xEB\x8B"	\
51 		"\xA0\xB0\x20\x86\x4E\x6C\x07\x17";
52 #endif
53 
54 /*
55  * Return the ROTPK hash in the following ASN.1 structure in DER format:
56  *
57  * AlgorithmIdentifier  ::=  SEQUENCE  {
58  *     algorithm         OBJECT IDENTIFIER,
59  *     parameters        ANY DEFINED BY algorithm OPTIONAL
60  * }
61  *
62  * DigestInfo ::= SEQUENCE {
63  *     digestAlgorithm   AlgorithmIdentifier,
64  *     digest            OCTET STRING
65  * }
66  */
67 int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
68 			unsigned int *flags)
69 {
70 	uint8_t *dst;
71 
72 	assert(key_ptr != NULL);
73 	assert(key_len != NULL);
74 	assert(flags != NULL);
75 
76 	/* Copy the DER header */
77 	memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
78 	dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len];
79 
80 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
81 	|| (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
82 	memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES);
83 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
84 	uint32_t *src, tmp;
85 	unsigned int words, i;
86 
87 	/*
88 	 * Append the hash from Trusted Root-Key Storage registers. The hash has
89 	 * not been written linearly into the registers, so we have to do a bit
90 	 * of byte swapping:
91 	 *
92 	 *     0x00    0x04    0x08    0x0C    0x10    0x14    0x18    0x1C
93 	 * +---------------------------------------------------------------+
94 	 * | Reg0  | Reg1  | Reg2  | Reg3  | Reg4  | Reg5  | Reg6  | Reg7  |
95 	 * +---------------------------------------------------------------+
96 	 *  | ...                    ... |   | ...                   ...  |
97 	 *  |       +--------------------+   |                    +-------+
98 	 *  |       |                        |                    |
99 	 *  +----------------------------+   +----------------------------+
100 	 *          |                    |                        |       |
101 	 *  +-------+                    |   +--------------------+       |
102 	 *  |                            |   |                            |
103 	 *  v                            v   v                            v
104 	 * +---------------------------------------------------------------+
105 	 * |                               |                               |
106 	 * +---------------------------------------------------------------+
107 	 *  0                           15  16                           31
108 	 *
109 	 * Additionally, we have to access the registers in 32-bit words
110 	 */
111 	words = SHA256_BYTES >> 3;
112 
113 	/* Swap bytes 0-15 (first four registers) */
114 	src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
115 	for (i = 0 ; i < words ; i++) {
116 		tmp = src[words - 1 - i];
117 		/* Words are read in little endian */
118 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
119 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
120 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
121 		*dst++ = (uint8_t)(tmp & 0xFF);
122 	}
123 
124 	/* Swap bytes 16-31 (last four registers) */
125 	src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2);
126 	for (i = 0 ; i < words ; i++) {
127 		tmp = src[words - 1 - i];
128 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
129 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
130 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
131 		*dst++ = (uint8_t)(tmp & 0xFF);
132 	}
133 #endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
134 		  || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) */
135 
136 	*key_ptr = (void *)rotpk_hash_der;
137 	*key_len = (unsigned int)sizeof(rotpk_hash_der);
138 	*flags = ROTPK_IS_HASH;
139 	return 0;
140 }
141 
142 /*
143  * Return the non-volatile counter value stored in the platform. The cookie
144  * will contain the OID of the counter in the certificate.
145  *
146  * Return: 0 = success, Otherwise = error
147  */
148 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
149 {
150 	const char *oid;
151 	uint32_t *nv_ctr_addr;
152 
153 	assert(cookie != NULL);
154 	assert(nv_ctr != NULL);
155 
156 	oid = (const char *)cookie;
157 	if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
158 		nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE;
159 	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
160 		nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE;
161 	} else {
162 		return 1;
163 	}
164 
165 	*nv_ctr = (unsigned int)(*nv_ctr_addr);
166 
167 	return 0;
168 }
169 
170 /*
171  * Store a new non-volatile counter value. By default on ARM development
172  * platforms, the non-volatile counters are RO and cannot be modified. We expect
173  * the values in the certificates to always match the RO values so that this
174  * function is never called.
175  *
176  * Return: 0 = success, Otherwise = error
177  */
178 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
179 {
180 	return 1;
181 }
182 #else /* ARM_CRYPTOCELL_INTEG */
183 
184 #include <drivers/arm/cryptocell/cc_rotpk.h>
185 
186 /*
187  * Return the ROTPK hash in the following ASN.1 structure in DER format:
188  *
189  * AlgorithmIdentifier  ::=  SEQUENCE  {
190  *     algorithm         OBJECT IDENTIFIER,
191  *     parameters        ANY DEFINED BY algorithm OPTIONAL
192  * }
193  *
194  * DigestInfo ::= SEQUENCE {
195  *     digestAlgorithm   AlgorithmIdentifier,
196  *     digest            OCTET STRING
197  * }
198  */
199 int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
200 			unsigned int *flags)
201 {
202 	unsigned char *dst;
203 
204 	assert(key_ptr != NULL);
205 	assert(key_len != NULL);
206 	assert(flags != NULL);
207 
208 	/* Copy the DER header */
209 	memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
210 	dst = &rotpk_hash_der[rotpk_hash_hdr_len];
211 	*key_ptr = rotpk_hash_der;
212 	*key_len = sizeof(rotpk_hash_der);
213 	return cc_get_rotpk_hash(dst, SHA256_BYTES, flags);
214 }
215 #endif /* ARM_CRYPTOCELL_INTEG */
216