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