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