blob: 5df1cc014f293d80a9eceb664eb86812835888ac [file] [log] [blame]
Dan Handley9df48042015-03-19 18:58:55 +00001/*
Masahiro Yamadad1f97752017-05-23 19:41:36 +09002 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
Dan Handley9df48042015-03-19 18:58:55 +00003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Dan Handley9df48042015-03-19 18:58:55 +00005 */
6
Juan Castillo31a68f02015-04-14 12:49:03 +01007#include <arm_def.h>
8#include <assert.h>
9#include <platform.h>
10#include <stdint.h>
11#include <string.h>
Masahiro Yamadad1f97752017-05-23 19:41:36 +090012#include <tbbr_oid.h>
Juan Castillo31a68f02015-04-14 12:49:03 +010013
Dan Handley9df48042015-03-19 18:58:55 +000014/* Weak definition may be overridden in specific platform */
Juan Castillobfb7fa62016-01-22 11:05:57 +000015#pragma weak plat_get_nv_ctr
16#pragma weak plat_set_nv_ctr
Juan Castillo31a68f02015-04-14 12:49:03 +010017
18/* SHA256 algorithm */
19#define SHA256_BYTES 32
20
21/* ROTPK locations */
22#define ARM_ROTPK_REGS_ID 1
23#define ARM_ROTPK_DEVEL_RSA_ID 2
24
25#if !ARM_ROTPK_LOCATION_ID
26 #error "ARM_ROTPK_LOCATION_ID not defined"
27#endif
28
29static const unsigned char rotpk_hash_hdr[] = \
30 "\x30\x31\x30\x0D\x06\x09\x60\x86\x48" \
31 "\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
32static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1;
33static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES];
34
35#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
36static const unsigned char arm_devel_rotpk_hash[] = \
37 "\xB0\xF3\x82\x09\x12\x97\xD8\x3A" \
38 "\x37\x7A\x72\x47\x1B\xEC\x32\x73" \
39 "\xE9\x92\x32\xE2\x49\x59\xF6\x5E" \
40 "\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA";
41#endif
42
Dan Handley9df48042015-03-19 18:58:55 +000043/*
Juan Castillo31a68f02015-04-14 12:49:03 +010044 * Return the ROTPK hash in the following ASN.1 structure in DER format:
45 *
46 * AlgorithmIdentifier ::= SEQUENCE {
47 * algorithm OBJECT IDENTIFIER,
48 * parameters ANY DEFINED BY algorithm OPTIONAL
49 * }
50 *
51 * DigestInfo ::= SEQUENCE {
52 * digestAlgorithm AlgorithmIdentifier,
53 * digest OCTET STRING
54 * }
55 */
56int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
57 unsigned int *flags)
58{
59 uint8_t *dst;
60
61 assert(key_ptr != NULL);
62 assert(key_len != NULL);
63 assert(flags != NULL);
64
65 /* Copy the DER header */
66 memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
67 dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len];
68
69#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
70 memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES);
71#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
72 uint32_t *src, tmp;
73 unsigned int words, i;
74
75 /*
76 * Append the hash from Trusted Root-Key Storage registers. The hash has
77 * not been written linearly into the registers, so we have to do a bit
78 * of byte swapping:
79 *
80 * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C
81 * +---------------------------------------------------------------+
82 * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 |
83 * +---------------------------------------------------------------+
84 * | ... ... | | ... ... |
85 * | +--------------------+ | +-------+
86 * | | | |
87 * +----------------------------+ +----------------------------+
88 * | | | |
89 * +-------+ | +--------------------+ |
90 * | | | |
91 * v v v v
92 * +---------------------------------------------------------------+
93 * | | |
94 * +---------------------------------------------------------------+
95 * 0 15 16 31
96 *
97 * Additionally, we have to access the registers in 32-bit words
98 */
99 words = SHA256_BYTES >> 3;
100
101 /* Swap bytes 0-15 (first four registers) */
102 src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
103 for (i = 0 ; i < words ; i++) {
104 tmp = src[words - 1 - i];
105 /* Words are read in little endian */
106 *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
107 *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
108 *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
109 *dst++ = (uint8_t)(tmp & 0xFF);
110 }
111
112 /* Swap bytes 16-31 (last four registers) */
113 src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2);
114 for (i = 0 ; i < words ; i++) {
115 tmp = src[words - 1 - i];
116 *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
117 *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
118 *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
119 *dst++ = (uint8_t)(tmp & 0xFF);
120 }
121#endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) */
122
123 *key_ptr = (void *)rotpk_hash_der;
124 *key_len = (unsigned int)sizeof(rotpk_hash_der);
125 *flags = ROTPK_IS_HASH;
126 return 0;
127}
128
Juan Castillobfb7fa62016-01-22 11:05:57 +0000129/*
130 * Return the non-volatile counter value stored in the platform. The cookie
131 * will contain the OID of the counter in the certificate.
132 *
133 * Return: 0 = success, Otherwise = error
134 */
135int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
136{
137 const char *oid;
138 uint32_t *nv_ctr_addr;
139
140 assert(cookie != NULL);
141 assert(nv_ctr != NULL);
142
143 oid = (const char *)cookie;
144 if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
145 nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE;
146 } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
147 nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE;
148 } else {
149 return 1;
150 }
151
152 *nv_ctr = (unsigned int)(*nv_ctr_addr);
153
154 return 0;
155}
156
157/*
Antonio Nino Diaz9d602fe2016-05-20 14:14:16 +0100158 * Store a new non-volatile counter value. By default on ARM development
159 * platforms, the non-volatile counters are RO and cannot be modified. We expect
160 * the values in the certificates to always match the RO values so that this
161 * function is never called.
Juan Castillobfb7fa62016-01-22 11:05:57 +0000162 *
163 * Return: 0 = success, Otherwise = error
164 */
165int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
166{
167 return 1;
168}