blob: 8239e0d1a7af596038b0336c1abec970bee17e3b [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
50static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
Juan Castillo31a68f02015-04-14 12:49:03 +010051
Dan Handley9df48042015-03-19 18:58:55 +000052/*
Max Shvetsov06dba292019-12-06 11:50:12 +000053 * Return the ROTPK hash stored in dedicated registers.
Juan Castillo31a68f02015-04-14 12:49:03 +010054 */
Max Shvetsov06dba292019-12-06 11:50:12 +000055int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
Juan Castillo31a68f02015-04-14 12:49:03 +010056 unsigned int *flags)
57{
58 uint8_t *dst;
Max Shvetsov06dba292019-12-06 11:50:12 +000059 uint32_t *src, tmp;
60 unsigned int words, i;
Juan Castillo31a68f02015-04-14 12:49:03 +010061
62 assert(key_ptr != NULL);
63 assert(key_len != NULL);
64 assert(flags != NULL);
65
66 /* Copy the DER header */
Juan Castillo31a68f02015-04-14 12:49:03 +010067
Max Shvetsov06dba292019-12-06 11:50:12 +000068 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
69 dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
Juan Castillo31a68f02015-04-14 12:49:03 +010070
Max Shvetsov06dba292019-12-06 11:50:12 +000071 words = ARM_ROTPK_HASH_LEN >> 2;
Juan Castillo31a68f02015-04-14 12:49:03 +010072
Juan Castillo31a68f02015-04-14 12:49:03 +010073 src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
74 for (i = 0 ; i < words ; i++) {
75 tmp = src[words - 1 - i];
76 /* Words are read in little endian */
Juan Castillo31a68f02015-04-14 12:49:03 +010077 *dst++ = (uint8_t)(tmp & 0xFF);
Juan Castillo31a68f02015-04-14 12:49:03 +010078 *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
Max Shvetsov06dba292019-12-06 11:50:12 +000079 *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
80 *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
Juan Castillo31a68f02015-04-14 12:49:03 +010081 }
Juan Castillo31a68f02015-04-14 12:49:03 +010082
83 *key_ptr = (void *)rotpk_hash_der;
84 *key_len = (unsigned int)sizeof(rotpk_hash_der);
85 *flags = ROTPK_IS_HASH;
86 return 0;
87}
88
Max Shvetsov06dba292019-12-06 11:50:12 +000089#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
90 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
91/*
92 * Return development ROTPK hash generated from ROT_KEY.
93 */
94int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
95 unsigned int *flags)
96{
97 *key_ptr = arm_rotpk_header;
98 *key_len = arm_rotpk_hash_end - arm_rotpk_header;
99 *flags = ROTPK_IS_HASH;
100 return 0;
101}
102#endif
103
104#if ARM_CRYPTOCELL_INTEG
105/*
106 * Return ROTPK hash from CryptoCell.
107 */
108int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len,
109 unsigned int *flags)
110{
111 unsigned char *dst;
112
113 assert(key_ptr != NULL);
114 assert(key_len != NULL);
115 assert(flags != NULL);
116
117 /* Copy the DER header */
118 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
119 dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
120 *key_ptr = rotpk_hash_der;
121 *key_len = sizeof(rotpk_hash_der);
122 return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags);
123}
124#endif
125
126/*
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +0100127 * Wrapper function for most Arm platforms to get ROTPK hash.
Max Shvetsov06dba292019-12-06 11:50:12 +0000128 */
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +0100129static int get_rotpk_info(void **key_ptr, unsigned int *key_len,
130 unsigned int *flags)
Max Shvetsov06dba292019-12-06 11:50:12 +0000131{
132#if ARM_CRYPTOCELL_INTEG
133 return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
134#else
135
136#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
137 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
138 return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
139#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
140 return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
141#else
142 return 1;
143#endif
Max Shvetsov06dba292019-12-06 11:50:12 +0000144#endif /* ARM_CRYPTOCELL_INTEG */
145}
146
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +0100147#if defined(ARM_COT_tbbr)
148
149int arm_get_rotpk_info(void *cookie __unused, void **key_ptr,
150 unsigned int *key_len, unsigned int *flags)
151{
152 return get_rotpk_info(key_ptr, key_len, flags);
153}
154
155#elif defined(ARM_COT_dualroot)
156
157int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
158 unsigned int *flags)
159{
160 /*
161 * Return the right root of trust key hash based on the cookie value:
162 * - NULL means the primary ROTPK.
163 * - Otherwise, interpret cookie as the OID of the certificate
164 * extension containing the key.
165 */
166 if (cookie == NULL) {
167 return get_rotpk_info(key_ptr, key_len, flags);
168 } else if (strcmp(cookie, PROT_PK_OID) == 0) {
169 extern unsigned char arm_protpk_hash[];
170 extern unsigned char arm_protpk_hash_end[];
171 *key_ptr = arm_protpk_hash;
172 *key_len = arm_protpk_hash_end - arm_protpk_hash;
173 *flags = ROTPK_IS_HASH;
174 return 0;
175 } else {
176 /* Invalid key ID. */
177 return 1;
178 }
179}
180#endif
181
Juan Castillobfb7fa62016-01-22 11:05:57 +0000182/*
183 * Return the non-volatile counter value stored in the platform. The cookie
184 * will contain the OID of the counter in the certificate.
185 *
186 * Return: 0 = success, Otherwise = error
187 */
188int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
189{
190 const char *oid;
191 uint32_t *nv_ctr_addr;
192
193 assert(cookie != NULL);
194 assert(nv_ctr != NULL);
195
196 oid = (const char *)cookie;
197 if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
Manish V Badarkhe09a192c2020-08-23 09:58:44 +0100198 nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
199 TRUSTED_NV_CTR_ID);
Juan Castillobfb7fa62016-01-22 11:05:57 +0000200 } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
Manish V Badarkhe09a192c2020-08-23 09:58:44 +0100201 nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
202 NON_TRUSTED_NV_CTR_ID);
Juan Castillobfb7fa62016-01-22 11:05:57 +0000203 } else {
204 return 1;
205 }
206
207 *nv_ctr = (unsigned int)(*nv_ctr_addr);
208
209 return 0;
210}
211
212/*
Antonio Nino Diaz9d602fe2016-05-20 14:14:16 +0100213 * Store a new non-volatile counter value. By default on ARM development
214 * platforms, the non-volatile counters are RO and cannot be modified. We expect
215 * the values in the certificates to always match the RO values so that this
216 * function is never called.
Juan Castillobfb7fa62016-01-22 11:05:57 +0000217 *
218 * Return: 0 = success, Otherwise = error
219 */
220int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
221{
222 return 1;
223}