xref: /arm-trusted-firmware/plat/arm/board/juno/juno_trusted_boot.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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