cmds.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * (C) Copyright 2018 Xilinx, Inc.
  4. * Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
  5. */
  6. #include <common.h>
  7. #include <command.h>
  8. #include <cpu_func.h>
  9. #include <env.h>
  10. #include <malloc.h>
  11. #include <memalign.h>
  12. #include <zynqmp_firmware.h>
  13. #include <asm/arch/hardware.h>
  14. #include <asm/arch/sys_proto.h>
  15. #include <asm/io.h>
  16. struct aes {
  17. u64 srcaddr;
  18. u64 ivaddr;
  19. u64 keyaddr;
  20. u64 dstaddr;
  21. u64 len;
  22. u64 op;
  23. u64 keysrc;
  24. };
  25. static int do_zynqmp_verify_secure(struct cmd_tbl *cmdtp, int flag, int argc,
  26. char *const argv[])
  27. {
  28. u64 src_addr, addr;
  29. u32 len, src_lo, src_hi;
  30. u8 *key_ptr = NULL;
  31. int ret;
  32. u32 key_lo = 0;
  33. u32 key_hi = 0;
  34. u32 ret_payload[PAYLOAD_ARG_CNT];
  35. if (argc < 4)
  36. return CMD_RET_USAGE;
  37. src_addr = simple_strtoull(argv[2], NULL, 16);
  38. len = hextoul(argv[3], NULL);
  39. if (argc == 5)
  40. key_ptr = (uint8_t *)(uintptr_t)simple_strtoull(argv[4],
  41. NULL, 16);
  42. if ((ulong)src_addr != ALIGN((ulong)src_addr,
  43. CONFIG_SYS_CACHELINE_SIZE)) {
  44. printf("Failed: source address not aligned:%lx\n",
  45. (ulong)src_addr);
  46. return -EINVAL;
  47. }
  48. src_lo = lower_32_bits((ulong)src_addr);
  49. src_hi = upper_32_bits((ulong)src_addr);
  50. flush_dcache_range((ulong)src_addr, (ulong)(src_addr + len));
  51. if (key_ptr) {
  52. key_lo = lower_32_bits((ulong)key_ptr);
  53. key_hi = upper_32_bits((ulong)key_ptr);
  54. flush_dcache_range((ulong)key_ptr,
  55. (ulong)(key_ptr + KEY_PTR_LEN));
  56. }
  57. ret = xilinx_pm_request(PM_SECURE_IMAGE, src_lo, src_hi,
  58. key_lo, key_hi, ret_payload);
  59. if (ret) {
  60. printf("Failed: secure op status:0x%x\n", ret);
  61. } else {
  62. addr = (u64)ret_payload[1] << 32 | ret_payload[2];
  63. printf("Verified image at 0x%llx\n", addr);
  64. env_set_hex("zynqmp_verified_img_addr", addr);
  65. }
  66. return ret;
  67. }
  68. static int do_zynqmp_mmio_read(struct cmd_tbl *cmdtp, int flag, int argc,
  69. char *const argv[])
  70. {
  71. u32 read_val, addr;
  72. int ret;
  73. if (argc != cmdtp->maxargs)
  74. return CMD_RET_USAGE;
  75. addr = hextoul(argv[2], NULL);
  76. ret = zynqmp_mmio_read(addr, &read_val);
  77. if (!ret)
  78. printf("mmio read value at 0x%x = 0x%x\n",
  79. addr, read_val);
  80. else
  81. printf("Failed: mmio read\n");
  82. return ret;
  83. }
  84. static int do_zynqmp_mmio_write(struct cmd_tbl *cmdtp, int flag, int argc,
  85. char *const argv[])
  86. {
  87. u32 addr, mask, val;
  88. int ret;
  89. if (argc != cmdtp->maxargs)
  90. return CMD_RET_USAGE;
  91. addr = hextoul(argv[2], NULL);
  92. mask = hextoul(argv[3], NULL);
  93. val = hextoul(argv[4], NULL);
  94. ret = zynqmp_mmio_write(addr, mask, val);
  95. if (ret != 0)
  96. printf("Failed: mmio write\n");
  97. return ret;
  98. }
  99. static int do_zynqmp_aes(struct cmd_tbl *cmdtp, int flag, int argc,
  100. char * const argv[])
  101. {
  102. ALLOC_CACHE_ALIGN_BUFFER(struct aes, aes, 1);
  103. int ret;
  104. u32 ret_payload[PAYLOAD_ARG_CNT];
  105. if (zynqmp_firmware_version() <= PMUFW_V1_0) {
  106. puts("ERR: PMUFW v1.0 or less is detected\n");
  107. puts("ERR: Encrypt/Decrypt feature is not supported\n");
  108. puts("ERR: Please upgrade PMUFW\n");
  109. return CMD_RET_FAILURE;
  110. }
  111. if (argc < cmdtp->maxargs - 1)
  112. return CMD_RET_USAGE;
  113. aes->srcaddr = hextoul(argv[2], NULL);
  114. aes->ivaddr = hextoul(argv[3], NULL);
  115. aes->len = hextoul(argv[4], NULL);
  116. aes->op = hextoul(argv[5], NULL);
  117. aes->keysrc = hextoul(argv[6], NULL);
  118. aes->dstaddr = hextoul(argv[7], NULL);
  119. flush_dcache_range((ulong)aes, (ulong)(aes) +
  120. roundup(sizeof(struct aes), ARCH_DMA_MINALIGN));
  121. if (aes->srcaddr && aes->ivaddr && aes->dstaddr) {
  122. flush_dcache_range(aes->srcaddr,
  123. (aes->srcaddr +
  124. roundup(aes->len, ARCH_DMA_MINALIGN)));
  125. flush_dcache_range(aes->ivaddr,
  126. (aes->ivaddr +
  127. roundup(IV_SIZE, ARCH_DMA_MINALIGN)));
  128. flush_dcache_range(aes->dstaddr,
  129. (aes->dstaddr +
  130. roundup(aes->len, ARCH_DMA_MINALIGN)));
  131. }
  132. if (aes->keysrc == 0) {
  133. if (argc < cmdtp->maxargs)
  134. return CMD_RET_USAGE;
  135. aes->keyaddr = hextoul(argv[8], NULL);
  136. if (aes->keyaddr)
  137. flush_dcache_range(aes->keyaddr,
  138. (aes->keyaddr +
  139. roundup(KEY_PTR_LEN,
  140. ARCH_DMA_MINALIGN)));
  141. }
  142. ret = xilinx_pm_request(PM_SECURE_AES, upper_32_bits((ulong)aes),
  143. lower_32_bits((ulong)aes), 0, 0, ret_payload);
  144. if (ret || ret_payload[1])
  145. printf("Failed: AES op status:0x%x, errcode:0x%x\n",
  146. ret, ret_payload[1]);
  147. return ret;
  148. }
  149. #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
  150. static int do_zynqmp_tcm_init(struct cmd_tbl *cmdtp, int flag, int argc,
  151. char *const argv[])
  152. {
  153. u8 mode;
  154. if (argc != cmdtp->maxargs)
  155. return CMD_RET_USAGE;
  156. mode = hextoul(argv[2], NULL);
  157. if (mode != TCM_LOCK && mode != TCM_SPLIT) {
  158. printf("Mode should be either 0(lock)/1(split)\n");
  159. return CMD_RET_FAILURE;
  160. }
  161. dcache_disable();
  162. tcm_init(mode);
  163. dcache_enable();
  164. return CMD_RET_SUCCESS;
  165. }
  166. #endif
  167. static int do_zynqmp_pmufw(struct cmd_tbl *cmdtp, int flag, int argc,
  168. char * const argv[])
  169. {
  170. u32 addr, size;
  171. if (argc != cmdtp->maxargs)
  172. return CMD_RET_USAGE;
  173. addr = hextoul(argv[2], NULL);
  174. size = hextoul(argv[3], NULL);
  175. flush_dcache_range((ulong)addr, (ulong)(addr + size));
  176. zynqmp_pmufw_load_config_object((const void *)(uintptr_t)addr,
  177. (size_t)size);
  178. return 0;
  179. }
  180. static int do_zynqmp_rsa(struct cmd_tbl *cmdtp, int flag, int argc,
  181. char * const argv[])
  182. {
  183. u64 srcaddr, mod, exp;
  184. u32 srclen, rsaop, size, ret_payload[PAYLOAD_ARG_CNT];
  185. int ret;
  186. if (argc != cmdtp->maxargs)
  187. return CMD_RET_USAGE;
  188. if (zynqmp_firmware_version() <= PMUFW_V1_0) {
  189. puts("ERR: PMUFW v1.0 or less is detected\n");
  190. puts("ERR: Encrypt/Decrypt feature is not supported\n");
  191. puts("ERR: Please upgrade PMUFW\n");
  192. return CMD_RET_FAILURE;
  193. }
  194. srcaddr = hextoul(argv[2], NULL);
  195. srclen = hextoul(argv[3], NULL);
  196. if (srclen != RSA_KEY_SIZE) {
  197. puts("ERR: srclen should be equal to 0x200(512 bytes)\n");
  198. return CMD_RET_USAGE;
  199. }
  200. mod = hextoul(argv[4], NULL);
  201. exp = hextoul(argv[5], NULL);
  202. rsaop = hextoul(argv[6], NULL);
  203. if (!(rsaop == 0 || rsaop == 1)) {
  204. puts("ERR: rsaop should be either 0 or 1\n");
  205. return CMD_RET_USAGE;
  206. }
  207. memcpy((void *)srcaddr + srclen, (void *)mod, MODULUS_LEN);
  208. /*
  209. * For encryption we load public exponent (key size 4096-bits),
  210. * for decryption we load private exponent (32-bits)
  211. */
  212. if (rsaop) {
  213. memcpy((void *)srcaddr + srclen + MODULUS_LEN,
  214. (void *)exp, PUB_EXPO_LEN);
  215. size = srclen + MODULUS_LEN + PUB_EXPO_LEN;
  216. } else {
  217. memcpy((void *)srcaddr + srclen + MODULUS_LEN,
  218. (void *)exp, PRIV_EXPO_LEN);
  219. size = srclen + MODULUS_LEN + PRIV_EXPO_LEN;
  220. }
  221. flush_dcache_range((ulong)srcaddr,
  222. (ulong)(srcaddr) + roundup(size, ARCH_DMA_MINALIGN));
  223. ret = xilinx_pm_request(PM_SECURE_RSA, upper_32_bits((ulong)srcaddr),
  224. lower_32_bits((ulong)srcaddr), srclen, rsaop,
  225. ret_payload);
  226. if (ret || ret_payload[1]) {
  227. printf("Failed: RSA status:0x%x, errcode:0x%x\n",
  228. ret, ret_payload[1]);
  229. return CMD_RET_FAILURE;
  230. }
  231. return CMD_RET_SUCCESS;
  232. }
  233. static int do_zynqmp_sha3(struct cmd_tbl *cmdtp, int flag,
  234. int argc, char * const argv[])
  235. {
  236. u64 srcaddr, hashaddr;
  237. u32 srclen, ret_payload[PAYLOAD_ARG_CNT];
  238. int ret;
  239. if (argc > cmdtp->maxargs || argc < (cmdtp->maxargs - 1))
  240. return CMD_RET_USAGE;
  241. if (zynqmp_firmware_version() <= PMUFW_V1_0) {
  242. puts("ERR: PMUFW v1.0 or less is detected\n");
  243. puts("ERR: Encrypt/Decrypt feature is not supported\n");
  244. puts("ERR: Please upgrade PMUFW\n");
  245. return CMD_RET_FAILURE;
  246. }
  247. srcaddr = hextoul(argv[2], NULL);
  248. srclen = hextoul(argv[3], NULL);
  249. if (argc == 5) {
  250. hashaddr = hextoul(argv[4], NULL);
  251. flush_dcache_range(hashaddr,
  252. hashaddr + roundup(ZYNQMP_SHA3_SIZE,
  253. ARCH_DMA_MINALIGN));
  254. } else {
  255. hashaddr = srcaddr;
  256. }
  257. /* Check srcaddr or srclen != 0 */
  258. if (!srcaddr || !srclen) {
  259. puts("ERR: srcaddr & srclen should not be 0\n");
  260. return CMD_RET_USAGE;
  261. }
  262. flush_dcache_range(srcaddr,
  263. srcaddr + roundup(srclen, ARCH_DMA_MINALIGN));
  264. ret = xilinx_pm_request(PM_SECURE_SHA, 0, 0, 0,
  265. ZYNQMP_SHA3_INIT, ret_payload);
  266. if (ret || ret_payload[1]) {
  267. printf("Failed: SHA INIT status:0x%x, errcode:0x%x\n",
  268. ret, ret_payload[1]);
  269. return CMD_RET_FAILURE;
  270. }
  271. ret = xilinx_pm_request(PM_SECURE_SHA, upper_32_bits((ulong)srcaddr),
  272. lower_32_bits((ulong)srcaddr),
  273. srclen, ZYNQMP_SHA3_UPDATE, ret_payload);
  274. if (ret || ret_payload[1]) {
  275. printf("Failed: SHA UPDATE status:0x%x, errcode:0x%x\n",
  276. ret, ret_payload[1]);
  277. return CMD_RET_FAILURE;
  278. }
  279. ret = xilinx_pm_request(PM_SECURE_SHA, upper_32_bits((ulong)hashaddr),
  280. lower_32_bits((ulong)hashaddr),
  281. ZYNQMP_SHA3_SIZE, ZYNQMP_SHA3_FINAL,
  282. ret_payload);
  283. if (ret || ret_payload[1]) {
  284. printf("Failed: SHA FINAL status:0x%x, errcode:0x%x\n",
  285. ret, ret_payload[1]);
  286. return CMD_RET_FAILURE;
  287. }
  288. return CMD_RET_SUCCESS;
  289. }
  290. static struct cmd_tbl cmd_zynqmp_sub[] = {
  291. U_BOOT_CMD_MKENT(secure, 5, 0, do_zynqmp_verify_secure, "", ""),
  292. U_BOOT_CMD_MKENT(pmufw, 4, 0, do_zynqmp_pmufw, "", ""),
  293. U_BOOT_CMD_MKENT(mmio_read, 3, 0, do_zynqmp_mmio_read, "", ""),
  294. U_BOOT_CMD_MKENT(mmio_write, 5, 0, do_zynqmp_mmio_write, "", ""),
  295. U_BOOT_CMD_MKENT(aes, 9, 0, do_zynqmp_aes, "", ""),
  296. U_BOOT_CMD_MKENT(rsa, 7, 0, do_zynqmp_rsa, "", ""),
  297. U_BOOT_CMD_MKENT(sha3, 5, 0, do_zynqmp_sha3, "", ""),
  298. #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
  299. U_BOOT_CMD_MKENT(tcminit, 3, 0, do_zynqmp_tcm_init, "", ""),
  300. #endif
  301. };
  302. /**
  303. * do_zynqmp - Handle the "zynqmp" command-line command
  304. * @cmdtp: Command data struct pointer
  305. * @flag: Command flag
  306. * @argc: Command-line argument count
  307. * @argv: Array of command-line arguments
  308. *
  309. * Processes the zynqmp specific commands
  310. *
  311. * Return: return 0 on success and CMD_RET_USAGE incase of misuse and error
  312. */
  313. static int do_zynqmp(struct cmd_tbl *cmdtp, int flag, int argc,
  314. char *const argv[])
  315. {
  316. struct cmd_tbl *c;
  317. if (argc < 2)
  318. return CMD_RET_USAGE;
  319. c = find_cmd_tbl(argv[1], &cmd_zynqmp_sub[0],
  320. ARRAY_SIZE(cmd_zynqmp_sub));
  321. if (c)
  322. return c->cmd(c, flag, argc, argv);
  323. else
  324. return CMD_RET_USAGE;
  325. }
  326. /***************************************************/
  327. #ifdef CONFIG_SYS_LONGHELP
  328. static char zynqmp_help_text[] =
  329. "secure src len [key_addr] - verifies secure images of $len bytes\n"
  330. " long at address $src. Optional key_addr\n"
  331. " can be specified if user key needs to\n"
  332. " be used for decryption\n"
  333. "zynqmp mmio_read address - read from address\n"
  334. "zynqmp mmio_write address mask value - write value after masking to\n"
  335. " address\n"
  336. "zynqmp aes srcaddr ivaddr len aesop keysrc dstaddr [keyaddr] -\n"
  337. " Encrypts or decrypts blob of data at src address and puts it\n"
  338. " back to dstaddr using key and iv at keyaddr and ivaddr\n"
  339. " respectively. keysrc value specifies from which source key\n"
  340. " has to be used, it can be User/Device/PUF key. A value of 0\n"
  341. " for KUP(user key),1 for DeviceKey and 2 for PUF key. The\n"
  342. " aesop value specifies the operation which can be 0 for\n"
  343. " decrypt and 1 for encrypt operation\n"
  344. #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
  345. "zynqmp tcminit mode - Initialize the TCM with zeros. TCM needs to be\n"
  346. " initialized before accessing to avoid ECC\n"
  347. " errors. mode specifies in which mode TCM has\n"
  348. " to be initialized. Supported modes will be\n"
  349. " lock(0)/split(1)\n"
  350. #endif
  351. "zynqmp pmufw address size - load PMU FW configuration object\n"
  352. "zynqmp rsa srcaddr srclen mod exp rsaop -\n"
  353. " Performs RSA encryption and RSA decryption on blob of data\n"
  354. " at srcaddr and puts it back in srcaddr using modulus and\n"
  355. " public or private exponent\n"
  356. " srclen : must be key size(4096 bits)\n"
  357. " exp : private key exponent for RSA decryption(4096 bits)\n"
  358. " public key exponent for RSA encryption(32 bits)\n"
  359. " rsaop : 0 for RSA Decryption, 1 for RSA Encryption\n"
  360. "zynqmp sha3 srcaddr srclen [key_addr] -\n"
  361. " Generates sha3 hash value for data blob at srcaddr and puts\n"
  362. " 48 bytes hash value into srcaddr\n"
  363. " Optional key_addr can be specified for saving sha3 hash value\n"
  364. " Note: srcaddr/srclen should not be 0\n"
  365. ;
  366. #endif
  367. U_BOOT_CMD(
  368. zynqmp, 9, 1, do_zynqmp,
  369. "ZynqMP sub-system",
  370. zynqmp_help_text
  371. )