tcti-cmd.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. /* SPDX-License-Identifier: BSD-2-Clause */
  2. #ifdef HAVE_CONFIG_H
  3. #include <config.h>
  4. #endif
  5. #include <inttypes.h>
  6. #include <limits.h>
  7. #include <setjmp.h>
  8. #include <stdarg.h>
  9. #include <stdbool.h>
  10. #include <stdint.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <cmocka.h>
  15. #include <unistd.h>
  16. #include <signal.h>
  17. #if defined (__FreeBSD__)
  18. #include <sys/procctl.h>
  19. #else
  20. #include <sys/prctl.h>
  21. #endif
  22. #include <sys/types.h>
  23. #include <sys/wait.h>
  24. #include <sys/time.h>
  25. #include "tss2_tcti.h"
  26. #include "tss2_tcti_cmd.h"
  27. #include "tcti-cmd-test.h"
  28. #include "tss2-tcti/tcti-common.h"
  29. #include "tss2-tcti/tcti-cmd.h"
  30. #define LOGMODULE tests
  31. #include "util/log.h"
  32. #define EXECLP_CMD "test/helper/tpm_cmd_tcti_dummy"
  33. extern TSS2_TCTI_INFO *Tss2_Tcti_Info (void);
  34. static inline
  35. TSS2_TCTI_CONTEXT *state_cast (void **state)
  36. {
  37. return (TSS2_TCTI_CONTEXT *)*state;
  38. }
  39. int tcti_cmd_pipe (int pipefd[2])
  40. {
  41. int rc = mock_type (int);
  42. if (!rc) {
  43. return pipe (pipefd);
  44. }
  45. errno = rc;
  46. return -1;
  47. }
  48. int tcti_cmd_fork (void)
  49. {
  50. int rc = mock_type (int);
  51. if (!rc) {
  52. return fork ();
  53. }
  54. errno = rc;
  55. return -1;
  56. }
  57. FILE *tcti_cmd_fdopen (int fd, const char *mode)
  58. {
  59. int rc = mock_type (int);
  60. if (!rc) {
  61. return fdopen (fd, mode);
  62. }
  63. errno = rc;
  64. return NULL;
  65. }
  66. int tcti_cmd_sigprocmask (int how, const sigset_t *set, sigset_t *oldset)
  67. {
  68. int rc = mock_type (int);
  69. if (!rc) {
  70. return sigprocmask (how, set, oldset);
  71. }
  72. errno = rc;
  73. return -1;
  74. }
  75. int tcti_cmd_ferror (FILE *stream)
  76. {
  77. int rc = mock_type (int);
  78. if (!rc) {
  79. return ferror (stream);
  80. }
  81. errno = rc;
  82. return -1;
  83. }
  84. size_t tcti_cmd_fwrite (const void *ptr, size_t size, size_t nmemb,
  85. FILE *stream)
  86. {
  87. int rc = mock_type (int);
  88. if (!rc) {
  89. return fwrite (ptr, size, nmemb, stream);
  90. }
  91. will_return (tcti_cmd_ferror, rc);
  92. errno = rc;
  93. return 0;
  94. }
  95. TSS2_TCTI_CONTEXT *
  96. test_common_setup (const char *cmd)
  97. {
  98. will_return_always (tcti_cmd_sigprocmask, 0);
  99. will_return_always (tcti_cmd_fdopen, 0);
  100. will_return_always (tcti_cmd_fork, 0);
  101. will_return_always (tcti_cmd_pipe, 0);
  102. size_t tcti_size = 0;
  103. TSS2_RC rval = Tss2_Tcti_Cmd_Init (NULL, &tcti_size, cmd);
  104. assert_int_equal (rval, TSS2_RC_SUCCESS);
  105. TSS2_TCTI_CONTEXT *tcti_context = calloc (1, tcti_size);
  106. assert_non_null (tcti_context);
  107. rval = Tss2_Tcti_Cmd_Init (tcti_context, &tcti_size, cmd);
  108. assert_int_equal (rval, TSS2_RC_SUCCESS);
  109. return tcti_context;
  110. }
  111. static int
  112. test_teardown (void **state)
  113. {
  114. will_return_always (tcti_cmd_sigprocmask, 0);
  115. TSS2_TCTI_CONTEXT *tcti_context = state_cast (state);
  116. if (tcti_context) {
  117. Tss2_Tcti_Finalize (tcti_context);
  118. free (tcti_context);
  119. }
  120. return 0;
  121. }
  122. /*
  123. * Unit Test Code Starts Here
  124. */
  125. /* When passed all NULL values ensure that we get back the expected RC. */
  126. static void
  127. tcti_cmd_init_all_null_test (void **state)
  128. {
  129. TSS2_RC rval = Tss2_Tcti_Cmd_Init (NULL, NULL, NULL);
  130. assert_int_equal (rval, TSS2_TCTI_RC_BAD_VALUE);
  131. }
  132. /*
  133. * Determine the size of a TCTI context structure. Requires calling the
  134. * initialization function for the cmd TCTI with the first parameter
  135. * (the TCTI context) NULL.
  136. */
  137. static void
  138. tcti_cmd_init_size_test (void **state)
  139. {
  140. size_t tcti_size = 0;
  141. TSS2_RC rval = Tss2_Tcti_Cmd_Init (NULL, &tcti_size, __func__);
  142. assert_int_equal (rval, TSS2_RC_SUCCESS);
  143. assert_int_equal (tcti_size, sizeof (TSS2_TCTI_CMD_CONTEXT));
  144. }
  145. static void
  146. tcti_cmd_test_pipe_1_fail (void **state)
  147. {
  148. uint8_t buf[4096];
  149. size_t tcti_size = sizeof (buf);
  150. TSS2_TCTI_CONTEXT *tcti_context = (TSS2_TCTI_CONTEXT *)buf;
  151. will_return (tcti_cmd_pipe, EFAULT);
  152. TSS2_RC rval = Tss2_Tcti_Cmd_Init (tcti_context, &tcti_size, __func__);
  153. assert_int_equal (rval, TSS2_TCTI_RC_GENERAL_FAILURE);
  154. }
  155. static void
  156. tcti_cmd_test_pipe_2_fail (void **state)
  157. {
  158. uint8_t buf[4096];
  159. size_t tcti_size = sizeof (buf);
  160. TSS2_TCTI_CONTEXT *tcti_context = (TSS2_TCTI_CONTEXT *)buf;
  161. /* first pipe works, second pipe fails */
  162. will_return (tcti_cmd_pipe, 0);
  163. will_return (tcti_cmd_pipe, EFAULT);
  164. TSS2_RC rval = Tss2_Tcti_Cmd_Init (tcti_context, &tcti_size, __func__);
  165. assert_int_equal (rval, TSS2_TCTI_RC_GENERAL_FAILURE);
  166. }
  167. static void
  168. tcti_cmd_test_fork_fail (void **state)
  169. {
  170. uint8_t buf[4096];
  171. size_t tcti_size = sizeof (buf);
  172. TSS2_TCTI_CONTEXT *tcti_context = (TSS2_TCTI_CONTEXT *)buf;
  173. will_return_always (tcti_cmd_pipe, 0);
  174. will_return_always (tcti_cmd_sigprocmask, 0);
  175. will_return (tcti_cmd_fork, ENOMEM);
  176. TSS2_RC rval = Tss2_Tcti_Cmd_Init (tcti_context, &tcti_size, __func__);
  177. assert_int_equal (rval, TSS2_TCTI_RC_GENERAL_FAILURE);
  178. }
  179. static void
  180. tcti_cmd_test_fdopen_1_fail (void **state)
  181. {
  182. uint8_t buf[4096];
  183. size_t tcti_size = sizeof (buf);
  184. TSS2_TCTI_CONTEXT *tcti_context = (TSS2_TCTI_CONTEXT *)buf;
  185. will_return_always (tcti_cmd_pipe, 0);
  186. will_return_always (tcti_cmd_fork, 0);
  187. will_return_always (tcti_cmd_sigprocmask, 0);
  188. will_return (tcti_cmd_fdopen, EINVAL);
  189. TSS2_RC rval = Tss2_Tcti_Cmd_Init (tcti_context, &tcti_size, __func__);
  190. assert_int_equal (rval, TSS2_TCTI_RC_GENERAL_FAILURE);
  191. }
  192. static void
  193. tcti_cmd_test_fdopen_2_fail (void **state)
  194. {
  195. uint8_t buf[4096];
  196. size_t tcti_size = sizeof (buf);
  197. TSS2_TCTI_CONTEXT *tcti_context = (TSS2_TCTI_CONTEXT *)buf;
  198. will_return_always (tcti_cmd_pipe, 0);
  199. will_return_always (tcti_cmd_fork, 0);
  200. will_return_always (tcti_cmd_sigprocmask, 0);
  201. /* first fdopen works, second fails */
  202. will_return (tcti_cmd_fdopen, 0);
  203. will_return (tcti_cmd_fdopen, EINVAL);
  204. TSS2_RC rval = Tss2_Tcti_Cmd_Init (tcti_context, &tcti_size, __func__);
  205. assert_int_equal (rval, TSS2_TCTI_RC_GENERAL_FAILURE);
  206. }
  207. static void
  208. tcti_cmd_test_sigprocmask_1_fail (void **state)
  209. {
  210. uint8_t buf[4096];
  211. size_t tcti_size = sizeof (buf);
  212. TSS2_TCTI_CONTEXT *tcti_context = (TSS2_TCTI_CONTEXT *)buf;
  213. will_return_always (tcti_cmd_pipe, 0);
  214. will_return (tcti_cmd_sigprocmask, EINVAL);
  215. TSS2_RC rval = Tss2_Tcti_Cmd_Init (tcti_context, &tcti_size, __func__);
  216. assert_int_equal (rval, TSS2_TCTI_RC_GENERAL_FAILURE);
  217. }
  218. static void
  219. tcti_cmd_test_good (void **state)
  220. {
  221. will_return_always (tcti_cmd_fwrite, 0);
  222. will_return_always (tcti_cmd_ferror, 0);
  223. TSS2_TCTI_CONTEXT *tcti_context = *state =
  224. test_common_setup (EXECLP_CMD" good");
  225. assert_non_null (tcti_context);
  226. /* send the command buffer */
  227. TSS2_RC rval = Tss2_Tcti_Transmit (tcti_context,
  228. sizeof (getcap_command), getcap_command);
  229. assert_int_equal (rval, TSS2_RC_SUCCESS);
  230. uint8_t rbuf[sizeof (getcap_good_resp)];
  231. size_t rsize = sizeof (rbuf);
  232. /* get the valid response */
  233. rval = Tss2_Tcti_Receive (tcti_context, &rsize, rbuf,
  234. TSS2_TCTI_TIMEOUT_BLOCK);
  235. assert_int_equal (rval, TSS2_RC_SUCCESS);
  236. /* Should be the expected getcap good response */
  237. assert_int_equal (rsize, sizeof (getcap_good_resp));
  238. assert_memory_equal (rbuf, getcap_good_resp, rsize);
  239. }
  240. static void
  241. tcti_cmd_test_malformed_size_smaller (void **state)
  242. {
  243. will_return_always (tcti_cmd_fwrite, 0);
  244. will_return_always (tcti_cmd_ferror, 0);
  245. TSS2_TCTI_CONTEXT *tcti_context = *state =
  246. test_common_setup (EXECLP_CMD" smaller");
  247. assert_non_null (tcti_context);
  248. /* send the command buffer */
  249. TSS2_RC rval = Tss2_Tcti_Transmit (tcti_context,
  250. sizeof (getcap_command), getcap_command);
  251. assert_int_equal (rval, TSS2_RC_SUCCESS);
  252. uint8_t rbuf[sizeof (getcap_good_resp)];
  253. size_t rsize = sizeof (rbuf);
  254. /* Attempt to receive a malformed response */
  255. rval = Tss2_Tcti_Receive (tcti_context, &rsize, rbuf,
  256. TSS2_TCTI_TIMEOUT_BLOCK);
  257. assert_int_equal (rval, TSS2_TCTI_RC_MALFORMED_RESPONSE);
  258. }
  259. static void
  260. tcti_cmd_test_malformed_size_bigger (void **state)
  261. {
  262. will_return_always (tcti_cmd_fwrite, 0);
  263. will_return_always (tcti_cmd_ferror, 0);
  264. TSS2_TCTI_CONTEXT *tcti_context = *state =
  265. test_common_setup (EXECLP_CMD" bigger");
  266. assert_non_null (tcti_context);
  267. /* send the command buffer */
  268. TSS2_RC rval = Tss2_Tcti_Transmit (tcti_context,
  269. sizeof (getcap_command), getcap_command);
  270. assert_int_equal (rval, TSS2_RC_SUCCESS);
  271. uint8_t rbuf[sizeof (getcap_good_resp)];
  272. size_t rsize = sizeof (rbuf);
  273. /*
  274. * Attempt to receive a malformed response with command header size
  275. * larger than buffer size.
  276. */
  277. rval = Tss2_Tcti_Receive (tcti_context, &rsize, rbuf,
  278. TSS2_TCTI_TIMEOUT_BLOCK);
  279. assert_int_equal (rval, TSS2_TCTI_RC_MALFORMED_RESPONSE);
  280. }
  281. static void
  282. tcti_cmd_test_transmit_fail (void **state)
  283. {
  284. will_return_always (tcti_cmd_fwrite, EBADF);
  285. TSS2_TCTI_CONTEXT *tcti_context = *state =
  286. test_common_setup (EXECLP_CMD" good");
  287. assert_non_null (tcti_context);
  288. /* send the command buffer */
  289. TSS2_RC rval = Tss2_Tcti_Transmit (tcti_context,
  290. sizeof (getcap_command), getcap_command);
  291. assert_int_equal (rval, TSS2_TCTI_RC_IO_ERROR);
  292. uint8_t rbuf[sizeof (getcap_good_resp)];
  293. size_t rsize = sizeof (rbuf);
  294. /*
  295. * Attempt to receive a response in the wrong state
  296. */
  297. rval = Tss2_Tcti_Receive (tcti_context, &rsize, rbuf,
  298. TSS2_TCTI_TIMEOUT_BLOCK);
  299. assert_int_equal (rval, TSS2_TCTI_RC_BAD_SEQUENCE);
  300. }
  301. static void
  302. tcti_cmd_test_set_locality (void **state)
  303. {
  304. TSS2_TCTI_CONTEXT *tcti_context = *state =
  305. test_common_setup (EXECLP_CMD" good");
  306. assert_non_null (tcti_context);
  307. /* send the command buffer */
  308. TSS2_RC rval = Tss2_Tcti_SetLocality (tcti_context, 42);
  309. assert_int_equal (rval, TSS2_TCTI_RC_NOT_IMPLEMENTED);
  310. }
  311. static void
  312. tcti_cmd_test_cancel (void **state)
  313. {
  314. TSS2_TCTI_CONTEXT *tcti_context = *state =
  315. test_common_setup (EXECLP_CMD" good");
  316. assert_non_null (tcti_context);
  317. /* send the command buffer */
  318. TSS2_RC rval = Tss2_Tcti_Cancel (tcti_context);
  319. assert_int_equal (rval, TSS2_TCTI_RC_NOT_IMPLEMENTED);
  320. }
  321. static void
  322. tcti_cmd_test_get_poll_handles_ok (void **state)
  323. {
  324. TSS2_TCTI_CONTEXT *tcti_context = *state =
  325. test_common_setup (EXECLP_CMD" good");
  326. assert_non_null (tcti_context);
  327. size_t num_of_handles = 1;
  328. TSS2_TCTI_POLL_HANDLE poll_handle;
  329. /* send the command buffer */
  330. TSS2_RC rval = Tss2_Tcti_GetPollHandles (tcti_context, &poll_handle, &num_of_handles);
  331. assert_int_equal (rval, TSS2_RC_SUCCESS);
  332. assert_int_equal(num_of_handles, 1);
  333. }
  334. static void
  335. tcti_cmd_test_get_info (void **state)
  336. {
  337. TSS2_TCTI_CONTEXT *tcti_context = *state =
  338. test_common_setup (EXECLP_CMD" good");
  339. assert_non_null (tcti_context);
  340. const TSS2_TCTI_INFO *info = Tss2_Tcti_Info ();
  341. assert_non_null (info);
  342. assert_int_equal (info->version, TCTI_VERSION);
  343. assert_int_equal (info->init, Tss2_Tcti_Cmd_Init);
  344. assert_string_equal (info->name, TCTI_CMD_NAME);
  345. assert_string_equal (info->description, TCTI_CMD_DESCRIPTION);
  346. assert_string_equal (info->config_help, TCTI_CMD_HELP);
  347. }
  348. int
  349. main (int argc,
  350. char *argv[])
  351. {
  352. const struct CMUnitTest tests[] = {
  353. /*
  354. * Tests that do not require the setup and teardown routine as they
  355. * don't fork successfully
  356. */
  357. cmocka_unit_test (tcti_cmd_init_all_null_test),
  358. cmocka_unit_test (tcti_cmd_init_size_test),
  359. cmocka_unit_test (tcti_cmd_test_pipe_1_fail),
  360. cmocka_unit_test (tcti_cmd_test_pipe_2_fail),
  361. cmocka_unit_test (tcti_cmd_test_fork_fail),
  362. cmocka_unit_test (tcti_cmd_test_fdopen_1_fail),
  363. cmocka_unit_test (tcti_cmd_test_fdopen_2_fail),
  364. cmocka_unit_test (tcti_cmd_test_sigprocmask_1_fail),
  365. /*
  366. * Tests that **do** require a teardown routine as they
  367. * **do** fork/exec successfully and thus get a TCTI_CONTEXT
  368. */
  369. cmocka_unit_test_teardown (
  370. tcti_cmd_test_good,
  371. test_teardown),
  372. cmocka_unit_test_teardown (
  373. tcti_cmd_test_malformed_size_smaller,
  374. test_teardown),
  375. cmocka_unit_test_teardown (
  376. tcti_cmd_test_malformed_size_bigger,
  377. test_teardown),
  378. cmocka_unit_test_teardown (
  379. tcti_cmd_test_transmit_fail,
  380. test_teardown),
  381. cmocka_unit_test_teardown (
  382. tcti_cmd_test_set_locality,
  383. test_teardown),
  384. cmocka_unit_test_teardown (
  385. tcti_cmd_test_cancel,
  386. test_teardown),
  387. cmocka_unit_test_teardown (
  388. tcti_cmd_test_get_poll_handles_ok,
  389. test_teardown),
  390. cmocka_unit_test_teardown (
  391. tcti_cmd_test_get_info,
  392. test_teardown),
  393. };
  394. return cmocka_run_group_tests (tests, NULL, NULL);
  395. }