boot.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. // SPDX-License-Identifier: GPL-2.0+
  2. #include <common.h>
  3. #include <command.h>
  4. #include <net.h>
  5. #include <asm/io.h>
  6. #include <dm.h>
  7. #include <fdt_support.h>
  8. #include <fdtdec.h>
  9. #include <mmc.h>
  10. #include <opensbi.h>
  11. #include <asm/csr.h>
  12. #include <asm/arch-thead/boot_mode.h>
  13. #include "../../../lib/sec_library/include/csi_efuse_api.h"
  14. #include "../../../lib/sec_library/include/sec_crypto_sha.h"
  15. #include "../../../lib/sec_library/include/kdf.h"
  16. #include "../../../lib/sec_library/include/sec_crypto_mac.h"
  17. #if CONFIG_IS_ENABLED(LIGHT_SEC_UPGRADE)
  18. /* The macro is used to enable NON-COT boot with non-signed image */
  19. #define LIGHT_NON_COT_BOOT 1
  20. /* The macro is used to enable uboot version in efuse */
  21. #define LIGHT_UBOOT_VERSION_IN_ENV 1
  22. /* The macro is used to enble RPMB ACCESS KEY from KDF */
  23. //#define LIGHT_KDF_RPMB_KEY 1
  24. /* The macro is used to enable secure image version check in boot */
  25. //#define LIGHT_IMG_VERSION_CHECK_IN_BOOT 1
  26. /* the sample rpmb key is only used for testing */
  27. #ifndef LIGHT_KDF_RPMB_KEY
  28. static const unsigned char emmc_rpmb_key_sample[32] = {0x33, 0x22, 0x11, 0x00, 0x77, 0x66, 0x55, 0x44, \
  29. 0xbb, 0xaa, 0x99, 0x88, 0xff, 0xee, 0xdd, 0xcc, \
  30. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
  31. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  32. #endif
  33. static unsigned int upgrade_image_version = 0;
  34. #define RPMB_EMMC_CID_SIZE 16
  35. #define RPMB_CID_PRV_OFFSET 9
  36. #define RPMB_CID_CRC_OFFSET 15
  37. static int tee_rpmb_key_gen(uint8_t* key, uint32_t * length)
  38. {
  39. uint32_t data[RPMB_EMMC_CID_SIZE / 4];
  40. uint8_t huk[32];
  41. uint32_t huk_len;
  42. struct mmc *mmc = find_mmc_device(0);
  43. int i;
  44. sc_mac_t mac_handle;
  45. int ret = 0;
  46. if (!mmc)
  47. return -1;
  48. if (!mmc->ext_csd)
  49. return -1;
  50. for (i = 0; i < ARRAY_SIZE(mmc->cid); i++)
  51. data[i] = cpu_to_be32(mmc->cid[i]);
  52. /*
  53. * PRV/CRC would be changed when doing eMMC FFU
  54. * The following fields should be masked off when deriving RPMB key
  55. *
  56. * CID [55: 48]: PRV (Product revision)
  57. * CID [07: 01]: CRC (CRC7 checksum)
  58. * CID [00]: not used
  59. */
  60. memset((void *)((uint64_t)data + RPMB_CID_PRV_OFFSET), 0, 1);
  61. memset((void *)((uint64_t)data + RPMB_CID_CRC_OFFSET), 0, 1);
  62. /* Step1: Derive HUK from KDF function */
  63. ret = csi_kdf_gen_hmac_key(huk, &huk_len);
  64. if (ret) {
  65. printf("kdf gen hmac key faild[%d]\r\n", ret);
  66. return -1;
  67. }
  68. /* Step2: Using HUK and data to generate RPMB key */
  69. ret = sc_mac_init(&mac_handle, 0);
  70. if (ret) {
  71. printf("mac init faild[%d]\r\n", ret);
  72. ret = -1;
  73. return -1;
  74. }
  75. /* LSB 16 bytes are used as key */
  76. ret = sc_mac_set_key(&mac_handle, huk, 16);
  77. if (ret) {
  78. printf("mac set key faild[%d]\r\n", ret);
  79. ret = -1;
  80. goto func_exit;
  81. }
  82. ret = sc_mac_calc(&mac_handle, SC_SHA_MODE_256, (uint8_t *)&data, sizeof(data), key, length);
  83. if (ret) {
  84. printf("mac calc faild[%d]\r\n", ret);
  85. ret = -1;
  86. goto func_exit;
  87. }
  88. func_exit:
  89. sc_mac_uninit(&mac_handle);
  90. return ret;
  91. }
  92. int csi_rpmb_write_access_key(void)
  93. {
  94. unsigned long *temp_rpmb_key_addr = NULL;
  95. char runcmd[64] = {0};
  96. uint8_t blkdata[256] = {0};
  97. __attribute__((__aligned__(8))) uint8_t kdf_rpmb_key[32];
  98. uint32_t kdf_rpmb_key_length = 0;
  99. int ret = 0;
  100. #ifdef LIGHT_KDF_RPMB_KEY
  101. /* Step1: retrive RPMB key from KDF function */
  102. ret = tee_rpmb_key_gen(kdf_rpmb_key, &kdf_rpmb_key_length);
  103. if (ret != 0) {
  104. return -1;
  105. }
  106. /* Make sure rpmb key length must be 32*/
  107. if (kdf_rpmb_key_length != 32) {
  108. return -1;
  109. }
  110. temp_rpmb_key_addr = (unsigned long *)kdf_rpmb_key;
  111. /* Step2: check whether RPMB key is available */
  112. sprintf(runcmd, "mmc rpmb read 0x%lx 0 1 0x%lx", (unsigned long)blkdata, (unsigned long)temp_rpmb_key_addr);
  113. ret = run_command(runcmd, 0);
  114. if (ret == CMD_RET_SUCCESS) {
  115. return -1;
  116. }
  117. /* Step3: Write RPMB key at once */
  118. sprintf(runcmd, "mmc rpmb key 0x%lx", (unsigned long)temp_rpmb_key_addr);
  119. ret = run_command(runcmd, 0);
  120. if (ret != CMD_RET_SUCCESS) {
  121. return -1;
  122. }
  123. return 0;
  124. #else
  125. return 1;
  126. #endif
  127. }
  128. int csi_tf_get_image_version(unsigned int *ver)
  129. {
  130. char runcmd[64] = {0};
  131. unsigned char blkdata[256];
  132. int ret = 0;
  133. /* tf version reside in RPMB block#0, offset#16*/
  134. sprintf(runcmd, "mmc rpmb read 0x%lx 0 1", (unsigned long)blkdata);
  135. ret = run_command(runcmd, 0);
  136. if (ret == 0) {
  137. *ver = (blkdata[16] << 8) + blkdata[17];
  138. }
  139. return ret;
  140. }
  141. int csi_tf_set_image_version(unsigned int ver)
  142. {
  143. char runcmd[64] = {0};
  144. unsigned char blkdata[256];
  145. unsigned long *temp_rpmb_key_addr = NULL;
  146. /* tf version reside in RPMB block#0, offset#16*/
  147. sprintf(runcmd, "mmc rpmb read 0x%lx 0 1", (unsigned long)blkdata);
  148. run_command(runcmd, 0);
  149. blkdata[16] = (ver & 0xFF00) >> 8;
  150. blkdata[17] = ver & 0xFF;
  151. /* tf version reside in RPMB block#0, offset#16*/
  152. #ifndef LIGHT_KDF_RPMB_KEY
  153. temp_rpmb_key_addr = (unsigned long *)emmc_rpmb_key_sample;
  154. #else
  155. uint8_t kdf_rpmb_key[32];
  156. uint32_t kdf_rpmb_key_length = 0;
  157. int ret = 0;
  158. ret = csi_kdf_gen_hmac_key(kdf_rpmb_key, &kdf_rpmb_key_length);
  159. if (ret != 0) {
  160. return -1;
  161. }
  162. temp_rpmb_key_addr = (unsigned long *)kdf_rpmb_key;
  163. #endif
  164. sprintf(runcmd, "mmc rpmb write 0x%lx 0 1 0x%lx", (unsigned long)blkdata, (unsigned long)temp_rpmb_key_addr);
  165. run_command(runcmd, 0);
  166. return 0;
  167. }
  168. int csi_tf_set_upgrade_version(void)
  169. {
  170. return csi_tf_set_image_version(upgrade_image_version);
  171. }
  172. int csi_tee_get_image_version(unsigned int *ver)
  173. {
  174. char runcmd[64] = {0};
  175. unsigned char blkdata[256];
  176. int ret = 0;
  177. /* tf version reside in RPMB block#0, offset#0*/
  178. sprintf(runcmd, "mmc rpmb read 0x%lx 0 1", (unsigned long)blkdata);
  179. ret = run_command(runcmd, 0);
  180. if (ret == 0) {
  181. *ver = (blkdata[0] << 8) + blkdata[1];
  182. }
  183. return ret;
  184. }
  185. int csi_kernel_get_image_version(unsigned int *ver)
  186. {
  187. char runcmd[64] = {0};
  188. unsigned char blkdata[256];
  189. /* kernel version reside in RPMB block#0, offset#32*/
  190. sprintf(runcmd, "mmc rpmb read 0x%lx 0 1", (unsigned long)blkdata);
  191. run_command(runcmd, 0);
  192. *ver = (blkdata[32] << 8) + blkdata[33];
  193. return 0;
  194. }
  195. int csi_tee_set_image_version(unsigned int ver)
  196. {
  197. char runcmd[64] = {0};
  198. unsigned char blkdata[256];
  199. unsigned long *temp_rpmb_key_addr = NULL;
  200. /* tf version reside in RPMB block#0, offset#0*/
  201. sprintf(runcmd, "mmc rpmb read 0x%lx 0 1", (unsigned long)blkdata);
  202. run_command(runcmd, 0);
  203. blkdata[0] = (ver & 0xFF00) >> 8;
  204. blkdata[1] = ver & 0xFF;
  205. /* tf version reside in RPMB block#0, offset#16*/
  206. #ifndef LIGHT_KDF_RPMB_KEY
  207. temp_rpmb_key_addr = (unsigned long *)emmc_rpmb_key_sample;
  208. #else
  209. uint8_t kdf_rpmb_key[32];
  210. uint32_t kdf_rpmb_key_length = 0;
  211. int ret = 0;
  212. ret = csi_kdf_gen_hmac_key(kdf_rpmb_key, &kdf_rpmb_key_length);
  213. if (ret != 0) {
  214. return -1;
  215. }
  216. temp_rpmb_key_addr = (unsigned long *)kdf_rpmb_key;
  217. #endif
  218. sprintf(runcmd, "mmc rpmb write 0x%lx 0 1 0x%lx", (unsigned long)blkdata, (unsigned long)temp_rpmb_key_addr);
  219. run_command(runcmd, 0);
  220. return 0;
  221. }
  222. int csi_tee_set_upgrade_version(void)
  223. {
  224. return csi_tee_set_image_version(upgrade_image_version);
  225. }
  226. int csi_uboot_get_image_version(unsigned int *ver)
  227. {
  228. #ifdef LIGHT_UBOOT_VERSION_IN_ENV
  229. long long uboot_ver = 0;
  230. unsigned char ver_x = 1;
  231. int i;
  232. // TODO
  233. // To avoid waste efuse resource, we define uboot_version env parameter to standd for BL1_VERSION in efuse
  234. uboot_ver = env_get_hex("uboot_version", 0xffffffffffffffff);
  235. // Add getting uboot version here.
  236. for (i = 0; i < (UBOOT_MAX_VER-1); i++) {
  237. if ((uboot_ver >> i) & 0x1) {
  238. ver_x ++;
  239. } else {
  240. break;
  241. }
  242. }
  243. if ( i <= (UBOOT_MAX_VER-1) ) {
  244. *ver = ver_x << 8;
  245. } else {
  246. *ver = 1 << 8;
  247. }
  248. #else
  249. unsigned int ver_x = 0;
  250. int ret = 0;
  251. ret = csi_efuse_api_int();
  252. if (ret) {
  253. printf("efuse api init fail \n");
  254. return -1;
  255. }
  256. ret = csi_efuse_get_bl1_version(&ver_x);
  257. if (ret) {
  258. printf("csi_efuse_get_bl1_version fail\n");
  259. return -1;
  260. }
  261. csi_efuse_api_uninit();
  262. *ver = (ver_x + 1) << 8;
  263. #endif
  264. return 0;
  265. }
  266. int csi_uboot_set_image_version(unsigned int ver)
  267. {
  268. #ifdef LIGHT_UBOOT_VERSION_IN_ENV
  269. //TODO
  270. unsigned long long uboot_ver = 0;
  271. unsigned char ver_x = (ver & 0xff00) >> 8;
  272. char ver_str[32] = {0};
  273. uboot_ver = env_get_hex("uboot_version", 0xffffffffffffffff);
  274. // Add getting uboot version here.
  275. if (ver_x == 1) {
  276. printf("This is initial version !");
  277. return 0;
  278. }
  279. uboot_ver |= ((unsigned long long)1 << (ver_x - 2));
  280. // To avoid waste efuse resource, we define uboot_version env parameter to stand for BL1_VERSION in efuse
  281. env_set_hex("uboot_version", uboot_ver);
  282. #else
  283. unsigned int ver_x = 0;
  284. int ret = 0;
  285. ver_x = (ver & 0xff00) >> 8;
  286. if (ver_x == 1) {
  287. printf("This is initial version !");
  288. return 0;
  289. }
  290. ret = csi_efuse_api_int();
  291. if (ret) {
  292. printf("efuse api init fail \n");
  293. return -1;
  294. }
  295. ver_x = ver_x - 1;
  296. ret = csi_efuse_set_bl1_version(ver_x);
  297. if (ret) {
  298. printf("csi_efuse_set_bl1_version fail \n");
  299. return -1;
  300. }
  301. csi_efuse_api_uninit();
  302. #endif
  303. return 0;
  304. }
  305. int csi_uboot_set_upgrade_version(void)
  306. {
  307. return csi_uboot_set_image_version(upgrade_image_version);
  308. }
  309. int verify_image_version_rule(unsigned int new_ver, unsigned int cur_ver)
  310. {
  311. unsigned char new_ver_x = 0, new_ver_y = 0;
  312. unsigned char cur_ver_x = 0, cur_ver_y = 0;
  313. /* Get secure version X from image version X.Y */
  314. new_ver_x = (new_ver & 0xFF00) >> 8;
  315. new_ver_y = new_ver & 0xFF;
  316. cur_ver_x = (cur_ver & 0xFF00) >> 8;
  317. cur_ver_y = cur_ver & 0xFF;
  318. printf("\n\n");
  319. printf("cur image version: %d.%d\n", cur_ver_x, cur_ver_y);
  320. printf("new image version: %d.%d\n", new_ver_x, new_ver_y);
  321. /* According the version rule, the X value must increase by 1 */
  322. if ((new_ver_x - cur_ver_x) == 0) {
  323. /* This is unsecure function */
  324. if ((new_ver_y - cur_ver_y) == 0) {
  325. printf("New version is equal to Current version, upgrade process terminates \n\n\n");
  326. return -1;
  327. }
  328. printf("This is unsecure function upgrade, going on uprade anyway\n");
  329. } else if ((new_ver_x - cur_ver_x) != 1) {
  330. /* Check the seure version rule */
  331. printf("The upgrade version(X) breaks against the rule\n\n\n");
  332. return -1;
  333. }
  334. printf("check image verison rule pass\n\n\n");
  335. return 0;
  336. }
  337. int check_image_version_rule(unsigned int new_ver, unsigned int cur_ver)
  338. {
  339. unsigned char new_ver_x = 0, new_ver_y = 0;
  340. unsigned char cur_ver_x = 0, cur_ver_y = 0;
  341. /* Get secure version X from image version X.Y */
  342. new_ver_x = (new_ver & 0xFF00) >> 8;
  343. new_ver_y = new_ver & 0xFF;
  344. cur_ver_x = (cur_ver & 0xFF00) >> 8;
  345. cur_ver_y = cur_ver & 0xFF;
  346. /* Ensure image version must be less than expected version */
  347. if (new_ver_x < cur_ver_x) {
  348. return -1;
  349. }
  350. return 0;
  351. }
  352. int check_tf_version_in_boot(unsigned long tf_addr)
  353. {
  354. int ret = 0;
  355. unsigned int img_version = 0;
  356. unsigned int expected_img_version = 0;
  357. img_version = get_image_version(tf_addr);
  358. if (img_version == 0) {
  359. printf("get tf image version fail\n");
  360. return -1;
  361. }
  362. ret = csi_tf_get_image_version(&expected_img_version);
  363. if (ret != 0) {
  364. printf("Get tf expected img version fail\n");
  365. return -1;
  366. }
  367. ret = check_image_version_rule(img_version, expected_img_version);
  368. if (ret != 0) {
  369. printf("Image version breaks the rule\n");
  370. return -1;
  371. }
  372. return 0;
  373. }
  374. int check_tee_version_in_boot(unsigned long tee_addr)
  375. {
  376. int ret = 0;
  377. unsigned int img_version = 0;
  378. unsigned int expected_img_version = 0;
  379. img_version = get_image_version(tee_addr);
  380. if (img_version == 0) {
  381. printf("get tee image version fail\n");
  382. return -1;
  383. }
  384. ret = csi_tee_get_image_version(&expected_img_version);
  385. if (ret != 0) {
  386. printf("Get tee expected img version fail\n");
  387. return -1;
  388. }
  389. ret = check_image_version_rule(img_version, expected_img_version);
  390. if (ret != 0) {
  391. printf("Image version breaks the rule\n");
  392. return -1;
  393. }
  394. return 0;
  395. }
  396. int light_vimage(int argc, char *const argv[])
  397. {
  398. int ret = 0;
  399. unsigned long vimage_addr = 0;
  400. unsigned int new_img_version = 0;
  401. unsigned int cur_img_version = 0;
  402. char imgname[32] = {0};
  403. if (argc < 3)
  404. return CMD_RET_USAGE;
  405. /* Parse input parameters */
  406. vimage_addr = simple_strtoul(argv[1], NULL, 16);
  407. strcpy(imgname, argv[2]);
  408. /* Retrieve desired information from image header */
  409. new_img_version = get_image_version(vimage_addr);
  410. if (new_img_version == 0) {
  411. printf("get new img version fail\n");
  412. return CMD_RET_FAILURE;
  413. }
  414. if (strcmp(imgname, UBOOT_PART_NAME) == 0) {
  415. new_img_version = (((new_img_version & 0xff )+1) << 8) | ((new_img_version & 0xff00)>>8);
  416. }
  417. printf("Get new image version from image header: v%d.%d\n", (new_img_version & 0xff00)>>8, new_img_version & 0xff);
  418. /* Check image version for ROLLBACK resisance */
  419. if (strcmp(imgname, TF_PART_NAME) == 0) {
  420. ret = csi_tf_get_image_version(&cur_img_version);
  421. if (ret != 0) {
  422. printf("Get tf img version fail\n");
  423. return CMD_RET_FAILURE;
  424. }
  425. } else if (strcmp(imgname, TEE_PART_NAME) == 0){
  426. ret = csi_tee_get_image_version(&cur_img_version);
  427. if (ret != 0) {
  428. printf("Get tee img version fail\n");
  429. return CMD_RET_FAILURE;
  430. }
  431. } else if (strcmp(imgname, KERNEL_PART_NAME) == 0){
  432. ret = csi_kernel_get_image_version(&cur_img_version);
  433. if (ret != 0) {
  434. printf("Get kernel img version fail\n");
  435. return CMD_RET_FAILURE;
  436. }
  437. } else if (strcmp(imgname, UBOOT_PART_NAME) == 0) {
  438. ret = csi_uboot_get_image_version(&cur_img_version);
  439. if (ret != 0) {
  440. printf("Get uboot img version fail\n");
  441. return CMD_RET_FAILURE;
  442. }
  443. // Check uboot maximization version > 64
  444. if (((new_img_version & 0xFF00) >> 8) > UBOOT_MAX_VER) {
  445. printf("UBOOT Image version has reached to max-version\n");
  446. return CMD_RET_FAILURE;
  447. }
  448. } else {
  449. printf("unsupport image file\n");
  450. return CMD_RET_FAILURE;
  451. }
  452. /* Verify image version rule */
  453. ret = verify_image_version_rule(new_img_version, cur_img_version);
  454. if (ret != 0) {
  455. return CMD_RET_FAILURE;
  456. }
  457. /* Save new image version to allow caller upgrade image version */
  458. upgrade_image_version = new_img_version;
  459. /* Initialize secure basis of functions */
  460. ret = csi_sec_init();
  461. if (ret != 0) {
  462. return CMD_RET_FAILURE;
  463. }
  464. /* Do image verification for TF and TEE */
  465. if (strcmp(imgname, TF_PART_NAME) == 0) {
  466. ret = verify_customer_image(T_TF, vimage_addr);
  467. if (ret != 0) {
  468. return CMD_RET_FAILURE;
  469. }
  470. } else if (strcmp(imgname, TEE_PART_NAME) == 0) {
  471. ret = verify_customer_image(T_TEE, vimage_addr);
  472. if (ret != 0) {
  473. return CMD_RET_FAILURE;
  474. }
  475. } else if (strcmp(imgname, KERNEL_PART_NAME) == 0) {
  476. ret = verify_customer_image(T_KRLIMG, vimage_addr);
  477. if (ret != 0) {
  478. return CMD_RET_FAILURE;
  479. }
  480. } else if (strcmp(imgname, UBOOT_PART_NAME) == 0) {
  481. ret = verify_customer_image(T_UBOOT, vimage_addr);
  482. if (ret != 0) {
  483. return CMD_RET_FAILURE;
  484. }
  485. } else {
  486. printf("Error: unknow image name\n");
  487. return CMD_RET_FAILURE;
  488. }
  489. return 0;
  490. }
  491. int light_secboot(int argc, char * const argv[])
  492. {
  493. int ret = 0;
  494. unsigned long tf_addr = LIGHT_TF_FW_ADDR;
  495. unsigned long tee_addr = LIGHT_TEE_FW_ADDR;
  496. unsigned long kernel_addr = LIGHT_KERNEL_ADDR;
  497. unsigned int tf_image_size = 0;
  498. unsigned int tee_image_size = 0;
  499. unsigned int kernel_image_size = 0;
  500. printf("\n\n");
  501. printf("Now, we start to verify all trust firmware before boot kernel !\n");
  502. /* Enject RPMB KEY directly in startup */
  503. csi_rpmb_write_access_key();
  504. /* Initialize secure basis of functions */
  505. ret = csi_sec_init();
  506. if (ret != 0) {
  507. return CMD_RET_FAILURE;
  508. }
  509. /* Step1. Check and verify TF image */
  510. if (image_have_head(LIGHT_TF_FW_TMP_ADDR) == 1) {
  511. #ifdef LIGHT_IMG_VERSION_CHECK_IN_BOOT
  512. printf("check TF version in boot \n");
  513. ret = check_tf_version_in_boot(LIGHT_TF_FW_TMP_ADDR);
  514. if (ret != 0) {
  515. return CMD_RET_FAILURE;
  516. }
  517. #endif
  518. printf("Process TF image verification ...\n");
  519. ret = verify_customer_image(T_TF, LIGHT_TF_FW_TMP_ADDR);
  520. if (ret != 0) {
  521. return CMD_RET_FAILURE;
  522. }
  523. tf_image_size = get_image_size(LIGHT_TF_FW_TMP_ADDR);
  524. printf("TF image size: %d\n", tf_image_size);
  525. if (tf_image_size < 0) {
  526. printf("GET TF image size error\n");
  527. return CMD_RET_FAILURE;
  528. }
  529. memmove((void *)tf_addr, (const void *)(LIGHT_TF_FW_TMP_ADDR + HEADER_SIZE), tf_image_size);
  530. } else {
  531. #ifdef LIGHT_NON_COT_BOOT
  532. run_command("ext4load mmc 0:3 0x0 trust_firmware.bin", 0);
  533. #else
  534. return CMD_RET_FAILURE;
  535. #endif
  536. }
  537. /* Step2. Check and verify TEE image */
  538. if (image_have_head(tee_addr) == 1) {
  539. #ifdef LIGHT_IMG_VERSION_CHECK_IN_BOOT
  540. printf("check TEE version in boot \n");
  541. ret = check_tee_version_in_boot(tee_addr);
  542. if (ret != 0) {
  543. return CMD_RET_FAILURE;
  544. }
  545. #endif
  546. printf("Process TEE image verification ...\n");
  547. ret = verify_customer_image(T_TEE, tee_addr);
  548. if (ret != 0) {
  549. return CMD_RET_FAILURE;
  550. }
  551. tee_image_size = get_image_size(tee_addr);
  552. printf("TEE image size: %d\n", tee_image_size);
  553. if (tee_image_size < 0) {
  554. printf("GET TEE image size error\n");
  555. return CMD_RET_FAILURE;
  556. }
  557. memmove((void *)tee_addr, (const void *)(tee_addr + HEADER_SIZE), tee_image_size);
  558. } else {
  559. #ifndef LIGHT_NON_COT_BOOT
  560. return CMD_RET_FAILURE;
  561. #endif
  562. }
  563. // /* Step3. Check and verify light kernel image */
  564. // if (image_have_head(kernel_addr) == 1) {
  565. // printf("Process kernel image verification ...\n");
  566. // ret = verify_customer_image(T_KRLIMG, kernel_addr);
  567. // if (ret != 0) {
  568. // return CMD_RET_FAILURE;
  569. // }
  570. // kernel_image_size = get_image_size(kernel_addr);
  571. // printf("Kernel image size: %d\n", kernel_image_size);
  572. // if (kernel_image_size < 0) {
  573. // printf("GET kernel image size error\n");
  574. // return CMD_RET_FAILURE;
  575. // }
  576. // memmove((void *)kernel_addr, (const void *)(kernel_addr + HEADER_SIZE), kernel_image_size);
  577. // } else {
  578. // #ifndef LIGHT_NON_COT_BOOT
  579. // return CMD_RET_FAILURE;
  580. // #endif
  581. // }
  582. return 0;
  583. }
  584. void sec_firmware_version_dump(void)
  585. {
  586. unsigned int tf_ver = 0;
  587. unsigned int tee_ver = 0;
  588. unsigned int uboot_ver = 0;
  589. unsigned int tf_ver_env = 0;
  590. unsigned int tee_ver_env = 0;
  591. csi_uboot_get_image_version(&uboot_ver);
  592. csi_tf_get_image_version(&tf_ver);
  593. csi_tee_get_image_version(&tee_ver);
  594. /* Keep sync with version in RPMB, the Following version could be leveraged by OTA client */
  595. tee_ver_env = env_get_hex("tee_version", 0);
  596. tf_ver_env = env_get_hex("tf_version", 0);
  597. if ((tee_ver_env != tee_ver) && (tee_ver != 0)) {
  598. env_set_hex("tee_version", tee_ver);
  599. }
  600. if ((tf_ver_env != tf_ver) && (tf_ver != 0)) {
  601. env_set_hex("tf_version", tf_ver);
  602. }
  603. printf("\n\n");
  604. printf("Secure Firmware image version info: \n");
  605. printf("uboot Firmware v%d.0\n", (uboot_ver & 0xff00) >> 8);
  606. printf("Trust Firmware v%d.%d\n", (tf_ver & 0xff00) >> 8, tf_ver & 0xff);
  607. printf("TEE OS v%d.%d\n", (tee_ver & 0xff00) >> 8, tee_ver & 0xff);
  608. printf("\n\n");
  609. }
  610. void sec_upgrade_thread(void)
  611. {
  612. const unsigned long temp_addr=0x200000;
  613. char runcmd[80];
  614. uint8_t * image_buffer = NULL;
  615. uint8_t * image_malloc_buffer = NULL;
  616. int ret = 0;
  617. unsigned int sec_upgrade_flag = 0;
  618. unsigned int upgrade_file_size = 0;
  619. sec_upgrade_flag = env_get_hex("sec_upgrade_mode", 0);
  620. if (sec_upgrade_flag == 0)
  621. return;
  622. printf("bootstrap: sec_upgrade_flag: %x\n", sec_upgrade_flag);
  623. if (sec_upgrade_flag == TF_SEC_UPGRADE_FLAG) {
  624. /* STEP 1: read upgrade image (trust_firmware.bin) from stash partition */
  625. printf("read upgrade image (trust_firmware.bin) from stash partition \n");
  626. sprintf(runcmd, "ext4load mmc 0:5 0x%p trust_firmware.bin", (void *)temp_addr);
  627. printf("runcmd:%s\n", runcmd);
  628. ret = run_command(runcmd, 0);
  629. if (ret != 0) {
  630. printf("TF upgrade process is terminated due to some reason\n");
  631. goto _upgrade_tf_exit;
  632. }
  633. /* Fetch the total file size after read out operation end */
  634. upgrade_file_size = env_get_hex("filesize", 0);
  635. printf("upgrade file size: %d\n", upgrade_file_size);
  636. /*store image to temp buffer as temp_addr may be decrypted*/
  637. image_malloc_buffer = malloc(upgrade_file_size);
  638. if ( image_malloc_buffer == NULL ) {
  639. image_buffer = (uint8_t*)temp_addr + upgrade_file_size;
  640. } else {
  641. image_buffer = image_malloc_buffer;
  642. }
  643. memcpy(image_buffer, temp_addr, upgrade_file_size);
  644. /* STEP 2: verify its authentiticy here */
  645. sprintf(runcmd, "vimage 0x%p tf", (void *)temp_addr);
  646. printf("runcmd:%s\n", runcmd);
  647. ret = run_command(runcmd, 0);
  648. if (ret != 0) {
  649. printf("TF Image verification fail and upgrade process terminates\n");
  650. goto _upgrade_tf_exit;
  651. }
  652. /* STEP 3: update tf partition */
  653. printf("read upgrade image (trust_firmware.bin) into tf partition \n");
  654. sprintf(runcmd, "ext4write mmc 0:3 0x%p /trust_firmware.bin 0x%x", (void *)image_buffer, upgrade_file_size);
  655. printf("runcmd:%s\n", runcmd);
  656. ret = run_command(runcmd, 0);
  657. if (ret != 0) {
  658. printf("TF upgrade process is terminated due to some reason\n");
  659. goto _upgrade_tf_exit;
  660. }
  661. /* STEP 4: update tf version */
  662. ret = csi_tf_set_upgrade_version();
  663. if (ret != 0) {
  664. printf("Set trustfirmware upgrade version fail\n");
  665. goto _upgrade_tf_exit;
  666. }
  667. printf("\n\nTF image ugprade process is successful\n\n");
  668. _upgrade_tf_exit:
  669. /* set secure upgrade flag to 0 that indicate upgrade over */
  670. run_command("env set sec_upgrade_mode 0", 0);
  671. run_command("saveenv", 0);
  672. run_command("reset", 0);
  673. if ( image_malloc_buffer != NULL ) {
  674. free(image_malloc_buffer);
  675. image_malloc_buffer = NULL;
  676. }
  677. } else if (sec_upgrade_flag == TEE_SEC_UPGRADE_FLAG) {
  678. /* STEP 1: read upgrade image (tee.bin) from stash partition */
  679. printf("read upgrade image (tee.bin) from stash partition \n");
  680. sprintf(runcmd, "ext4load mmc 0:5 0x%p tee.bin", (void *)temp_addr);
  681. printf("runcmd:%s\n", runcmd);
  682. ret = run_command(runcmd, 0);
  683. if (ret != 0) {
  684. printf("TEE Upgrade process is terminated due to some reason\n");
  685. goto _upgrade_tee_exit;
  686. }
  687. /* Fetch the total file size after read out operation end */
  688. upgrade_file_size = env_get_hex("filesize", 0);
  689. printf("TEE upgrade file size: %d\n", upgrade_file_size);
  690. /*store image to temp buffer as temp_addr may be decrypted*/
  691. image_malloc_buffer = malloc(upgrade_file_size);
  692. if ( image_malloc_buffer == NULL ) {
  693. image_buffer = (uint8_t*)temp_addr + upgrade_file_size;
  694. } else {
  695. image_buffer = image_malloc_buffer;
  696. }
  697. memcpy(image_buffer, temp_addr, upgrade_file_size);
  698. /* STEP 2: verify its authentiticy here */
  699. sprintf(runcmd, "vimage 0x%p tee", (void *)temp_addr);
  700. printf("runcmd:%s\n", runcmd);
  701. ret = run_command(runcmd, 0);
  702. if (ret != 0) {
  703. printf("TEE Image verification fail and upgrade process terminates\n");
  704. goto _upgrade_tee_exit;
  705. }
  706. /* STEP 3: update tee partition */
  707. printf("read upgrade image (tee.bin) into tf partition \n");
  708. sprintf(runcmd, "ext4write mmc 0:4 0x%p /tee.bin 0x%x", (void *)image_buffer, upgrade_file_size);
  709. printf("runcmd:%s\n", runcmd);
  710. ret = run_command(runcmd, 0);
  711. if (ret != 0) {
  712. printf("TEE upgrade process is terminated due to some reason\n");
  713. goto _upgrade_tee_exit;
  714. }
  715. /* STEP 4: update tee version */
  716. ret = csi_tee_set_upgrade_version();
  717. if (ret != 0) {
  718. printf("Set tee upgrade version fail\n");
  719. goto _upgrade_tee_exit;
  720. }
  721. printf("\n\nTEE image ugprade process is successful\n\n");
  722. _upgrade_tee_exit:
  723. /* set secure upgrade flag to 0 that indicate upgrade over */
  724. run_command("env set sec_upgrade_mode 0", 0);
  725. run_command("saveenv", 0);
  726. run_command("reset", 0);
  727. if ( image_malloc_buffer != NULL ) {
  728. free(image_malloc_buffer);
  729. image_malloc_buffer = NULL;
  730. }
  731. } else if (sec_upgrade_flag == UBOOT_SEC_UPGRADE_FLAG) {
  732. unsigned int block_cnt;
  733. struct blk_desc *dev_desc;
  734. const unsigned long uboot_temp_addr=0x80000000;
  735. #define BLOCK_SIZE 512
  736. #define PUBKEY_HEADER_SIZE 0x1000
  737. /* STEP 1: read upgrade image (u-boot-with-spl.bin) from stash partition */
  738. printf("read upgrade image (u-boot-with-spl.bin) from stash partition \n");
  739. sprintf(runcmd, "ext4load mmc 0:5 0x%p u-boot-with-spl.bin", (void *)temp_addr);
  740. printf("runcmd:%s\n", runcmd);
  741. ret = run_command(runcmd, 0);
  742. if (ret != 0) {
  743. printf("UBOOT Upgrade process is terminated due to some reason\n");
  744. goto _upgrade_uboot_exit;
  745. }
  746. /* Fetch the total file size after read out operation end */
  747. upgrade_file_size = env_get_hex("filesize", 0);
  748. printf("uboot upgrade file size: %d\n", upgrade_file_size);
  749. /* STEP 2: verify its authentiticy here */
  750. memmove((void *)uboot_temp_addr, (const void *)temp_addr, upgrade_file_size);
  751. sprintf(runcmd, "vimage 0x%p uboot", (void *)(uboot_temp_addr+PUBKEY_HEADER_SIZE));
  752. printf("runcmd:%s\n", runcmd);
  753. ret = run_command(runcmd, 0);
  754. if (ret != 0) {
  755. printf("UBOOT Image verification fail and upgrade process terminates\n");
  756. goto _upgrade_uboot_exit;
  757. }
  758. /* STEP 3: update uboot partition */
  759. printf("write upgrade image (u-boot-with-spl.bin) into boot partition \n");
  760. dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
  761. if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
  762. printf("Invalid mmc device\n");
  763. goto _upgrade_uboot_exit;
  764. }
  765. block_cnt = upgrade_file_size / BLOCK_SIZE;
  766. if (upgrade_file_size % BLOCK_SIZE) {
  767. block_cnt = block_cnt +1;
  768. }
  769. run_command("mmc partconf 0 1 0 1", 0);
  770. sprintf(runcmd, "mmc write 0x%p 0 %x", (void *)temp_addr, block_cnt);
  771. printf("runcmd:%s\n", runcmd);
  772. ret = run_command(runcmd, 0);
  773. run_command("mmc partconf 0 1 0 0", 0);
  774. if (ret != 0) {
  775. printf("UBOOT upgrade process is terminated due to some reason\n");
  776. goto _upgrade_uboot_exit;
  777. }
  778. /* STEP 4: update tee version */
  779. ret = csi_uboot_set_upgrade_version();
  780. if (ret != 0) {
  781. printf("Set uboot upgrade version fail\n");
  782. goto _upgrade_uboot_exit;
  783. }
  784. printf("\n\nUBOOT image ugprade process is successful\n\n");
  785. _upgrade_uboot_exit:
  786. /* set secure upgrade flag to 0 that indicate upgrade over */
  787. run_command("env set sec_upgrade_mode 0", 0);
  788. run_command("saveenv", 0);
  789. run_command("reset", 0);
  790. } else {
  791. printf("Unknown bootstrap, Force sysem reboot\n");
  792. run_command("reset", 0);
  793. }
  794. }
  795. #endif