blob: 714c444e7c962bc031844a5c00ec4da5155384b8 [file] [log] [blame]
Dan Handley9df48042015-03-19 18:58:55 +00001/*
laurenw-arma5746de2022-04-21 16:53:37 -05002 * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
Dan Handley9df48042015-03-19 18:58:55 +00003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Dan Handley9df48042015-03-19 18:58:55 +00005 */
6
Juan Castillo31a68f02015-04-14 12:49:03 +01007#include <assert.h>
Juan Castillo31a68f02015-04-14 12:49:03 +01008#include <stdint.h>
9#include <string.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010
Max Shvetsov06dba292019-12-06 11:50:12 +000011#include <common/debug.h>
12#include <drivers/arm/cryptocell/cc_rotpk.h>
13#include <drivers/delay_timer.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000014#include <lib/cassert.h>
Manish V Badarkhe09a192c2020-08-23 09:58:44 +010015#include <lib/fconf/fconf.h>
Max Shvetsov06dba292019-12-06 11:50:12 +000016#include <plat/common/common_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000017#include <plat/common/platform.h>
laurenw-arma5746de2022-04-21 16:53:37 -050018#if defined(ARM_COT_cca)
19#include <tools_share/cca_oid.h>
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +010020#elif defined(ARM_COT_dualroot)
21#include <tools_share/dualroot_oid.h>
laurenw-arma5746de2022-04-21 16:53:37 -050022#elif defined(ARM_COT_tbbr)
23#include <tools_share/tbbr_oid.h>
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +010024#endif
Juan Castillo31a68f02015-04-14 12:49:03 +010025
laurenw-arma5746de2022-04-21 16:53:37 -050026#include <plat/arm/common/fconf_nv_cntr_getter.h>
27#include <plat/arm/common/plat_arm.h>
28#include <platform_def.h>
29
Soby Mathew3e6bbda2017-06-02 17:44:07 +010030#if !ARM_CRYPTOCELL_INTEG
31#if !ARM_ROTPK_LOCATION_ID
32 #error "ARM_ROTPK_LOCATION_ID not defined"
33#endif
Max Shvetsov06dba292019-12-06 11:50:12 +000034#endif
Soby Mathew3e6bbda2017-06-02 17:44:07 +010035
Manish V Badarkhe09a192c2020-08-23 09:58:44 +010036#if COT_DESC_IN_DTB && defined(IMAGE_BL2)
37uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS];
38#else
39uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS] = {
40 TFW_NVCTR_BASE,
41 NTFW_CTR_BASE
42};
43#endif
44
45
Soby Mathew3e6bbda2017-06-02 17:44:07 +010046/* Weak definition may be overridden in specific platform */
47#pragma weak plat_get_nv_ctr
48#pragma weak plat_set_nv_ctr
49
Max Shvetsov06dba292019-12-06 11:50:12 +000050extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[];
51
Usama Arif997fb3b2020-10-05 10:18:52 +010052#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) || ARM_CRYPTOCELL_INTEG
Max Shvetsov06dba292019-12-06 11:50:12 +000053static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
Usama Arif997fb3b2020-10-05 10:18:52 +010054#endif
Juan Castillo31a68f02015-04-14 12:49:03 +010055
Usama Arif997fb3b2020-10-05 10:18:52 +010056#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
Dan Handley9df48042015-03-19 18:58:55 +000057/*
Max Shvetsov06dba292019-12-06 11:50:12 +000058 * Return the ROTPK hash stored in dedicated registers.
Juan Castillo31a68f02015-04-14 12:49:03 +010059 */
Max Shvetsov06dba292019-12-06 11:50:12 +000060int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
Juan Castillo31a68f02015-04-14 12:49:03 +010061 unsigned int *flags)
62{
63 uint8_t *dst;
Max Shvetsov06dba292019-12-06 11:50:12 +000064 uint32_t *src, tmp;
65 unsigned int words, i;
Juan Castillo31a68f02015-04-14 12:49:03 +010066
67 assert(key_ptr != NULL);
68 assert(key_len != NULL);
69 assert(flags != NULL);
70
71 /* Copy the DER header */
Juan Castillo31a68f02015-04-14 12:49:03 +010072
Max Shvetsov06dba292019-12-06 11:50:12 +000073 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
74 dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
Juan Castillo31a68f02015-04-14 12:49:03 +010075
Max Shvetsov06dba292019-12-06 11:50:12 +000076 words = ARM_ROTPK_HASH_LEN >> 2;
Juan Castillo31a68f02015-04-14 12:49:03 +010077
Juan Castillo31a68f02015-04-14 12:49:03 +010078 src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
79 for (i = 0 ; i < words ; i++) {
80 tmp = src[words - 1 - i];
81 /* Words are read in little endian */
Juan Castillo31a68f02015-04-14 12:49:03 +010082 *dst++ = (uint8_t)(tmp & 0xFF);
Juan Castillo31a68f02015-04-14 12:49:03 +010083 *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
Max Shvetsov06dba292019-12-06 11:50:12 +000084 *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
85 *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
Juan Castillo31a68f02015-04-14 12:49:03 +010086 }
Juan Castillo31a68f02015-04-14 12:49:03 +010087
88 *key_ptr = (void *)rotpk_hash_der;
89 *key_len = (unsigned int)sizeof(rotpk_hash_der);
90 *flags = ROTPK_IS_HASH;
91 return 0;
92}
Usama Arif997fb3b2020-10-05 10:18:52 +010093#endif
Juan Castillo31a68f02015-04-14 12:49:03 +010094
Max Shvetsov06dba292019-12-06 11:50:12 +000095#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
96 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
97/*
98 * Return development ROTPK hash generated from ROT_KEY.
99 */
100int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
101 unsigned int *flags)
102{
103 *key_ptr = arm_rotpk_header;
104 *key_len = arm_rotpk_hash_end - arm_rotpk_header;
105 *flags = ROTPK_IS_HASH;
106 return 0;
107}
108#endif
109
110#if ARM_CRYPTOCELL_INTEG
111/*
112 * Return ROTPK hash from CryptoCell.
113 */
114int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len,
115 unsigned int *flags)
116{
117 unsigned char *dst;
118
119 assert(key_ptr != NULL);
120 assert(key_len != NULL);
121 assert(flags != NULL);
122
123 /* Copy the DER header */
124 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
125 dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
126 *key_ptr = rotpk_hash_der;
127 *key_len = sizeof(rotpk_hash_der);
128 return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags);
129}
130#endif
131
132/*
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +0100133 * Wrapper function for most Arm platforms to get ROTPK hash.
Max Shvetsov06dba292019-12-06 11:50:12 +0000134 */
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +0100135static int get_rotpk_info(void **key_ptr, unsigned int *key_len,
136 unsigned int *flags)
Max Shvetsov06dba292019-12-06 11:50:12 +0000137{
138#if ARM_CRYPTOCELL_INTEG
139 return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
140#else
141
142#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
143 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
144 return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
145#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
146 return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
147#else
148 return 1;
149#endif
Max Shvetsov06dba292019-12-06 11:50:12 +0000150#endif /* ARM_CRYPTOCELL_INTEG */
151}
152
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +0100153#if defined(ARM_COT_tbbr)
154
155int arm_get_rotpk_info(void *cookie __unused, void **key_ptr,
156 unsigned int *key_len, unsigned int *flags)
157{
158 return get_rotpk_info(key_ptr, key_len, flags);
159}
160
161#elif defined(ARM_COT_dualroot)
162
163int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
164 unsigned int *flags)
165{
166 /*
167 * Return the right root of trust key hash based on the cookie value:
168 * - NULL means the primary ROTPK.
169 * - Otherwise, interpret cookie as the OID of the certificate
170 * extension containing the key.
171 */
172 if (cookie == NULL) {
173 return get_rotpk_info(key_ptr, key_len, flags);
174 } else if (strcmp(cookie, PROT_PK_OID) == 0) {
175 extern unsigned char arm_protpk_hash[];
176 extern unsigned char arm_protpk_hash_end[];
177 *key_ptr = arm_protpk_hash;
178 *key_len = arm_protpk_hash_end - arm_protpk_hash;
179 *flags = ROTPK_IS_HASH;
180 return 0;
181 } else {
182 /* Invalid key ID. */
183 return 1;
184 }
185}
laurenw-arma5746de2022-04-21 16:53:37 -0500186
187#elif defined(ARM_COT_cca)
188
189int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
190 unsigned int *flags)
191{
192 /*
193 * Return the right root of trust key hash based on the cookie value:
194 * - NULL means the primary ROTPK.
195 * - Otherwise, interpret cookie as the OID of the certificate
196 * extension containing the key.
197 */
198 if (cookie == NULL) {
199 return get_rotpk_info(key_ptr, key_len, flags);
200 } else if (strcmp(cookie, PROT_PK_OID) == 0) {
201 extern unsigned char arm_protpk_hash[];
202 extern unsigned char arm_protpk_hash_end[];
203 *key_ptr = arm_protpk_hash;
204 *key_len = arm_protpk_hash_end - arm_protpk_hash;
205 *flags = ROTPK_IS_HASH;
206 return 0;
207 } else if (strcmp(cookie, SWD_ROT_PK_OID) == 0) {
208 extern unsigned char arm_swd_rotpk_hash[];
209 extern unsigned char arm_swd_rotpk_hash_end[];
210 *key_ptr = arm_swd_rotpk_hash;
211 *key_len = arm_swd_rotpk_hash_end - arm_swd_rotpk_hash;
212 *flags = ROTPK_IS_HASH;
213 return 0;
214 } else {
215 /* Invalid key ID. */
216 return 1;
217 }
218}
219
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +0100220#endif
221
Juan Castillobfb7fa62016-01-22 11:05:57 +0000222/*
223 * Return the non-volatile counter value stored in the platform. The cookie
224 * will contain the OID of the counter in the certificate.
225 *
226 * Return: 0 = success, Otherwise = error
227 */
228int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
229{
230 const char *oid;
231 uint32_t *nv_ctr_addr;
232
233 assert(cookie != NULL);
234 assert(nv_ctr != NULL);
235
236 oid = (const char *)cookie;
237 if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
Manish V Badarkhe09a192c2020-08-23 09:58:44 +0100238 nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
239 TRUSTED_NV_CTR_ID);
Juan Castillobfb7fa62016-01-22 11:05:57 +0000240 } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
Manish V Badarkhe09a192c2020-08-23 09:58:44 +0100241 nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
242 NON_TRUSTED_NV_CTR_ID);
Juan Castillobfb7fa62016-01-22 11:05:57 +0000243 } else {
244 return 1;
245 }
246
247 *nv_ctr = (unsigned int)(*nv_ctr_addr);
248
249 return 0;
250}
251
252/*
Antonio Nino Diaz9d602fe2016-05-20 14:14:16 +0100253 * Store a new non-volatile counter value. By default on ARM development
254 * platforms, the non-volatile counters are RO and cannot be modified. We expect
255 * the values in the certificates to always match the RO values so that this
256 * function is never called.
Juan Castillobfb7fa62016-01-22 11:05:57 +0000257 *
258 * Return: 0 = success, Otherwise = error
259 */
260int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
261{
262 return 1;
263}