tpm_vtpm_proxy.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. /*
  2. * Copyright (C) 2015, 2016 IBM Corporation
  3. *
  4. * Author: Stefan Berger <stefanb@us.ibm.com>
  5. *
  6. * Maintained by: <tpmdd-devel@lists.sourceforge.net>
  7. *
  8. * Device driver for vTPM (vTPM proxy driver)
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License as
  12. * published by the Free Software Foundation, version 2 of the
  13. * License.
  14. *
  15. */
  16. #include <linux/types.h>
  17. #include <linux/spinlock.h>
  18. #include <linux/uaccess.h>
  19. #include <linux/wait.h>
  20. #include <linux/miscdevice.h>
  21. #include <linux/vtpm_proxy.h>
  22. #include <linux/file.h>
  23. #include <linux/anon_inodes.h>
  24. #include <linux/poll.h>
  25. #include <linux/compat.h>
  26. #include "tpm.h"
  27. #define VTPM_PROXY_REQ_COMPLETE_FLAG BIT(0)
  28. struct proxy_dev {
  29. struct tpm_chip *chip;
  30. u32 flags; /* public API flags */
  31. wait_queue_head_t wq;
  32. struct mutex buf_lock; /* protect buffer and flags */
  33. long state; /* internal state */
  34. #define STATE_OPENED_FLAG BIT(0)
  35. #define STATE_WAIT_RESPONSE_FLAG BIT(1) /* waiting for emulator response */
  36. size_t req_len; /* length of queued TPM request */
  37. size_t resp_len; /* length of queued TPM response */
  38. u8 buffer[TPM_BUFSIZE]; /* request/response buffer */
  39. struct work_struct work; /* task that retrieves TPM timeouts */
  40. };
  41. /* all supported flags */
  42. #define VTPM_PROXY_FLAGS_ALL (VTPM_PROXY_FLAG_TPM2)
  43. static struct workqueue_struct *workqueue;
  44. static void vtpm_proxy_delete_device(struct proxy_dev *proxy_dev);
  45. /*
  46. * Functions related to 'server side'
  47. */
  48. /**
  49. * vtpm_proxy_fops_read - Read TPM commands on 'server side'
  50. *
  51. * Return value:
  52. * Number of bytes read or negative error code
  53. */
  54. static ssize_t vtpm_proxy_fops_read(struct file *filp, char __user *buf,
  55. size_t count, loff_t *off)
  56. {
  57. struct proxy_dev *proxy_dev = filp->private_data;
  58. size_t len;
  59. int sig, rc;
  60. sig = wait_event_interruptible(proxy_dev->wq,
  61. proxy_dev->req_len != 0 ||
  62. !(proxy_dev->state & STATE_OPENED_FLAG));
  63. if (sig)
  64. return -EINTR;
  65. mutex_lock(&proxy_dev->buf_lock);
  66. if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
  67. mutex_unlock(&proxy_dev->buf_lock);
  68. return -EPIPE;
  69. }
  70. len = proxy_dev->req_len;
  71. if (count < len) {
  72. mutex_unlock(&proxy_dev->buf_lock);
  73. pr_debug("Invalid size in recv: count=%zd, req_len=%zd\n",
  74. count, len);
  75. return -EIO;
  76. }
  77. rc = copy_to_user(buf, proxy_dev->buffer, len);
  78. memset(proxy_dev->buffer, 0, len);
  79. proxy_dev->req_len = 0;
  80. if (!rc)
  81. proxy_dev->state |= STATE_WAIT_RESPONSE_FLAG;
  82. mutex_unlock(&proxy_dev->buf_lock);
  83. if (rc)
  84. return -EFAULT;
  85. return len;
  86. }
  87. /**
  88. * vtpm_proxy_fops_write - Write TPM responses on 'server side'
  89. *
  90. * Return value:
  91. * Number of bytes read or negative error value
  92. */
  93. static ssize_t vtpm_proxy_fops_write(struct file *filp, const char __user *buf,
  94. size_t count, loff_t *off)
  95. {
  96. struct proxy_dev *proxy_dev = filp->private_data;
  97. mutex_lock(&proxy_dev->buf_lock);
  98. if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
  99. mutex_unlock(&proxy_dev->buf_lock);
  100. return -EPIPE;
  101. }
  102. if (count > sizeof(proxy_dev->buffer) ||
  103. !(proxy_dev->state & STATE_WAIT_RESPONSE_FLAG)) {
  104. mutex_unlock(&proxy_dev->buf_lock);
  105. return -EIO;
  106. }
  107. proxy_dev->state &= ~STATE_WAIT_RESPONSE_FLAG;
  108. proxy_dev->req_len = 0;
  109. if (copy_from_user(proxy_dev->buffer, buf, count)) {
  110. mutex_unlock(&proxy_dev->buf_lock);
  111. return -EFAULT;
  112. }
  113. proxy_dev->resp_len = count;
  114. mutex_unlock(&proxy_dev->buf_lock);
  115. wake_up_interruptible(&proxy_dev->wq);
  116. return count;
  117. }
  118. /*
  119. * vtpm_proxy_fops_poll: Poll status on 'server side'
  120. *
  121. * Return value:
  122. * Poll flags
  123. */
  124. static unsigned int vtpm_proxy_fops_poll(struct file *filp, poll_table *wait)
  125. {
  126. struct proxy_dev *proxy_dev = filp->private_data;
  127. unsigned ret;
  128. poll_wait(filp, &proxy_dev->wq, wait);
  129. ret = POLLOUT;
  130. mutex_lock(&proxy_dev->buf_lock);
  131. if (proxy_dev->req_len)
  132. ret |= POLLIN | POLLRDNORM;
  133. if (!(proxy_dev->state & STATE_OPENED_FLAG))
  134. ret |= POLLHUP;
  135. mutex_unlock(&proxy_dev->buf_lock);
  136. return ret;
  137. }
  138. /*
  139. * vtpm_proxy_fops_open - Open vTPM device on 'server side'
  140. *
  141. * Called when setting up the anonymous file descriptor
  142. */
  143. static void vtpm_proxy_fops_open(struct file *filp)
  144. {
  145. struct proxy_dev *proxy_dev = filp->private_data;
  146. proxy_dev->state |= STATE_OPENED_FLAG;
  147. }
  148. /**
  149. * vtpm_proxy_fops_undo_open - counter-part to vtpm_fops_open
  150. *
  151. * Call to undo vtpm_proxy_fops_open
  152. */
  153. static void vtpm_proxy_fops_undo_open(struct proxy_dev *proxy_dev)
  154. {
  155. mutex_lock(&proxy_dev->buf_lock);
  156. proxy_dev->state &= ~STATE_OPENED_FLAG;
  157. mutex_unlock(&proxy_dev->buf_lock);
  158. /* no more TPM responses -- wake up anyone waiting for them */
  159. wake_up_interruptible(&proxy_dev->wq);
  160. }
  161. /*
  162. * vtpm_proxy_fops_release: Close 'server side'
  163. *
  164. * Return value:
  165. * Always returns 0.
  166. */
  167. static int vtpm_proxy_fops_release(struct inode *inode, struct file *filp)
  168. {
  169. struct proxy_dev *proxy_dev = filp->private_data;
  170. filp->private_data = NULL;
  171. vtpm_proxy_delete_device(proxy_dev);
  172. return 0;
  173. }
  174. static const struct file_operations vtpm_proxy_fops = {
  175. .owner = THIS_MODULE,
  176. .llseek = no_llseek,
  177. .read = vtpm_proxy_fops_read,
  178. .write = vtpm_proxy_fops_write,
  179. .poll = vtpm_proxy_fops_poll,
  180. .release = vtpm_proxy_fops_release,
  181. };
  182. /*
  183. * Functions invoked by the core TPM driver to send TPM commands to
  184. * 'server side' and receive responses from there.
  185. */
  186. /*
  187. * Called when core TPM driver reads TPM responses from 'server side'
  188. *
  189. * Return value:
  190. * Number of TPM response bytes read, negative error value otherwise
  191. */
  192. static int vtpm_proxy_tpm_op_recv(struct tpm_chip *chip, u8 *buf, size_t count)
  193. {
  194. struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
  195. size_t len;
  196. /* process gone ? */
  197. mutex_lock(&proxy_dev->buf_lock);
  198. if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
  199. mutex_unlock(&proxy_dev->buf_lock);
  200. return -EPIPE;
  201. }
  202. len = proxy_dev->resp_len;
  203. if (count < len) {
  204. dev_err(&chip->dev,
  205. "Invalid size in recv: count=%zd, resp_len=%zd\n",
  206. count, len);
  207. len = -EIO;
  208. goto out;
  209. }
  210. memcpy(buf, proxy_dev->buffer, len);
  211. proxy_dev->resp_len = 0;
  212. out:
  213. mutex_unlock(&proxy_dev->buf_lock);
  214. return len;
  215. }
  216. /*
  217. * Called when core TPM driver forwards TPM requests to 'server side'.
  218. *
  219. * Return value:
  220. * 0 in case of success, negative error value otherwise.
  221. */
  222. static int vtpm_proxy_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t count)
  223. {
  224. struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
  225. int rc = 0;
  226. if (count > sizeof(proxy_dev->buffer)) {
  227. dev_err(&chip->dev,
  228. "Invalid size in send: count=%zd, buffer size=%zd\n",
  229. count, sizeof(proxy_dev->buffer));
  230. return -EIO;
  231. }
  232. mutex_lock(&proxy_dev->buf_lock);
  233. if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
  234. mutex_unlock(&proxy_dev->buf_lock);
  235. return -EPIPE;
  236. }
  237. proxy_dev->resp_len = 0;
  238. proxy_dev->req_len = count;
  239. memcpy(proxy_dev->buffer, buf, count);
  240. proxy_dev->state &= ~STATE_WAIT_RESPONSE_FLAG;
  241. mutex_unlock(&proxy_dev->buf_lock);
  242. wake_up_interruptible(&proxy_dev->wq);
  243. return rc;
  244. }
  245. static void vtpm_proxy_tpm_op_cancel(struct tpm_chip *chip)
  246. {
  247. /* not supported */
  248. }
  249. static u8 vtpm_proxy_tpm_op_status(struct tpm_chip *chip)
  250. {
  251. struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
  252. if (proxy_dev->resp_len)
  253. return VTPM_PROXY_REQ_COMPLETE_FLAG;
  254. return 0;
  255. }
  256. static bool vtpm_proxy_tpm_req_canceled(struct tpm_chip *chip, u8 status)
  257. {
  258. struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
  259. bool ret;
  260. mutex_lock(&proxy_dev->buf_lock);
  261. ret = !(proxy_dev->state & STATE_OPENED_FLAG);
  262. mutex_unlock(&proxy_dev->buf_lock);
  263. return ret;
  264. }
  265. static const struct tpm_class_ops vtpm_proxy_tpm_ops = {
  266. .flags = TPM_OPS_AUTO_STARTUP,
  267. .recv = vtpm_proxy_tpm_op_recv,
  268. .send = vtpm_proxy_tpm_op_send,
  269. .cancel = vtpm_proxy_tpm_op_cancel,
  270. .status = vtpm_proxy_tpm_op_status,
  271. .req_complete_mask = VTPM_PROXY_REQ_COMPLETE_FLAG,
  272. .req_complete_val = VTPM_PROXY_REQ_COMPLETE_FLAG,
  273. .req_canceled = vtpm_proxy_tpm_req_canceled,
  274. };
  275. /*
  276. * Code related to the startup of the TPM 2 and startup of TPM 1.2 +
  277. * retrieval of timeouts and durations.
  278. */
  279. static void vtpm_proxy_work(struct work_struct *work)
  280. {
  281. struct proxy_dev *proxy_dev = container_of(work, struct proxy_dev,
  282. work);
  283. int rc;
  284. rc = tpm_chip_register(proxy_dev->chip);
  285. if (rc)
  286. goto err;
  287. return;
  288. err:
  289. vtpm_proxy_fops_undo_open(proxy_dev);
  290. }
  291. /*
  292. * vtpm_proxy_work_stop: make sure the work has finished
  293. *
  294. * This function is useful when user space closed the fd
  295. * while the driver still determines timeouts.
  296. */
  297. static void vtpm_proxy_work_stop(struct proxy_dev *proxy_dev)
  298. {
  299. vtpm_proxy_fops_undo_open(proxy_dev);
  300. flush_work(&proxy_dev->work);
  301. }
  302. /*
  303. * vtpm_proxy_work_start: Schedule the work for TPM 1.2 & 2 initialization
  304. */
  305. static inline void vtpm_proxy_work_start(struct proxy_dev *proxy_dev)
  306. {
  307. queue_work(workqueue, &proxy_dev->work);
  308. }
  309. /*
  310. * Code related to creation and deletion of device pairs
  311. */
  312. static struct proxy_dev *vtpm_proxy_create_proxy_dev(void)
  313. {
  314. struct proxy_dev *proxy_dev;
  315. struct tpm_chip *chip;
  316. int err;
  317. proxy_dev = kzalloc(sizeof(*proxy_dev), GFP_KERNEL);
  318. if (proxy_dev == NULL)
  319. return ERR_PTR(-ENOMEM);
  320. init_waitqueue_head(&proxy_dev->wq);
  321. mutex_init(&proxy_dev->buf_lock);
  322. INIT_WORK(&proxy_dev->work, vtpm_proxy_work);
  323. chip = tpm_chip_alloc(NULL, &vtpm_proxy_tpm_ops);
  324. if (IS_ERR(chip)) {
  325. err = PTR_ERR(chip);
  326. goto err_proxy_dev_free;
  327. }
  328. dev_set_drvdata(&chip->dev, proxy_dev);
  329. proxy_dev->chip = chip;
  330. return proxy_dev;
  331. err_proxy_dev_free:
  332. kfree(proxy_dev);
  333. return ERR_PTR(err);
  334. }
  335. /*
  336. * Undo what has been done in vtpm_create_proxy_dev
  337. */
  338. static inline void vtpm_proxy_delete_proxy_dev(struct proxy_dev *proxy_dev)
  339. {
  340. put_device(&proxy_dev->chip->dev); /* frees chip */
  341. kfree(proxy_dev);
  342. }
  343. /*
  344. * Create a /dev/tpm%d and 'server side' file descriptor pair
  345. *
  346. * Return value:
  347. * Returns file pointer on success, an error value otherwise
  348. */
  349. static struct file *vtpm_proxy_create_device(
  350. struct vtpm_proxy_new_dev *vtpm_new_dev)
  351. {
  352. struct proxy_dev *proxy_dev;
  353. int rc, fd;
  354. struct file *file;
  355. if (vtpm_new_dev->flags & ~VTPM_PROXY_FLAGS_ALL)
  356. return ERR_PTR(-EOPNOTSUPP);
  357. proxy_dev = vtpm_proxy_create_proxy_dev();
  358. if (IS_ERR(proxy_dev))
  359. return ERR_CAST(proxy_dev);
  360. proxy_dev->flags = vtpm_new_dev->flags;
  361. /* setup an anonymous file for the server-side */
  362. fd = get_unused_fd_flags(O_RDWR);
  363. if (fd < 0) {
  364. rc = fd;
  365. goto err_delete_proxy_dev;
  366. }
  367. file = anon_inode_getfile("[vtpms]", &vtpm_proxy_fops, proxy_dev,
  368. O_RDWR);
  369. if (IS_ERR(file)) {
  370. rc = PTR_ERR(file);
  371. goto err_put_unused_fd;
  372. }
  373. /* from now on we can unwind with put_unused_fd() + fput() */
  374. /* simulate an open() on the server side */
  375. vtpm_proxy_fops_open(file);
  376. if (proxy_dev->flags & VTPM_PROXY_FLAG_TPM2)
  377. proxy_dev->chip->flags |= TPM_CHIP_FLAG_TPM2;
  378. vtpm_proxy_work_start(proxy_dev);
  379. vtpm_new_dev->fd = fd;
  380. vtpm_new_dev->major = MAJOR(proxy_dev->chip->dev.devt);
  381. vtpm_new_dev->minor = MINOR(proxy_dev->chip->dev.devt);
  382. vtpm_new_dev->tpm_num = proxy_dev->chip->dev_num;
  383. return file;
  384. err_put_unused_fd:
  385. put_unused_fd(fd);
  386. err_delete_proxy_dev:
  387. vtpm_proxy_delete_proxy_dev(proxy_dev);
  388. return ERR_PTR(rc);
  389. }
  390. /*
  391. * Counter part to vtpm_create_device.
  392. */
  393. static void vtpm_proxy_delete_device(struct proxy_dev *proxy_dev)
  394. {
  395. vtpm_proxy_work_stop(proxy_dev);
  396. /*
  397. * A client may hold the 'ops' lock, so let it know that the server
  398. * side shuts down before we try to grab the 'ops' lock when
  399. * unregistering the chip.
  400. */
  401. vtpm_proxy_fops_undo_open(proxy_dev);
  402. tpm_chip_unregister(proxy_dev->chip);
  403. vtpm_proxy_delete_proxy_dev(proxy_dev);
  404. }
  405. /*
  406. * Code related to the control device /dev/vtpmx
  407. */
  408. /*
  409. * vtpmx_fops_ioctl: ioctl on /dev/vtpmx
  410. *
  411. * Return value:
  412. * Returns 0 on success, a negative error code otherwise.
  413. */
  414. static long vtpmx_fops_ioctl(struct file *f, unsigned int ioctl,
  415. unsigned long arg)
  416. {
  417. void __user *argp = (void __user *)arg;
  418. struct vtpm_proxy_new_dev __user *vtpm_new_dev_p;
  419. struct vtpm_proxy_new_dev vtpm_new_dev;
  420. struct file *file;
  421. switch (ioctl) {
  422. case VTPM_PROXY_IOC_NEW_DEV:
  423. if (!capable(CAP_SYS_ADMIN))
  424. return -EPERM;
  425. vtpm_new_dev_p = argp;
  426. if (copy_from_user(&vtpm_new_dev, vtpm_new_dev_p,
  427. sizeof(vtpm_new_dev)))
  428. return -EFAULT;
  429. file = vtpm_proxy_create_device(&vtpm_new_dev);
  430. if (IS_ERR(file))
  431. return PTR_ERR(file);
  432. if (copy_to_user(vtpm_new_dev_p, &vtpm_new_dev,
  433. sizeof(vtpm_new_dev))) {
  434. put_unused_fd(vtpm_new_dev.fd);
  435. fput(file);
  436. return -EFAULT;
  437. }
  438. fd_install(vtpm_new_dev.fd, file);
  439. return 0;
  440. default:
  441. return -ENOIOCTLCMD;
  442. }
  443. }
  444. #ifdef CONFIG_COMPAT
  445. static long vtpmx_fops_compat_ioctl(struct file *f, unsigned int ioctl,
  446. unsigned long arg)
  447. {
  448. return vtpmx_fops_ioctl(f, ioctl, (unsigned long)compat_ptr(arg));
  449. }
  450. #endif
  451. static const struct file_operations vtpmx_fops = {
  452. .owner = THIS_MODULE,
  453. .unlocked_ioctl = vtpmx_fops_ioctl,
  454. #ifdef CONFIG_COMPAT
  455. .compat_ioctl = vtpmx_fops_compat_ioctl,
  456. #endif
  457. .llseek = noop_llseek,
  458. };
  459. static struct miscdevice vtpmx_miscdev = {
  460. .minor = MISC_DYNAMIC_MINOR,
  461. .name = "vtpmx",
  462. .fops = &vtpmx_fops,
  463. };
  464. static int vtpmx_init(void)
  465. {
  466. return misc_register(&vtpmx_miscdev);
  467. }
  468. static void vtpmx_cleanup(void)
  469. {
  470. misc_deregister(&vtpmx_miscdev);
  471. }
  472. static int __init vtpm_module_init(void)
  473. {
  474. int rc;
  475. rc = vtpmx_init();
  476. if (rc) {
  477. pr_err("couldn't create vtpmx device\n");
  478. return rc;
  479. }
  480. workqueue = create_workqueue("tpm-vtpm");
  481. if (!workqueue) {
  482. pr_err("couldn't create workqueue\n");
  483. rc = -ENOMEM;
  484. goto err_vtpmx_cleanup;
  485. }
  486. return 0;
  487. err_vtpmx_cleanup:
  488. vtpmx_cleanup();
  489. return rc;
  490. }
  491. static void __exit vtpm_module_exit(void)
  492. {
  493. destroy_workqueue(workqueue);
  494. vtpmx_cleanup();
  495. }
  496. module_init(vtpm_module_init);
  497. module_exit(vtpm_module_exit);
  498. MODULE_AUTHOR("Stefan Berger (stefanb@us.ibm.com)");
  499. MODULE_DESCRIPTION("vTPM Driver");
  500. MODULE_VERSION("0.1");
  501. MODULE_LICENSE("GPL");