blob: 38cbba9e934e13f33ca867e802c4d1ff71619152 [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>
Max Shvetsov06dba292019-12-06 11:50:12 +000015#include <plat/arm/common/plat_arm.h>
16#include <plat/common/common_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000017#include <plat/common/platform.h>
Antonio Nino Diaza320ecd2019-01-15 14:19:50 +000018#include <platform_def.h>
Juan Castillo31a68f02015-04-14 12:49:03 +010019
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +010020#if defined(ARM_COT_tbbr)
21#include <tools_share/tbbr_oid.h>
22#elif defined(ARM_COT_dualroot)
23#include <tools_share/dualroot_oid.h>
24#endif
Juan Castillo31a68f02015-04-14 12:49:03 +010025
Soby Mathew3e6bbda2017-06-02 17:44:07 +010026#if !ARM_CRYPTOCELL_INTEG
27#if !ARM_ROTPK_LOCATION_ID
28 #error "ARM_ROTPK_LOCATION_ID not defined"
29#endif
Max Shvetsov06dba292019-12-06 11:50:12 +000030#endif
Soby Mathew3e6bbda2017-06-02 17:44:07 +010031
32/* Weak definition may be overridden in specific platform */
33#pragma weak plat_get_nv_ctr
34#pragma weak plat_set_nv_ctr
35
Max Shvetsov06dba292019-12-06 11:50:12 +000036extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[];
37
38static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
Juan Castillo31a68f02015-04-14 12:49:03 +010039
Dan Handley9df48042015-03-19 18:58:55 +000040/*
Max Shvetsov06dba292019-12-06 11:50:12 +000041 * Return the ROTPK hash stored in dedicated registers.
Juan Castillo31a68f02015-04-14 12:49:03 +010042 */
Max Shvetsov06dba292019-12-06 11:50:12 +000043int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
Juan Castillo31a68f02015-04-14 12:49:03 +010044 unsigned int *flags)
45{
46 uint8_t *dst;
Max Shvetsov06dba292019-12-06 11:50:12 +000047 uint32_t *src, tmp;
48 unsigned int words, i;
Juan Castillo31a68f02015-04-14 12:49:03 +010049
50 assert(key_ptr != NULL);
51 assert(key_len != NULL);
52 assert(flags != NULL);
53
54 /* Copy the DER header */
Juan Castillo31a68f02015-04-14 12:49:03 +010055
Max Shvetsov06dba292019-12-06 11:50:12 +000056 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
57 dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
Juan Castillo31a68f02015-04-14 12:49:03 +010058
Max Shvetsov06dba292019-12-06 11:50:12 +000059 words = ARM_ROTPK_HASH_LEN >> 2;
Juan Castillo31a68f02015-04-14 12:49:03 +010060
Juan Castillo31a68f02015-04-14 12:49:03 +010061 src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
62 for (i = 0 ; i < words ; i++) {
63 tmp = src[words - 1 - i];
64 /* Words are read in little endian */
Juan Castillo31a68f02015-04-14 12:49:03 +010065 *dst++ = (uint8_t)(tmp & 0xFF);
Juan Castillo31a68f02015-04-14 12:49:03 +010066 *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
Max Shvetsov06dba292019-12-06 11:50:12 +000067 *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
68 *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
Juan Castillo31a68f02015-04-14 12:49:03 +010069 }
Juan Castillo31a68f02015-04-14 12:49:03 +010070
71 *key_ptr = (void *)rotpk_hash_der;
72 *key_len = (unsigned int)sizeof(rotpk_hash_der);
73 *flags = ROTPK_IS_HASH;
74 return 0;
75}
76
Max Shvetsov06dba292019-12-06 11:50:12 +000077#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
78 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
79/*
80 * Return development ROTPK hash generated from ROT_KEY.
81 */
82int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
83 unsigned int *flags)
84{
85 *key_ptr = arm_rotpk_header;
86 *key_len = arm_rotpk_hash_end - arm_rotpk_header;
87 *flags = ROTPK_IS_HASH;
88 return 0;
89}
90#endif
91
92#if ARM_CRYPTOCELL_INTEG
93/*
94 * Return ROTPK hash from CryptoCell.
95 */
96int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len,
97 unsigned int *flags)
98{
99 unsigned char *dst;
100
101 assert(key_ptr != NULL);
102 assert(key_len != NULL);
103 assert(flags != NULL);
104
105 /* Copy the DER header */
106 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
107 dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
108 *key_ptr = rotpk_hash_der;
109 *key_len = sizeof(rotpk_hash_der);
110 return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags);
111}
112#endif
113
114/*
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +0100115 * Wrapper function for most Arm platforms to get ROTPK hash.
Max Shvetsov06dba292019-12-06 11:50:12 +0000116 */
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +0100117static int get_rotpk_info(void **key_ptr, unsigned int *key_len,
118 unsigned int *flags)
Max Shvetsov06dba292019-12-06 11:50:12 +0000119{
120#if ARM_CRYPTOCELL_INTEG
121 return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
122#else
123
124#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
125 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
126 return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
127#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
128 return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
129#else
130 return 1;
131#endif
Max Shvetsov06dba292019-12-06 11:50:12 +0000132#endif /* ARM_CRYPTOCELL_INTEG */
133}
134
Sandrine Bailleuxa13c0e52020-02-05 16:33:37 +0100135#if defined(ARM_COT_tbbr)
136
137int arm_get_rotpk_info(void *cookie __unused, void **key_ptr,
138 unsigned int *key_len, unsigned int *flags)
139{
140 return get_rotpk_info(key_ptr, key_len, flags);
141}
142
143#elif defined(ARM_COT_dualroot)
144
145int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
146 unsigned int *flags)
147{
148 /*
149 * Return the right root of trust key hash based on the cookie value:
150 * - NULL means the primary ROTPK.
151 * - Otherwise, interpret cookie as the OID of the certificate
152 * extension containing the key.
153 */
154 if (cookie == NULL) {
155 return get_rotpk_info(key_ptr, key_len, flags);
156 } else if (strcmp(cookie, PROT_PK_OID) == 0) {
157 extern unsigned char arm_protpk_hash[];
158 extern unsigned char arm_protpk_hash_end[];
159 *key_ptr = arm_protpk_hash;
160 *key_len = arm_protpk_hash_end - arm_protpk_hash;
161 *flags = ROTPK_IS_HASH;
162 return 0;
163 } else {
164 /* Invalid key ID. */
165 return 1;
166 }
167}
168#endif
169
Juan Castillobfb7fa62016-01-22 11:05:57 +0000170/*
171 * Return the non-volatile counter value stored in the platform. The cookie
172 * will contain the OID of the counter in the certificate.
173 *
174 * Return: 0 = success, Otherwise = error
175 */
176int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
177{
178 const char *oid;
179 uint32_t *nv_ctr_addr;
180
181 assert(cookie != NULL);
182 assert(nv_ctr != NULL);
183
184 oid = (const char *)cookie;
185 if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
186 nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE;
187 } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
188 nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE;
189 } else {
190 return 1;
191 }
192
193 *nv_ctr = (unsigned int)(*nv_ctr_addr);
194
195 return 0;
196}
197
198/*
Antonio Nino Diaz9d602fe2016-05-20 14:14:16 +0100199 * Store a new non-volatile counter value. By default on ARM development
200 * platforms, the non-volatile counters are RO and cannot be modified. We expect
201 * the values in the certificates to always match the RO values so that this
202 * function is never called.
Juan Castillobfb7fa62016-01-22 11:05:57 +0000203 *
204 * Return: 0 = success, Otherwise = error
205 */
206int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
207{
208 return 1;
209}