tcti-swtpm.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. /* SPDX-License-Identifier: BSD-2-Clause */
  2. /***********************************************************************;
  3. * Copyright (c) 2015 - 2018, Intel Corporation
  4. * All rights reserved.
  5. ***********************************************************************/
  6. #ifdef HAVE_CONFIG_H
  7. #include <config.h>
  8. #endif
  9. #include <inttypes.h>
  10. #include <limits.h>
  11. #include <stdio.h>
  12. #include <stdbool.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <setjmp.h>
  16. #include <cmocka.h>
  17. #include "tss2_tcti.h"
  18. #include "tss2_tcti_swtpm.h"
  19. #include "tss2-tcti/tcti-common.h"
  20. #include "tss2-tcti/tcti-swtpm.h"
  21. #include "util/key-value-parse.h"
  22. /*
  23. * This function is defined in the tcti-swtpm module but not exposed through
  24. * the header.
  25. */
  26. TSS2_RC
  27. swtpm_kv_callback (const key_value_t *key_value,
  28. void *user_data);
  29. /*
  30. * In the tests below where 'host' is set (implying TCP and excluding unix domain
  31. * sockets), we ensure that 'path' comes back NULL. Similarly, when 'path' is
  32. * set (implying unix domain sockets), we ensure that 'host' is NULL.
  33. */
  34. #define NO_HOST_VALUE "no.host.xyz"
  35. #define NO_PORT_VALUE 646
  36. #define NO_PATH_VALUE "/bad/path"
  37. /*
  38. * This tests our ability to handle conf strings that have a port component. In
  39. * this case the 'conf_str_to_host_port' function should set the 'host' and
  40. * 'port' parameters and so we check to be sure they're set. (And that 'path'
  41. * is unset.)
  42. */
  43. static void
  44. conf_str_to_host_port_success_test (void **state)
  45. {
  46. TSS2_RC rc;
  47. char conf[] = "host=127.0.0.1,port=2321";
  48. char unusedpath[] = NO_PATH_VALUE;
  49. swtpm_conf_t swtpm_conf = {
  50. .path = unusedpath
  51. };
  52. rc = parse_key_value_string (conf, swtpm_kv_callback, &swtpm_conf);
  53. assert_int_equal (rc, TSS2_RC_SUCCESS);
  54. assert_int_equal (swtpm_conf.port, 2321);
  55. assert_string_equal (swtpm_conf.host, "127.0.0.1");
  56. assert_null (swtpm_conf.path);
  57. }
  58. /*
  59. * This tests our ability to handle conf strings that don't have the port
  60. * component of the URI. In this case the 'conf_str_to_host_port' function
  61. * should not touch the 'port' parameter and so we check to be sure it's
  62. * unchanged. (And that 'path' is unset.)
  63. */
  64. static void
  65. conf_str_to_host_port_no_port_test (void **state)
  66. {
  67. TSS2_RC rc;
  68. char conf[] = "host=127.0.0.1";
  69. char unusedpath[] = NO_PATH_VALUE;
  70. swtpm_conf_t swtpm_conf = {
  71. .host = "foo",
  72. .port = NO_PORT_VALUE,
  73. .path = unusedpath
  74. };
  75. rc = parse_key_value_string (conf, swtpm_kv_callback, &swtpm_conf);
  76. assert_int_equal (rc, TSS2_RC_SUCCESS);
  77. assert_string_equal (swtpm_conf.host, "127.0.0.1");
  78. assert_int_equal (swtpm_conf.port, NO_PORT_VALUE);
  79. assert_null (swtpm_conf.path);
  80. }
  81. /*
  82. * This tests our ability to handle conf strings that have an IPv6 address
  83. * and port component. In this case the 'conf_str_to_host_port' function
  84. * should set the 'hostname' parameter and so we check to be sure it's
  85. * set without the [] brackets. (And that 'path' is unset.)
  86. */
  87. static void
  88. conf_str_to_host_ipv6_port_success_test (void **state)
  89. {
  90. TSS2_RC rc;
  91. char conf[] = "host=::1,port=2321";
  92. char unusedpath[] = NO_PATH_VALUE;
  93. swtpm_conf_t swtpm_conf = {
  94. .path = unusedpath
  95. };
  96. rc = parse_key_value_string (conf, swtpm_kv_callback, &swtpm_conf);
  97. assert_int_equal (rc, TSS2_RC_SUCCESS);
  98. assert_int_equal (swtpm_conf.port, 2321);
  99. assert_string_equal (swtpm_conf.host, "::1");
  100. assert_null (swtpm_conf.path);
  101. }
  102. /*
  103. * This tests our ability to handle conf strings that have an IPv6 address
  104. * but no port component. In this case the 'conf_str_to_host_port' function
  105. * should not touch the 'port' parameter and so we check to be sure it's
  106. * unchanged. (And that 'path' is unset.)
  107. */
  108. static void
  109. conf_str_to_host_ipv6_port_no_port_test (void **state)
  110. {
  111. TSS2_RC rc;
  112. char conf[] = "host=::1";
  113. swtpm_conf_t swtpm_conf = {
  114. .port = NO_PORT_VALUE,
  115. .path = NO_PATH_VALUE
  116. };
  117. rc = parse_key_value_string (conf, swtpm_kv_callback, &swtpm_conf);
  118. assert_int_equal (rc, TSS2_RC_SUCCESS);
  119. assert_int_equal (swtpm_conf.port, NO_PORT_VALUE);
  120. assert_string_equal (swtpm_conf.host, "::1");
  121. assert_null (swtpm_conf.path);
  122. }
  123. /*
  124. * The 'conf_str_to_host_port' function rejects ports over UINT16_MAX.
  125. */
  126. static void
  127. conf_str_to_host_port_invalid_port_large_test (void **state)
  128. {
  129. TSS2_RC rc;
  130. char conf[] = "host=127.0.0.1,port=99999";
  131. swtpm_conf_t swtpm_conf = { 0 };
  132. rc = parse_key_value_string (conf, swtpm_kv_callback, &swtpm_conf);
  133. assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
  134. }
  135. /* The 'conf_str_to_host_port' function rejects URIs with port == 0 */
  136. static void
  137. conf_str_to_host_port_invalid_port_0_test (void **state)
  138. {
  139. TSS2_RC rc;
  140. char conf[] = "host=127.0.0.1,port=0";
  141. swtpm_conf_t swtpm_conf = { 0 };
  142. rc = parse_key_value_string (conf, swtpm_kv_callback, &swtpm_conf);
  143. assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
  144. }
  145. /*
  146. * This tests our ability to handle conf strings that have a path
  147. * component. In this case the 'conf_str_to_host_port' function
  148. * should set the 'path' parameter and so we check to be sure it's
  149. * set. (And that 'host' is unset.)
  150. */
  151. static void
  152. conf_str_to_path_success_test (void **state)
  153. {
  154. TSS2_RC rc;
  155. char conf[] = "path=/some/path";
  156. char unusedhost[] = NO_HOST_VALUE;
  157. swtpm_conf_t swtpm_conf = {
  158. .host = unusedhost
  159. };
  160. rc = parse_key_value_string (conf, swtpm_kv_callback, &swtpm_conf);
  161. assert_int_equal (rc, TSS2_RC_SUCCESS);
  162. assert_string_equal (swtpm_conf.path, "/some/path");
  163. assert_null (swtpm_conf.host);
  164. }
  165. /* When passed all NULL values ensure that we get back the expected RC. */
  166. static void
  167. tcti_swtpm_init_all_null_test (void **state)
  168. {
  169. TSS2_RC rc;
  170. rc = Tss2_Tcti_Swtpm_Init (NULL, NULL, NULL);
  171. assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
  172. }
  173. /*
  174. * Determine the size of a TCTI context structure. Requires calling the
  175. * initialization function for the device TCTI with the first parameter
  176. * (the TCTI context) NULL.
  177. */
  178. static void
  179. tcti_swtpm_init_size_test (void **state)
  180. {
  181. size_t tcti_size = 0;
  182. TSS2_RC ret = TSS2_RC_SUCCESS;
  183. ret = Tss2_Tcti_Swtpm_Init (NULL, &tcti_size, NULL);
  184. assert_int_equal (ret, TSS2_RC_SUCCESS);
  185. assert_int_equal (tcti_size, sizeof (TSS2_TCTI_SWTPM_CONTEXT));
  186. }
  187. /*
  188. * Wrap the 'connect' system call. The mock queue for this function must have
  189. * an integer to return as a response.
  190. */
  191. int
  192. __wrap_connect (int sockfd,
  193. const struct sockaddr *addr,
  194. socklen_t addrlen)
  195. {
  196. return mock_type (int);
  197. }
  198. /*
  199. * Wrap the 'recv' system call. The mock queue for this function must have an
  200. * integer return value (the number of byts recv'd), as well as a pointer to
  201. * a buffer to copy data from to return to the caller.
  202. */
  203. ssize_t
  204. __wrap_read (int sockfd,
  205. void *buf,
  206. size_t len)
  207. {
  208. ssize_t ret = mock_type (ssize_t);
  209. uint8_t *buf_in = mock_ptr_type (uint8_t*);
  210. memcpy (buf, buf_in, ret);
  211. return ret;
  212. }
  213. /*
  214. * Wrap the 'send' system call. The mock queue for this function must have an
  215. * integer to return as a response.
  216. */
  217. ssize_t
  218. __wrap_write (int sockfd,
  219. const void *buf,
  220. size_t len)
  221. {
  222. return mock_type (TSS2_RC);
  223. }
  224. /*
  225. * This is a utility function used by other tests to setup a TCTI context. It
  226. * effectively wraps the init / allocate / init pattern as well as priming the
  227. * mock functions necessary for a the successful call to
  228. * 'Tss2_Tcti_Swtpm_Init'.
  229. */
  230. static TSS2_TCTI_CONTEXT*
  231. tcti_swtpm_init_from_conf (const char *conf)
  232. {
  233. size_t tcti_size = 0;
  234. uint8_t recv_buf[4] = { 0 };
  235. TSS2_RC ret = TSS2_RC_SUCCESS;
  236. TSS2_TCTI_CONTEXT *ctx = NULL;
  237. printf ("%s: before first init\n", __func__);
  238. ret = Tss2_Tcti_Swtpm_Init (NULL, &tcti_size, NULL);
  239. assert_true (ret == TSS2_RC_SUCCESS);
  240. ctx = calloc (1, tcti_size);
  241. assert_non_null (ctx);
  242. /*
  243. * two calls to connect, one for the data socket, one for the command
  244. * socket
  245. */
  246. will_return (__wrap_connect, 0);
  247. will_return (__wrap_connect, 0);
  248. /*
  249. * one control command is sent on init (5 byte write, 4 byte read)
  250. */
  251. will_return (__wrap_write, 5);
  252. will_return (__wrap_read, 4);
  253. will_return (__wrap_read, recv_buf);
  254. printf ("%s: before second_init\n", __func__);
  255. ret = Tss2_Tcti_Swtpm_Init (ctx, &tcti_size, conf);
  256. printf ("%s: after second init\n", __func__);
  257. assert_int_equal (ret, TSS2_RC_SUCCESS);
  258. return ctx;
  259. }
  260. /*
  261. * This is a utility function to setup the "default" TCTI context.
  262. */
  263. static int
  264. tcti_swtpm_setup (void **state)
  265. {
  266. printf ("%s: before tcti_swtpm_init_from_conf\n", __func__);
  267. *state = tcti_swtpm_init_from_conf ("host=127.0.0.1,port=666");
  268. printf ("%s: done\n", __func__);
  269. return 0;
  270. }
  271. #ifndef _WIN32
  272. /* variant of tcti_swtpm_setup() for unix domain sockets. */
  273. static int
  274. tcti_swtpm_setup_unix (void **state)
  275. {
  276. printf ("%s: before tcti_swtpm_init_from_conf\n", __func__);
  277. *state = tcti_swtpm_init_from_conf ("path=/notarealdirectory/notarealfile");
  278. printf ("%s: done\n", __func__);
  279. return 0;
  280. }
  281. #endif
  282. static void
  283. tcti_swtpm_init_null_conf_test (void **state)
  284. {
  285. TSS2_TCTI_CONTEXT *ctx = tcti_swtpm_init_from_conf (NULL);
  286. assert_non_null (ctx);
  287. free (ctx);
  288. }
  289. /*
  290. * This test excersises the Tss2_Tcti_Info function
  291. */
  292. const TSS2_TCTI_INFO *Tss2_Tcti_Info (void);
  293. static void
  294. tcti_swtpm_get_info_test (void **state)
  295. {
  296. const TSS2_TCTI_INFO *info;
  297. info = Tss2_Tcti_Info ();
  298. assert_string_equal (info->name, "tcti-swtpm");
  299. assert_int_equal (info->init, &Tss2_Tcti_Swtpm_Init);
  300. }
  301. /*
  302. * This is a utility function to teardown a TCTI context allocated by the
  303. * tcti_swtpm_setup function.
  304. */
  305. static int
  306. tcti_swtpm_teardown (void **state)
  307. {
  308. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  309. Tss2_Tcti_Finalize (ctx);
  310. free (ctx);
  311. return 0;
  312. }
  313. /*
  314. * This test exercised a failed connect check in the Tss2_Tcti_Swtpm_Init function
  315. */
  316. static void
  317. tcti_swtpm_init_fail_connect_test (void **state)
  318. {
  319. size_t tcti_size = 0;
  320. TSS2_RC ret = TSS2_RC_SUCCESS;
  321. TSS2_TCTI_CONTEXT *ctx = NULL;
  322. /* get tcti size */
  323. ret = Tss2_Tcti_Swtpm_Init (NULL, &tcti_size, NULL);
  324. assert_true (ret == TSS2_RC_SUCCESS);
  325. ctx = calloc (1, tcti_size);
  326. assert_non_null (ctx);
  327. /* first connect fails */
  328. will_return (__wrap_connect, -1);
  329. ret = Tss2_Tcti_Swtpm_Init (ctx, &tcti_size, "host=127.0.0.1,port=666");
  330. assert_int_equal (ret, TSS2_TCTI_RC_IO_ERROR);
  331. /* second connect fails */
  332. will_return (__wrap_connect, 0);
  333. will_return (__wrap_connect, -1);
  334. ret = Tss2_Tcti_Swtpm_Init (ctx, &tcti_size, "host=127.0.0.1,port=666");
  335. assert_int_equal (ret, TSS2_TCTI_RC_IO_ERROR);
  336. free(((TSS2_TCTI_SWTPM_CONTEXT*)ctx)->conf_copy);
  337. free(ctx);
  338. }
  339. /*
  340. * This test ensures that the GetPollHandles function in the device TCTI
  341. * returns the expected value. Since this TCTI does not support async I/O
  342. * on account of limitations in the kernel it just returns the
  343. * NOT_IMPLEMENTED response code.
  344. */
  345. static void
  346. tcti_swtpm_get_poll_handles_test (void **state)
  347. {
  348. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  349. size_t num_handles = 5;
  350. TSS2_TCTI_POLL_HANDLE handles [5] = { 0 };
  351. TSS2_RC rc;
  352. rc = Tss2_Tcti_GetPollHandles (ctx, handles, &num_handles);
  353. assert_int_equal (rc, TSS2_TCTI_RC_NOT_IMPLEMENTED);
  354. }
  355. /*
  356. * This test exercises the null check of tcti_swtpm_receive ()
  357. */
  358. static void
  359. tcti_swtpm_receive_null_test (void **state)
  360. {
  361. TSS2_RC rc;
  362. rc = Tss2_Tcti_Receive (NULL, NULL, NULL, TSS2_TCTI_TIMEOUT_BLOCK);
  363. assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
  364. }
  365. /*
  366. */
  367. static void
  368. tcti_swtpm_receive_null_size_test (void **state)
  369. {
  370. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  371. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  372. TSS2_RC rc;
  373. /* Keep state machine check in `receive` from returning error. */
  374. tcti_common->state = TCTI_STATE_RECEIVE;
  375. rc = Tss2_Tcti_Receive (ctx,
  376. NULL, /* NULL 'size' parameter */
  377. NULL,
  378. TSS2_TCTI_TIMEOUT_BLOCK);
  379. assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
  380. rc = Tss2_Tcti_Receive (ctx,
  381. NULL, /* NULL 'size' parameter */
  382. (uint8_t*)1, /* non-NULL buffer */
  383. TSS2_TCTI_TIMEOUT_BLOCK);
  384. assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
  385. }
  386. /*
  387. * This test exercises the successful code path through the receive function.
  388. */
  389. static void
  390. tcti_swtpm_receive_success_test (void **state)
  391. {
  392. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  393. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  394. TSS2_RC rc = TSS2_RC_SUCCESS;
  395. uint8_t response_in [] = { 0x80, 0x02,
  396. 0x00, 0x00, 0x00, 0x0c,
  397. 0x00, 0x00, 0x00, 0x00,
  398. 0x01, 0x02 };
  399. size_t response_size = sizeof(response_in);
  400. uint8_t response_out [12] = { 0 };
  401. /* Keep state machine check in `receive` from returning error. */
  402. tcti_common->state = TCTI_STATE_RECEIVE;
  403. /* receive response header */
  404. will_return (__wrap_read, 10);
  405. will_return (__wrap_read, response_in);
  406. /* receive remaining response */
  407. will_return (__wrap_read, response_size - 10);
  408. will_return (__wrap_read, &response_in [10]);
  409. rc = Tss2_Tcti_Receive (ctx, &response_size, response_out, TSS2_TCTI_TIMEOUT_BLOCK);
  410. assert_int_equal (rc, TSS2_RC_SUCCESS);
  411. assert_memory_equal (response_in, response_out, response_size);
  412. }
  413. /*
  414. */
  415. static void
  416. tcti_swtpm_receive_size_success_test (void **state)
  417. {
  418. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  419. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  420. TSS2_RC rc = TSS2_RC_SUCCESS;
  421. size_t response_size = 0;
  422. uint8_t response_in [] = { 0x80, 0x02,
  423. 0x00, 0x00, 0x00, 0x0c,
  424. 0x00, 0x00, 0x00, 0x00,
  425. 0x01, 0x02 };
  426. uint8_t response_out [12] = { 0 };
  427. /* Keep state machine check in `receive` from returning error. */
  428. tcti_common->state = TCTI_STATE_RECEIVE;
  429. /* receive response header */
  430. will_return (__wrap_read, 10);
  431. will_return (__wrap_read, response_in);
  432. rc = Tss2_Tcti_Receive (ctx, &response_size, NULL, TSS2_TCTI_TIMEOUT_BLOCK);
  433. assert_int_equal (rc, TSS2_RC_SUCCESS);
  434. assert_int_equal (response_size, 0xc);
  435. /* receive remaining response */
  436. will_return (__wrap_read, response_size - 10);
  437. will_return (__wrap_read, &response_in [10]);
  438. rc = Tss2_Tcti_Receive (ctx, &response_size, response_out, TSS2_TCTI_TIMEOUT_BLOCK);
  439. assert_int_equal (rc, TSS2_RC_SUCCESS);
  440. assert_memory_equal (response_in, response_out, response_size);
  441. }
  442. /*
  443. * This test causes the underlying 'read' call to return 0 / EOF when we
  444. * call the TCTI 'receive' function. In this case the TCTI should return an
  445. * IO error.
  446. */
  447. static void
  448. tcti_swtpm_receive_eof_first_read_test (void **state)
  449. {
  450. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  451. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  452. TSS2_RC rc;
  453. /* output buffer for response */
  454. uint8_t buf [TPM_HEADER_SIZE] = { 0 };
  455. size_t size = sizeof (buf);
  456. /* Keep state machine check in `receive` from returning error. */
  457. tcti_common->state = TCTI_STATE_RECEIVE;
  458. will_return (__wrap_read, 0);
  459. will_return (__wrap_read, buf);
  460. rc = Tss2_Tcti_Receive (ctx,
  461. &size,
  462. buf,
  463. TSS2_TCTI_TIMEOUT_BLOCK);
  464. assert_true (rc == TSS2_TCTI_RC_IO_ERROR);
  465. }
  466. /*
  467. * This test causes the underlying 'read' call to return EOF but only after
  468. * a successful read that gets us the response size. This results in the
  469. * an IO_ERROR RC being returned.
  470. */
  471. static void
  472. tcti_swtpm_receive_eof_second_read_test (void **state)
  473. {
  474. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  475. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  476. TSS2_RC rc;
  477. /* input response buffer */
  478. uint8_t response_in [] = { 0x80, 0x02,
  479. 0x00, 0x00, 0x00, 0x0c,
  480. 0x00, 0x00, 0x00, 0x00,
  481. 0x01, 0x02,
  482. /* simulator appends 4 bytes of 0's to every response */
  483. 0x00, 0x00, 0x00, 0x00 };
  484. /* output response buffer */
  485. uint8_t response_out [12] = { 0 };
  486. size_t size = sizeof (response_out);
  487. /* Keep state machine check in `receive` from returning error. */
  488. tcti_common->state = TCTI_STATE_RECEIVE;
  489. /* setup response size for first read */
  490. will_return (__wrap_read, 4);
  491. will_return (__wrap_read, &response_in [2]);
  492. /* setup 0 for EOF on second read */
  493. will_return (__wrap_read, 0);
  494. will_return (__wrap_read, response_in);
  495. rc = Tss2_Tcti_Receive (ctx,
  496. &size,
  497. response_out,
  498. TSS2_TCTI_TIMEOUT_BLOCK);
  499. assert_true (rc == TSS2_TCTI_RC_IO_ERROR);
  500. }
  501. /*
  502. * This test exercises the (fake) timeout mechanism of the receive function.
  503. */
  504. static void
  505. tcti_swtpm_receive_timeout_try_again_test (void **state)
  506. {
  507. #ifdef TEST_FAPI_ASYNC
  508. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  509. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  510. TSS2_RC rc = TSS2_RC_SUCCESS;
  511. /* Keep state machine check in `receive` from returning error. */
  512. tcti_common->state = TCTI_STATE_RECEIVE;
  513. rc = Tss2_Tcti_Receive (ctx, (size_t*) 1, NULL, TSS2_TCTI_TIMEOUT_NONE);
  514. assert_int_equal (rc, TSS2_TCTI_RC_TRY_AGAIN);
  515. #endif /* TEST_FAPI_ASYNC */
  516. }
  517. /*
  518. * This test exercises the successful code path through the transmit function.
  519. */
  520. static void
  521. tcti_swtpm_transmit_success_test (void **state)
  522. {
  523. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  524. TSS2_RC rc = TSS2_RC_SUCCESS;
  525. uint8_t command [] = { 0x80, 0x02,
  526. 0x00, 0x00, 0x00, 0x0c,
  527. 0x00, 0x00, 0x00, 0x00,
  528. 0x01, 0x02 };
  529. size_t command_size = sizeof (command);
  530. /* connect to tpm_sock */
  531. will_return (__wrap_connect, 0);
  532. /* send the command buffer */
  533. will_return (__wrap_write, 0xc);
  534. rc = Tss2_Tcti_Transmit (ctx, command_size, command);
  535. assert_int_equal (rc, TSS2_RC_SUCCESS);
  536. }
  537. /*
  538. * This test exercises the NULL checks of the transmit function.
  539. */
  540. static void
  541. tcti_swtpm_transmit_null_test (void **state)
  542. {
  543. TSS2_RC rc = TSS2_RC_SUCCESS;
  544. rc = Tss2_Tcti_Transmit (NULL, 0, NULL);
  545. assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
  546. }
  547. /*
  548. * This test exercises the header check of the transmit function.
  549. * Also it exercises a marshaling failure check.
  550. */
  551. static void
  552. tcti_swtpm_transmit_fail_header_test (void **state)
  553. {
  554. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  555. TSS2_RC rc = TSS2_RC_SUCCESS;
  556. uint8_t command [] = { 0x80, 0x02,
  557. 0x00, 0x00, 0x00, 0xFF,
  558. 0x00, 0x00, 0x00, 0x00,
  559. 0x01, 0x02 };
  560. size_t command_size = sizeof (command);
  561. rc = Tss2_Tcti_Transmit (ctx, command_size, command);
  562. assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
  563. rc = Tss2_Tcti_Transmit (ctx, 0, command);
  564. assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
  565. }
  566. /*
  567. * This test exercises the successful code path through the tcti_control_command
  568. * function
  569. */
  570. TSS2_RC tcti_control_command (
  571. TSS2_TCTI_CONTEXT *tctiContext,
  572. uint32_t cmd_code, const void *cmd_sdu, size_t cmd_sdu_len,
  573. uint32_t *resp_code, void *resp_sdu, size_t *resp_sdu_len);
  574. static void
  575. tcti_swtpm_control_command_success_test (void **state)
  576. {
  577. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  578. TSS2_RC rc = TSS2_RC_SUCCESS;
  579. const uint32_t CMD_SET_BUFFERSIZE = 0x11;
  580. uint32_t buffersize_in = 0;
  581. uint8_t response[] = {0x00, 0x00, 0x00, 0x00,
  582. 0x00, 0x00, 0x10, 0x00,
  583. 0x00, 0x00, 0x0A, 0x2A,
  584. 0x00, 0x00, 0x10, 0x00};
  585. uint32_t respcode_out = 0;
  586. size_t payload_len_out_expected = sizeof(response) - sizeof(respcode_out);
  587. uint8_t payload_out[payload_len_out_expected];
  588. size_t payload_len_out;
  589. /*
  590. * Here we send the command CMD_SET_BUFFERSIZE.
  591. * Request
  592. * 00 00 00 11 (command code CMD_SET_BUFFERSIZE)
  593. * 00 00 00 00 (buffersize 0 -> do not set but query buffersize)
  594. * Response
  595. * 00 00 00 00 (response code success)
  596. * 00 00 10 00 (payload, buffersize)
  597. * 00 00 0A 2A (payload, minsize)
  598. * 00 00 10 00 (payload, maxsize)
  599. */
  600. will_return (__wrap_connect, 0);
  601. will_return (__wrap_write, 8);
  602. will_return (__wrap_read, 16);
  603. will_return (__wrap_read, response);
  604. rc = tcti_control_command (ctx, CMD_SET_BUFFERSIZE, &buffersize_in,
  605. sizeof(buffersize_in), &respcode_out,
  606. payload_out, &payload_len_out);
  607. assert_int_equal (rc, TSS2_RC_SUCCESS);
  608. assert_int_equal (respcode_out, 0);
  609. assert_int_equal (payload_len_out, payload_len_out_expected);
  610. assert_int_equal (memcmp(payload_out,
  611. response + sizeof(respcode_out),
  612. payload_len_out),
  613. 0);
  614. }
  615. /*
  616. * This test exercises the NULL checks for tctiContext and resp_sdu_len
  617. */
  618. static void
  619. tcti_swtpm_control_command_null_test (void **state)
  620. {
  621. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  622. TSS2_RC rc;
  623. /* tcti context NULL */
  624. rc = tcti_control_command (NULL, 0, NULL, 0, NULL, NULL, NULL);
  625. assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
  626. /* cmd_sdu NULL with cmd_sdu_len not 0 */
  627. rc = tcti_control_command (ctx, 0, NULL, 4, NULL, NULL, NULL);
  628. assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
  629. }
  630. /*
  631. * This test exercises a failed receive for the two cases
  632. * - too few bytes received
  633. * - response code not success
  634. */
  635. static void
  636. tcti_swtpm_control_command_recv_fail_test (void **state)
  637. {
  638. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  639. TSS2_RC rc = TSS2_RC_SUCCESS;
  640. const uint32_t CMD_CANCEL_TPM_CMD = 0x09;
  641. uint32_t response = 0xFFFFFFFF;
  642. uint32_t respcode_out = 0;
  643. will_return (__wrap_connect, 0);
  644. will_return (__wrap_write, 8);
  645. will_return (__wrap_read, 0);
  646. will_return (__wrap_read, response);
  647. rc = tcti_control_command (ctx, CMD_CANCEL_TPM_CMD, NULL, 0, &respcode_out,
  648. NULL, NULL);
  649. assert_int_equal (rc, TSS2_TCTI_RC_IO_ERROR);
  650. will_return (__wrap_connect, 0);
  651. will_return (__wrap_write, 8);
  652. will_return (__wrap_read, 4);
  653. will_return (__wrap_read, (uint8_t *) &response);
  654. rc = tcti_control_command (ctx, CMD_CANCEL_TPM_CMD, NULL, 0, &respcode_out,
  655. NULL, NULL);
  656. assert_int_equal (rc, TSS2_TCTI_RC_IO_ERROR);
  657. assert_int_equal (respcode_out, response);
  658. }
  659. /*
  660. * This test checks the return code of tcti_swtpm_cancel
  661. */
  662. static void
  663. tcti_swtpm_cancel_test (void **state)
  664. {
  665. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  666. TSS2_RC rc = TSS2_RC_SUCCESS;
  667. rc = Tss2_Tcti_Cancel (ctx);
  668. assert_int_equal (rc, TSS2_TCTI_RC_NOT_IMPLEMENTED);
  669. }
  670. /*
  671. * This test excersises all paths through the set locality function
  672. */
  673. static void
  674. tcti_swtpm_locality_test (void **state)
  675. {
  676. TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
  677. TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
  678. TSS2_RC rc = TSS2_RC_SUCCESS;
  679. uint32_t response;
  680. /* test NULL check */
  681. rc = Tss2_Tcti_SetLocality (NULL, 3);
  682. assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
  683. /* fail due to non-success response code */
  684. response = 0xFFFFFFFF;
  685. will_return (__wrap_connect, 0);
  686. will_return (__wrap_write, 8);
  687. will_return (__wrap_read, 4);
  688. will_return (__wrap_read, (uint8_t *) &response);
  689. rc = Tss2_Tcti_SetLocality (ctx, 3);
  690. assert_int_equal (rc, TSS2_TCTI_RC_IO_ERROR);
  691. /* success */
  692. response = 0x00000000;
  693. will_return (__wrap_connect, 0);
  694. will_return (__wrap_write, 8);
  695. will_return (__wrap_read, 4);
  696. will_return (__wrap_read, (uint8_t *) &response);
  697. rc = Tss2_Tcti_SetLocality (ctx, 3);
  698. assert_int_equal (rc, TSS2_RC_SUCCESS);
  699. /* put state machine into `receive` to provoke an bad sequence error. */
  700. tcti_common->state = TCTI_STATE_RECEIVE;
  701. rc = Tss2_Tcti_SetLocality (ctx, 3);
  702. assert_int_equal (rc, TSS2_TCTI_RC_BAD_SEQUENCE);
  703. }
  704. int
  705. main (int argc,
  706. char *argv[])
  707. {
  708. const struct CMUnitTest tests[] = {
  709. cmocka_unit_test (conf_str_to_host_port_success_test),
  710. cmocka_unit_test (conf_str_to_host_port_no_port_test),
  711. cmocka_unit_test (conf_str_to_host_ipv6_port_success_test),
  712. cmocka_unit_test (conf_str_to_host_ipv6_port_no_port_test),
  713. cmocka_unit_test (conf_str_to_host_port_invalid_port_large_test),
  714. cmocka_unit_test (conf_str_to_host_port_invalid_port_0_test),
  715. cmocka_unit_test (conf_str_to_path_success_test),
  716. cmocka_unit_test (tcti_swtpm_init_all_null_test),
  717. cmocka_unit_test (tcti_swtpm_init_size_test),
  718. cmocka_unit_test (tcti_swtpm_init_null_conf_test),
  719. cmocka_unit_test (tcti_swtpm_get_info_test),
  720. cmocka_unit_test_setup_teardown (tcti_swtpm_init_fail_connect_test,
  721. tcti_swtpm_setup,
  722. tcti_swtpm_teardown),
  723. cmocka_unit_test_setup_teardown (tcti_swtpm_get_poll_handles_test,
  724. tcti_swtpm_setup,
  725. tcti_swtpm_teardown),
  726. cmocka_unit_test_setup_teardown (tcti_swtpm_receive_null_test,
  727. tcti_swtpm_setup,
  728. tcti_swtpm_teardown),
  729. cmocka_unit_test_setup_teardown (tcti_swtpm_receive_null_size_test,
  730. tcti_swtpm_setup,
  731. tcti_swtpm_teardown),
  732. cmocka_unit_test_setup_teardown (tcti_swtpm_receive_success_test,
  733. tcti_swtpm_setup,
  734. tcti_swtpm_teardown),
  735. cmocka_unit_test_setup_teardown (tcti_swtpm_receive_size_success_test,
  736. tcti_swtpm_setup,
  737. tcti_swtpm_teardown),
  738. cmocka_unit_test_setup_teardown (tcti_swtpm_receive_eof_first_read_test,
  739. tcti_swtpm_setup,
  740. tcti_swtpm_teardown),
  741. cmocka_unit_test_setup_teardown (tcti_swtpm_receive_eof_second_read_test,
  742. tcti_swtpm_setup,
  743. tcti_swtpm_teardown),
  744. cmocka_unit_test_setup_teardown (tcti_swtpm_receive_timeout_try_again_test,
  745. tcti_swtpm_setup,
  746. tcti_swtpm_teardown),
  747. cmocka_unit_test_setup_teardown (tcti_swtpm_transmit_success_test,
  748. tcti_swtpm_setup,
  749. tcti_swtpm_teardown),
  750. cmocka_unit_test_setup_teardown (tcti_swtpm_transmit_null_test,
  751. tcti_swtpm_setup,
  752. tcti_swtpm_teardown),
  753. cmocka_unit_test_setup_teardown (tcti_swtpm_transmit_fail_header_test,
  754. tcti_swtpm_setup,
  755. tcti_swtpm_teardown),
  756. cmocka_unit_test_setup_teardown (tcti_swtpm_control_command_success_test,
  757. tcti_swtpm_setup,
  758. tcti_swtpm_teardown),
  759. cmocka_unit_test_setup_teardown (tcti_swtpm_control_command_null_test,
  760. tcti_swtpm_setup,
  761. tcti_swtpm_teardown),
  762. cmocka_unit_test_setup_teardown (tcti_swtpm_control_command_recv_fail_test,
  763. tcti_swtpm_setup,
  764. tcti_swtpm_teardown),
  765. cmocka_unit_test_setup_teardown (tcti_swtpm_cancel_test,
  766. tcti_swtpm_setup,
  767. tcti_swtpm_teardown),
  768. cmocka_unit_test_setup_teardown (tcti_swtpm_locality_test,
  769. tcti_swtpm_setup,
  770. tcti_swtpm_teardown),
  771. #ifndef _WIN32
  772. cmocka_unit_test_setup_teardown (tcti_swtpm_receive_success_test,
  773. tcti_swtpm_setup_unix,
  774. tcti_swtpm_teardown),
  775. #endif
  776. };
  777. return cmocka_run_group_tests (tests, NULL, NULL);
  778. }