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