board_arm_trusted_boot.c 16 KB

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