1 /* 2 * Copyright (c) 2015-2020, 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 <plat/arm/common/plat_arm.h> 16 #include <plat/common/common_def.h> 17 #include <plat/common/platform.h> 18 #include <platform_def.h> 19 20 #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 25 26 #if !ARM_CRYPTOCELL_INTEG 27 #if !ARM_ROTPK_LOCATION_ID 28 #error "ARM_ROTPK_LOCATION_ID not defined" 29 #endif 30 #endif 31 32 /* Weak definition may be overridden in specific platform */ 33 #pragma weak plat_get_nv_ctr 34 #pragma weak plat_set_nv_ctr 35 36 extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[]; 37 38 static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; 39 40 /* 41 * Return the ROTPK hash stored in dedicated registers. 42 */ 43 int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, 44 unsigned int *flags) 45 { 46 uint8_t *dst; 47 uint32_t *src, tmp; 48 unsigned int words, i; 49 50 assert(key_ptr != NULL); 51 assert(key_len != NULL); 52 assert(flags != NULL); 53 54 /* Copy the DER header */ 55 56 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); 57 dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; 58 59 words = ARM_ROTPK_HASH_LEN >> 2; 60 61 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 */ 65 *dst++ = (uint8_t)(tmp & 0xFF); 66 *dst++ = (uint8_t)((tmp >> 8) & 0xFF); 67 *dst++ = (uint8_t)((tmp >> 16) & 0xFF); 68 *dst++ = (uint8_t)((tmp >> 24) & 0xFF); 69 } 70 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 77 #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 */ 82 int 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 */ 96 int 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 /* 115 * Wrapper function for most Arm platforms to get ROTPK hash. 116 */ 117 static int get_rotpk_info(void **key_ptr, unsigned int *key_len, 118 unsigned int *flags) 119 { 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 132 #endif /* ARM_CRYPTOCELL_INTEG */ 133 } 134 135 #if defined(ARM_COT_tbbr) 136 137 int 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 145 int 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 170 /* 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 */ 176 int 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 /* 199 * 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. 203 * 204 * Return: 0 = success, Otherwise = error 205 */ 206 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) 207 { 208 return 1; 209 } 210