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 */
juno_get_rotpk_info_regs(void ** key_ptr,unsigned int * key_len,unsigned int * flags)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 */
plat_get_rotpk_info(void * cookie,void ** key_ptr,unsigned int * key_len,unsigned int * flags)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