tcti-device.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. /* SPDX-License-Identifier: BSD-2-Clause */
  2. /***********************************************************************
  3. * Copyright (c) 2017-2018, Intel Corporation
  4. *
  5. * All rights reserved.
  6. ***********************************************************************/
  7. #ifdef HAVE_CONFIG_H
  8. #include <config.h>
  9. #endif
  10. #include <inttypes.h>
  11. #include <stdarg.h>
  12. #include <stdbool.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <poll.h>
  16. #include <setjmp.h>
  17. #include <cmocka.h>
  18. #include "tss2_mu.h"
  19. #include "tss2_tcti_device.h"
  20. #include "tss2-tcti/tcti-common.h"
  21. #include "tss2-tcti/tcti-device.h"
  22. /*
  23. * Size of the TPM2 buffer used in these tests. In some cases this will be
  24. * the command sent (transmit tests) and in others it's used as the response
  25. * buffer returned by the TCTI. The only field used by the TCTI is the size
  26. * field.
  27. */
  28. #define BUF_SIZE 20
  29. static uint8_t tpm2_buf [BUF_SIZE] = {
  30. 0x80, 0x02, /* TAG */
  31. 0x00, 0x00, 0x00, 0x14, /* size (BUF_SIZE) */
  32. 0x00, 0x00, 0x00, 0x00, /* rc (success) */
  33. 0xde, 0xad, 0xbe, 0xef, /* junk data */
  34. 0xca, 0xfe, 0xba, 0xbe,
  35. 0xfe, 0xef
  36. };
  37. int
  38. __real_open(const char *pathname, int flags, ...);
  39. /* wrap function for open required to test init */
  40. int
  41. __wrap_open(const char *pathname, int flags, ...)
  42. {
  43. const char* pathname_prefix_dev = "/dev";
  44. if (strncmp(pathname, pathname_prefix_dev, strlen(pathname_prefix_dev)) == 0) {
  45. return mock_type (int);
  46. } else {
  47. /* only mock opening of device files as the open() syscall is needed
  48. for code coverage reports as well */
  49. return __real_open(pathname, flags);
  50. }
  51. }
  52. /**
  53. * When passed all NULL values ensure that we get back the expected RC
  54. * indicating bad values.
  55. */
  56. static void
  57. tcti_device_init_all_null_test (void **state)
  58. {
  59. TSS2_RC rc;
  60. rc = Tss2_Tcti_Device_Init (NULL, NULL, NULL);
  61. assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
  62. }
  63. /* Determine the size of a TCTI context structure. Requires calling the
  64. * initialization function for the device TCTI with the first parameter
  65. * (the TCTI context) NULL.
  66. */
  67. static void
  68. tcti_device_init_size_test (void **state)
  69. {
  70. size_t tcti_size = 0;
  71. TSS2_RC ret = TSS2_RC_SUCCESS;
  72. ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL);
  73. assert_int_equal (ret, TSS2_RC_SUCCESS);
  74. }
  75. /* Test the failure of opening a specified device file */
  76. static void
  77. tcti_device_init_conf_fail (void **state)
  78. {
  79. size_t tcti_size = 0;
  80. TSS2_RC ret = TSS2_RC_SUCCESS;
  81. TSS2_TCTI_CONTEXT *ctx = NULL;
  82. ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL);
  83. assert_true (ret == TSS2_RC_SUCCESS);
  84. ctx = calloc (1, tcti_size);
  85. assert_non_null (ctx);
  86. errno = ENOENT; /* No such file or directory */
  87. will_return (__wrap_open, -1);
  88. ret = Tss2_Tcti_Device_Init (ctx, &tcti_size, "/dev/nonexistent");
  89. assert_true (ret == TSS2_TCTI_RC_IO_ERROR);
  90. free(ctx);
  91. }
  92. /* Test the device file recognition if no config string was specified */
  93. static void
  94. tcti_device_init_conf_default_fail (void **state)
  95. {
  96. size_t tcti_size = 0;
  97. TSS2_RC ret = TSS2_RC_SUCCESS;
  98. TSS2_TCTI_CONTEXT *ctx = NULL;
  99. ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL);
  100. assert_true (ret == TSS2_RC_SUCCESS);
  101. ctx = calloc (1, tcti_size);
  102. assert_non_null (ctx);
  103. errno = EACCES; /* Permission denied */
  104. will_return (__wrap_open, -1);
  105. will_return (__wrap_open, -1);
  106. ret = Tss2_Tcti_Device_Init (ctx, &tcti_size, NULL);
  107. assert_true (ret == TSS2_TCTI_RC_IO_ERROR);
  108. free(ctx);
  109. }
  110. /* Test the device file recognition if no config string was specified */
  111. static void
  112. tcti_device_init_conf_default_success (void **state)
  113. {
  114. size_t tcti_size = 0;
  115. TSS2_RC ret = TSS2_RC_SUCCESS;
  116. TSS2_TCTI_CONTEXT *ctx = NULL;
  117. ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL);
  118. assert_true (ret == TSS2_RC_SUCCESS);
  119. ctx = calloc (1, tcti_size);
  120. assert_non_null (ctx);
  121. will_return (__wrap_open, 3);
  122. will_return (__wrap_write, 12);
  123. will_return (__wrap_write, tpm2_buf);
  124. will_return (__wrap_poll, 1);
  125. will_return (__wrap_read, 10);
  126. will_return (__wrap_read, tpm2_buf);
  127. will_return (__wrap_poll, 1);
  128. will_return (__wrap_read, 8);
  129. will_return (__wrap_read, tpm2_buf);
  130. ret = Tss2_Tcti_Device_Init (ctx, &tcti_size, NULL);
  131. assert_true (ret == TSS2_RC_SUCCESS);
  132. free(ctx);
  133. }
  134. /* wrap functions for read & write required to test receive / transmit */
  135. ssize_t
  136. __wrap_read (int fd, void *buf, size_t count)
  137. {
  138. ssize_t ret = mock_type (ssize_t);
  139. uint8_t *buf_in = mock_type (uint8_t*);
  140. memcpy (buf, buf_in, ret);
  141. return ret;
  142. }
  143. ssize_t
  144. __wrap_write (int fd, const void *buffer, size_t buffer_size)
  145. {
  146. ssize_t ret = mock_type (ssize_t);
  147. uint8_t *buf_out = mock_type (uint8_t*);
  148. memcpy (buf_out, buffer, ret);
  149. return ret;
  150. }
  151. int
  152. __wrap_poll (struct pollfd *fds, nfds_t nfds, int timeout)
  153. {
  154. int ret = mock_type (int);
  155. fds->revents = fds->events;
  156. return ret;
  157. }
  158. /* Setup functions to create the context for the device TCTI */
  159. static int
  160. tcti_device_setup (void **state)
  161. {
  162. size_t tcti_size = 0;
  163. TSS2_RC ret = TSS2_RC_SUCCESS;
  164. TSS2_TCTI_CONTEXT *ctx = NULL;
  165. ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL);
  166. assert_true (ret == TSS2_RC_SUCCESS);
  167. ctx = calloc (1, tcti_size);
  168. assert_non_null (ctx);
  169. will_return (__wrap_open, 3);
  170. will_return (__wrap_write, 12);
  171. will_return (__wrap_write, tpm2_buf);
  172. will_return (__wrap_poll, 1);
  173. will_return (__wrap_read, 10);
  174. will_return (__wrap_read, tpm2_buf);
  175. will_return (__wrap_poll, 1);
  176. will_return (__wrap_read, 0);
  177. will_return (__wrap_read, tpm2_buf);
  178. will_return (__wrap_open, 3);
  179. ret = Tss2_Tcti_Device_Init (ctx, &tcti_size, "/dev/null");
  180. assert_true (ret == TSS2_RC_SUCCESS);
  181. *state = ctx;
  182. return 0;
  183. }
  184. static int
  185. tcti_device_teardown (void **state)
  186. {
  187. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  188. Tss2_Tcti_Finalize (ctx);
  189. free (ctx);
  190. return 0;
  191. }
  192. /*
  193. * This test ensures that the GetPollHandles function in the device TCTI
  194. * returns the expected value. Since this TCTI does not support async I/O
  195. * on account of limitations in the kernel it just returns the
  196. * NOT_IMPLEMENTED response code.
  197. */
  198. static void
  199. tcti_device_get_poll_handles_test (void **state)
  200. {
  201. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  202. size_t num_handles = 5;
  203. TSS2_TCTI_POLL_HANDLE handles [5] = { 0 };
  204. TSS2_RC rc;
  205. rc = Tss2_Tcti_GetPollHandles (ctx, handles, &num_handles);
  206. assert_int_equal (rc, TSS2_RC_SUCCESS);
  207. assert_int_equal (num_handles, 1);
  208. }
  209. /*
  210. */
  211. static void
  212. tcti_device_receive_null_size_test (void **state)
  213. {
  214. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  215. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  216. TSS2_RC rc;
  217. /* Keep state machine check in `receive` from returning error. */
  218. tcti_common->state = TCTI_STATE_RECEIVE;
  219. rc = Tss2_Tcti_Receive (ctx,
  220. NULL, /* NULL 'size' parameter */
  221. NULL,
  222. TSS2_TCTI_TIMEOUT_BLOCK);
  223. assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
  224. rc = Tss2_Tcti_Receive (ctx,
  225. NULL, /* NULL 'size' parameter */
  226. (uint8_t*)1, /* non-NULL buffer */
  227. TSS2_TCTI_TIMEOUT_BLOCK);
  228. assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
  229. }
  230. /*
  231. * A test case for a successful call to the receive function. This requires
  232. * that the context and the command buffer be valid (including the size
  233. * field being set appropriately). The result should be an RC indicating
  234. * success and the size parameter be updated to reflect the size of the
  235. * data received.
  236. */
  237. static void
  238. tcti_device_receive_success (void **state)
  239. {
  240. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  241. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  242. TSS2_RC rc;
  243. /* output buffer for response */
  244. uint8_t buf_out [BUF_SIZE + 5] = { 0 };
  245. size_t size = BUF_SIZE + 5;
  246. /* Keep state machine check in `receive` from returning error. */
  247. tcti_common->state = TCTI_STATE_RECEIVE;
  248. will_return (__wrap_poll, 1);
  249. will_return (__wrap_read, BUF_SIZE);
  250. will_return (__wrap_read, tpm2_buf);
  251. rc = Tss2_Tcti_Receive (ctx,
  252. &size,
  253. buf_out,
  254. TSS2_TCTI_TIMEOUT_BLOCK);
  255. assert_true (rc == TSS2_RC_SUCCESS);
  256. assert_int_equal (BUF_SIZE, size);
  257. assert_memory_equal (tpm2_buf, buf_out, size);
  258. }
  259. /*
  260. * Ensure that when the 'read' results in an EOF, we get a response code
  261. * indicating as much. EOF happens if / when the device driver kills our
  262. * connection.
  263. */
  264. static void
  265. tcti_device_receive_eof_test (void **state)
  266. {
  267. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  268. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  269. TSS2_RC rc;
  270. /* output buffer for response */
  271. uint8_t buf_out [BUF_SIZE + 5] = { 0 };
  272. size_t size = BUF_SIZE + 5;
  273. /* Keep state machine check in `receive` from returning error. */
  274. tcti_common->state = TCTI_STATE_RECEIVE;
  275. will_return (__wrap_poll, 1);
  276. will_return (__wrap_read, 0);
  277. will_return (__wrap_read, tpm2_buf);
  278. rc = Tss2_Tcti_Receive (ctx,
  279. &size,
  280. buf_out,
  281. TSS2_TCTI_TIMEOUT_BLOCK);
  282. assert_int_equal (rc, TSS2_TCTI_RC_NO_CONNECTION);
  283. }
  284. /*
  285. * This is a weird test: The device TCTI can't read the header for the
  286. * response buffer separately from the body. This means it can't know the size
  287. * of the response before reading the whole thing. In the event that the caller
  288. * provides a buffer that isn't large enough to hold the full response the TCTI
  289. * will just read as much data as the buffer will hold. Subsequent interactions
  290. * with the kernel driver will likely result in an error.
  291. */
  292. static void
  293. tcti_device_receive_buffer_lt_response (void **state)
  294. {
  295. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  296. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  297. TSS2_RC rc;
  298. uint8_t buf_out [BUF_SIZE] = { 0 };
  299. /* set size to lt the size in the header of the TPM2 response buffer */
  300. size_t size = BUF_SIZE - 1;
  301. size_t small_size = TPM_HEADER_SIZE + 1;
  302. /* Keep state machine check in `receive` from returning error. */
  303. tcti_common->state = TCTI_STATE_RECEIVE;
  304. will_return (__wrap_poll, 1);
  305. will_return (__wrap_read, size);
  306. will_return (__wrap_read, tpm2_buf);
  307. rc = Tss2_Tcti_Receive (ctx,
  308. &small_size,
  309. buf_out,
  310. TSS2_TCTI_TIMEOUT_BLOCK);
  311. assert_int_equal (rc, TSS2_TCTI_RC_GENERAL_FAILURE);
  312. }
  313. /*
  314. * A test case for a successful call to the transmit function. This requires
  315. * that the context and the cmmand buffer be valid. The only indication of
  316. * success is the RC.
  317. */
  318. static void
  319. tcti_device_transmit_success (void **state)
  320. {
  321. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  322. TSS2_RC rc;
  323. /* output buffer for response */
  324. uint8_t buf_out [BUF_SIZE] = { 0 };
  325. will_return (__wrap_write, BUF_SIZE);
  326. will_return (__wrap_write, buf_out);
  327. rc = Tss2_Tcti_Transmit (ctx,
  328. BUF_SIZE,
  329. tpm2_buf);
  330. assert_true (rc == TSS2_RC_SUCCESS);
  331. assert_memory_equal (tpm2_buf, buf_out, BUF_SIZE);
  332. }
  333. /*
  334. * A test case for a successful poll
  335. */
  336. static void
  337. tcti_device_poll_success (void **state)
  338. {
  339. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  340. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  341. TSS2_RC rc;
  342. /* output buffer for response */
  343. uint8_t buf_out [BUF_SIZE] = { 0 };
  344. size_t size = BUF_SIZE;
  345. /* Keep state machine check in `receive` from returning error. */
  346. tcti_common->state = TCTI_STATE_RECEIVE;
  347. will_return (__wrap_poll, 1);
  348. will_return (__wrap_read, BUF_SIZE);
  349. will_return (__wrap_read, tpm2_buf);
  350. rc = Tss2_Tcti_Receive (ctx,
  351. &size,
  352. buf_out,
  353. TSS2_TCTI_TIMEOUT_BLOCK);
  354. assert_true (rc == TSS2_RC_SUCCESS);
  355. assert_int_equal (BUF_SIZE, size);
  356. assert_memory_equal (tpm2_buf, buf_out, size);
  357. }
  358. /*
  359. * A test case for poll timeout
  360. */
  361. static void
  362. tcti_device_poll_timeout (void **state)
  363. {
  364. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  365. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  366. TSS2_RC rc;
  367. /* output buffer for response */
  368. uint8_t buf_out [BUF_SIZE] = { 0 };
  369. size_t size = BUF_SIZE;
  370. /* Keep state machine check in `receive` from returning error. */
  371. tcti_common->state = TCTI_STATE_RECEIVE;
  372. will_return (__wrap_poll, 0);
  373. rc = Tss2_Tcti_Receive (ctx,
  374. &size,
  375. buf_out,
  376. TSS2_TCTI_TIMEOUT_BLOCK);
  377. assert_true (rc == TSS2_TCTI_RC_TRY_AGAIN);
  378. }
  379. /*
  380. * A test case for poll io-error
  381. */
  382. static void
  383. tcti_device_poll_io_error (void **state)
  384. {
  385. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  386. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  387. TSS2_RC rc;
  388. /* output buffer for response */
  389. uint8_t buf_out [BUF_SIZE] = { 0 };
  390. size_t size = BUF_SIZE;
  391. /* Keep state machine check in `receive` from returning error. */
  392. tcti_common->state = TCTI_STATE_RECEIVE;
  393. will_return (__wrap_poll, -1);
  394. rc = Tss2_Tcti_Receive (ctx,
  395. &size,
  396. buf_out,
  397. TSS2_TCTI_TIMEOUT_BLOCK);
  398. assert_true (rc == TSS2_TCTI_RC_IO_ERROR);
  399. }
  400. int
  401. main(int argc, char* argv[])
  402. {
  403. const struct CMUnitTest tests[] = {
  404. cmocka_unit_test (tcti_device_init_all_null_test),
  405. cmocka_unit_test(tcti_device_init_size_test),
  406. cmocka_unit_test(tcti_device_init_conf_fail),
  407. cmocka_unit_test(tcti_device_init_conf_default_fail),
  408. cmocka_unit_test(tcti_device_init_conf_default_success),
  409. cmocka_unit_test_setup_teardown (tcti_device_get_poll_handles_test,
  410. tcti_device_setup,
  411. tcti_device_teardown),
  412. cmocka_unit_test_setup_teardown (tcti_device_receive_null_size_test,
  413. tcti_device_setup,
  414. tcti_device_teardown),
  415. cmocka_unit_test_setup_teardown (tcti_device_receive_success,
  416. tcti_device_setup,
  417. tcti_device_teardown),
  418. cmocka_unit_test_setup_teardown (tcti_device_receive_eof_test,
  419. tcti_device_setup,
  420. tcti_device_teardown),
  421. cmocka_unit_test_setup_teardown (tcti_device_receive_buffer_lt_response,
  422. tcti_device_setup,
  423. tcti_device_teardown),
  424. cmocka_unit_test_setup_teardown (tcti_device_transmit_success,
  425. tcti_device_setup,
  426. tcti_device_teardown),
  427. cmocka_unit_test_setup_teardown (tcti_device_poll_success,
  428. tcti_device_setup,
  429. tcti_device_teardown),
  430. cmocka_unit_test_setup_teardown (tcti_device_poll_timeout,
  431. tcti_device_setup,
  432. tcti_device_teardown),
  433. cmocka_unit_test_setup_teardown (tcti_device_poll_io_error,
  434. tcti_device_setup,
  435. tcti_device_teardown),
  436. };
  437. return cmocka_run_group_tests (tests, NULL, NULL);
  438. }