turris-mox-rwtm.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Turris Mox rWTM firmware driver
  4. *
  5. * Copyright (C) 2019 Marek Behún <[email protected]>
  6. */
  7. #include <linux/armada-37xx-rwtm-mailbox.h>
  8. #include <linux/completion.h>
  9. #include <linux/debugfs.h>
  10. #include <linux/dma-mapping.h>
  11. #include <linux/hw_random.h>
  12. #include <linux/mailbox_client.h>
  13. #include <linux/module.h>
  14. #include <linux/mutex.h>
  15. #include <linux/of.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/slab.h>
  18. #define DRIVER_NAME "turris-mox-rwtm"
  19. /*
  20. * The macros and constants below come from Turris Mox's rWTM firmware code.
  21. * This firmware is open source and it's sources can be found at
  22. * https://gitlab.labs.nic.cz/turris/mox-boot-builder/tree/master/wtmi.
  23. */
  24. #define MBOX_STS_SUCCESS (0 << 30)
  25. #define MBOX_STS_FAIL (1 << 30)
  26. #define MBOX_STS_BADCMD (2 << 30)
  27. #define MBOX_STS_ERROR(s) ((s) & (3 << 30))
  28. #define MBOX_STS_VALUE(s) (((s) >> 10) & 0xfffff)
  29. #define MBOX_STS_CMD(s) ((s) & 0x3ff)
  30. enum mbox_cmd {
  31. MBOX_CMD_GET_RANDOM = 1,
  32. MBOX_CMD_BOARD_INFO = 2,
  33. MBOX_CMD_ECDSA_PUB_KEY = 3,
  34. MBOX_CMD_HASH = 4,
  35. MBOX_CMD_SIGN = 5,
  36. MBOX_CMD_VERIFY = 6,
  37. MBOX_CMD_OTP_READ = 7,
  38. MBOX_CMD_OTP_WRITE = 8,
  39. };
  40. struct mox_kobject;
  41. struct mox_rwtm {
  42. struct device *dev;
  43. struct mbox_client mbox_client;
  44. struct mbox_chan *mbox;
  45. struct mox_kobject *kobj;
  46. struct hwrng hwrng;
  47. struct armada_37xx_rwtm_rx_msg reply;
  48. void *buf;
  49. dma_addr_t buf_phys;
  50. struct mutex busy;
  51. struct completion cmd_done;
  52. /* board information */
  53. int has_board_info;
  54. u64 serial_number;
  55. int board_version, ram_size;
  56. u8 mac_address1[6], mac_address2[6];
  57. /* public key burned in eFuse */
  58. int has_pubkey;
  59. u8 pubkey[135];
  60. #ifdef CONFIG_DEBUG_FS
  61. /*
  62. * Signature process. This is currently done via debugfs, because it
  63. * does not conform to the sysfs standard "one file per attribute".
  64. * It should be rewritten via crypto API once akcipher API is available
  65. * from userspace.
  66. */
  67. struct dentry *debugfs_root;
  68. u32 last_sig[34];
  69. int last_sig_done;
  70. #endif
  71. };
  72. struct mox_kobject {
  73. struct kobject kobj;
  74. struct mox_rwtm *rwtm;
  75. };
  76. static inline struct kobject *rwtm_to_kobj(struct mox_rwtm *rwtm)
  77. {
  78. return &rwtm->kobj->kobj;
  79. }
  80. static inline struct mox_rwtm *to_rwtm(struct kobject *kobj)
  81. {
  82. return container_of(kobj, struct mox_kobject, kobj)->rwtm;
  83. }
  84. static void mox_kobj_release(struct kobject *kobj)
  85. {
  86. kfree(to_rwtm(kobj)->kobj);
  87. }
  88. static struct kobj_type mox_kobj_ktype = {
  89. .release = mox_kobj_release,
  90. .sysfs_ops = &kobj_sysfs_ops,
  91. };
  92. static int mox_kobj_create(struct mox_rwtm *rwtm)
  93. {
  94. rwtm->kobj = kzalloc(sizeof(*rwtm->kobj), GFP_KERNEL);
  95. if (!rwtm->kobj)
  96. return -ENOMEM;
  97. kobject_init(rwtm_to_kobj(rwtm), &mox_kobj_ktype);
  98. if (kobject_add(rwtm_to_kobj(rwtm), firmware_kobj, "turris-mox-rwtm")) {
  99. kobject_put(rwtm_to_kobj(rwtm));
  100. return -ENXIO;
  101. }
  102. rwtm->kobj->rwtm = rwtm;
  103. return 0;
  104. }
  105. #define MOX_ATTR_RO(name, format, cat) \
  106. static ssize_t \
  107. name##_show(struct kobject *kobj, struct kobj_attribute *a, \
  108. char *buf) \
  109. { \
  110. struct mox_rwtm *rwtm = to_rwtm(kobj); \
  111. if (!rwtm->has_##cat) \
  112. return -ENODATA; \
  113. return sprintf(buf, format, rwtm->name); \
  114. } \
  115. static struct kobj_attribute mox_attr_##name = __ATTR_RO(name)
  116. MOX_ATTR_RO(serial_number, "%016llX\n", board_info);
  117. MOX_ATTR_RO(board_version, "%i\n", board_info);
  118. MOX_ATTR_RO(ram_size, "%i\n", board_info);
  119. MOX_ATTR_RO(mac_address1, "%pM\n", board_info);
  120. MOX_ATTR_RO(mac_address2, "%pM\n", board_info);
  121. MOX_ATTR_RO(pubkey, "%s\n", pubkey);
  122. static int mox_get_status(enum mbox_cmd cmd, u32 retval)
  123. {
  124. if (MBOX_STS_CMD(retval) != cmd)
  125. return -EIO;
  126. else if (MBOX_STS_ERROR(retval) == MBOX_STS_FAIL)
  127. return -(int)MBOX_STS_VALUE(retval);
  128. else if (MBOX_STS_ERROR(retval) == MBOX_STS_BADCMD)
  129. return -ENOSYS;
  130. else if (MBOX_STS_ERROR(retval) != MBOX_STS_SUCCESS)
  131. return -EIO;
  132. else
  133. return MBOX_STS_VALUE(retval);
  134. }
  135. static const struct attribute *mox_rwtm_attrs[] = {
  136. &mox_attr_serial_number.attr,
  137. &mox_attr_board_version.attr,
  138. &mox_attr_ram_size.attr,
  139. &mox_attr_mac_address1.attr,
  140. &mox_attr_mac_address2.attr,
  141. &mox_attr_pubkey.attr,
  142. NULL
  143. };
  144. static void mox_rwtm_rx_callback(struct mbox_client *cl, void *data)
  145. {
  146. struct mox_rwtm *rwtm = dev_get_drvdata(cl->dev);
  147. struct armada_37xx_rwtm_rx_msg *msg = data;
  148. rwtm->reply = *msg;
  149. complete(&rwtm->cmd_done);
  150. }
  151. static void reply_to_mac_addr(u8 *mac, u32 t1, u32 t2)
  152. {
  153. mac[0] = t1 >> 8;
  154. mac[1] = t1;
  155. mac[2] = t2 >> 24;
  156. mac[3] = t2 >> 16;
  157. mac[4] = t2 >> 8;
  158. mac[5] = t2;
  159. }
  160. static int mox_get_board_info(struct mox_rwtm *rwtm)
  161. {
  162. struct armada_37xx_rwtm_tx_msg msg;
  163. struct armada_37xx_rwtm_rx_msg *reply = &rwtm->reply;
  164. int ret;
  165. msg.command = MBOX_CMD_BOARD_INFO;
  166. ret = mbox_send_message(rwtm->mbox, &msg);
  167. if (ret < 0)
  168. return ret;
  169. ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2);
  170. if (ret < 0)
  171. return ret;
  172. ret = mox_get_status(MBOX_CMD_BOARD_INFO, reply->retval);
  173. if (ret == -ENODATA) {
  174. dev_warn(rwtm->dev,
  175. "Board does not have manufacturing information burned!\n");
  176. } else if (ret == -ENOSYS) {
  177. dev_notice(rwtm->dev,
  178. "Firmware does not support the BOARD_INFO command\n");
  179. } else if (ret < 0) {
  180. return ret;
  181. } else {
  182. rwtm->serial_number = reply->status[1];
  183. rwtm->serial_number <<= 32;
  184. rwtm->serial_number |= reply->status[0];
  185. rwtm->board_version = reply->status[2];
  186. rwtm->ram_size = reply->status[3];
  187. reply_to_mac_addr(rwtm->mac_address1, reply->status[4],
  188. reply->status[5]);
  189. reply_to_mac_addr(rwtm->mac_address2, reply->status[6],
  190. reply->status[7]);
  191. rwtm->has_board_info = 1;
  192. pr_info("Turris Mox serial number %016llX\n",
  193. rwtm->serial_number);
  194. pr_info(" board version %i\n", rwtm->board_version);
  195. pr_info(" burned RAM size %i MiB\n", rwtm->ram_size);
  196. }
  197. msg.command = MBOX_CMD_ECDSA_PUB_KEY;
  198. ret = mbox_send_message(rwtm->mbox, &msg);
  199. if (ret < 0)
  200. return ret;
  201. ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2);
  202. if (ret < 0)
  203. return ret;
  204. ret = mox_get_status(MBOX_CMD_ECDSA_PUB_KEY, reply->retval);
  205. if (ret == -ENODATA) {
  206. dev_warn(rwtm->dev, "Board has no public key burned!\n");
  207. } else if (ret == -ENOSYS) {
  208. dev_notice(rwtm->dev,
  209. "Firmware does not support the ECDSA_PUB_KEY command\n");
  210. } else if (ret < 0) {
  211. return ret;
  212. } else {
  213. u32 *s = reply->status;
  214. rwtm->has_pubkey = 1;
  215. sprintf(rwtm->pubkey,
  216. "%06x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
  217. ret, s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7],
  218. s[8], s[9], s[10], s[11], s[12], s[13], s[14], s[15]);
  219. }
  220. return 0;
  221. }
  222. static int check_get_random_support(struct mox_rwtm *rwtm)
  223. {
  224. struct armada_37xx_rwtm_tx_msg msg;
  225. int ret;
  226. msg.command = MBOX_CMD_GET_RANDOM;
  227. msg.args[0] = 1;
  228. msg.args[1] = rwtm->buf_phys;
  229. msg.args[2] = 4;
  230. ret = mbox_send_message(rwtm->mbox, &msg);
  231. if (ret < 0)
  232. return ret;
  233. ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2);
  234. if (ret < 0)
  235. return ret;
  236. return mox_get_status(MBOX_CMD_GET_RANDOM, rwtm->reply.retval);
  237. }
  238. static int mox_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
  239. {
  240. struct mox_rwtm *rwtm = (struct mox_rwtm *) rng->priv;
  241. struct armada_37xx_rwtm_tx_msg msg;
  242. int ret;
  243. if (max > 4096)
  244. max = 4096;
  245. msg.command = MBOX_CMD_GET_RANDOM;
  246. msg.args[0] = 1;
  247. msg.args[1] = rwtm->buf_phys;
  248. msg.args[2] = (max + 3) & ~3;
  249. if (!wait) {
  250. if (!mutex_trylock(&rwtm->busy))
  251. return -EBUSY;
  252. } else {
  253. mutex_lock(&rwtm->busy);
  254. }
  255. ret = mbox_send_message(rwtm->mbox, &msg);
  256. if (ret < 0)
  257. goto unlock_mutex;
  258. ret = wait_for_completion_interruptible(&rwtm->cmd_done);
  259. if (ret < 0)
  260. goto unlock_mutex;
  261. ret = mox_get_status(MBOX_CMD_GET_RANDOM, rwtm->reply.retval);
  262. if (ret < 0)
  263. goto unlock_mutex;
  264. memcpy(data, rwtm->buf, max);
  265. ret = max;
  266. unlock_mutex:
  267. mutex_unlock(&rwtm->busy);
  268. return ret;
  269. }
  270. #ifdef CONFIG_DEBUG_FS
  271. static int rwtm_debug_open(struct inode *inode, struct file *file)
  272. {
  273. file->private_data = inode->i_private;
  274. return nonseekable_open(inode, file);
  275. }
  276. static ssize_t do_sign_read(struct file *file, char __user *buf, size_t len,
  277. loff_t *ppos)
  278. {
  279. struct mox_rwtm *rwtm = file->private_data;
  280. ssize_t ret;
  281. /* only allow one read, of 136 bytes, from position 0 */
  282. if (*ppos != 0)
  283. return 0;
  284. if (len < 136)
  285. return -EINVAL;
  286. if (!rwtm->last_sig_done)
  287. return -ENODATA;
  288. /* 2 arrays of 17 32-bit words are 136 bytes */
  289. ret = simple_read_from_buffer(buf, len, ppos, rwtm->last_sig, 136);
  290. rwtm->last_sig_done = 0;
  291. return ret;
  292. }
  293. static ssize_t do_sign_write(struct file *file, const char __user *buf,
  294. size_t len, loff_t *ppos)
  295. {
  296. struct mox_rwtm *rwtm = file->private_data;
  297. struct armada_37xx_rwtm_rx_msg *reply = &rwtm->reply;
  298. struct armada_37xx_rwtm_tx_msg msg;
  299. loff_t dummy = 0;
  300. ssize_t ret;
  301. /* the input is a SHA-512 hash, so exactly 64 bytes have to be read */
  302. if (len != 64)
  303. return -EINVAL;
  304. /* if last result is not zero user has not read that information yet */
  305. if (rwtm->last_sig_done)
  306. return -EBUSY;
  307. if (!mutex_trylock(&rwtm->busy))
  308. return -EBUSY;
  309. /*
  310. * Here we have to send:
  311. * 1. Address of the input to sign.
  312. * The input is an array of 17 32-bit words, the first (most
  313. * significat) is 0, the rest 16 words are copied from the SHA-512
  314. * hash given by the user and converted from BE to LE.
  315. * 2. Address of the buffer where ECDSA signature value R shall be
  316. * stored by the rWTM firmware.
  317. * 3. Address of the buffer where ECDSA signature value S shall be
  318. * stored by the rWTM firmware.
  319. */
  320. memset(rwtm->buf, 0, 4);
  321. ret = simple_write_to_buffer(rwtm->buf + 4, 64, &dummy, buf, len);
  322. if (ret < 0)
  323. goto unlock_mutex;
  324. be32_to_cpu_array(rwtm->buf, rwtm->buf, 17);
  325. msg.command = MBOX_CMD_SIGN;
  326. msg.args[0] = 1;
  327. msg.args[1] = rwtm->buf_phys;
  328. msg.args[2] = rwtm->buf_phys + 68;
  329. msg.args[3] = rwtm->buf_phys + 2 * 68;
  330. ret = mbox_send_message(rwtm->mbox, &msg);
  331. if (ret < 0)
  332. goto unlock_mutex;
  333. ret = wait_for_completion_interruptible(&rwtm->cmd_done);
  334. if (ret < 0)
  335. goto unlock_mutex;
  336. ret = MBOX_STS_VALUE(reply->retval);
  337. if (MBOX_STS_ERROR(reply->retval) != MBOX_STS_SUCCESS)
  338. goto unlock_mutex;
  339. /*
  340. * Here we read the R and S values of the ECDSA signature
  341. * computed by the rWTM firmware and convert their words from
  342. * LE to BE.
  343. */
  344. memcpy(rwtm->last_sig, rwtm->buf + 68, 136);
  345. cpu_to_be32_array(rwtm->last_sig, rwtm->last_sig, 34);
  346. rwtm->last_sig_done = 1;
  347. mutex_unlock(&rwtm->busy);
  348. return len;
  349. unlock_mutex:
  350. mutex_unlock(&rwtm->busy);
  351. return ret;
  352. }
  353. static const struct file_operations do_sign_fops = {
  354. .owner = THIS_MODULE,
  355. .open = rwtm_debug_open,
  356. .read = do_sign_read,
  357. .write = do_sign_write,
  358. .llseek = no_llseek,
  359. };
  360. static int rwtm_register_debugfs(struct mox_rwtm *rwtm)
  361. {
  362. struct dentry *root, *entry;
  363. root = debugfs_create_dir("turris-mox-rwtm", NULL);
  364. if (IS_ERR(root))
  365. return PTR_ERR(root);
  366. entry = debugfs_create_file_unsafe("do_sign", 0600, root, rwtm,
  367. &do_sign_fops);
  368. if (IS_ERR(entry))
  369. goto err_remove;
  370. rwtm->debugfs_root = root;
  371. return 0;
  372. err_remove:
  373. debugfs_remove_recursive(root);
  374. return PTR_ERR(entry);
  375. }
  376. static void rwtm_unregister_debugfs(struct mox_rwtm *rwtm)
  377. {
  378. debugfs_remove_recursive(rwtm->debugfs_root);
  379. }
  380. #else
  381. static inline int rwtm_register_debugfs(struct mox_rwtm *rwtm)
  382. {
  383. return 0;
  384. }
  385. static inline void rwtm_unregister_debugfs(struct mox_rwtm *rwtm)
  386. {
  387. }
  388. #endif
  389. static int turris_mox_rwtm_probe(struct platform_device *pdev)
  390. {
  391. struct mox_rwtm *rwtm;
  392. struct device *dev = &pdev->dev;
  393. int ret;
  394. rwtm = devm_kzalloc(dev, sizeof(*rwtm), GFP_KERNEL);
  395. if (!rwtm)
  396. return -ENOMEM;
  397. rwtm->dev = dev;
  398. rwtm->buf = dmam_alloc_coherent(dev, PAGE_SIZE, &rwtm->buf_phys,
  399. GFP_KERNEL);
  400. if (!rwtm->buf)
  401. return -ENOMEM;
  402. ret = mox_kobj_create(rwtm);
  403. if (ret < 0) {
  404. dev_err(dev, "Cannot create turris-mox-rwtm kobject!\n");
  405. return ret;
  406. }
  407. ret = sysfs_create_files(rwtm_to_kobj(rwtm), mox_rwtm_attrs);
  408. if (ret < 0) {
  409. dev_err(dev, "Cannot create sysfs files!\n");
  410. goto put_kobj;
  411. }
  412. platform_set_drvdata(pdev, rwtm);
  413. mutex_init(&rwtm->busy);
  414. rwtm->mbox_client.dev = dev;
  415. rwtm->mbox_client.rx_callback = mox_rwtm_rx_callback;
  416. rwtm->mbox = mbox_request_channel(&rwtm->mbox_client, 0);
  417. if (IS_ERR(rwtm->mbox)) {
  418. ret = PTR_ERR(rwtm->mbox);
  419. if (ret != -EPROBE_DEFER)
  420. dev_err(dev, "Cannot request mailbox channel: %i\n",
  421. ret);
  422. goto remove_files;
  423. }
  424. init_completion(&rwtm->cmd_done);
  425. ret = mox_get_board_info(rwtm);
  426. if (ret < 0)
  427. dev_warn(dev, "Cannot read board information: %i\n", ret);
  428. ret = check_get_random_support(rwtm);
  429. if (ret < 0) {
  430. dev_notice(dev,
  431. "Firmware does not support the GET_RANDOM command\n");
  432. goto free_channel;
  433. }
  434. rwtm->hwrng.name = DRIVER_NAME "_hwrng";
  435. rwtm->hwrng.read = mox_hwrng_read;
  436. rwtm->hwrng.priv = (unsigned long) rwtm;
  437. rwtm->hwrng.quality = 1024;
  438. ret = devm_hwrng_register(dev, &rwtm->hwrng);
  439. if (ret < 0) {
  440. dev_err(dev, "Cannot register HWRNG: %i\n", ret);
  441. goto free_channel;
  442. }
  443. ret = rwtm_register_debugfs(rwtm);
  444. if (ret < 0) {
  445. dev_err(dev, "Failed creating debugfs entries: %i\n", ret);
  446. goto free_channel;
  447. }
  448. dev_info(dev, "HWRNG successfully registered\n");
  449. return 0;
  450. free_channel:
  451. mbox_free_channel(rwtm->mbox);
  452. remove_files:
  453. sysfs_remove_files(rwtm_to_kobj(rwtm), mox_rwtm_attrs);
  454. put_kobj:
  455. kobject_put(rwtm_to_kobj(rwtm));
  456. return ret;
  457. }
  458. static int turris_mox_rwtm_remove(struct platform_device *pdev)
  459. {
  460. struct mox_rwtm *rwtm = platform_get_drvdata(pdev);
  461. rwtm_unregister_debugfs(rwtm);
  462. sysfs_remove_files(rwtm_to_kobj(rwtm), mox_rwtm_attrs);
  463. kobject_put(rwtm_to_kobj(rwtm));
  464. mbox_free_channel(rwtm->mbox);
  465. return 0;
  466. }
  467. static const struct of_device_id turris_mox_rwtm_match[] = {
  468. { .compatible = "cznic,turris-mox-rwtm", },
  469. { .compatible = "marvell,armada-3700-rwtm-firmware", },
  470. { },
  471. };
  472. MODULE_DEVICE_TABLE(of, turris_mox_rwtm_match);
  473. static struct platform_driver turris_mox_rwtm_driver = {
  474. .probe = turris_mox_rwtm_probe,
  475. .remove = turris_mox_rwtm_remove,
  476. .driver = {
  477. .name = DRIVER_NAME,
  478. .of_match_table = turris_mox_rwtm_match,
  479. },
  480. };
  481. module_platform_driver(turris_mox_rwtm_driver);
  482. MODULE_LICENSE("GPL v2");
  483. MODULE_DESCRIPTION("Turris Mox rWTM firmware driver");
  484. MODULE_AUTHOR("Marek Behun <[email protected]>");