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