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