1 /* 2 * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <stdint.h> 9 #include <string.h> 10 11 #include <common/debug.h> 12 #include <drivers/arm/cryptocell/cc_rotpk.h> 13 #include <drivers/delay_timer.h> 14 #include <lib/cassert.h> 15 #include <lib/fconf/fconf.h> 16 #include <plat/common/common_def.h> 17 #include <plat/common/platform.h> 18 #if defined(ARM_COT_cca) 19 #include <tools_share/cca_oid.h> 20 #elif defined(ARM_COT_dualroot) 21 #include <tools_share/dualroot_oid.h> 22 #elif defined(ARM_COT_tbbr) 23 #include <tools_share/tbbr_oid.h> 24 #endif 25 26 #include <plat/arm/common/fconf_nv_cntr_getter.h> 27 #include <plat/arm/common/plat_arm.h> 28 #include <platform_def.h> 29 30 #if !ARM_CRYPTOCELL_INTEG 31 #if !ARM_ROTPK_LOCATION_ID 32 #error "ARM_ROTPK_LOCATION_ID not defined" 33 #endif 34 #endif 35 36 #if COT_DESC_IN_DTB && defined(IMAGE_BL2) 37 uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS]; 38 #else 39 uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS] = { 40 TFW_NVCTR_BASE, 41 NTFW_CTR_BASE 42 }; 43 #endif 44 45 46 /* Weak definition may be overridden in specific platform */ 47 #pragma weak plat_get_nv_ctr 48 #pragma weak plat_set_nv_ctr 49 50 extern unsigned char arm_rotpk_header[], arm_rotpk_key[], arm_rotpk_hash_end[], 51 arm_rotpk_key_end[]; 52 53 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) || ARM_CRYPTOCELL_INTEG 54 static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; 55 #endif 56 57 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) 58 /* 59 * Return the ROTPK hash stored in dedicated registers. 60 */ 61 int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, 62 unsigned int *flags) 63 { 64 uint8_t *dst; 65 uint32_t *src, tmp; 66 unsigned int words, i; 67 68 assert(key_ptr != NULL); 69 assert(key_len != NULL); 70 assert(flags != NULL); 71 72 /* Copy the DER header */ 73 74 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); 75 dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; 76 77 words = ARM_ROTPK_HASH_LEN >> 2; 78 79 src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; 80 for (i = 0 ; i < words ; i++) { 81 tmp = src[words - 1 - i]; 82 /* Words are read in little endian */ 83 *dst++ = (uint8_t)(tmp & 0xFF); 84 *dst++ = (uint8_t)((tmp >> 8) & 0xFF); 85 *dst++ = (uint8_t)((tmp >> 16) & 0xFF); 86 *dst++ = (uint8_t)((tmp >> 24) & 0xFF); 87 } 88 89 *key_ptr = (void *)rotpk_hash_der; 90 *key_len = (unsigned int)sizeof(rotpk_hash_der); 91 *flags = ROTPK_IS_HASH; 92 return 0; 93 } 94 #endif 95 96 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ 97 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) || \ 98 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID) 99 int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len, 100 unsigned int *flags) 101 { 102 if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID) { 103 *key_ptr = arm_rotpk_key; 104 *key_len = arm_rotpk_key_end - arm_rotpk_key; 105 *flags = 0; 106 } else { 107 *key_ptr = arm_rotpk_header; 108 *key_len = arm_rotpk_hash_end - arm_rotpk_header; 109 *flags = ROTPK_IS_HASH; 110 } 111 return 0; 112 } 113 #endif 114 115 #if ARM_CRYPTOCELL_INTEG 116 /* 117 * Return ROTPK hash from CryptoCell. 118 */ 119 int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len, 120 unsigned int *flags) 121 { 122 unsigned char *dst; 123 124 assert(key_ptr != NULL); 125 assert(key_len != NULL); 126 assert(flags != NULL); 127 128 /* Copy the DER header */ 129 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); 130 dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; 131 *key_ptr = rotpk_hash_der; 132 *key_len = sizeof(rotpk_hash_der); 133 return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags); 134 } 135 #endif 136 137 /* 138 * Wrapper function for most Arm platforms to get ROTPK info. 139 */ 140 static int get_rotpk_info(void **key_ptr, unsigned int *key_len, 141 unsigned int *flags) 142 { 143 #if ARM_CRYPTOCELL_INTEG 144 return arm_get_rotpk_info_cc(key_ptr, key_len, flags); 145 #else 146 147 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ 148 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) || \ 149 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID) 150 return arm_get_rotpk_info_dev(key_ptr, key_len, flags); 151 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) 152 return arm_get_rotpk_info_regs(key_ptr, key_len, flags); 153 #else 154 return 1; 155 #endif 156 #endif /* ARM_CRYPTOCELL_INTEG */ 157 } 158 159 #if defined(ARM_COT_tbbr) 160 161 int arm_get_rotpk_info(void *cookie __unused, void **key_ptr, 162 unsigned int *key_len, unsigned int *flags) 163 { 164 return get_rotpk_info(key_ptr, key_len, flags); 165 } 166 167 #elif defined(ARM_COT_dualroot) 168 169 int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, 170 unsigned int *flags) 171 { 172 /* 173 * Return the right root of trust key hash based on the cookie value: 174 * - NULL means the primary ROTPK. 175 * - Otherwise, interpret cookie as the OID of the certificate 176 * extension containing the key. 177 */ 178 if (cookie == NULL) { 179 return get_rotpk_info(key_ptr, key_len, flags); 180 } else if (strcmp(cookie, PROT_PK_OID) == 0) { 181 extern unsigned char arm_protpk_hash[]; 182 extern unsigned char arm_protpk_hash_end[]; 183 *key_ptr = arm_protpk_hash; 184 *key_len = arm_protpk_hash_end - arm_protpk_hash; 185 *flags = ROTPK_IS_HASH; 186 return 0; 187 } else { 188 /* Invalid key ID. */ 189 return 1; 190 } 191 } 192 193 #elif defined(ARM_COT_cca) 194 195 int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, 196 unsigned int *flags) 197 { 198 /* 199 * Return the right root of trust key hash based on the cookie value: 200 * - NULL means the primary ROTPK. 201 * - Otherwise, interpret cookie as the OID of the certificate 202 * extension containing the key. 203 */ 204 if (cookie == NULL) { 205 return get_rotpk_info(key_ptr, key_len, flags); 206 } else if (strcmp(cookie, PROT_PK_OID) == 0) { 207 extern unsigned char arm_protpk_hash[]; 208 extern unsigned char arm_protpk_hash_end[]; 209 *key_ptr = arm_protpk_hash; 210 *key_len = arm_protpk_hash_end - arm_protpk_hash; 211 *flags = ROTPK_IS_HASH; 212 return 0; 213 } else if (strcmp(cookie, SWD_ROT_PK_OID) == 0) { 214 extern unsigned char arm_swd_rotpk_hash[]; 215 extern unsigned char arm_swd_rotpk_hash_end[]; 216 *key_ptr = arm_swd_rotpk_hash; 217 *key_len = arm_swd_rotpk_hash_end - arm_swd_rotpk_hash; 218 *flags = ROTPK_IS_HASH; 219 return 0; 220 } else { 221 /* Invalid key ID. */ 222 return 1; 223 } 224 } 225 226 #endif 227 228 /* 229 * Return the non-volatile counter value stored in the platform. The cookie 230 * will contain the OID of the counter in the certificate. 231 * 232 * Return: 0 = success, Otherwise = error 233 */ 234 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) 235 { 236 const char *oid; 237 uint32_t *nv_ctr_addr; 238 239 assert(cookie != NULL); 240 assert(nv_ctr != NULL); 241 242 oid = (const char *)cookie; 243 if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { 244 nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr, 245 TRUSTED_NV_CTR_ID); 246 } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { 247 nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr, 248 NON_TRUSTED_NV_CTR_ID); 249 } else { 250 return 1; 251 } 252 253 *nv_ctr = (unsigned int)(*nv_ctr_addr); 254 255 return 0; 256 } 257 258 /* 259 * Store a new non-volatile counter value. By default on ARM development 260 * platforms, the non-volatile counters are RO and cannot be modified. We expect 261 * the values in the certificates to always match the RO values so that this 262 * function is never called. 263 * 264 * Return: 0 = success, Otherwise = error 265 */ 266 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) 267 { 268 return 1; 269 } 270