xref: /rk3399_ARM-atf/plat/arm/board/common/board_arm_trusted_boot.c (revision 51faada71a219a8b94cd8d8e423f0f22e9da4d8f)
1 /*
2  * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of ARM nor the names of its contributors may be used
15  * to endorse or promote products derived from this software without specific
16  * prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <arm_def.h>
32 #include <assert.h>
33 #include <platform.h>
34 #include <platform_oid.h>
35 #include <stdint.h>
36 #include <string.h>
37 
38 /* Weak definition may be overridden in specific platform */
39 #pragma weak plat_match_rotpk
40 #pragma weak plat_get_nv_ctr
41 #pragma weak plat_set_nv_ctr
42 
43 /* SHA256 algorithm */
44 #define SHA256_BYTES			32
45 
46 /* ROTPK locations */
47 #define ARM_ROTPK_REGS_ID		1
48 #define ARM_ROTPK_DEVEL_RSA_ID		2
49 
50 #if !ARM_ROTPK_LOCATION_ID
51   #error "ARM_ROTPK_LOCATION_ID not defined"
52 #endif
53 
54 static const unsigned char rotpk_hash_hdr[] =		\
55 		"\x30\x31\x30\x0D\x06\x09\x60\x86\x48"	\
56 		"\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
57 static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1;
58 static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES];
59 
60 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
61 static const unsigned char arm_devel_rotpk_hash[] =	\
62 		"\xB0\xF3\x82\x09\x12\x97\xD8\x3A"	\
63 		"\x37\x7A\x72\x47\x1B\xEC\x32\x73"	\
64 		"\xE9\x92\x32\xE2\x49\x59\xF6\x5E"	\
65 		"\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA";
66 #endif
67 
68 /*
69  * Return the ROTPK hash in the following ASN.1 structure in DER format:
70  *
71  * AlgorithmIdentifier  ::=  SEQUENCE  {
72  *     algorithm         OBJECT IDENTIFIER,
73  *     parameters        ANY DEFINED BY algorithm OPTIONAL
74  * }
75  *
76  * DigestInfo ::= SEQUENCE {
77  *     digestAlgorithm   AlgorithmIdentifier,
78  *     digest            OCTET STRING
79  * }
80  */
81 int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
82 			unsigned int *flags)
83 {
84 	uint8_t *dst;
85 
86 	assert(key_ptr != NULL);
87 	assert(key_len != NULL);
88 	assert(flags != NULL);
89 
90 	/* Copy the DER header */
91 	memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
92 	dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len];
93 
94 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
95 	memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES);
96 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
97 	uint32_t *src, tmp;
98 	unsigned int words, i;
99 
100 	/*
101 	 * Append the hash from Trusted Root-Key Storage registers. The hash has
102 	 * not been written linearly into the registers, so we have to do a bit
103 	 * of byte swapping:
104 	 *
105 	 *     0x00    0x04    0x08    0x0C    0x10    0x14    0x18    0x1C
106 	 * +---------------------------------------------------------------+
107 	 * | Reg0  | Reg1  | Reg2  | Reg3  | Reg4  | Reg5  | Reg6  | Reg7  |
108 	 * +---------------------------------------------------------------+
109 	 *  | ...                    ... |   | ...                   ...  |
110 	 *  |       +--------------------+   |                    +-------+
111 	 *  |       |                        |                    |
112 	 *  +----------------------------+   +----------------------------+
113 	 *          |                    |                        |       |
114 	 *  +-------+                    |   +--------------------+       |
115 	 *  |                            |   |                            |
116 	 *  v                            v   v                            v
117 	 * +---------------------------------------------------------------+
118 	 * |                               |                               |
119 	 * +---------------------------------------------------------------+
120 	 *  0                           15  16                           31
121 	 *
122 	 * Additionally, we have to access the registers in 32-bit words
123 	 */
124 	words = SHA256_BYTES >> 3;
125 
126 	/* Swap bytes 0-15 (first four registers) */
127 	src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
128 	for (i = 0 ; i < words ; i++) {
129 		tmp = src[words - 1 - i];
130 		/* Words are read in little endian */
131 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
132 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
133 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
134 		*dst++ = (uint8_t)(tmp & 0xFF);
135 	}
136 
137 	/* Swap bytes 16-31 (last four registers) */
138 	src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2);
139 	for (i = 0 ; i < words ; i++) {
140 		tmp = src[words - 1 - i];
141 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
142 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
143 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
144 		*dst++ = (uint8_t)(tmp & 0xFF);
145 	}
146 #endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) */
147 
148 	*key_ptr = (void *)rotpk_hash_der;
149 	*key_len = (unsigned int)sizeof(rotpk_hash_der);
150 	*flags = ROTPK_IS_HASH;
151 	return 0;
152 }
153 
154 /*
155  * Return the non-volatile counter value stored in the platform. The cookie
156  * will contain the OID of the counter in the certificate.
157  *
158  * Return: 0 = success, Otherwise = error
159  */
160 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
161 {
162 	const char *oid;
163 	uint32_t *nv_ctr_addr;
164 
165 	assert(cookie != NULL);
166 	assert(nv_ctr != NULL);
167 
168 	oid = (const char *)cookie;
169 	if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
170 		nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE;
171 	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
172 		nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE;
173 	} else {
174 		return 1;
175 	}
176 
177 	*nv_ctr = (unsigned int)(*nv_ctr_addr);
178 
179 	return 0;
180 }
181 
182 /*
183  * Store a new non-volatile counter value. By default on ARM development
184  * platforms, the non-volatile counters are RO and cannot be modified. We expect
185  * the values in the certificates to always match the RO values so that this
186  * function is never called.
187  *
188  * Return: 0 = success, Otherwise = error
189  */
190 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
191 {
192 	return 1;
193 }
194