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