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