xref: /rk3399_ARM-atf/plat/arm/board/common/board_arm_trusted_boot.c (revision 665e71b8ea28162ec7737c1411bca3ea89e5957e)
1 /*
2  * Copyright (c) 2015-2020, 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 <common/debug.h>
12 #include <drivers/arm/cryptocell/cc_rotpk.h>
13 #include <drivers/delay_timer.h>
14 #include <lib/cassert.h>
15 #include <plat/arm/common/plat_arm.h>
16 #include <plat/common/common_def.h>
17 #include <plat/common/platform.h>
18 #include <platform_def.h>
19 #include <tools_share/tbbr_oid.h>
20 
21 
22 #if !ARM_CRYPTOCELL_INTEG
23 #if !ARM_ROTPK_LOCATION_ID
24   #error "ARM_ROTPK_LOCATION_ID not defined"
25 #endif
26 #endif
27 
28 /* Weak definition may be overridden in specific platform */
29 #pragma weak plat_get_nv_ctr
30 #pragma weak plat_set_nv_ctr
31 
32 extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[];
33 
34 static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
35 
36 /*
37  * Return the ROTPK hash stored in dedicated registers.
38  */
39 int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
40 			unsigned int *flags)
41 {
42 	uint8_t *dst;
43 	uint32_t *src, tmp;
44 	unsigned int words, i;
45 
46 	assert(key_ptr != NULL);
47 	assert(key_len != NULL);
48 	assert(flags != NULL);
49 
50 	/* Copy the DER header */
51 
52 	memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
53 	dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
54 
55 	words = ARM_ROTPK_HASH_LEN >> 2;
56 
57 	src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
58 	for (i = 0 ; i < words ; i++) {
59 		tmp = src[words - 1 - i];
60 		/* Words are read in little endian */
61 		*dst++ = (uint8_t)(tmp & 0xFF);
62 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
63 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
64 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
65 	}
66 
67 	*key_ptr = (void *)rotpk_hash_der;
68 	*key_len = (unsigned int)sizeof(rotpk_hash_der);
69 	*flags = ROTPK_IS_HASH;
70 	return 0;
71 }
72 
73 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
74     (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
75 /*
76  * Return development ROTPK hash generated from ROT_KEY.
77  */
78 int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
79 			unsigned int *flags)
80 {
81 	*key_ptr = arm_rotpk_header;
82 	*key_len = arm_rotpk_hash_end - arm_rotpk_header;
83 	*flags = ROTPK_IS_HASH;
84 	return 0;
85 }
86 #endif
87 
88 #if ARM_CRYPTOCELL_INTEG
89 /*
90  * Return ROTPK hash from CryptoCell.
91  */
92 int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len,
93 			unsigned int *flags)
94 {
95 	unsigned char *dst;
96 
97 	assert(key_ptr != NULL);
98 	assert(key_len != NULL);
99 	assert(flags != NULL);
100 
101 	/* Copy the DER header */
102 	memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
103 	dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
104 	*key_ptr = rotpk_hash_der;
105 	*key_len = sizeof(rotpk_hash_der);
106 	return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags);
107 }
108 #endif
109 
110 /*
111  * Wraper function for most Arm platforms to get ROTPK hash.
112  */
113 int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len,
114 			unsigned int *flags)
115 {
116 #if ARM_CRYPTOCELL_INTEG
117 	return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
118 #else
119 
120 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
121     (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
122 	return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
123 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
124 	return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
125 #else
126 	return 1;
127 #endif
128 
129 #endif /* ARM_CRYPTOCELL_INTEG */
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