1 /* 2 * Copyright (c) 2015, 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 <stdint.h> 35 #include <string.h> 36 37 /* Weak definition may be overridden in specific platform */ 38 #pragma weak plat_match_rotpk 39 40 /* SHA256 algorithm */ 41 #define SHA256_BYTES 32 42 43 /* ROTPK locations */ 44 #define ARM_ROTPK_REGS_ID 1 45 #define ARM_ROTPK_DEVEL_RSA_ID 2 46 47 #if !ARM_ROTPK_LOCATION_ID 48 #error "ARM_ROTPK_LOCATION_ID not defined" 49 #endif 50 51 static const unsigned char rotpk_hash_hdr[] = \ 52 "\x30\x31\x30\x0D\x06\x09\x60\x86\x48" \ 53 "\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"; 54 static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1; 55 static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES]; 56 57 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) 58 static const unsigned char arm_devel_rotpk_hash[] = \ 59 "\xB0\xF3\x82\x09\x12\x97\xD8\x3A" \ 60 "\x37\x7A\x72\x47\x1B\xEC\x32\x73" \ 61 "\xE9\x92\x32\xE2\x49\x59\xF6\x5E" \ 62 "\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA"; 63 #endif 64 65 /* 66 * Return the ROTPK hash in the following ASN.1 structure in DER format: 67 * 68 * AlgorithmIdentifier ::= SEQUENCE { 69 * algorithm OBJECT IDENTIFIER, 70 * parameters ANY DEFINED BY algorithm OPTIONAL 71 * } 72 * 73 * DigestInfo ::= SEQUENCE { 74 * digestAlgorithm AlgorithmIdentifier, 75 * digest OCTET STRING 76 * } 77 */ 78 int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, 79 unsigned int *flags) 80 { 81 uint8_t *dst; 82 83 assert(key_ptr != NULL); 84 assert(key_len != NULL); 85 assert(flags != NULL); 86 87 /* Copy the DER header */ 88 memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len); 89 dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len]; 90 91 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) 92 memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES); 93 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) 94 uint32_t *src, tmp; 95 unsigned int words, i; 96 97 /* 98 * Append the hash from Trusted Root-Key Storage registers. The hash has 99 * not been written linearly into the registers, so we have to do a bit 100 * of byte swapping: 101 * 102 * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C 103 * +---------------------------------------------------------------+ 104 * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 | 105 * +---------------------------------------------------------------+ 106 * | ... ... | | ... ... | 107 * | +--------------------+ | +-------+ 108 * | | | | 109 * +----------------------------+ +----------------------------+ 110 * | | | | 111 * +-------+ | +--------------------+ | 112 * | | | | 113 * v v v v 114 * +---------------------------------------------------------------+ 115 * | | | 116 * +---------------------------------------------------------------+ 117 * 0 15 16 31 118 * 119 * Additionally, we have to access the registers in 32-bit words 120 */ 121 words = SHA256_BYTES >> 3; 122 123 /* Swap bytes 0-15 (first four registers) */ 124 src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; 125 for (i = 0 ; i < words ; i++) { 126 tmp = src[words - 1 - i]; 127 /* Words are read in little endian */ 128 *dst++ = (uint8_t)((tmp >> 24) & 0xFF); 129 *dst++ = (uint8_t)((tmp >> 16) & 0xFF); 130 *dst++ = (uint8_t)((tmp >> 8) & 0xFF); 131 *dst++ = (uint8_t)(tmp & 0xFF); 132 } 133 134 /* Swap bytes 16-31 (last four registers) */ 135 src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2); 136 for (i = 0 ; i < words ; i++) { 137 tmp = src[words - 1 - i]; 138 *dst++ = (uint8_t)((tmp >> 24) & 0xFF); 139 *dst++ = (uint8_t)((tmp >> 16) & 0xFF); 140 *dst++ = (uint8_t)((tmp >> 8) & 0xFF); 141 *dst++ = (uint8_t)(tmp & 0xFF); 142 } 143 #endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) */ 144 145 *key_ptr = (void *)rotpk_hash_der; 146 *key_len = (unsigned int)sizeof(rotpk_hash_der); 147 *flags = ROTPK_IS_HASH; 148 return 0; 149 } 150 151