1 /* 2 * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <arm_def.h> 32 #include <assert.h> 33 #include <platform.h> 34 #include <platform_oid.h> 35 #include <stdint.h> 36 #include <string.h> 37 38 /* Weak definition may be overridden in specific platform */ 39 #pragma weak plat_match_rotpk 40 #pragma weak plat_get_nv_ctr 41 #pragma weak plat_set_nv_ctr 42 43 /* SHA256 algorithm */ 44 #define SHA256_BYTES 32 45 46 /* ROTPK locations */ 47 #define ARM_ROTPK_REGS_ID 1 48 #define ARM_ROTPK_DEVEL_RSA_ID 2 49 50 #if !ARM_ROTPK_LOCATION_ID 51 #error "ARM_ROTPK_LOCATION_ID not defined" 52 #endif 53 54 static const unsigned char rotpk_hash_hdr[] = \ 55 "\x30\x31\x30\x0D\x06\x09\x60\x86\x48" \ 56 "\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"; 57 static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1; 58 static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES]; 59 60 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) 61 static const unsigned char arm_devel_rotpk_hash[] = \ 62 "\xB0\xF3\x82\x09\x12\x97\xD8\x3A" \ 63 "\x37\x7A\x72\x47\x1B\xEC\x32\x73" \ 64 "\xE9\x92\x32\xE2\x49\x59\xF6\x5E" \ 65 "\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA"; 66 #endif 67 68 /* 69 * Return the ROTPK hash in the following ASN.1 structure in DER format: 70 * 71 * AlgorithmIdentifier ::= SEQUENCE { 72 * algorithm OBJECT IDENTIFIER, 73 * parameters ANY DEFINED BY algorithm OPTIONAL 74 * } 75 * 76 * DigestInfo ::= SEQUENCE { 77 * digestAlgorithm AlgorithmIdentifier, 78 * digest OCTET STRING 79 * } 80 */ 81 int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, 82 unsigned int *flags) 83 { 84 uint8_t *dst; 85 86 assert(key_ptr != NULL); 87 assert(key_len != NULL); 88 assert(flags != NULL); 89 90 /* Copy the DER header */ 91 memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len); 92 dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len]; 93 94 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) 95 memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES); 96 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) 97 uint32_t *src, tmp; 98 unsigned int words, i; 99 100 /* 101 * Append the hash from Trusted Root-Key Storage registers. The hash has 102 * not been written linearly into the registers, so we have to do a bit 103 * of byte swapping: 104 * 105 * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C 106 * +---------------------------------------------------------------+ 107 * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 | 108 * +---------------------------------------------------------------+ 109 * | ... ... | | ... ... | 110 * | +--------------------+ | +-------+ 111 * | | | | 112 * +----------------------------+ +----------------------------+ 113 * | | | | 114 * +-------+ | +--------------------+ | 115 * | | | | 116 * v v v v 117 * +---------------------------------------------------------------+ 118 * | | | 119 * +---------------------------------------------------------------+ 120 * 0 15 16 31 121 * 122 * Additionally, we have to access the registers in 32-bit words 123 */ 124 words = SHA256_BYTES >> 3; 125 126 /* Swap bytes 0-15 (first four registers) */ 127 src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; 128 for (i = 0 ; i < words ; i++) { 129 tmp = src[words - 1 - i]; 130 /* Words are read in little endian */ 131 *dst++ = (uint8_t)((tmp >> 24) & 0xFF); 132 *dst++ = (uint8_t)((tmp >> 16) & 0xFF); 133 *dst++ = (uint8_t)((tmp >> 8) & 0xFF); 134 *dst++ = (uint8_t)(tmp & 0xFF); 135 } 136 137 /* Swap bytes 16-31 (last four registers) */ 138 src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2); 139 for (i = 0 ; i < words ; i++) { 140 tmp = src[words - 1 - i]; 141 *dst++ = (uint8_t)((tmp >> 24) & 0xFF); 142 *dst++ = (uint8_t)((tmp >> 16) & 0xFF); 143 *dst++ = (uint8_t)((tmp >> 8) & 0xFF); 144 *dst++ = (uint8_t)(tmp & 0xFF); 145 } 146 #endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) */ 147 148 *key_ptr = (void *)rotpk_hash_der; 149 *key_len = (unsigned int)sizeof(rotpk_hash_der); 150 *flags = ROTPK_IS_HASH; 151 return 0; 152 } 153 154 /* 155 * Return the non-volatile counter value stored in the platform. The cookie 156 * will contain the OID of the counter in the certificate. 157 * 158 * Return: 0 = success, Otherwise = error 159 */ 160 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) 161 { 162 const char *oid; 163 uint32_t *nv_ctr_addr; 164 165 assert(cookie != NULL); 166 assert(nv_ctr != NULL); 167 168 oid = (const char *)cookie; 169 if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { 170 nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE; 171 } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { 172 nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE; 173 } else { 174 return 1; 175 } 176 177 *nv_ctr = (unsigned int)(*nv_ctr_addr); 178 179 return 0; 180 } 181 182 /* 183 * Store a new non-volatile counter value. By default on ARM development 184 * platforms, the non-volatile counters are RO and cannot be modified. We expect 185 * the values in the certificates to always match the RO values so that this 186 * function is never called. 187 * 188 * Return: 0 = success, Otherwise = error 189 */ 190 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) 191 { 192 return 1; 193 } 194