blob: 66cc3e94963c365badda3aa43de2d25e469b8b70 [file] [log] [blame]
Dan Handley9df48042015-03-19 18:58:55 +00001/*
Max Shvetsov06dba292019-12-06 11:50:12 +00002 * Copyright (c) 2015-2020, 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/arm/common/plat_arm.h>
Manish V Badarkhe09a192c2020-08-23 09:58:44 +010017#include <plat/arm/common/fconf_nv_cntr_getter.h>
Max Shvetsov06dba292019-12-06 11:50:12 +000018#include <plat/common/common_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000019#include <plat/common/platform.h>
Antonio Nino Diaza320ecd2019-01-15 14:19:50 +000020#include <platform_def.h>
Juan Castillo31a68f02015-04-14 12:49:03 +010021
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +010022#if defined(ARM_COT_tbbr)
23#include <tools_share/tbbr_oid.h>
24#elif defined(ARM_COT_dualroot)
25#include <tools_share/dualroot_oid.h>
26#endif
Juan Castillo31a68f02015-04-14 12:49:03 +010027
Soby Mathew3e6bbda2017-06-02 17:44:07 +010028#if !ARM_CRYPTOCELL_INTEG
29#if !ARM_ROTPK_LOCATION_ID
30 #error "ARM_ROTPK_LOCATION_ID not defined"
31#endif
Max Shvetsov06dba292019-12-06 11:50:12 +000032#endif
Soby Mathew3e6bbda2017-06-02 17:44:07 +010033
Manish V Badarkhe09a192c2020-08-23 09:58:44 +010034#if COT_DESC_IN_DTB && defined(IMAGE_BL2)
35uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS];
36#else
37uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS] = {
38 TFW_NVCTR_BASE,
39 NTFW_CTR_BASE
40};
41#endif
42
43
Soby Mathew3e6bbda2017-06-02 17:44:07 +010044/* Weak definition may be overridden in specific platform */
45#pragma weak plat_get_nv_ctr
46#pragma weak plat_set_nv_ctr
47
Max Shvetsov06dba292019-12-06 11:50:12 +000048extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[];
49
Usama Arif997fb3b2020-10-05 10:18:52 +010050#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) || ARM_CRYPTOCELL_INTEG
Max Shvetsov06dba292019-12-06 11:50:12 +000051static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
Usama Arif997fb3b2020-10-05 10:18:52 +010052#endif
Juan Castillo31a68f02015-04-14 12:49:03 +010053
Usama Arif997fb3b2020-10-05 10:18:52 +010054#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
Dan Handley9df48042015-03-19 18:58:55 +000055/*
Max Shvetsov06dba292019-12-06 11:50:12 +000056 * Return the ROTPK hash stored in dedicated registers.
Juan Castillo31a68f02015-04-14 12:49:03 +010057 */
Max Shvetsov06dba292019-12-06 11:50:12 +000058int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
Juan Castillo31a68f02015-04-14 12:49:03 +010059 unsigned int *flags)
60{
61 uint8_t *dst;
Max Shvetsov06dba292019-12-06 11:50:12 +000062 uint32_t *src, tmp;
63 unsigned int words, i;
Juan Castillo31a68f02015-04-14 12:49:03 +010064
65 assert(key_ptr != NULL);
66 assert(key_len != NULL);
67 assert(flags != NULL);
68
69 /* Copy the DER header */
Juan Castillo31a68f02015-04-14 12:49:03 +010070
Max Shvetsov06dba292019-12-06 11:50:12 +000071 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
72 dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
Juan Castillo31a68f02015-04-14 12:49:03 +010073
Max Shvetsov06dba292019-12-06 11:50:12 +000074 words = ARM_ROTPK_HASH_LEN >> 2;
Juan Castillo31a68f02015-04-14 12:49:03 +010075
Juan Castillo31a68f02015-04-14 12:49:03 +010076 src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
77 for (i = 0 ; i < words ; i++) {
78 tmp = src[words - 1 - i];
79 /* Words are read in little endian */
Juan Castillo31a68f02015-04-14 12:49:03 +010080 *dst++ = (uint8_t)(tmp & 0xFF);
Juan Castillo31a68f02015-04-14 12:49:03 +010081 *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
Max Shvetsov06dba292019-12-06 11:50:12 +000082 *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
83 *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
Juan Castillo31a68f02015-04-14 12:49:03 +010084 }
Juan Castillo31a68f02015-04-14 12:49:03 +010085
86 *key_ptr = (void *)rotpk_hash_der;
87 *key_len = (unsigned int)sizeof(rotpk_hash_der);
88 *flags = ROTPK_IS_HASH;
89 return 0;
90}
Usama Arif997fb3b2020-10-05 10:18:52 +010091#endif
Juan Castillo31a68f02015-04-14 12:49:03 +010092
Max Shvetsov06dba292019-12-06 11:50:12 +000093#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
94 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
95/*
96 * Return development ROTPK hash generated from ROT_KEY.
97 */
98int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
99 unsigned int *flags)
100{
101 *key_ptr = arm_rotpk_header;
102 *key_len = arm_rotpk_hash_end - arm_rotpk_header;
103 *flags = ROTPK_IS_HASH;
104 return 0;
105}
106#endif
107
108#if ARM_CRYPTOCELL_INTEG
109/*
110 * Return ROTPK hash from CryptoCell.
111 */
112int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len,
113 unsigned int *flags)
114{
115 unsigned char *dst;
116
117 assert(key_ptr != NULL);
118 assert(key_len != NULL);
119 assert(flags != NULL);
120
121 /* Copy the DER header */
122 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
123 dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
124 *key_ptr = rotpk_hash_der;
125 *key_len = sizeof(rotpk_hash_der);
126 return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags);
127}
128#endif
129
130/*
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +0100131 * Wrapper function for most Arm platforms to get ROTPK hash.
Max Shvetsov06dba292019-12-06 11:50:12 +0000132 */
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +0100133static int get_rotpk_info(void **key_ptr, unsigned int *key_len,
134 unsigned int *flags)
Max Shvetsov06dba292019-12-06 11:50:12 +0000135{
136#if ARM_CRYPTOCELL_INTEG
137 return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
138#else
139
140#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
141 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
142 return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
143#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
144 return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
145#else
146 return 1;
147#endif
Max Shvetsov06dba292019-12-06 11:50:12 +0000148#endif /* ARM_CRYPTOCELL_INTEG */
149}
150
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +0100151#if defined(ARM_COT_tbbr)
152
153int arm_get_rotpk_info(void *cookie __unused, void **key_ptr,
154 unsigned int *key_len, unsigned int *flags)
155{
156 return get_rotpk_info(key_ptr, key_len, flags);
157}
158
159#elif defined(ARM_COT_dualroot)
160
161int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
162 unsigned int *flags)
163{
164 /*
165 * Return the right root of trust key hash based on the cookie value:
166 * - NULL means the primary ROTPK.
167 * - Otherwise, interpret cookie as the OID of the certificate
168 * extension containing the key.
169 */
170 if (cookie == NULL) {
171 return get_rotpk_info(key_ptr, key_len, flags);
172 } else if (strcmp(cookie, PROT_PK_OID) == 0) {
173 extern unsigned char arm_protpk_hash[];
174 extern unsigned char arm_protpk_hash_end[];
175 *key_ptr = arm_protpk_hash;
176 *key_len = arm_protpk_hash_end - arm_protpk_hash;
177 *flags = ROTPK_IS_HASH;
178 return 0;
179 } else {
180 /* Invalid key ID. */
181 return 1;
182 }
183}
184#endif
185
Juan Castillobfb7fa62016-01-22 11:05:57 +0000186/*
187 * Return the non-volatile counter value stored in the platform. The cookie
188 * will contain the OID of the counter in the certificate.
189 *
190 * Return: 0 = success, Otherwise = error
191 */
192int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
193{
194 const char *oid;
195 uint32_t *nv_ctr_addr;
196
197 assert(cookie != NULL);
198 assert(nv_ctr != NULL);
199
200 oid = (const char *)cookie;
201 if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
Manish V Badarkhe09a192c2020-08-23 09:58:44 +0100202 nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
203 TRUSTED_NV_CTR_ID);
Juan Castillobfb7fa62016-01-22 11:05:57 +0000204 } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
Manish V Badarkhe09a192c2020-08-23 09:58:44 +0100205 nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
206 NON_TRUSTED_NV_CTR_ID);
Juan Castillobfb7fa62016-01-22 11:05:57 +0000207 } else {
208 return 1;
209 }
210
211 *nv_ctr = (unsigned int)(*nv_ctr_addr);
212
213 return 0;
214}
215
216/*
Antonio Nino Diaz9d602fe2016-05-20 14:14:16 +0100217 * Store a new non-volatile counter value. By default on ARM development
218 * platforms, the non-volatile counters are RO and cannot be modified. We expect
219 * the values in the certificates to always match the RO values so that this
220 * function is never called.
Juan Castillobfb7fa62016-01-22 11:05:57 +0000221 *
222 * Return: 0 = success, Otherwise = error
223 */
224int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
225{
226 return 1;
227}