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_hash_end[]; 51 52 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) || ARM_CRYPTOCELL_INTEG 53 static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; 54 #endif 55 56 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) 57 /* 58 * Return the ROTPK hash stored in dedicated registers. 59 */ 60 int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, 61 unsigned int *flags) 62 { 63 uint8_t *dst; 64 uint32_t *src, tmp; 65 unsigned int words, i; 66 67 assert(key_ptr != NULL); 68 assert(key_len != NULL); 69 assert(flags != NULL); 70 71 /* Copy the DER header */ 72 73 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); 74 dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; 75 76 words = ARM_ROTPK_HASH_LEN >> 2; 77 78 src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; 79 for (i = 0 ; i < words ; i++) { 80 tmp = src[words - 1 - i]; 81 /* Words are read in little endian */ 82 *dst++ = (uint8_t)(tmp & 0xFF); 83 *dst++ = (uint8_t)((tmp >> 8) & 0xFF); 84 *dst++ = (uint8_t)((tmp >> 16) & 0xFF); 85 *dst++ = (uint8_t)((tmp >> 24) & 0xFF); 86 } 87 88 *key_ptr = (void *)rotpk_hash_der; 89 *key_len = (unsigned int)sizeof(rotpk_hash_der); 90 *flags = ROTPK_IS_HASH; 91 return 0; 92 } 93 #endif 94 95 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ 96 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) 97 /* 98 * Return development ROTPK hash generated from ROT_KEY. 99 */ 100 int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len, 101 unsigned int *flags) 102 { 103 *key_ptr = arm_rotpk_header; 104 *key_len = arm_rotpk_hash_end - arm_rotpk_header; 105 *flags = ROTPK_IS_HASH; 106 return 0; 107 } 108 #endif 109 110 #if ARM_CRYPTOCELL_INTEG 111 /* 112 * Return ROTPK hash from CryptoCell. 113 */ 114 int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len, 115 unsigned int *flags) 116 { 117 unsigned char *dst; 118 119 assert(key_ptr != NULL); 120 assert(key_len != NULL); 121 assert(flags != NULL); 122 123 /* Copy the DER header */ 124 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); 125 dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; 126 *key_ptr = rotpk_hash_der; 127 *key_len = sizeof(rotpk_hash_der); 128 return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags); 129 } 130 #endif 131 132 /* 133 * Wrapper function for most Arm platforms to get ROTPK hash. 134 */ 135 static int get_rotpk_info(void **key_ptr, unsigned int *key_len, 136 unsigned int *flags) 137 { 138 #if ARM_CRYPTOCELL_INTEG 139 return arm_get_rotpk_info_cc(key_ptr, key_len, flags); 140 #else 141 142 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ 143 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) 144 return arm_get_rotpk_info_dev(key_ptr, key_len, flags); 145 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) 146 return arm_get_rotpk_info_regs(key_ptr, key_len, flags); 147 #else 148 return 1; 149 #endif 150 #endif /* ARM_CRYPTOCELL_INTEG */ 151 } 152 153 #if defined(ARM_COT_tbbr) 154 155 int arm_get_rotpk_info(void *cookie __unused, void **key_ptr, 156 unsigned int *key_len, unsigned int *flags) 157 { 158 return get_rotpk_info(key_ptr, key_len, flags); 159 } 160 161 #elif defined(ARM_COT_dualroot) 162 163 int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, 164 unsigned int *flags) 165 { 166 /* 167 * Return the right root of trust key hash based on the cookie value: 168 * - NULL means the primary ROTPK. 169 * - Otherwise, interpret cookie as the OID of the certificate 170 * extension containing the key. 171 */ 172 if (cookie == NULL) { 173 return get_rotpk_info(key_ptr, key_len, flags); 174 } else if (strcmp(cookie, PROT_PK_OID) == 0) { 175 extern unsigned char arm_protpk_hash[]; 176 extern unsigned char arm_protpk_hash_end[]; 177 *key_ptr = arm_protpk_hash; 178 *key_len = arm_protpk_hash_end - arm_protpk_hash; 179 *flags = ROTPK_IS_HASH; 180 return 0; 181 } else { 182 /* Invalid key ID. */ 183 return 1; 184 } 185 } 186 187 #elif defined(ARM_COT_cca) 188 189 int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, 190 unsigned int *flags) 191 { 192 /* 193 * Return the right root of trust key hash based on the cookie value: 194 * - NULL means the primary ROTPK. 195 * - Otherwise, interpret cookie as the OID of the certificate 196 * extension containing the key. 197 */ 198 if (cookie == NULL) { 199 return get_rotpk_info(key_ptr, key_len, flags); 200 } else if (strcmp(cookie, PROT_PK_OID) == 0) { 201 extern unsigned char arm_protpk_hash[]; 202 extern unsigned char arm_protpk_hash_end[]; 203 *key_ptr = arm_protpk_hash; 204 *key_len = arm_protpk_hash_end - arm_protpk_hash; 205 *flags = ROTPK_IS_HASH; 206 return 0; 207 } else if (strcmp(cookie, SWD_ROT_PK_OID) == 0) { 208 extern unsigned char arm_swd_rotpk_hash[]; 209 extern unsigned char arm_swd_rotpk_hash_end[]; 210 *key_ptr = arm_swd_rotpk_hash; 211 *key_len = arm_swd_rotpk_hash_end - arm_swd_rotpk_hash; 212 *flags = ROTPK_IS_HASH; 213 return 0; 214 } else { 215 /* Invalid key ID. */ 216 return 1; 217 } 218 } 219 220 #endif 221 222 /* 223 * Return the non-volatile counter value stored in the platform. The cookie 224 * will contain the OID of the counter in the certificate. 225 * 226 * Return: 0 = success, Otherwise = error 227 */ 228 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) 229 { 230 const char *oid; 231 uint32_t *nv_ctr_addr; 232 233 assert(cookie != NULL); 234 assert(nv_ctr != NULL); 235 236 oid = (const char *)cookie; 237 if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { 238 nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr, 239 TRUSTED_NV_CTR_ID); 240 } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { 241 nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr, 242 NON_TRUSTED_NV_CTR_ID); 243 } else { 244 return 1; 245 } 246 247 *nv_ctr = (unsigned int)(*nv_ctr_addr); 248 249 return 0; 250 } 251 252 /* 253 * Store a new non-volatile counter value. By default on ARM development 254 * platforms, the non-volatile counters are RO and cannot be modified. We expect 255 * the values in the certificates to always match the RO values so that this 256 * function is never called. 257 * 258 * Return: 0 = success, Otherwise = error 259 */ 260 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) 261 { 262 return 1; 263 } 264