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