1 /* 2 * Copyright (c) 2019-2020, ARM Limited. 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 <drivers/arm/cryptocell/cc_rotpk.h> 12 #include <plat/arm/common/plat_arm.h> 13 #include <plat/common/common_def.h> 14 #include <plat/common/platform.h> 15 16 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) 17 18 static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; 19 20 extern unsigned char arm_rotpk_header[]; 21 22 /* 23 * Return the ROTPK hash stored in the registers of Juno board. 24 */ 25 static int juno_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, 26 unsigned int *flags) 27 { 28 uint8_t *dst; 29 uint32_t *src, tmp; 30 unsigned int words, i; 31 32 assert(key_ptr != NULL); 33 assert(key_len != NULL); 34 assert(flags != NULL); 35 36 /* Copy the DER header */ 37 memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); 38 dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; 39 40 41 /* 42 * Append the hash from Trusted Root-Key Storage registers. The hash has 43 * not been written linearly into the registers, so we have to do a bit 44 * of byte swapping: 45 * 46 * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C 47 * +---------------------------------------------------------------+ 48 * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 | 49 * +---------------------------------------------------------------+ 50 * | ... ... | | ... ... | 51 * | +--------------------+ | +-------+ 52 * | | | | 53 * +----------------------------+ +----------------------------+ 54 * | | | | 55 * +-------+ | +--------------------+ | 56 * | | | | 57 * v v v v 58 * +---------------------------------------------------------------+ 59 * | | | 60 * +---------------------------------------------------------------+ 61 * 0 15 16 31 62 * 63 * Additionally, we have to access the registers in 32-bit words 64 */ 65 words = ARM_ROTPK_HASH_LEN >> 3; 66 67 /* Swap bytes 0-15 (first four registers) */ 68 src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; 69 for (i = 0 ; i < words ; i++) { 70 tmp = src[words - 1 - i]; 71 /* Words are read in little endian */ 72 *dst++ = (uint8_t)((tmp >> 24) & 0xFF); 73 *dst++ = (uint8_t)((tmp >> 16) & 0xFF); 74 *dst++ = (uint8_t)((tmp >> 8) & 0xFF); 75 *dst++ = (uint8_t)(tmp & 0xFF); 76 } 77 78 /* Swap bytes 16-31 (last four registers) */ 79 src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + ARM_ROTPK_HASH_LEN / 2); 80 for (i = 0 ; i < words ; i++) { 81 tmp = src[words - 1 - i]; 82 *dst++ = (uint8_t)((tmp >> 24) & 0xFF); 83 *dst++ = (uint8_t)((tmp >> 16) & 0xFF); 84 *dst++ = (uint8_t)((tmp >> 8) & 0xFF); 85 *dst++ = (uint8_t)(tmp & 0xFF); 86 } 87 88 *key_ptr = (void *)rotpk_hash_der; 89 *key_len = (unsigned int)sizeof(rotpk_hash_der); 90 *flags = ROTPK_IS_HASH; 91 return 0; 92 } 93 94 #endif 95 96 /* 97 * Return the ROTPK hash in the following ASN.1 structure in DER format: 98 * 99 * AlgorithmIdentifier ::= SEQUENCE { 100 * algorithm OBJECT IDENTIFIER, 101 * parameters ANY DEFINED BY algorithm OPTIONAL 102 * } 103 * 104 * DigestInfo ::= SEQUENCE { 105 * digestAlgorithm AlgorithmIdentifier, 106 * digest OCTET STRING 107 * } 108 */ 109 int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, 110 unsigned int *flags) 111 { 112 #if ARM_CRYPTOCELL_INTEG 113 return arm_get_rotpk_info_cc(key_ptr, key_len, flags); 114 #else 115 116 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ 117 (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) 118 return arm_get_rotpk_info_dev(key_ptr, key_len, flags); 119 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) 120 return juno_get_rotpk_info_regs(key_ptr, key_len, flags); 121 #else 122 return 1; 123 #endif 124 125 #endif /* ARM_CRYPTOCELL_INTEG */ 126 } 127