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 #include <tools_share/tbbr_oid.h> 20 21 22 #if !ARM_CRYPTOCELL_INTEG 23 #if !ARM_ROTPK_LOCATION_ID 24 #error "ARM_ROTPK_LOCATION_ID not defined" 25 #endif 26 #endif 27 28 /* Weak definition may be overridden in specific platform */ 29 #pragma weak plat_get_nv_ctr 30 #pragma weak plat_set_nv_ctr 31 32 extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[]; 33 34 static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; 35 36 /* 37 * Return the ROTPK hash stored in dedicated registers. 38 */ 39 int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, 40 unsigned int *flags) 41 { 42 uint8_t *dst; 43 uint32_t *src, tmp; 44 unsigned int words, i; 45 46 assert(key_ptr != NULL); 47 assert(key_len != NULL); 48 assert(flags != NULL); 49 50 /* Copy the DER header */ 51 52 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); 53 dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; 54 55 words = ARM_ROTPK_HASH_LEN >> 2; 56 57 src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; 58 for (i = 0 ; i < words ; i++) { 59 tmp = src[words - 1 - i]; 60 /* Words are read in little endian */ 61 *dst++ = (uint8_t)(tmp & 0xFF); 62 *dst++ = (uint8_t)((tmp >> 8) & 0xFF); 63 *dst++ = (uint8_t)((tmp >> 16) & 0xFF); 64 *dst++ = (uint8_t)((tmp >> 24) & 0xFF); 65 } 66 67 *key_ptr = (void *)rotpk_hash_der; 68 *key_len = (unsigned int)sizeof(rotpk_hash_der); 69 *flags = ROTPK_IS_HASH; 70 return 0; 71 } 72 73 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ 74 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) 75 /* 76 * Return development ROTPK hash generated from ROT_KEY. 77 */ 78 int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len, 79 unsigned int *flags) 80 { 81 *key_ptr = arm_rotpk_header; 82 *key_len = arm_rotpk_hash_end - arm_rotpk_header; 83 *flags = ROTPK_IS_HASH; 84 return 0; 85 } 86 #endif 87 88 #if ARM_CRYPTOCELL_INTEG 89 /* 90 * Return ROTPK hash from CryptoCell. 91 */ 92 int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len, 93 unsigned int *flags) 94 { 95 unsigned char *dst; 96 97 assert(key_ptr != NULL); 98 assert(key_len != NULL); 99 assert(flags != NULL); 100 101 /* Copy the DER header */ 102 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); 103 dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; 104 *key_ptr = rotpk_hash_der; 105 *key_len = sizeof(rotpk_hash_der); 106 return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags); 107 } 108 #endif 109 110 /* 111 * Wraper function for most Arm platforms to get ROTPK hash. 112 */ 113 int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len, 114 unsigned int *flags) 115 { 116 #if ARM_CRYPTOCELL_INTEG 117 return arm_get_rotpk_info_cc(key_ptr, key_len, flags); 118 #else 119 120 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ 121 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) 122 return arm_get_rotpk_info_dev(key_ptr, key_len, flags); 123 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) 124 return arm_get_rotpk_info_regs(key_ptr, key_len, flags); 125 #else 126 return 1; 127 #endif 128 129 #endif /* ARM_CRYPTOCELL_INTEG */ 130 } 131 132 /* 133 * Return the non-volatile counter value stored in the platform. The cookie 134 * will contain the OID of the counter in the certificate. 135 * 136 * Return: 0 = success, Otherwise = error 137 */ 138 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) 139 { 140 const char *oid; 141 uint32_t *nv_ctr_addr; 142 143 assert(cookie != NULL); 144 assert(nv_ctr != NULL); 145 146 oid = (const char *)cookie; 147 if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { 148 nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE; 149 } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { 150 nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE; 151 } else { 152 return 1; 153 } 154 155 *nv_ctr = (unsigned int)(*nv_ctr_addr); 156 157 return 0; 158 } 159 160 /* 161 * Store a new non-volatile counter value. By default on ARM development 162 * platforms, the non-volatile counters are RO and cannot be modified. We expect 163 * the values in the certificates to always match the RO values so that this 164 * function is never called. 165 * 166 * Return: 0 = success, Otherwise = error 167 */ 168 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) 169 { 170 return 1; 171 } 172