127 lines
4.0 KiB
C
127 lines
4.0 KiB
C
/*
|
|
* Copyright (c) 2019-2020, ARM Limited. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include <drivers/arm/cryptocell/cc_rotpk.h>
|
|
#include <plat/arm/common/plat_arm.h>
|
|
#include <plat/common/common_def.h>
|
|
#include <plat/common/platform.h>
|
|
|
|
#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
|
|
|
|
static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
|
|
|
|
extern unsigned char arm_rotpk_header[];
|
|
|
|
/*
|
|
* Return the ROTPK hash stored in the registers of Juno board.
|
|
*/
|
|
static int juno_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
|
|
unsigned int *flags)
|
|
{
|
|
uint8_t *dst;
|
|
uint32_t *src, tmp;
|
|
unsigned int words, i;
|
|
|
|
assert(key_ptr != NULL);
|
|
assert(key_len != NULL);
|
|
assert(flags != NULL);
|
|
|
|
/* Copy the DER header */
|
|
memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
|
|
dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
|
|
|
|
|
|
/*
|
|
* Append the hash from Trusted Root-Key Storage registers. The hash has
|
|
* not been written linearly into the registers, so we have to do a bit
|
|
* of byte swapping:
|
|
*
|
|
* 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C
|
|
* +---------------------------------------------------------------+
|
|
* | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 |
|
|
* +---------------------------------------------------------------+
|
|
* | ... ... | | ... ... |
|
|
* | +--------------------+ | +-------+
|
|
* | | | |
|
|
* +----------------------------+ +----------------------------+
|
|
* | | | |
|
|
* +-------+ | +--------------------+ |
|
|
* | | | |
|
|
* v v v v
|
|
* +---------------------------------------------------------------+
|
|
* | | |
|
|
* +---------------------------------------------------------------+
|
|
* 0 15 16 31
|
|
*
|
|
* Additionally, we have to access the registers in 32-bit words
|
|
*/
|
|
words = ARM_ROTPK_HASH_LEN >> 3;
|
|
|
|
/* Swap bytes 0-15 (first four registers) */
|
|
src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
|
|
for (i = 0 ; i < words ; i++) {
|
|
tmp = src[words - 1 - i];
|
|
/* Words are read in little endian */
|
|
*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
|
|
*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
|
|
*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
|
|
*dst++ = (uint8_t)(tmp & 0xFF);
|
|
}
|
|
|
|
/* Swap bytes 16-31 (last four registers) */
|
|
src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + ARM_ROTPK_HASH_LEN / 2);
|
|
for (i = 0 ; i < words ; i++) {
|
|
tmp = src[words - 1 - i];
|
|
*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
|
|
*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
|
|
*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
|
|
*dst++ = (uint8_t)(tmp & 0xFF);
|
|
}
|
|
|
|
*key_ptr = (void *)rotpk_hash_der;
|
|
*key_len = (unsigned int)sizeof(rotpk_hash_der);
|
|
*flags = ROTPK_IS_HASH;
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
/*
|
|
* Return the ROTPK hash in the following ASN.1 structure in DER format:
|
|
*
|
|
* AlgorithmIdentifier ::= SEQUENCE {
|
|
* algorithm OBJECT IDENTIFIER,
|
|
* parameters ANY DEFINED BY algorithm OPTIONAL
|
|
* }
|
|
*
|
|
* DigestInfo ::= SEQUENCE {
|
|
* digestAlgorithm AlgorithmIdentifier,
|
|
* digest OCTET STRING
|
|
* }
|
|
*/
|
|
int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
|
|
unsigned int *flags)
|
|
{
|
|
#if ARM_CRYPTOCELL_INTEG
|
|
return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
|
|
#else
|
|
|
|
#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
|
|
(ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
|
|
return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
|
|
#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
|
|
return juno_get_rotpk_info_regs(key_ptr, key_len, flags);
|
|
#else
|
|
return 1;
|
|
#endif
|
|
|
|
#endif /* ARM_CRYPTOCELL_INTEG */
|
|
}
|