xref: /rk3399_ARM-atf/plat/brcm/board/common/board_arm_trusted_boot.c (revision 2242773ddbd959677af69d9df3aba3fd1b0bb4e1)
1f29d1e0cSSheetal Tigadoli /*
2f29d1e0cSSheetal Tigadoli  * Copyright 2015 - 2020 Broadcom
3f29d1e0cSSheetal Tigadoli  *
4f29d1e0cSSheetal Tigadoli  * SPDX-License-Identifier: BSD-3-Clause
5f29d1e0cSSheetal Tigadoli  */
6f29d1e0cSSheetal Tigadoli 
7f29d1e0cSSheetal Tigadoli #include <assert.h>
8*4ef449c1SManish Pandey #include <inttypes.h>
9f29d1e0cSSheetal Tigadoli #include <stdint.h>
10f29d1e0cSSheetal Tigadoli #include <string.h>
11f29d1e0cSSheetal Tigadoli 
12f29d1e0cSSheetal Tigadoli #include <common/debug.h>
13f29d1e0cSSheetal Tigadoli #include <lib/mmio.h>
14f29d1e0cSSheetal Tigadoli #include <plat/common/platform.h>
15f29d1e0cSSheetal Tigadoli #include <tools_share/tbbr_oid.h>
16f29d1e0cSSheetal Tigadoli 
17f29d1e0cSSheetal Tigadoli #include <sbl_util.h>
18f29d1e0cSSheetal Tigadoli #include <sotp.h>
19f29d1e0cSSheetal Tigadoli 
20f29d1e0cSSheetal Tigadoli /* Weak definition may be overridden in specific platform */
21f29d1e0cSSheetal Tigadoli #pragma weak plat_match_rotpk
22f29d1e0cSSheetal Tigadoli #pragma weak plat_get_nv_ctr
23f29d1e0cSSheetal Tigadoli #pragma weak plat_set_nv_ctr
24f29d1e0cSSheetal Tigadoli 
25f29d1e0cSSheetal Tigadoli /* SHA256 algorithm */
26f29d1e0cSSheetal Tigadoli #define SHA256_BYTES			32
27f29d1e0cSSheetal Tigadoli 
28f29d1e0cSSheetal Tigadoli /* ROTPK locations */
29f29d1e0cSSheetal Tigadoli #define ARM_ROTPK_REGS_ID		1
30f29d1e0cSSheetal Tigadoli #define ARM_ROTPK_DEVEL_RSA_ID		2
31f29d1e0cSSheetal Tigadoli #define BRCM_ROTPK_SOTP_RSA_ID		3
32f29d1e0cSSheetal Tigadoli 
33f29d1e0cSSheetal Tigadoli #if !ARM_ROTPK_LOCATION_ID
34f29d1e0cSSheetal Tigadoli   #error "ARM_ROTPK_LOCATION_ID not defined"
35f29d1e0cSSheetal Tigadoli #endif
36f29d1e0cSSheetal Tigadoli 
37f29d1e0cSSheetal Tigadoli static const unsigned char rotpk_hash_hdr[] =
38f29d1e0cSSheetal Tigadoli 		"\x30\x31\x30\x0D\x06\x09\x60\x86\x48"
39f29d1e0cSSheetal Tigadoli 		"\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
40f29d1e0cSSheetal Tigadoli static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1;
41f29d1e0cSSheetal Tigadoli static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES];
42f29d1e0cSSheetal Tigadoli 
43f29d1e0cSSheetal Tigadoli #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
44f29d1e0cSSheetal Tigadoli static const unsigned char arm_devel_rotpk_hash[] =
45f29d1e0cSSheetal Tigadoli 		"\xB0\xF3\x82\x09\x12\x97\xD8\x3A"
46f29d1e0cSSheetal Tigadoli 		"\x37\x7A\x72\x47\x1B\xEC\x32\x73"
47f29d1e0cSSheetal Tigadoli 		"\xE9\x92\x32\xE2\x49\x59\xF6\x5E"
48f29d1e0cSSheetal Tigadoli 		"\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA";
49f29d1e0cSSheetal Tigadoli #endif
50f29d1e0cSSheetal Tigadoli 
51f29d1e0cSSheetal Tigadoli #pragma weak plat_rotpk_hash
52f29d1e0cSSheetal Tigadoli const unsigned char plat_rotpk_hash[] =
53f29d1e0cSSheetal Tigadoli 		"\xdb\x06\x67\x95\x4f\x88\x2b\x88"
54f29d1e0cSSheetal Tigadoli 		"\x49\xbf\x70\x3f\xde\x50\x4a\x96"
55f29d1e0cSSheetal Tigadoli 		"\xd8\x17\x69\xd4\xa0\x6c\xba\xee"
56f29d1e0cSSheetal Tigadoli 		"\x66\x3e\x71\x82\x2d\x95\x69\xe4";
57f29d1e0cSSheetal Tigadoli 
58f29d1e0cSSheetal Tigadoli #pragma weak rom_slice
59f29d1e0cSSheetal Tigadoli const unsigned char rom_slice[] =
60f29d1e0cSSheetal Tigadoli 		"\x77\x06\xbc\x98\x40\xbe\xfd\xab"
61f29d1e0cSSheetal Tigadoli 		"\x60\x4b\x74\x3c\x9a\xb3\x80\x75"
62f29d1e0cSSheetal Tigadoli 		"\x39\xb6\xda\x27\x07\x2e\x5b\xbf"
63f29d1e0cSSheetal Tigadoli 		"\x5c\x47\x91\xc9\x95\x26\x26\x0c";
64f29d1e0cSSheetal Tigadoli 
65f29d1e0cSSheetal Tigadoli #if (ARM_ROTPK_LOCATION_ID == BRCM_ROTPK_SOTP_RSA_ID)
plat_is_trusted_boot(void)66f29d1e0cSSheetal Tigadoli static int plat_is_trusted_boot(void)
67f29d1e0cSSheetal Tigadoli {
68f29d1e0cSSheetal Tigadoli 	uint64_t section3_row0_data;
69f29d1e0cSSheetal Tigadoli 
70f29d1e0cSSheetal Tigadoli 	section3_row0_data = sotp_mem_read(SOTP_DEVICE_SECURE_CFG0_ROW, 0);
71f29d1e0cSSheetal Tigadoli 
72f29d1e0cSSheetal Tigadoli 	if ((section3_row0_data & SOTP_DEVICE_SECURE_CFG0_AB_MASK) == 0) {
73f29d1e0cSSheetal Tigadoli 		INFO("NOT AB\n");
74f29d1e0cSSheetal Tigadoli 		return 0;
75f29d1e0cSSheetal Tigadoli 	}
76f29d1e0cSSheetal Tigadoli 
77f29d1e0cSSheetal Tigadoli 	INFO("AB\n");
78f29d1e0cSSheetal Tigadoli 	return TRUSTED_BOARD_BOOT;
79f29d1e0cSSheetal Tigadoli }
80f29d1e0cSSheetal Tigadoli 
81f29d1e0cSSheetal Tigadoli /*
82f29d1e0cSSheetal Tigadoli  * FAST AUTH is enabled if all following conditions are met:
83f29d1e0cSSheetal Tigadoli  * - AB part
84f29d1e0cSSheetal Tigadoli  * - SOTP.DEV != 0
85f29d1e0cSSheetal Tigadoli  * - SOTP.CID != 0
86f29d1e0cSSheetal Tigadoli  * - SOTP.ENC_DEV_TYPE = ENC_AB_DEV
87f29d1e0cSSheetal Tigadoli  * - Manuf_debug strap set high
88f29d1e0cSSheetal Tigadoli  */
plat_fast_auth_enabled(void)89f29d1e0cSSheetal Tigadoli static int plat_fast_auth_enabled(void)
90f29d1e0cSSheetal Tigadoli {
91f29d1e0cSSheetal Tigadoli 	uint32_t chip_state;
92f29d1e0cSSheetal Tigadoli 	uint64_t section3_row0_data;
93f29d1e0cSSheetal Tigadoli 	uint64_t section3_row1_data;
94f29d1e0cSSheetal Tigadoli 
95f29d1e0cSSheetal Tigadoli 	section3_row0_data =
96f29d1e0cSSheetal Tigadoli 		sotp_mem_read(SOTP_DEVICE_SECURE_CFG0_ROW, 0);
97f29d1e0cSSheetal Tigadoli 	section3_row1_data =
98f29d1e0cSSheetal Tigadoli 		sotp_mem_read(SOTP_DEVICE_SECURE_CFG1_ROW, 0);
99f29d1e0cSSheetal Tigadoli 
100f29d1e0cSSheetal Tigadoli 	chip_state = mmio_read_32(SOTP_REGS_SOTP_CHIP_STATES);
101f29d1e0cSSheetal Tigadoli 
102f29d1e0cSSheetal Tigadoli 	if (plat_is_trusted_boot() &&
103f29d1e0cSSheetal Tigadoli 	    (section3_row0_data & SOTP_DEVICE_SECURE_CFG0_DEV_MASK) &&
104f29d1e0cSSheetal Tigadoli 	    (section3_row0_data & SOTP_DEVICE_SECURE_CFG0_CID_MASK) &&
105f29d1e0cSSheetal Tigadoli 	    ((section3_row1_data & SOTP_ENC_DEV_TYPE_MASK) ==
106f29d1e0cSSheetal Tigadoli 	     SOTP_ENC_DEV_TYPE_AB_DEV) &&
107f29d1e0cSSheetal Tigadoli 	    (chip_state & SOTP_CHIP_STATES_MANU_DEBUG_MASK))
108f29d1e0cSSheetal Tigadoli 		return 1;
109f29d1e0cSSheetal Tigadoli 
110f29d1e0cSSheetal Tigadoli 	return 0;
111f29d1e0cSSheetal Tigadoli }
112f29d1e0cSSheetal Tigadoli #endif
113f29d1e0cSSheetal Tigadoli 
114f29d1e0cSSheetal Tigadoli /*
115f29d1e0cSSheetal Tigadoli  * Return the ROTPK hash in the following ASN.1 structure in DER format:
116f29d1e0cSSheetal Tigadoli  *
117f29d1e0cSSheetal Tigadoli  * AlgorithmIdentifier  ::=  SEQUENCE  {
118f29d1e0cSSheetal Tigadoli  *     algorithm         OBJECT IDENTIFIER,
119f29d1e0cSSheetal Tigadoli  *     parameters        ANY DEFINED BY algorithm OPTIONAL
120f29d1e0cSSheetal Tigadoli  * }
121f29d1e0cSSheetal Tigadoli  *
122f29d1e0cSSheetal Tigadoli  * DigestInfo ::= SEQUENCE {
123f29d1e0cSSheetal Tigadoli  *     digestAlgorithm   AlgorithmIdentifier,
124f29d1e0cSSheetal Tigadoli  *     digest            OCTET STRING
125f29d1e0cSSheetal Tigadoli  * }
126f29d1e0cSSheetal Tigadoli  */
plat_get_rotpk_info(void * cookie,void ** key_ptr,unsigned int * key_len,unsigned int * flags)127f29d1e0cSSheetal Tigadoli int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
128f29d1e0cSSheetal Tigadoli 			unsigned int *flags)
129f29d1e0cSSheetal Tigadoli {
130f29d1e0cSSheetal Tigadoli 	uint8_t *dst;
131f29d1e0cSSheetal Tigadoli 
132f29d1e0cSSheetal Tigadoli 	assert(key_ptr != NULL);
133f29d1e0cSSheetal Tigadoli 	assert(key_len != NULL);
134f29d1e0cSSheetal Tigadoli 	assert(flags != NULL);
135f29d1e0cSSheetal Tigadoli 
136f29d1e0cSSheetal Tigadoli 	*flags = 0;
137f29d1e0cSSheetal Tigadoli 
138f29d1e0cSSheetal Tigadoli 	/* Copy the DER header */
139f29d1e0cSSheetal Tigadoli 	memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
140f29d1e0cSSheetal Tigadoli 	dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len];
141f29d1e0cSSheetal Tigadoli 
142f29d1e0cSSheetal Tigadoli #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
143f29d1e0cSSheetal Tigadoli 	memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES);
144f29d1e0cSSheetal Tigadoli #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
145f29d1e0cSSheetal Tigadoli 	uint32_t *src, tmp;
146f29d1e0cSSheetal Tigadoli 	unsigned int words, i;
147f29d1e0cSSheetal Tigadoli 
148f29d1e0cSSheetal Tigadoli 	/*
149f29d1e0cSSheetal Tigadoli 	 * Append the hash from Trusted Root-Key Storage registers. The hash has
150f29d1e0cSSheetal Tigadoli 	 * not been written linearly into the registers, so we have to do a bit
151f29d1e0cSSheetal Tigadoli 	 * of byte swapping:
152f29d1e0cSSheetal Tigadoli 	 *
153f29d1e0cSSheetal Tigadoli 	 *     0x00    0x04    0x08    0x0C    0x10    0x14    0x18    0x1C
154f29d1e0cSSheetal Tigadoli 	 * +---------------------------------------------------------------+
155f29d1e0cSSheetal Tigadoli 	 * | Reg0  | Reg1  | Reg2  | Reg3  | Reg4  | Reg5  | Reg6  | Reg7  |
156f29d1e0cSSheetal Tigadoli 	 * +---------------------------------------------------------------+
157f29d1e0cSSheetal Tigadoli 	 *  | ...                    ... |   | ...                   ...  |
158f29d1e0cSSheetal Tigadoli 	 *  |       +--------------------+   |                    +-------+
159f29d1e0cSSheetal Tigadoli 	 *  |       |                        |                    |
160f29d1e0cSSheetal Tigadoli 	 *  +----------------------------+   +----------------------------+
161f29d1e0cSSheetal Tigadoli 	 *          |                    |                        |       |
162f29d1e0cSSheetal Tigadoli 	 *  +-------+                    |   +--------------------+       |
163f29d1e0cSSheetal Tigadoli 	 *  |                            |   |                            |
164f29d1e0cSSheetal Tigadoli 	 *  v                            v   v                            v
165f29d1e0cSSheetal Tigadoli 	 * +---------------------------------------------------------------+
166f29d1e0cSSheetal Tigadoli 	 * |                               |                               |
167f29d1e0cSSheetal Tigadoli 	 * +---------------------------------------------------------------+
168f29d1e0cSSheetal Tigadoli 	 *  0                           15  16                           31
169f29d1e0cSSheetal Tigadoli 	 *
170f29d1e0cSSheetal Tigadoli 	 * Additionally, we have to access the registers in 32-bit words
171f29d1e0cSSheetal Tigadoli 	 */
172f29d1e0cSSheetal Tigadoli 	words = SHA256_BYTES >> 3;
173f29d1e0cSSheetal Tigadoli 
174f29d1e0cSSheetal Tigadoli 	/* Swap bytes 0-15 (first four registers) */
175f29d1e0cSSheetal Tigadoli 	src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
176f29d1e0cSSheetal Tigadoli 	for (i = 0 ; i < words ; i++) {
177f29d1e0cSSheetal Tigadoli 		tmp = src[words - 1 - i];
178f29d1e0cSSheetal Tigadoli 		/* Words are read in little endian */
179f29d1e0cSSheetal Tigadoli 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
180f29d1e0cSSheetal Tigadoli 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
181f29d1e0cSSheetal Tigadoli 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
182f29d1e0cSSheetal Tigadoli 		*dst++ = (uint8_t)(tmp & 0xFF);
183f29d1e0cSSheetal Tigadoli 	}
184f29d1e0cSSheetal Tigadoli 
185f29d1e0cSSheetal Tigadoli 	/* Swap bytes 16-31 (last four registers) */
186f29d1e0cSSheetal Tigadoli 	src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2);
187f29d1e0cSSheetal Tigadoli 	for (i = 0 ; i < words ; i++) {
188f29d1e0cSSheetal Tigadoli 		tmp = src[words - 1 - i];
189f29d1e0cSSheetal Tigadoli 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
190f29d1e0cSSheetal Tigadoli 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
191f29d1e0cSSheetal Tigadoli 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
192f29d1e0cSSheetal Tigadoli 		*dst++ = (uint8_t)(tmp & 0xFF);
193f29d1e0cSSheetal Tigadoli 	}
194f29d1e0cSSheetal Tigadoli #elif (ARM_ROTPK_LOCATION_ID == BRCM_ROTPK_SOTP_RSA_ID)
195f29d1e0cSSheetal Tigadoli {
196f29d1e0cSSheetal Tigadoli 	int i;
197f29d1e0cSSheetal Tigadoli 	int ret = -1;
198f29d1e0cSSheetal Tigadoli 
199f29d1e0cSSheetal Tigadoli 	/*
200f29d1e0cSSheetal Tigadoli 	 * In non-AB mode, we do not read the key.
201f29d1e0cSSheetal Tigadoli 	 * In AB mode:
202f29d1e0cSSheetal Tigadoli 	 * - The Dauth is in BL11 if SBL is enabled
203f29d1e0cSSheetal Tigadoli 	 * - The Dauth is in SOTP if SBL is disabled.
204f29d1e0cSSheetal Tigadoli 	 */
205f29d1e0cSSheetal Tigadoli 	if (plat_is_trusted_boot() == 0) {
206f29d1e0cSSheetal Tigadoli 
207f29d1e0cSSheetal Tigadoli 		INFO("NON-AB: Do not read DAUTH!\n");
208f29d1e0cSSheetal Tigadoli 		*flags = ROTPK_NOT_DEPLOYED;
209f29d1e0cSSheetal Tigadoli 		ret = 0;
210f29d1e0cSSheetal Tigadoli 
211f29d1e0cSSheetal Tigadoli 	} else if ((sbl_status() == SBL_ENABLED) &&
212f29d1e0cSSheetal Tigadoli 		(mmio_read_32(BL11_DAUTH_BASE) == BL11_DAUTH_ID)) {
213f29d1e0cSSheetal Tigadoli 
214f29d1e0cSSheetal Tigadoli 		/* Read hash from BL11 */
215f29d1e0cSSheetal Tigadoli 		INFO("readKeys (DAUTH) from BL11\n");
216f29d1e0cSSheetal Tigadoli 
217f29d1e0cSSheetal Tigadoli 		memcpy(dst,
218f29d1e0cSSheetal Tigadoli 			(void *)(BL11_DAUTH_BASE + sizeof(uint32_t)),
219f29d1e0cSSheetal Tigadoli 			SHA256_BYTES);
220f29d1e0cSSheetal Tigadoli 
221f29d1e0cSSheetal Tigadoli 		for (i = 0; i < SHA256_BYTES; i++)
222f29d1e0cSSheetal Tigadoli 			if (dst[i] != 0)
223f29d1e0cSSheetal Tigadoli 				break;
224f29d1e0cSSheetal Tigadoli 
225f29d1e0cSSheetal Tigadoli 		if (i >= SHA256_BYTES)
226f29d1e0cSSheetal Tigadoli 			ERROR("Hash not valid from BL11\n");
227f29d1e0cSSheetal Tigadoli 		else
228f29d1e0cSSheetal Tigadoli 			ret = 0;
229f29d1e0cSSheetal Tigadoli 
230f29d1e0cSSheetal Tigadoli 	} else if (sotp_key_erased()) {
231f29d1e0cSSheetal Tigadoli 
232f29d1e0cSSheetal Tigadoli 		memcpy(dst, plat_rotpk_hash, SHA256_BYTES);
233f29d1e0cSSheetal Tigadoli 
234f29d1e0cSSheetal Tigadoli 		INFO("SOTP erased, Use internal key hash.\n");
235f29d1e0cSSheetal Tigadoli 		ret = 0;
236f29d1e0cSSheetal Tigadoli 
237f29d1e0cSSheetal Tigadoli 	} else if (plat_fast_auth_enabled()) {
238f29d1e0cSSheetal Tigadoli 
239f29d1e0cSSheetal Tigadoli 		INFO("AB DEV: FAST AUTH!\n");
240f29d1e0cSSheetal Tigadoli 		*flags = ROTPK_NOT_DEPLOYED;
241f29d1e0cSSheetal Tigadoli 		ret = 0;
242f29d1e0cSSheetal Tigadoli 
243f29d1e0cSSheetal Tigadoli 	} else if (!(mmio_read_32(SOTP_STATUS_1) & SOTP_DAUTH_ECC_ERROR_MASK)) {
244f29d1e0cSSheetal Tigadoli 
245f29d1e0cSSheetal Tigadoli 		/* Read hash from SOTP */
246f29d1e0cSSheetal Tigadoli 		ret = sotp_read_key(dst,
247f29d1e0cSSheetal Tigadoli 				    SHA256_BYTES,
248f29d1e0cSSheetal Tigadoli 				    SOTP_DAUTH_ROW,
249f29d1e0cSSheetal Tigadoli 				    SOTP_K_HMAC_ROW-1);
250f29d1e0cSSheetal Tigadoli 
251f29d1e0cSSheetal Tigadoli 		INFO("sotp_read_key (DAUTH): %i\n", ret);
252f29d1e0cSSheetal Tigadoli 
253f29d1e0cSSheetal Tigadoli 	} else {
254f29d1e0cSSheetal Tigadoli 
255f29d1e0cSSheetal Tigadoli 		uint64_t row_data;
256f29d1e0cSSheetal Tigadoli 		uint32_t k;
257f29d1e0cSSheetal Tigadoli 
258f29d1e0cSSheetal Tigadoli 		for (k = 0; k < (SOTP_K_HMAC_ROW - SOTP_DAUTH_ROW); k++) {
259f29d1e0cSSheetal Tigadoli 			row_data = sotp_mem_read(SOTP_DAUTH_ROW + k,
260f29d1e0cSSheetal Tigadoli 					SOTP_ROW_NO_ECC);
261f29d1e0cSSheetal Tigadoli 
262f29d1e0cSSheetal Tigadoli 			if (row_data != 0)
263f29d1e0cSSheetal Tigadoli 				break;
264f29d1e0cSSheetal Tigadoli 		}
265f29d1e0cSSheetal Tigadoli 
266f29d1e0cSSheetal Tigadoli 		if (k == (SOTP_K_HMAC_ROW - SOTP_DAUTH_ROW)) {
267f29d1e0cSSheetal Tigadoli 			INFO("SOTP NOT PROGRAMMED: Do not use DAUTH!\n");
268f29d1e0cSSheetal Tigadoli 
269f29d1e0cSSheetal Tigadoli 			if (sotp_mem_read(SOTP_ATF2_CFG_ROW_ID,
270f29d1e0cSSheetal Tigadoli 					SOTP_ROW_NO_ECC) & SOTP_ROMKEY_MASK) {
271f29d1e0cSSheetal Tigadoli 				memcpy(dst, plat_rotpk_hash, SHA256_BYTES);
272f29d1e0cSSheetal Tigadoli 
273f29d1e0cSSheetal Tigadoli 				INFO("Use internal key hash.\n");
274f29d1e0cSSheetal Tigadoli 				ret = 0;
275f29d1e0cSSheetal Tigadoli 			} else {
276f29d1e0cSSheetal Tigadoli 				*flags = ROTPK_NOT_DEPLOYED;
277f29d1e0cSSheetal Tigadoli 				ret = 0;
278f29d1e0cSSheetal Tigadoli 			}
279f29d1e0cSSheetal Tigadoli 		} else {
280f29d1e0cSSheetal Tigadoli 			INFO("No hash found in SOTP\n");
281f29d1e0cSSheetal Tigadoli 		}
282f29d1e0cSSheetal Tigadoli 	}
283f29d1e0cSSheetal Tigadoli 	if (ret)
284f29d1e0cSSheetal Tigadoli 		return ret;
285f29d1e0cSSheetal Tigadoli }
286f29d1e0cSSheetal Tigadoli #endif
287f29d1e0cSSheetal Tigadoli 
288f29d1e0cSSheetal Tigadoli 	*key_ptr = (void *)rotpk_hash_der;
289f29d1e0cSSheetal Tigadoli 	*key_len = (unsigned int)sizeof(rotpk_hash_der);
290f29d1e0cSSheetal Tigadoli 	*flags |= ROTPK_IS_HASH;
291f29d1e0cSSheetal Tigadoli 
292f29d1e0cSSheetal Tigadoli 	return 0;
293f29d1e0cSSheetal Tigadoli }
294f29d1e0cSSheetal Tigadoli 
295f29d1e0cSSheetal Tigadoli #define SOTP_NUM_BITS_PER_ROW 41
296f29d1e0cSSheetal Tigadoli #define SOTP_NVCTR_ROW_ALL_ONES 0x1ffffffffff
297f29d1e0cSSheetal Tigadoli #define SOTP_NVCTR_TRUSTED_IN_USE \
298f29d1e0cSSheetal Tigadoli 		((uint64_t)0x3 << (SOTP_NUM_BITS_PER_ROW-2))
299f29d1e0cSSheetal Tigadoli #define SOTP_NVCTR_NON_TRUSTED_IN_USE ((uint64_t)0x3)
300f29d1e0cSSheetal Tigadoli #define SOTP_NVCTR_TRUSTED_NEAR_END SOTP_NVCTR_NON_TRUSTED_IN_USE
301f29d1e0cSSheetal Tigadoli #define SOTP_NVCTR_NON_TRUSTED_NEAR_END SOTP_NVCTR_TRUSTED_IN_USE
302f29d1e0cSSheetal Tigadoli 
303f29d1e0cSSheetal Tigadoli #define SOTP_NVCTR_ROW_START 64
304f29d1e0cSSheetal Tigadoli #define SOTP_NVCTR_ROW_END   75
305f29d1e0cSSheetal Tigadoli 
306f29d1e0cSSheetal Tigadoli /*
307f29d1e0cSSheetal Tigadoli  * SOTP NVCTR are stored in section 10 of SOTP (rows 64-75).
308f29d1e0cSSheetal Tigadoli  * Each row of SOTP is 41 bits.
309f29d1e0cSSheetal Tigadoli  * NVCTR's are stored in a bitstream format.
310f29d1e0cSSheetal Tigadoli  * We are tolerant to consecutive bit errors.
311f29d1e0cSSheetal Tigadoli  * Trusted NVCTR starts at the top of row 64 in bitstream format.
312f29d1e0cSSheetal Tigadoli  * Non Trusted NVCTR starts at the bottom of row 75 in reverse bitstream.
313f29d1e0cSSheetal Tigadoli  * Each row can only be used by 1 of the 2 counters.  This is determined
314f29d1e0cSSheetal Tigadoli  * by 2 zeros remaining at the beginning or end of the last available row.
315f29d1e0cSSheetal Tigadoli  * If one counter has already starting using a row, the other will be
316f29d1e0cSSheetal Tigadoli  * prevent from writing to that row.
317f29d1e0cSSheetal Tigadoli  *
318f29d1e0cSSheetal Tigadoli  * Example counter values for SOTP programmed below:
319f29d1e0cSSheetal Tigadoli  * Trusted Counter (rows64-69) = 5 * 41 + 40 = 245
320f29d1e0cSSheetal Tigadoli  * NonTrusted Counter (row75-71) = 3 * 41 + 4 = 127
321f29d1e0cSSheetal Tigadoli  *        40 39 38 37 36 ..... 5 4 3 2 1 0
322f29d1e0cSSheetal Tigadoli  * row 64  1  1  1  1  1       1 1 1 1 1 1
323f29d1e0cSSheetal Tigadoli  * row 65  1  1  1  1  1       1 1 1 1 1 1
324f29d1e0cSSheetal Tigadoli  * row 66  1  1  1  1  1       1 1 1 1 1 1
325f29d1e0cSSheetal Tigadoli  * row 67  1  1  1  1  1       1 1 1 1 1 1
326f29d1e0cSSheetal Tigadoli  * row 68  1  1  1  1  1       1 1 1 1 1 1
327f29d1e0cSSheetal Tigadoli  * row 69  1  1  1  1  1       1 1 1 1 1 0
328f29d1e0cSSheetal Tigadoli  * row 71  0  0  0  0  0       0 0 0 0 0 0
329f29d1e0cSSheetal Tigadoli  * row 71  0  0  0  0  0       0 0 0 0 0 0
330f29d1e0cSSheetal Tigadoli  * row 71  0  0  0  0  0       0 0 1 1 1 1
331f29d1e0cSSheetal Tigadoli  * row 73  1  1  1  1  1       1 1 1 1 1 1
332f29d1e0cSSheetal Tigadoli  * row 74  1  1  1  1  1       1 1 1 1 1 1
333f29d1e0cSSheetal Tigadoli  * row 75  1  1  1  1  1       1 1 1 1 1 1
334f29d1e0cSSheetal Tigadoli  *
335f29d1e0cSSheetal Tigadoli  */
336f29d1e0cSSheetal Tigadoli 
337f29d1e0cSSheetal Tigadoli #if (DEBUG == 1)
338f29d1e0cSSheetal Tigadoli /*
339f29d1e0cSSheetal Tigadoli  * Dump sotp rows
340f29d1e0cSSheetal Tigadoli  */
sotp_dump_rows(uint32_t start_row,uint32_t end_row)341f29d1e0cSSheetal Tigadoli void sotp_dump_rows(uint32_t start_row, uint32_t end_row)
342f29d1e0cSSheetal Tigadoli {
343f29d1e0cSSheetal Tigadoli 	int32_t rownum;
344f29d1e0cSSheetal Tigadoli 	uint64_t rowdata;
345f29d1e0cSSheetal Tigadoli 
346f29d1e0cSSheetal Tigadoli 	for (rownum = start_row; rownum <= end_row; rownum++) {
347f29d1e0cSSheetal Tigadoli 		rowdata = sotp_mem_read(rownum, SOTP_ROW_NO_ECC);
348*4ef449c1SManish Pandey 		INFO("%d 0x%" PRIx64 "\n", rownum, rowdata);
349f29d1e0cSSheetal Tigadoli 	}
350f29d1e0cSSheetal Tigadoli }
351f29d1e0cSSheetal Tigadoli #endif
352f29d1e0cSSheetal Tigadoli 
353f29d1e0cSSheetal Tigadoli /*
354f29d1e0cSSheetal Tigadoli  * Get SOTP Trusted nvctr
355f29d1e0cSSheetal Tigadoli  */
sotp_get_trusted_nvctr(void)356f29d1e0cSSheetal Tigadoli unsigned int sotp_get_trusted_nvctr(void)
357f29d1e0cSSheetal Tigadoli {
358f29d1e0cSSheetal Tigadoli 	uint64_t rowdata;
359f29d1e0cSSheetal Tigadoli 	uint64_t nextrowdata;
360f29d1e0cSSheetal Tigadoli 	uint32_t rownum;
361f29d1e0cSSheetal Tigadoli 	unsigned int nvctr;
362f29d1e0cSSheetal Tigadoli 
363f29d1e0cSSheetal Tigadoli 	rownum = SOTP_NVCTR_ROW_START;
364f29d1e0cSSheetal Tigadoli 	nvctr = SOTP_NUM_BITS_PER_ROW;
365f29d1e0cSSheetal Tigadoli 
366f29d1e0cSSheetal Tigadoli 	/*
367f29d1e0cSSheetal Tigadoli 	 * Determine what row has last valid data for trusted ctr
368f29d1e0cSSheetal Tigadoli 	 */
369f29d1e0cSSheetal Tigadoli 	rowdata = sotp_mem_read(rownum, SOTP_ROW_NO_ECC);
370f29d1e0cSSheetal Tigadoli 	while ((rowdata & SOTP_NVCTR_TRUSTED_IN_USE) &&
371f29d1e0cSSheetal Tigadoli 	       (rowdata & SOTP_NVCTR_TRUSTED_NEAR_END) &&
372f29d1e0cSSheetal Tigadoli 	       (rownum < SOTP_NVCTR_ROW_END)) {
373f29d1e0cSSheetal Tigadoli 		/*
374f29d1e0cSSheetal Tigadoli 		 * Current row in use and has data in last 2 bits as well.
375f29d1e0cSSheetal Tigadoli 		 * Check if next row also has data for this counter
376f29d1e0cSSheetal Tigadoli 		 */
377f29d1e0cSSheetal Tigadoli 		nextrowdata = sotp_mem_read(rownum+1, SOTP_ROW_NO_ECC);
378f29d1e0cSSheetal Tigadoli 		if (nextrowdata & SOTP_NVCTR_TRUSTED_IN_USE) {
379f29d1e0cSSheetal Tigadoli 			/* Next row also has data so increment rownum */
380f29d1e0cSSheetal Tigadoli 			rownum++;
381f29d1e0cSSheetal Tigadoli 			nvctr += SOTP_NUM_BITS_PER_ROW;
382f29d1e0cSSheetal Tigadoli 			rowdata = nextrowdata;
383f29d1e0cSSheetal Tigadoli 		} else {
384f29d1e0cSSheetal Tigadoli 			/* Next row does not have data */
385f29d1e0cSSheetal Tigadoli 			break;
386f29d1e0cSSheetal Tigadoli 		}
387f29d1e0cSSheetal Tigadoli 	}
388f29d1e0cSSheetal Tigadoli 
389f29d1e0cSSheetal Tigadoli 	if (rowdata & SOTP_NVCTR_TRUSTED_IN_USE) {
390f29d1e0cSSheetal Tigadoli 		while ((rowdata & 0x1) == 0) {
391f29d1e0cSSheetal Tigadoli 			nvctr--;
392f29d1e0cSSheetal Tigadoli 			rowdata >>= 1;
393f29d1e0cSSheetal Tigadoli 		}
394f29d1e0cSSheetal Tigadoli 	} else
395f29d1e0cSSheetal Tigadoli 		nvctr -= SOTP_NUM_BITS_PER_ROW;
396f29d1e0cSSheetal Tigadoli 
397f29d1e0cSSheetal Tigadoli 	INFO("CTR %i\n", nvctr);
398f29d1e0cSSheetal Tigadoli 	return nvctr;
399f29d1e0cSSheetal Tigadoli }
400f29d1e0cSSheetal Tigadoli 
401f29d1e0cSSheetal Tigadoli /*
402f29d1e0cSSheetal Tigadoli  * Get SOTP NonTrusted nvctr
403f29d1e0cSSheetal Tigadoli  */
sotp_get_nontrusted_nvctr(void)404f29d1e0cSSheetal Tigadoli unsigned int sotp_get_nontrusted_nvctr(void)
405f29d1e0cSSheetal Tigadoli {
406f29d1e0cSSheetal Tigadoli 	uint64_t rowdata;
407f29d1e0cSSheetal Tigadoli 	uint64_t nextrowdata;
408f29d1e0cSSheetal Tigadoli 	uint32_t rownum;
409f29d1e0cSSheetal Tigadoli 	unsigned int nvctr;
410f29d1e0cSSheetal Tigadoli 
411f29d1e0cSSheetal Tigadoli 	nvctr = SOTP_NUM_BITS_PER_ROW;
412f29d1e0cSSheetal Tigadoli 	rownum = SOTP_NVCTR_ROW_END;
413f29d1e0cSSheetal Tigadoli 
414f29d1e0cSSheetal Tigadoli 	/*
415f29d1e0cSSheetal Tigadoli 	 * Determine what row has last valid data for nontrusted ctr
416f29d1e0cSSheetal Tigadoli 	 */
417f29d1e0cSSheetal Tigadoli 	rowdata = sotp_mem_read(rownum, SOTP_ROW_NO_ECC);
418f29d1e0cSSheetal Tigadoli 	while ((rowdata & SOTP_NVCTR_NON_TRUSTED_NEAR_END) &&
419f29d1e0cSSheetal Tigadoli 	       (rowdata & SOTP_NVCTR_NON_TRUSTED_IN_USE) &&
420f29d1e0cSSheetal Tigadoli 	       (rownum > SOTP_NVCTR_ROW_START)) {
421f29d1e0cSSheetal Tigadoli 		/*
422f29d1e0cSSheetal Tigadoli 		 * Current row in use and has data in last 2 bits as well.
423f29d1e0cSSheetal Tigadoli 		 * Check if next row also has data for this counter
424f29d1e0cSSheetal Tigadoli 		 */
425f29d1e0cSSheetal Tigadoli 		nextrowdata = sotp_mem_read(rownum-1, SOTP_ROW_NO_ECC);
426f29d1e0cSSheetal Tigadoli 		if (nextrowdata & SOTP_NVCTR_NON_TRUSTED_IN_USE) {
427f29d1e0cSSheetal Tigadoli 			/* Next row also has data so decrement rownum */
428f29d1e0cSSheetal Tigadoli 			rownum--;
429f29d1e0cSSheetal Tigadoli 			nvctr += SOTP_NUM_BITS_PER_ROW;
430f29d1e0cSSheetal Tigadoli 			rowdata = nextrowdata;
431f29d1e0cSSheetal Tigadoli 		} else {
432f29d1e0cSSheetal Tigadoli 			/* Next row does not have data */
433f29d1e0cSSheetal Tigadoli 			break;
434f29d1e0cSSheetal Tigadoli 		}
435f29d1e0cSSheetal Tigadoli 	}
436f29d1e0cSSheetal Tigadoli 
437f29d1e0cSSheetal Tigadoli 	if (rowdata & SOTP_NVCTR_NON_TRUSTED_IN_USE) {
438f29d1e0cSSheetal Tigadoli 		while ((rowdata & ((uint64_t)0x1 << (SOTP_NUM_BITS_PER_ROW-1)))
439f29d1e0cSSheetal Tigadoli 			==
440f29d1e0cSSheetal Tigadoli 			0) {
441f29d1e0cSSheetal Tigadoli 			nvctr--;
442f29d1e0cSSheetal Tigadoli 			rowdata <<= 1;
443f29d1e0cSSheetal Tigadoli 		}
444f29d1e0cSSheetal Tigadoli 	} else
445f29d1e0cSSheetal Tigadoli 		nvctr -= SOTP_NUM_BITS_PER_ROW;
446f29d1e0cSSheetal Tigadoli 
447f29d1e0cSSheetal Tigadoli 	INFO("NCTR %i\n", nvctr);
448f29d1e0cSSheetal Tigadoli 	return nvctr;
449f29d1e0cSSheetal Tigadoli }
450f29d1e0cSSheetal Tigadoli 
451f29d1e0cSSheetal Tigadoli /*
452f29d1e0cSSheetal Tigadoli  * Set SOTP Trusted nvctr
453f29d1e0cSSheetal Tigadoli  */
sotp_set_trusted_nvctr(unsigned int nvctr)454f29d1e0cSSheetal Tigadoli int sotp_set_trusted_nvctr(unsigned int nvctr)
455f29d1e0cSSheetal Tigadoli {
456f29d1e0cSSheetal Tigadoli 	int numrows_available;
457f29d1e0cSSheetal Tigadoli 	uint32_t nontrusted_rownum;
458f29d1e0cSSheetal Tigadoli 	uint32_t trusted_rownum;
459f29d1e0cSSheetal Tigadoli 	uint64_t rowdata;
460f29d1e0cSSheetal Tigadoli 	unsigned int maxnvctr;
461f29d1e0cSSheetal Tigadoli 
462f29d1e0cSSheetal Tigadoli 	/*
463f29d1e0cSSheetal Tigadoli 	 * Read SOTP to find out how many rows are used by the
464f29d1e0cSSheetal Tigadoli 	 * NON Trusted nvctr
465f29d1e0cSSheetal Tigadoli 	 */
466f29d1e0cSSheetal Tigadoli 	nontrusted_rownum = SOTP_NVCTR_ROW_END;
467f29d1e0cSSheetal Tigadoli 	do {
468f29d1e0cSSheetal Tigadoli 		rowdata = sotp_mem_read(nontrusted_rownum, SOTP_ROW_NO_ECC);
469f29d1e0cSSheetal Tigadoli 		if (rowdata & SOTP_NVCTR_NON_TRUSTED_IN_USE)
470f29d1e0cSSheetal Tigadoli 			nontrusted_rownum--;
471f29d1e0cSSheetal Tigadoli 		else
472f29d1e0cSSheetal Tigadoli 			break;
473f29d1e0cSSheetal Tigadoli 	} while (nontrusted_rownum >= SOTP_NVCTR_ROW_START);
474f29d1e0cSSheetal Tigadoli 
475f29d1e0cSSheetal Tigadoli 	/*
476f29d1e0cSSheetal Tigadoli 	 * Calculate maximum value we can have for nvctr based on
477f29d1e0cSSheetal Tigadoli 	 * number of available rows.
478f29d1e0cSSheetal Tigadoli 	 */
479f29d1e0cSSheetal Tigadoli 	numrows_available = nontrusted_rownum - SOTP_NVCTR_ROW_START + 1;
480f29d1e0cSSheetal Tigadoli 	maxnvctr = numrows_available * SOTP_NUM_BITS_PER_ROW;
481f29d1e0cSSheetal Tigadoli 	if (maxnvctr) {
482f29d1e0cSSheetal Tigadoli 		/*
483f29d1e0cSSheetal Tigadoli 		 * Last 2 bits of counter can't be written or it will
484f29d1e0cSSheetal Tigadoli 		 * overflow with nontrusted counter
485f29d1e0cSSheetal Tigadoli 		 */
486f29d1e0cSSheetal Tigadoli 		maxnvctr -= 2;
487f29d1e0cSSheetal Tigadoli 	}
488f29d1e0cSSheetal Tigadoli 
489f29d1e0cSSheetal Tigadoli 	if (nvctr > maxnvctr) {
490f29d1e0cSSheetal Tigadoli 		/* Error - not enough room */
491f29d1e0cSSheetal Tigadoli 		WARN("tctr not set\n");
492f29d1e0cSSheetal Tigadoli 		return 1;
493f29d1e0cSSheetal Tigadoli 	}
494f29d1e0cSSheetal Tigadoli 
495f29d1e0cSSheetal Tigadoli 	/*
496f29d1e0cSSheetal Tigadoli 	 * It is safe to write the nvctr, fill all 1's up to the
497f29d1e0cSSheetal Tigadoli 	 * last row and then fill the last row with partial bitstream
498f29d1e0cSSheetal Tigadoli 	 */
499f29d1e0cSSheetal Tigadoli 	trusted_rownum = SOTP_NVCTR_ROW_START;
500f29d1e0cSSheetal Tigadoli 	rowdata = SOTP_NVCTR_ROW_ALL_ONES;
501f29d1e0cSSheetal Tigadoli 
502f29d1e0cSSheetal Tigadoli 	while (nvctr >= SOTP_NUM_BITS_PER_ROW) {
503f29d1e0cSSheetal Tigadoli 		sotp_mem_write(trusted_rownum, SOTP_ROW_NO_ECC, rowdata);
504f29d1e0cSSheetal Tigadoli 		nvctr -= SOTP_NUM_BITS_PER_ROW;
505f29d1e0cSSheetal Tigadoli 		trusted_rownum++;
506f29d1e0cSSheetal Tigadoli 	}
507f29d1e0cSSheetal Tigadoli 	rowdata <<= (SOTP_NUM_BITS_PER_ROW - nvctr);
508f29d1e0cSSheetal Tigadoli 	sotp_mem_write(trusted_rownum, SOTP_ROW_NO_ECC, rowdata);
509f29d1e0cSSheetal Tigadoli 	return 0;
510f29d1e0cSSheetal Tigadoli }
511f29d1e0cSSheetal Tigadoli 
512f29d1e0cSSheetal Tigadoli /*
513f29d1e0cSSheetal Tigadoli  * Set SOTP NonTrusted nvctr
514f29d1e0cSSheetal Tigadoli  */
sotp_set_nontrusted_nvctr(unsigned int nvctr)515f29d1e0cSSheetal Tigadoli int sotp_set_nontrusted_nvctr(unsigned int nvctr)
516f29d1e0cSSheetal Tigadoli {
517f29d1e0cSSheetal Tigadoli 	int numrows_available;
518f29d1e0cSSheetal Tigadoli 	uint32_t nontrusted_rownum;
519f29d1e0cSSheetal Tigadoli 	uint32_t trusted_rownum;
520f29d1e0cSSheetal Tigadoli 	uint64_t rowdata;
521f29d1e0cSSheetal Tigadoli 	unsigned int maxnvctr;
522f29d1e0cSSheetal Tigadoli 
523f29d1e0cSSheetal Tigadoli 	/*
524f29d1e0cSSheetal Tigadoli 	 * Read SOTP to find out how many rows are used by the
525f29d1e0cSSheetal Tigadoli 	 * Trusted nvctr
526f29d1e0cSSheetal Tigadoli 	 */
527f29d1e0cSSheetal Tigadoli 	trusted_rownum = SOTP_NVCTR_ROW_START;
528f29d1e0cSSheetal Tigadoli 	do {
529f29d1e0cSSheetal Tigadoli 		rowdata = sotp_mem_read(trusted_rownum, SOTP_ROW_NO_ECC);
530f29d1e0cSSheetal Tigadoli 		if (rowdata & SOTP_NVCTR_TRUSTED_IN_USE)
531f29d1e0cSSheetal Tigadoli 			trusted_rownum++;
532f29d1e0cSSheetal Tigadoli 		else
533f29d1e0cSSheetal Tigadoli 			break;
534f29d1e0cSSheetal Tigadoli 	} while (trusted_rownum <= SOTP_NVCTR_ROW_END);
535f29d1e0cSSheetal Tigadoli 
536f29d1e0cSSheetal Tigadoli 	/*
537f29d1e0cSSheetal Tigadoli 	 * Calculate maximum value we can have for nvctr based on
538f29d1e0cSSheetal Tigadoli 	 * number of available rows.
539f29d1e0cSSheetal Tigadoli 	 */
540f29d1e0cSSheetal Tigadoli 	numrows_available = SOTP_NVCTR_ROW_END - trusted_rownum + 1;
541f29d1e0cSSheetal Tigadoli 	maxnvctr = numrows_available * SOTP_NUM_BITS_PER_ROW;
542f29d1e0cSSheetal Tigadoli 	if (maxnvctr) {
543f29d1e0cSSheetal Tigadoli 		/*
544f29d1e0cSSheetal Tigadoli 		 * Last 2 bits of counter can't be written or it will
545f29d1e0cSSheetal Tigadoli 		 * overflow with nontrusted counter
546f29d1e0cSSheetal Tigadoli 		 */
547f29d1e0cSSheetal Tigadoli 		maxnvctr -= 2;
548f29d1e0cSSheetal Tigadoli 	}
549f29d1e0cSSheetal Tigadoli 
550f29d1e0cSSheetal Tigadoli 	if (nvctr > maxnvctr) {
551f29d1e0cSSheetal Tigadoli 		/* Error - not enough room */
552f29d1e0cSSheetal Tigadoli 		WARN("nctr not set\n");
553f29d1e0cSSheetal Tigadoli 		return 1;
554f29d1e0cSSheetal Tigadoli 	}
555f29d1e0cSSheetal Tigadoli 
556f29d1e0cSSheetal Tigadoli 	/*
557f29d1e0cSSheetal Tigadoli 	 * It is safe to write the nvctr, fill all 1's up to the
558f29d1e0cSSheetal Tigadoli 	 * last row and then fill the last row with partial bitstream
559f29d1e0cSSheetal Tigadoli 	 */
560f29d1e0cSSheetal Tigadoli 	nontrusted_rownum = SOTP_NVCTR_ROW_END;
561f29d1e0cSSheetal Tigadoli 	rowdata = SOTP_NVCTR_ROW_ALL_ONES;
562f29d1e0cSSheetal Tigadoli 
563f29d1e0cSSheetal Tigadoli 	while (nvctr >= SOTP_NUM_BITS_PER_ROW) {
564f29d1e0cSSheetal Tigadoli 		sotp_mem_write(nontrusted_rownum, SOTP_ROW_NO_ECC, rowdata);
565f29d1e0cSSheetal Tigadoli 		nvctr -= SOTP_NUM_BITS_PER_ROW;
566f29d1e0cSSheetal Tigadoli 		nontrusted_rownum--;
567f29d1e0cSSheetal Tigadoli 	}
568f29d1e0cSSheetal Tigadoli 	rowdata >>= (SOTP_NUM_BITS_PER_ROW - nvctr);
569f29d1e0cSSheetal Tigadoli 	sotp_mem_write(nontrusted_rownum, SOTP_ROW_NO_ECC, rowdata);
570f29d1e0cSSheetal Tigadoli 	return 0;
571f29d1e0cSSheetal Tigadoli }
572f29d1e0cSSheetal Tigadoli 
573f29d1e0cSSheetal Tigadoli /*
574f29d1e0cSSheetal Tigadoli  * Return the non-volatile counter value stored in the platform. The cookie
575f29d1e0cSSheetal Tigadoli  * will contain the OID of the counter in the certificate.
576f29d1e0cSSheetal Tigadoli  *
577f29d1e0cSSheetal Tigadoli  * Return: 0 = success, Otherwise = error
578f29d1e0cSSheetal Tigadoli  */
plat_get_nv_ctr(void * cookie,unsigned int * nv_ctr)579f29d1e0cSSheetal Tigadoli int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
580f29d1e0cSSheetal Tigadoli {
581f29d1e0cSSheetal Tigadoli 	const char *oid;
582f29d1e0cSSheetal Tigadoli 
583f29d1e0cSSheetal Tigadoli 	assert(cookie != NULL);
584f29d1e0cSSheetal Tigadoli 	assert(nv_ctr != NULL);
585f29d1e0cSSheetal Tigadoli 
586f29d1e0cSSheetal Tigadoli 	*nv_ctr = 0;
587f29d1e0cSSheetal Tigadoli 	if ((sotp_mem_read(SOTP_ATF_CFG_ROW_ID, SOTP_ROW_NO_ECC) &
588f29d1e0cSSheetal Tigadoli 			SOTP_ATF_NVCOUNTER_ENABLE_MASK)) {
589f29d1e0cSSheetal Tigadoli 		oid = (const char *)cookie;
590f29d1e0cSSheetal Tigadoli 		if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0)
591f29d1e0cSSheetal Tigadoli 			*nv_ctr = sotp_get_trusted_nvctr();
592f29d1e0cSSheetal Tigadoli 		else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0)
593f29d1e0cSSheetal Tigadoli 			*nv_ctr = sotp_get_nontrusted_nvctr();
594f29d1e0cSSheetal Tigadoli 		else
595f29d1e0cSSheetal Tigadoli 			return 1;
596f29d1e0cSSheetal Tigadoli 	}
597f29d1e0cSSheetal Tigadoli 	return 0;
598f29d1e0cSSheetal Tigadoli }
599f29d1e0cSSheetal Tigadoli 
600f29d1e0cSSheetal Tigadoli /*
601f29d1e0cSSheetal Tigadoli  * Store a new non-volatile counter value.
602f29d1e0cSSheetal Tigadoli  *
603f29d1e0cSSheetal Tigadoli  * Return: 0 = success, Otherwise = error
604f29d1e0cSSheetal Tigadoli  */
plat_set_nv_ctr(void * cookie,unsigned int nv_ctr)605f29d1e0cSSheetal Tigadoli int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
606f29d1e0cSSheetal Tigadoli {
607f29d1e0cSSheetal Tigadoli 	const char *oid;
608f29d1e0cSSheetal Tigadoli 
609f29d1e0cSSheetal Tigadoli 	if (sotp_mem_read(SOTP_ATF_CFG_ROW_ID, SOTP_ROW_NO_ECC) &
610f29d1e0cSSheetal Tigadoli 			SOTP_ATF_NVCOUNTER_ENABLE_MASK) {
611f29d1e0cSSheetal Tigadoli 		INFO("set CTR %i\n", nv_ctr);
612f29d1e0cSSheetal Tigadoli 		oid = (const char *)cookie;
613f29d1e0cSSheetal Tigadoli 		if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0)
614f29d1e0cSSheetal Tigadoli 			return sotp_set_trusted_nvctr(nv_ctr);
615f29d1e0cSSheetal Tigadoli 		else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0)
616f29d1e0cSSheetal Tigadoli 			return sotp_set_nontrusted_nvctr(nv_ctr);
617f29d1e0cSSheetal Tigadoli 		return 1;
618f29d1e0cSSheetal Tigadoli 	}
619f29d1e0cSSheetal Tigadoli 	return 0;
620f29d1e0cSSheetal Tigadoli }
621f29d1e0cSSheetal Tigadoli 
plat_get_mbedtls_heap(void ** heap_addr,size_t * heap_size)622f29d1e0cSSheetal Tigadoli int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
623f29d1e0cSSheetal Tigadoli {
624f29d1e0cSSheetal Tigadoli 	return get_mbedtls_heap_helper(heap_addr, heap_size);
625f29d1e0cSSheetal Tigadoli }
626