blob: 395b20621ce04619deb6fac2130ff424c3b34455 [file] [log] [blame]
Philip Tricca8e5afda2017-03-14 09:29:54 -07001#include <inttypes.h>
Philip Tricca09a5bcd2016-03-21 13:20:19 -07002#include <stdbool.h>
Philip Triccaa7d2e2c2016-11-17 14:47:21 -08003#include <stdio.h>
Philip Tricca910f17c2018-03-15 12:38:37 -07004#include <string.h>
Philip Triccaa7d2e2c2016-11-17 14:47:21 -08005
Philip Tricca09a5bcd2016-03-21 13:20:19 -07006#include <setjmp.h>
7#include <cmocka.h>
Philip Triccab194be92016-03-15 13:27:09 -07008
Philip Tricca8ffd3c42018-03-09 16:27:24 -08009#include "tss2_mu.h"
10#include "tss2_tcti_device.h"
Philip Tricca850bb592018-04-03 09:29:22 -070011
12#include "tss2-tcti/tcti-common.h"
13#include "tss2-tcti/tcti-device.h"
Philip Triccaa7d2e2c2016-11-17 14:47:21 -080014
Philip Tricca0b870442018-03-26 14:27:28 -070015/*
16 * Size of the TPM2 buffer used in these tests. In some cases this will be
17 * the command sent (transmit tests) and in others it's used as the response
18 * buffer returned by the TCTI. The only field used by the TCTI is the size
19 * field.
20 */
21#define BUF_SIZE 20
22static uint8_t tpm2_buf [BUF_SIZE] = {
23 0x80, 0x02, /* TAG */
24 0x00, 0x00, 0x00, 0x14, /* size (BUF_SIZE) */
25 0x00, 0x00, 0x00, 0x00, /* rc (success) */
26 0xde, 0xad, 0xbe, 0xef, /* junk data */
27 0xca, 0xfe, 0xba, 0xbe,
28 0xfe, 0xef
29};
Philip Tricca467d63b2016-11-17 18:56:41 -080030/**
31 * When passed all NULL values ensure that we get back the expected RC
32 * indicating bad values.
33 */
34static void
35tcti_device_init_all_null_test (void **state)
36{
37 TSS2_RC rc;
38
Philip Tricca1ae4cff2018-01-19 14:41:57 -080039 rc = Tss2_Tcti_Device_Init (NULL, NULL, NULL);
Philip Tricca467d63b2016-11-17 18:56:41 -080040 assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
41}
Philip Triccab194be92016-03-15 13:27:09 -070042/* Determine the size of a TCTI context structure. Requires calling the
43 * initialization function for the device TCTI with the first parameter
44 * (the TCTI context) NULL.
45 */
Philip Triccaae884f52016-11-17 14:54:56 -080046static void
47tcti_device_init_size_test (void **state)
Philip Triccab194be92016-03-15 13:27:09 -070048{
Philip Triccab194be92016-03-15 13:27:09 -070049 size_t tcti_size = 0;
50 TSS2_RC ret = TSS2_RC_SUCCESS;
51
Philip Tricca1ae4cff2018-01-19 14:41:57 -080052 ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL);
Philip Triccaae884f52016-11-17 14:54:56 -080053 assert_int_equal (ret, TSS2_RC_SUCCESS);
Philip Triccab194be92016-03-15 13:27:09 -070054}
Philip Tricca8e5afda2017-03-14 09:29:54 -070055/* wrap functions for read & write required to test receive / transmit */
56ssize_t
Philip Tricca7a10ee32018-03-06 12:48:39 -080057__wrap_read (int fd, void *buf, size_t count)
Philip Tricca8e5afda2017-03-14 09:29:54 -070058{
Philip Tricca7a10ee32018-03-06 12:48:39 -080059 ssize_t ret = mock_type (ssize_t);
60 uint8_t *buf_in = mock_type (uint8_t*);
61
62 memcpy (buf, buf_in, ret);
63 return ret;
Philip Tricca8e5afda2017-03-14 09:29:54 -070064}
65ssize_t
66__wrap_write (int fd, const void *buffer, size_t buffer_size)
67{
Philip Tricca0b870442018-03-26 14:27:28 -070068 ssize_t ret = mock_type (ssize_t);
69 uint8_t *buf_out = mock_type (uint8_t*);
70
71 memcpy (buf_out, buffer, ret);
72 return ret;
Philip Tricca8e5afda2017-03-14 09:29:54 -070073}
74
Philip Tricca8e5afda2017-03-14 09:29:54 -070075/* Setup functions to create the context for the device TCTI */
Philip Tricca25789b22018-03-07 15:23:47 -080076static int
Philip Tricca8e5afda2017-03-14 09:29:54 -070077tcti_device_setup (void **state)
78{
79 size_t tcti_size = 0;
80 TSS2_RC ret = TSS2_RC_SUCCESS;
81 TSS2_TCTI_CONTEXT *ctx = NULL;
Philip Tricca8e5afda2017-03-14 09:29:54 -070082
Philip Tricca1ae4cff2018-01-19 14:41:57 -080083 ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL);
Philip Tricca8e5afda2017-03-14 09:29:54 -070084 assert_true (ret == TSS2_RC_SUCCESS);
85 ctx = calloc (1, tcti_size);
86 assert_non_null (ctx);
Philip Tricca850bb592018-04-03 09:29:22 -070087 ret = Tss2_Tcti_Device_Init (ctx, &tcti_size, "/dev/null");
Philip Tricca8e5afda2017-03-14 09:29:54 -070088 assert_true (ret == TSS2_RC_SUCCESS);
Philip Tricca25789b22018-03-07 15:23:47 -080089
Philip Tricca8e5afda2017-03-14 09:29:54 -070090 *state = ctx;
Philip Tricca25789b22018-03-07 15:23:47 -080091 return 0;
Philip Tricca8e5afda2017-03-14 09:29:54 -070092}
93
Tadeusz Struk2147c492017-08-09 13:40:31 -070094static int
Philip Tricca8e5afda2017-03-14 09:29:54 -070095tcti_device_teardown (void **state)
96{
Philip Tricca25789b22018-03-07 15:23:47 -080097 TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
Philip Tricca8e5afda2017-03-14 09:29:54 -070098
Andreas Fuchs930b5c12017-11-20 11:28:57 +010099 Tss2_Tcti_Finalize (ctx);
Philip Tricca8e5afda2017-03-14 09:29:54 -0700100 free (ctx);
Philip Tricca25789b22018-03-07 15:23:47 -0800101
Tadeusz Struk2147c492017-08-09 13:40:31 -0700102 return 0;
Philip Tricca25789b22018-03-07 15:23:47 -0800103
104}
Philip Tricca25789b22018-03-07 15:23:47 -0800105/*
Philip Triccacaff7542018-04-04 09:00:02 -0700106 * This test ensures that the GetPollHandles function in the device TCTI
107 * returns the expected value. Since this TCTI does not support async I/O
108 * on account of limitations in the kernel it just returns the
109 * NOT_IMPLEMENTED response code.
110 */
111static void
112tcti_device_get_poll_handles_test (void **state)
113{
114 TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
115 size_t num_handles = 5;
116 TSS2_TCTI_POLL_HANDLE handles [5] = { 0 };
117 TSS2_RC rc;
118
119 rc = Tss2_Tcti_GetPollHandles (ctx, handles, &num_handles);
120 assert_int_equal (rc, TSS2_TCTI_RC_NOT_IMPLEMENTED);
121}
122/*
Philip Tricca25789b22018-03-07 15:23:47 -0800123 */
124static void
125tcti_device_receive_null_size_test (void **state)
126{
127 TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
Philip Tricca850bb592018-04-03 09:29:22 -0700128 TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
Philip Tricca25789b22018-03-07 15:23:47 -0800129 TSS2_RC rc;
130
131 /* Keep state machine check in `receive` from returning error. */
Philip Tricca850bb592018-04-03 09:29:22 -0700132 tcti_common->state = TCTI_STATE_RECEIVE;
Philip Tricca25789b22018-03-07 15:23:47 -0800133 rc = Tss2_Tcti_Receive (ctx,
134 NULL, /* NULL 'size' parameter */
135 NULL,
136 TSS2_TCTI_TIMEOUT_BLOCK);
137 assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
138 rc = Tss2_Tcti_Receive (ctx,
139 NULL, /* NULL 'size' parameter */
140 (uint8_t*)1, /* non-NULL buffer */
141 TSS2_TCTI_TIMEOUT_BLOCK);
142 assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
Philip Tricca8e5afda2017-03-14 09:29:54 -0700143}
144/*
145 * A test case for a successful call to the receive function. This requires
146 * that the context and the command buffer be valid (including the size
147 * field being set appropriately). The result should be an RC indicating
148 * success and the size parameter be updated to reflect the size of the
149 * data received.
150 */
151static void
Philip Tricca7ce0cc42018-04-08 18:41:05 -0700152tcti_device_receive_success (void **state)
Philip Tricca8e5afda2017-03-14 09:29:54 -0700153{
Philip Tricca0b870442018-03-26 14:27:28 -0700154 TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
Philip Tricca850bb592018-04-03 09:29:22 -0700155 TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
Philip Tricca8e5afda2017-03-14 09:29:54 -0700156 TSS2_RC rc;
Philip Tricca0b870442018-03-26 14:27:28 -0700157 /* output buffer for response */
158 uint8_t buf_out [BUF_SIZE + 5] = { 0 };
159 size_t size = BUF_SIZE + 5;
Philip Tricca8e5afda2017-03-14 09:29:54 -0700160
Philip Triccafa14abe2018-03-05 21:14:54 -0800161 /* Keep state machine check in `receive` from returning error. */
Philip Tricca850bb592018-04-03 09:29:22 -0700162 tcti_common->state = TCTI_STATE_RECEIVE;
Philip Tricca7ce0cc42018-04-08 18:41:05 -0700163 will_return (__wrap_read, BUF_SIZE);
Philip Tricca0b870442018-03-26 14:27:28 -0700164 will_return (__wrap_read, tpm2_buf);
Philip Tricca0b870442018-03-26 14:27:28 -0700165 rc = Tss2_Tcti_Receive (ctx,
166 &size,
167 buf_out,
Philip Tricca8e5afda2017-03-14 09:29:54 -0700168 TSS2_TCTI_TIMEOUT_BLOCK);
169 assert_true (rc == TSS2_RC_SUCCESS);
Philip Tricca0b870442018-03-26 14:27:28 -0700170 assert_int_equal (BUF_SIZE, size);
171 assert_memory_equal (tpm2_buf, buf_out, size);
Philip Tricca8e5afda2017-03-14 09:29:54 -0700172}
173/*
Philip Tricca7ce0cc42018-04-08 18:41:05 -0700174 * Ensure that when the 'read' results in an EOF, we get a response code
175 * indicating as much. EOF happens if / when the device driver kills our
176 * connection.
Philip Tricca83a7df12018-03-27 08:11:44 -0700177 */
178static void
Philip Tricca7ce0cc42018-04-08 18:41:05 -0700179tcti_device_receive_eof_test (void **state)
Philip Tricca83a7df12018-03-27 08:11:44 -0700180{
181 TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
Philip Tricca850bb592018-04-03 09:29:22 -0700182 TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
Philip Tricca83a7df12018-03-27 08:11:44 -0700183 TSS2_RC rc;
184 /* output buffer for response */
185 uint8_t buf_out [BUF_SIZE + 5] = { 0 };
Philip Tricca7ce0cc42018-04-08 18:41:05 -0700186 size_t size = BUF_SIZE + 5;
Philip Tricca83a7df12018-03-27 08:11:44 -0700187
188 /* Keep state machine check in `receive` from returning error. */
Philip Tricca850bb592018-04-03 09:29:22 -0700189 tcti_common->state = TCTI_STATE_RECEIVE;
Philip Tricca7ce0cc42018-04-08 18:41:05 -0700190 will_return (__wrap_read, 0);
Philip Tricca83a7df12018-03-27 08:11:44 -0700191 will_return (__wrap_read, tpm2_buf);
Philip Tricca83a7df12018-03-27 08:11:44 -0700192 rc = Tss2_Tcti_Receive (ctx,
193 &size,
194 buf_out,
195 TSS2_TCTI_TIMEOUT_BLOCK);
Philip Tricca7ce0cc42018-04-08 18:41:05 -0700196 assert_int_equal (rc, TSS2_TCTI_RC_NO_CONNECTION);
197}
198/*
199 * This is a weird test: The device TCTI can't read the header for the
200 * response buffer separately from the body. This means it can't know the size
201 * of the response before reading the whole thing. In the event that the caller
202 * provides a buffer that isn't large enough to hold the full response the TCTI
203 * will just read as much data as the buffer will hold. Subsequent interactions
204 * with the kernel driver will likely result in an error.
205 */
206static void
207tcti_device_receive_buffer_lt_response (void **state)
208{
209 TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
210 TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
211 TSS2_RC rc;
212 uint8_t buf_out [BUF_SIZE] = { 0 };
213 /* set size to lt the size in the header of the TPM2 response buffer */
214 size_t size = BUF_SIZE - 1;
215
216 /* Keep state machine check in `receive` from returning error. */
217 tcti_common->state = TCTI_STATE_RECEIVE;
218 will_return (__wrap_read, size);
219 will_return (__wrap_read, tpm2_buf);
220 rc = Tss2_Tcti_Receive (ctx,
221 &size,
222 buf_out,
223 TSS2_TCTI_TIMEOUT_BLOCK);
224 assert_int_equal (rc, TSS2_TCTI_RC_GENERAL_FAILURE);
Philip Tricca83a7df12018-03-27 08:11:44 -0700225}
226/*
Philip Tricca8e5afda2017-03-14 09:29:54 -0700227 * A test case for a successful call to the transmit function. This requires
228 * that the context and the cmmand buffer be valid. The only indication of
229 * success is the RC.
230 */
231static void
232tcti_device_transmit_success (void **state)
233{
Philip Tricca0b870442018-03-26 14:27:28 -0700234 TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
Philip Tricca8e5afda2017-03-14 09:29:54 -0700235 TSS2_RC rc;
Philip Tricca0b870442018-03-26 14:27:28 -0700236 /* output buffer for response */
237 uint8_t buf_out [BUF_SIZE] = { 0 };
Philip Tricca8e5afda2017-03-14 09:29:54 -0700238
Philip Tricca0b870442018-03-26 14:27:28 -0700239 will_return (__wrap_write, BUF_SIZE);
240 will_return (__wrap_write, buf_out);
241 rc = Tss2_Tcti_Transmit (ctx,
242 BUF_SIZE,
243 tpm2_buf);
Philip Tricca8e5afda2017-03-14 09:29:54 -0700244 assert_true (rc == TSS2_RC_SUCCESS);
Philip Tricca0b870442018-03-26 14:27:28 -0700245 assert_memory_equal (tpm2_buf, buf_out, BUF_SIZE);
Philip Tricca8e5afda2017-03-14 09:29:54 -0700246}
Philip Triccaa7d2e2c2016-11-17 14:47:21 -0800247
Philip Triccaa7d2e2c2016-11-17 14:47:21 -0800248int
249main(int argc, char* argv[])
250{
Tadeusz Struk2147c492017-08-09 13:40:31 -0700251 const struct CMUnitTest tests[] = {
252 cmocka_unit_test (tcti_device_init_all_null_test),
253 cmocka_unit_test(tcti_device_init_size_test),
Philip Triccacaff7542018-04-04 09:00:02 -0700254 cmocka_unit_test_setup_teardown (tcti_device_get_poll_handles_test,
255 tcti_device_setup,
256 tcti_device_teardown),
Philip Tricca25789b22018-03-07 15:23:47 -0800257 cmocka_unit_test_setup_teardown (tcti_device_receive_null_size_test,
258 tcti_device_setup,
259 tcti_device_teardown),
Philip Tricca7ce0cc42018-04-08 18:41:05 -0700260 cmocka_unit_test_setup_teardown (tcti_device_receive_success,
Philip Tricca0b870442018-03-26 14:27:28 -0700261 tcti_device_setup,
262 tcti_device_teardown),
Philip Tricca7ce0cc42018-04-08 18:41:05 -0700263 cmocka_unit_test_setup_teardown (tcti_device_receive_eof_test,
264 tcti_device_setup,
265 tcti_device_teardown),
266 cmocka_unit_test_setup_teardown (tcti_device_receive_buffer_lt_response,
Philip Tricca0b870442018-03-26 14:27:28 -0700267 tcti_device_setup,
268 tcti_device_teardown),
Tadeusz Struk2147c492017-08-09 13:40:31 -0700269 cmocka_unit_test_setup_teardown (tcti_device_transmit_success,
Philip Tricca0b870442018-03-26 14:27:28 -0700270 tcti_device_setup,
271 tcti_device_teardown),
Philip Tricca097cae62018-04-08 13:42:29 -0700272 cmocka_unit_test_setup_teardown (tcti_device_transmit_success,
273 tcti_device_setup,
274 tcti_device_teardown),
Philip Triccaa7d2e2c2016-11-17 14:47:21 -0800275 };
Tadeusz Struk2147c492017-08-09 13:40:31 -0700276 return cmocka_run_group_tests (tests, NULL, NULL);
Philip Triccaa7d2e2c2016-11-17 14:47:21 -0800277}