xref: /rk3399_ARM-atf/plat/arm/board/common/board_arm_trusted_boot.c (revision 5808766210f4e127d150c9165dcd14c644c5bc9d)
1b4315306SDan Handley /*
27423e5e8SPranav Madhu  * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
3b4315306SDan Handley  *
482cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
5b4315306SDan Handley  */
6b4315306SDan Handley 
795cfd4adSJuan Castillo #include <assert.h>
895cfd4adSJuan Castillo #include <stdint.h>
995cfd4adSJuan Castillo #include <string.h>
1009d40e0eSAntonio Nino Diaz 
11a6ffddecSMax Shvetsov #include <common/debug.h>
12a6ffddecSMax Shvetsov #include <drivers/delay_timer.h>
1309d40e0eSAntonio Nino Diaz #include <lib/cassert.h>
1414d095c3SManish V Badarkhe #include <lib/fconf/fconf.h>
15a6ffddecSMax Shvetsov #include <plat/common/common_def.h>
1609d40e0eSAntonio Nino Diaz #include <plat/common/platform.h>
1750b44977Slaurenw-arm #if defined(ARM_COT_cca)
1850b44977Slaurenw-arm #include <tools_share/cca_oid.h>
19d25625caSSandrine Bailleux #elif defined(ARM_COT_dualroot)
20d25625caSSandrine Bailleux #include <tools_share/dualroot_oid.h>
2150b44977Slaurenw-arm #elif defined(ARM_COT_tbbr)
2250b44977Slaurenw-arm #include <tools_share/tbbr_oid.h>
23d25625caSSandrine Bailleux #endif
2495cfd4adSJuan Castillo 
2550b44977Slaurenw-arm #include <plat/arm/common/fconf_nv_cntr_getter.h>
2650b44977Slaurenw-arm #include <plat/arm/common/plat_arm.h>
2750b44977Slaurenw-arm #include <platform_def.h>
2850b44977Slaurenw-arm 
29f143cafeSSoby Mathew #if !ARM_ROTPK_LOCATION_ID
30f143cafeSSoby Mathew   #error "ARM_ROTPK_LOCATION_ID not defined"
31f143cafeSSoby Mathew #endif
32f143cafeSSoby Mathew 
3314d095c3SManish V Badarkhe #if COT_DESC_IN_DTB && defined(IMAGE_BL2)
3414d095c3SManish V Badarkhe uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS];
3514d095c3SManish V Badarkhe #else
3614d095c3SManish V Badarkhe uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS] = {
3714d095c3SManish V Badarkhe 	TFW_NVCTR_BASE,
3814d095c3SManish V Badarkhe 	NTFW_CTR_BASE
3914d095c3SManish V Badarkhe };
4014d095c3SManish V Badarkhe #endif
4114d095c3SManish V Badarkhe 
4214d095c3SManish V Badarkhe 
43f143cafeSSoby Mathew /* Weak definition may be overridden in specific platform */
44f143cafeSSoby Mathew #pragma weak plat_get_nv_ctr
45f143cafeSSoby Mathew #pragma weak plat_set_nv_ctr
46f143cafeSSoby Mathew 
47*bd9b01c6SRyan Everett extern unsigned char arm_rotpk_hash_der_header[], arm_rotpk_key[], arm_rotpk_hash_end[],
485f899286Slaurenw-arm        arm_rotpk_key_end[];
49a6ffddecSMax Shvetsov 
50b65dfe40SSandrine Bailleux #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
51*bd9b01c6SRyan Everett static unsigned char rotpk_hash_der[ARM_ROTPK_HASH_DER_HEADER_LEN + ARM_ROTPK_HASH_LEN];
523bfcc9d7SUsama Arif #endif
5395cfd4adSJuan Castillo 
543bfcc9d7SUsama Arif #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
55b4315306SDan Handley /*
56a6ffddecSMax Shvetsov  * Return the ROTPK hash stored in dedicated registers.
5795cfd4adSJuan Castillo  */
arm_get_rotpk_info_regs(void ** key_ptr,unsigned int * key_len,unsigned int * flags)58a6ffddecSMax Shvetsov int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
5995cfd4adSJuan Castillo 			unsigned int *flags)
6095cfd4adSJuan Castillo {
6195cfd4adSJuan Castillo 	uint8_t *dst;
62a6ffddecSMax Shvetsov 	uint32_t *src, tmp;
63a6ffddecSMax Shvetsov 	unsigned int words, i;
6495cfd4adSJuan Castillo 
6595cfd4adSJuan Castillo 	assert(key_ptr != NULL);
6695cfd4adSJuan Castillo 	assert(key_len != NULL);
6795cfd4adSJuan Castillo 	assert(flags != NULL);
6895cfd4adSJuan Castillo 
6995cfd4adSJuan Castillo 	/* Copy the DER header */
7095cfd4adSJuan Castillo 
71*bd9b01c6SRyan Everett 	memcpy(rotpk_hash_der, arm_rotpk_hash_der_header, ARM_ROTPK_HASH_DER_HEADER_LEN);
72*bd9b01c6SRyan Everett 	dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HASH_DER_HEADER_LEN];
7395cfd4adSJuan Castillo 
74a6ffddecSMax Shvetsov 	words = ARM_ROTPK_HASH_LEN >> 2;
7595cfd4adSJuan Castillo 
7695cfd4adSJuan Castillo 	src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
7795cfd4adSJuan Castillo 	for (i = 0 ; i < words ; i++) {
7895cfd4adSJuan Castillo 		tmp = src[words - 1 - i];
7995cfd4adSJuan Castillo 		/* Words are read in little endian */
8095cfd4adSJuan Castillo 		*dst++ = (uint8_t)(tmp & 0xFF);
8195cfd4adSJuan Castillo 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
82a6ffddecSMax Shvetsov 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
83a6ffddecSMax Shvetsov 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
8495cfd4adSJuan Castillo 	}
8595cfd4adSJuan Castillo 
8695cfd4adSJuan Castillo 	*key_ptr = (void *)rotpk_hash_der;
8795cfd4adSJuan Castillo 	*key_len = (unsigned int)sizeof(rotpk_hash_der);
8895cfd4adSJuan Castillo 	*flags = ROTPK_IS_HASH;
8995cfd4adSJuan Castillo 	return 0;
9095cfd4adSJuan Castillo }
913bfcc9d7SUsama Arif #endif
9295cfd4adSJuan Castillo 
93a6ffddecSMax Shvetsov #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
94b8ae6890Slaurenw-arm     (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
arm_get_rotpk_info_dev(void ** key_ptr,unsigned int * key_len,unsigned int * flags)95a6ffddecSMax Shvetsov int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
96a6ffddecSMax Shvetsov 			unsigned int *flags)
97a6ffddecSMax Shvetsov {
98*bd9b01c6SRyan Everett 	*key_ptr = arm_rotpk_hash_der_header;
99*bd9b01c6SRyan Everett 	*key_len = arm_rotpk_hash_end - arm_rotpk_hash_der_header;
100a6ffddecSMax Shvetsov 	*flags = ROTPK_IS_HASH;
101b8ae6890Slaurenw-arm 	return 0;
1025f899286Slaurenw-arm }
103b8ae6890Slaurenw-arm #endif
104b8ae6890Slaurenw-arm 
105b8ae6890Slaurenw-arm #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID) || \
106b8ae6890Slaurenw-arm     (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_ECDSA_KEY_ID)
arm_get_rotpk_info_dev(void ** key_ptr,unsigned int * key_len,unsigned int * flags)107b8ae6890Slaurenw-arm int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
108b8ae6890Slaurenw-arm 			unsigned int *flags)
109b8ae6890Slaurenw-arm {
110b8ae6890Slaurenw-arm 	*key_ptr = arm_rotpk_key;
111b8ae6890Slaurenw-arm 	*key_len = arm_rotpk_key_end - arm_rotpk_key;
112b8ae6890Slaurenw-arm 	*flags = 0;
113a6ffddecSMax Shvetsov 	return 0;
114a6ffddecSMax Shvetsov }
115a6ffddecSMax Shvetsov #endif
116a6ffddecSMax Shvetsov 
117a6ffddecSMax Shvetsov /*
1185f899286Slaurenw-arm  * Wrapper function for most Arm platforms to get ROTPK info.
119a6ffddecSMax Shvetsov  */
get_rotpk_info(void ** key_ptr,unsigned int * key_len,unsigned int * flags)120d25625caSSandrine Bailleux static int get_rotpk_info(void **key_ptr, unsigned int *key_len,
121a6ffddecSMax Shvetsov 				unsigned int *flags)
122a6ffddecSMax Shvetsov {
123b8ae6890Slaurenw-arm #if ARM_USE_DEVEL_ROTPK
124a6ffddecSMax Shvetsov 	return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
125a6ffddecSMax Shvetsov #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
126a6ffddecSMax Shvetsov 	return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
127a6ffddecSMax Shvetsov #else
128a6ffddecSMax Shvetsov 	return 1;
129a6ffddecSMax Shvetsov #endif
130a6ffddecSMax Shvetsov }
131a6ffddecSMax Shvetsov 
132d25625caSSandrine Bailleux #if defined(ARM_COT_tbbr)
133d25625caSSandrine Bailleux 
arm_get_rotpk_info(void * cookie __unused,void ** key_ptr,unsigned int * key_len,unsigned int * flags)134d25625caSSandrine Bailleux int arm_get_rotpk_info(void *cookie __unused, void **key_ptr,
135d25625caSSandrine Bailleux 		       unsigned int *key_len, unsigned int *flags)
136d25625caSSandrine Bailleux {
137d25625caSSandrine Bailleux 	return get_rotpk_info(key_ptr, key_len, flags);
138d25625caSSandrine Bailleux }
139d25625caSSandrine Bailleux 
140d25625caSSandrine Bailleux #elif defined(ARM_COT_dualroot)
141d25625caSSandrine Bailleux 
arm_get_rotpk_info(void * cookie,void ** key_ptr,unsigned int * key_len,unsigned int * flags)142d25625caSSandrine Bailleux int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
143d25625caSSandrine Bailleux 		       unsigned int *flags)
144d25625caSSandrine Bailleux {
145d25625caSSandrine Bailleux 	/*
146d25625caSSandrine Bailleux 	 * Return the right root of trust key hash based on the cookie value:
147d25625caSSandrine Bailleux 	 *  - NULL means the primary ROTPK.
148d25625caSSandrine Bailleux 	 *  - Otherwise, interpret cookie as the OID of the certificate
149d25625caSSandrine Bailleux 	 *    extension containing the key.
150d25625caSSandrine Bailleux 	 */
151d25625caSSandrine Bailleux 	if (cookie == NULL) {
152d25625caSSandrine Bailleux 		return get_rotpk_info(key_ptr, key_len, flags);
153d25625caSSandrine Bailleux 	} else if (strcmp(cookie, PROT_PK_OID) == 0) {
154d25625caSSandrine Bailleux 		extern unsigned char arm_protpk_hash[];
155d25625caSSandrine Bailleux 		extern unsigned char arm_protpk_hash_end[];
156d25625caSSandrine Bailleux 		*key_ptr = arm_protpk_hash;
157d25625caSSandrine Bailleux 		*key_len = arm_protpk_hash_end - arm_protpk_hash;
158d25625caSSandrine Bailleux 		*flags = ROTPK_IS_HASH;
159d25625caSSandrine Bailleux 		return 0;
160d25625caSSandrine Bailleux 	} else {
161d25625caSSandrine Bailleux 		/* Invalid key ID. */
162d25625caSSandrine Bailleux 		return 1;
163d25625caSSandrine Bailleux 	}
164d25625caSSandrine Bailleux }
16550b44977Slaurenw-arm 
16650b44977Slaurenw-arm #elif defined(ARM_COT_cca)
16750b44977Slaurenw-arm 
arm_get_rotpk_info(void * cookie,void ** key_ptr,unsigned int * key_len,unsigned int * flags)16850b44977Slaurenw-arm int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
16950b44977Slaurenw-arm 		       unsigned int *flags)
17050b44977Slaurenw-arm {
17150b44977Slaurenw-arm 	/*
17250b44977Slaurenw-arm 	 * Return the right root of trust key hash based on the cookie value:
17350b44977Slaurenw-arm 	 *  - NULL means the primary ROTPK.
17450b44977Slaurenw-arm 	 *  - Otherwise, interpret cookie as the OID of the certificate
17550b44977Slaurenw-arm 	 *    extension containing the key.
17650b44977Slaurenw-arm 	 */
17750b44977Slaurenw-arm 	if (cookie == NULL) {
17850b44977Slaurenw-arm 		return get_rotpk_info(key_ptr, key_len, flags);
17950b44977Slaurenw-arm 	} else if (strcmp(cookie, PROT_PK_OID) == 0) {
18050b44977Slaurenw-arm 		extern unsigned char arm_protpk_hash[];
18150b44977Slaurenw-arm 		extern unsigned char arm_protpk_hash_end[];
18250b44977Slaurenw-arm 		*key_ptr = arm_protpk_hash;
18350b44977Slaurenw-arm 		*key_len = arm_protpk_hash_end - arm_protpk_hash;
18450b44977Slaurenw-arm 		*flags = ROTPK_IS_HASH;
18550b44977Slaurenw-arm 		return 0;
18650b44977Slaurenw-arm 	} else if (strcmp(cookie, SWD_ROT_PK_OID) == 0) {
18750b44977Slaurenw-arm 		extern unsigned char arm_swd_rotpk_hash[];
18850b44977Slaurenw-arm 		extern unsigned char arm_swd_rotpk_hash_end[];
18950b44977Slaurenw-arm 		*key_ptr = arm_swd_rotpk_hash;
19050b44977Slaurenw-arm 		*key_len = arm_swd_rotpk_hash_end - arm_swd_rotpk_hash;
19150b44977Slaurenw-arm 		*flags = ROTPK_IS_HASH;
19250b44977Slaurenw-arm 		return 0;
19350b44977Slaurenw-arm 	} else {
19450b44977Slaurenw-arm 		/* Invalid key ID. */
19550b44977Slaurenw-arm 		return 1;
19650b44977Slaurenw-arm 	}
19750b44977Slaurenw-arm }
19850b44977Slaurenw-arm 
199d25625caSSandrine Bailleux #endif
200d25625caSSandrine Bailleux 
20148279d52SJuan Castillo /*
20248279d52SJuan Castillo  * Return the non-volatile counter value stored in the platform. The cookie
20348279d52SJuan Castillo  * will contain the OID of the counter in the certificate.
20448279d52SJuan Castillo  *
20548279d52SJuan Castillo  * Return: 0 = success, Otherwise = error
20648279d52SJuan Castillo  */
plat_get_nv_ctr(void * cookie,unsigned int * nv_ctr)20748279d52SJuan Castillo int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
20848279d52SJuan Castillo {
20948279d52SJuan Castillo 	const char *oid;
21048279d52SJuan Castillo 	uint32_t *nv_ctr_addr;
21148279d52SJuan Castillo 
21248279d52SJuan Castillo 	assert(cookie != NULL);
21348279d52SJuan Castillo 	assert(nv_ctr != NULL);
21448279d52SJuan Castillo 
21548279d52SJuan Castillo 	oid = (const char *)cookie;
21648279d52SJuan Castillo 	if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
21714d095c3SManish V Badarkhe 		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
21814d095c3SManish V Badarkhe 							TRUSTED_NV_CTR_ID);
21948279d52SJuan Castillo 	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
22014d095c3SManish V Badarkhe 		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
22114d095c3SManish V Badarkhe 							NON_TRUSTED_NV_CTR_ID);
2227423e5e8SPranav Madhu #if defined(ARM_COT_cca)
2237423e5e8SPranav Madhu 	} else if (strcmp(oid, CCA_FW_NVCOUNTER_OID) == 0) {
2247423e5e8SPranav Madhu 		/*
2257423e5e8SPranav Madhu 		 * Use Trusted NV counter for platforms that don't support
2267423e5e8SPranav Madhu 		 * the CCA NV Counter.
2277423e5e8SPranav Madhu 		 */
2287423e5e8SPranav Madhu 		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
2297423e5e8SPranav Madhu 							TRUSTED_NV_CTR_ID);
2307423e5e8SPranav Madhu #endif
23148279d52SJuan Castillo 	} else {
23248279d52SJuan Castillo 		return 1;
23348279d52SJuan Castillo 	}
23448279d52SJuan Castillo 
23548279d52SJuan Castillo 	*nv_ctr = (unsigned int)(*nv_ctr_addr);
23648279d52SJuan Castillo 
23748279d52SJuan Castillo 	return 0;
23848279d52SJuan Castillo }
23948279d52SJuan Castillo 
24048279d52SJuan Castillo /*
241fe7de035SAntonio Nino Diaz  * Store a new non-volatile counter value. By default on ARM development
242fe7de035SAntonio Nino Diaz  * platforms, the non-volatile counters are RO and cannot be modified. We expect
243fe7de035SAntonio Nino Diaz  * the values in the certificates to always match the RO values so that this
244fe7de035SAntonio Nino Diaz  * function is never called.
24548279d52SJuan Castillo  *
24648279d52SJuan Castillo  * Return: 0 = success, Otherwise = error
24748279d52SJuan Castillo  */
plat_set_nv_ctr(void * cookie,unsigned int nv_ctr)24848279d52SJuan Castillo int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
24948279d52SJuan Castillo {
25048279d52SJuan Castillo 	return 1;
25148279d52SJuan Castillo }
252