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