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