1 /*
2  * SPDX-License-Identifier: BSD-2-Clause
3  * Copyright (c) 2019, Intel Corporation
4  */
5 #include <errno.h>
6 #include <glib.h>
7 #include <inttypes.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/socket.h>
12 #if defined(__FreeBSD__)
13 #include <sys/poll.h>
14 #else
15 #include <poll.h>
16 #endif
17 
18 #include <setjmp.h>
19 #include <cmocka.h>
20 
21 #include <tss2/tss2_tpm2_types.h>
22 
23 #include "tcti-tabrmd-priv.h"
24 #include "mock-funcs.h"
25 
26 /*
27  * This tests the tcti_tabrmd_poll function, ensuring that it returns the
28  * expected response code for the POLIN event.
29  */
30 static void
tcti_tabrmd_poll_fd_ready_pollin(void ** state)31 tcti_tabrmd_poll_fd_ready_pollin (void **state)
32 {
33     UNUSED_PARAM (state);
34     int ret;
35 
36     will_return (__wrap_poll, POLLIN);
37     will_return (__wrap_poll, 0);
38     will_return (__wrap_poll, 1);
39 
40     ret = tcti_tabrmd_poll (TEST_FD, TSS2_TCTI_TIMEOUT_BLOCK);
41     assert_int_equal (ret, 0);
42 }
43 /*
44  * This tests the tcti_tabrmd_poll function, ensuring that it returns the
45  * expected response code for the POLLPRI event.
46  */
47 static void
tcti_tabrmd_poll_fd_ready_pollpri(void ** state)48 tcti_tabrmd_poll_fd_ready_pollpri (void **state)
49 {
50     UNUSED_PARAM (state);
51     int ret;
52 
53     will_return (__wrap_poll, POLLPRI);
54     will_return (__wrap_poll, 0);
55     will_return (__wrap_poll, 1);
56 
57     ret = tcti_tabrmd_poll (TEST_FD, TSS2_TCTI_TIMEOUT_BLOCK);
58     assert_int_equal (ret, 0);
59 }
60 /*
61  * This tests the tcti_tabrmd_poll function, ensuring that it returns the
62  * expected response code for the POLLRDHUP event.
63  */
64 
65 #if defined(__FreeBSD__)
66 #ifndef POLLRDHUP
67 #define POLLRDHUP 0x0
68 #endif
69 #endif
70 static void
tcti_tabrmd_poll_fd_ready_pollrdhup(void ** state)71 tcti_tabrmd_poll_fd_ready_pollrdhup (void **state)
72 {
73     UNUSED_PARAM (state);
74     int ret;
75 
76     will_return (__wrap_poll, POLLRDHUP);
77     will_return (__wrap_poll, 0);
78     will_return (__wrap_poll, 1);
79 
80     ret = tcti_tabrmd_poll (TEST_FD, TSS2_TCTI_TIMEOUT_BLOCK);
81     assert_int_equal (ret, 0);
82 }
83 /*
84  * This tests the tcti_tabrmd_poll function, ensuring that it returns the
85  * expected response code when a timeout occurs.
86  */
87 static void
tcti_tabrmd_poll_timeout(void ** state)88 tcti_tabrmd_poll_timeout (void **state)
89 {
90     UNUSED_PARAM (state);
91     int ret;
92 
93     will_return (__wrap_poll, 0);
94     will_return (__wrap_poll, 0);
95     will_return (__wrap_poll, 0);
96 
97     ret = tcti_tabrmd_poll (TEST_FD, TSS2_TCTI_TIMEOUT_BLOCK);
98     assert_int_equal (ret, -1);
99 }
100 /*
101  * This tests the tcti_tabrmd_poll function, ensuring that it returns the
102  * expected response when an error occurs.
103  */
104 static void
tcti_tabrmd_poll_error(void ** state)105 tcti_tabrmd_poll_error (void **state)
106 {
107     UNUSED_PARAM (state);
108     int ret;
109 
110     will_return (__wrap_poll, 0);
111     will_return (__wrap_poll, EINVAL);
112     will_return (__wrap_poll, -1);
113 
114     ret = tcti_tabrmd_poll (TEST_FD, TSS2_TCTI_TIMEOUT_BLOCK);
115     assert_int_equal (ret, EINVAL);
116 }
117 /*
118  * This is the setup function used to create a skeletal / minimal context
119  * for testing purposes.
120  */
121 static int
tcti_tabrmd_setup(void ** state)122 tcti_tabrmd_setup (void **state)
123 {
124     TSS2_TCTI_TABRMD_CONTEXT *tcti_ctx;
125     TSS2_TCTI_CONTEXT_COMMON_V1 *common_ctx;
126 
127     tcti_ctx = calloc (1, sizeof (TSS2_TCTI_TABRMD_CONTEXT));
128     tcti_ctx->state = TABRMD_STATE_RECEIVE;
129     tcti_ctx->sock_connect = TEST_CONNECTION;
130     tcti_ctx->index = 0;
131     tcti_ctx->state = TABRMD_STATE_TRANSMIT;
132     common_ctx = (TSS2_TCTI_CONTEXT_COMMON_V1*)tcti_ctx;
133     common_ctx->magic = TSS2_TCTI_TABRMD_MAGIC;
134     common_ctx->version = TSS2_TCTI_TABRMD_VERSION;
135 
136     *state = tcti_ctx;
137     return 0;
138 }
139 /*
140  * This is the setup function used to create a skeletal / minimal context
141  * for testing the 'receive' function from the TCTI.
142  */
143 static int
tcti_tabrmd_receive_setup(void ** state)144 tcti_tabrmd_receive_setup (void **state)
145 {
146     TSS2_TCTI_TABRMD_CONTEXT *tcti_ctx;
147 
148     tcti_tabrmd_setup (state);
149     tcti_ctx = (TSS2_TCTI_TABRMD_CONTEXT*)*state;
150     tcti_ctx->state = TABRMD_STATE_RECEIVE;
151 
152     *state = tcti_ctx;
153     return 0;
154 }
155 /*
156  * This is a teardown function to deallocate / cleanup all resources
157  * associated with these tests.
158  */
159 static int
tcti_tabrmd_teardown(void ** state)160 tcti_tabrmd_teardown (void **state)
161 {
162     free (*state);
163     return 0;
164 }
165 /*
166  * This test ensures that a call to tcti_tabrmd_read that causes poll to
167  * timeout will return the appropriate RC.
168  */
169 static void
tcti_tabrmd_read_poll_timeout(void ** state)170 tcti_tabrmd_read_poll_timeout (void **state)
171 {
172     TSS2_RC rc;
173     uint8_t resp [TPM2_MAX_RESPONSE_SIZE] = { 0, };
174     size_t resp_size = sizeof (resp);
175     uint32_t timeout = TSS2_TCTI_TIMEOUT_BLOCK;
176     TSS2_TCTI_TABRMD_CONTEXT *tcti_ctx = (TSS2_TCTI_TABRMD_CONTEXT*)*state;
177 
178     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
179     will_return (__wrap_g_socket_get_fd, TEST_FD);
180 
181     /* prime mock stack for poll, will return 0 indicating timeout */
182     will_return (__wrap_poll, 0);
183     will_return (__wrap_poll, 0);
184     will_return (__wrap_poll, 0);
185 
186     rc = tcti_tabrmd_read (tcti_ctx, resp, resp_size, timeout);
187     assert_int_equal (rc, TSS2_TCTI_RC_TRY_AGAIN);
188 }
189 /*
190  * This test ensures that a call to tcti_tabrmd_read that causes poll to
191  * fail / return an error that it will return the appropriate RC.
192  */
193 static void
tcti_tabrmd_read_poll_fail(void ** state)194 tcti_tabrmd_read_poll_fail (void **state)
195 {
196     TSS2_RC rc;
197     uint8_t resp [TPM2_MAX_RESPONSE_SIZE] = { 0, };
198     size_t resp_size = sizeof (resp);
199     uint32_t timeout = TSS2_TCTI_TIMEOUT_BLOCK;
200     TSS2_TCTI_TABRMD_CONTEXT *tcti_ctx = (TSS2_TCTI_TABRMD_CONTEXT*)*state;
201 
202     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
203     will_return (__wrap_g_socket_get_fd, TEST_FD);
204 
205     will_return (__wrap_poll, 0);
206     will_return (__wrap_poll, EINVAL);
207     will_return (__wrap_poll, -1);
208 
209     rc = tcti_tabrmd_read (tcti_ctx, resp, resp_size, timeout);
210     assert_int_equal (rc, TSS2_TCTI_RC_GENERAL_FAILURE);
211 }
212 /*
213  * This test ensures that a call to tcti_tabrmd_read that causes
214  * g_input_stream_read to return EOF will return the appropriate RC.
215  */
216 static void
tcti_tabrmd_read_eof(void ** state)217 tcti_tabrmd_read_eof (void **state)
218 {
219     int ret;
220     uint8_t resp [TPM2_MAX_RESPONSE_SIZE] = { 0, };
221     size_t resp_size = sizeof (resp);
222     uint32_t timeout = TSS2_TCTI_TIMEOUT_BLOCK;
223     TSS2_TCTI_TABRMD_CONTEXT *tcti_ctx = (TSS2_TCTI_TABRMD_CONTEXT*)*state;
224 
225     /* mock stack required to extract the fd from the GSocketConnection */
226     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
227     will_return (__wrap_g_socket_get_fd, TEST_FD);
228 
229     /* prime mock stack for poll to indicate data is ready */
230     will_return (__wrap_poll, POLLIN);
231     will_return (__wrap_poll, 0);
232     will_return (__wrap_poll, 1);
233 
234     /* mock stack required to extract GIStream */
235     will_return (__wrap_g_io_stream_get_input_stream, TEST_CONNECTION);
236     /* cause g_input_stream_read to return 0 indicating EOF */
237     will_return (__wrap_g_input_stream_read, 0);
238 
239     ret = tcti_tabrmd_read (tcti_ctx, resp, resp_size, timeout);
240     assert_int_equal (ret, TSS2_TCTI_RC_NO_CONNECTION);
241 }
242 /*
243  * This test ensures that a call to tcti_tabrmd_read that causes
244  * g_input_stream_read to indicate that it would block, returns the
245  * appropriate RC.
246  */
247 static void
tcti_tabrmd_read_block_error(void ** state)248 tcti_tabrmd_read_block_error (void **state)
249 {
250     int ret;
251     uint8_t resp [TPM2_MAX_RESPONSE_SIZE] = { 0, };
252     size_t resp_size = sizeof (resp);
253     uint32_t timeout = TSS2_TCTI_TIMEOUT_BLOCK;
254     TSS2_TCTI_TABRMD_CONTEXT *tcti_ctx = (TSS2_TCTI_TABRMD_CONTEXT*)*state;
255     GError* error;
256 
257     /* mock stack required to extract the fd from the GSocketConnection */
258     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
259     will_return (__wrap_g_socket_get_fd, TEST_FD);
260 
261     /* prime mock stack for poll to indicate data is ready */
262     will_return (__wrap_poll, POLLIN);
263     will_return (__wrap_poll, 0);
264     will_return (__wrap_poll, 1);
265 
266     /* mock stack required to extract GIStream & read data */
267     will_return (__wrap_g_io_stream_get_input_stream, TEST_CONNECTION);
268     error = g_error_new (1, G_IO_ERROR_WOULD_BLOCK, __func__);
269     will_return (__wrap_g_input_stream_read, -1);
270     will_return (__wrap_g_input_stream_read, error);
271 
272     ret = tcti_tabrmd_read (tcti_ctx, resp, resp_size, timeout);
273     assert_int_equal (ret, TSS2_TCTI_RC_TRY_AGAIN);
274 }
275 /*
276  * This test forces the call to 'g_input_stream_read' to read fewer bytes
277  * than requested by the caller (the 'tcti_tabrmd_read' in this case). This
278  * is a "short read" and should return an RC telling the caller to retry.
279  */
280 static void
tcti_tabrmd_read_short(void ** state)281 tcti_tabrmd_read_short (void **state)
282 {
283     int ret;
284     uint8_t resp [TPM2_MAX_RESPONSE_SIZE] = { 0, };
285     size_t resp_size = sizeof (resp), read_size = resp_size / 2;
286     uint32_t timeout = TSS2_TCTI_TIMEOUT_BLOCK;
287     TSS2_TCTI_TABRMD_CONTEXT *tcti_ctx = (TSS2_TCTI_TABRMD_CONTEXT*)*state;
288     uint8_t buf [sizeof (resp)] = { 0, };
289 
290     /* mock stack required to extract the fd from the GSocketConnection */
291     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
292     will_return (__wrap_g_socket_get_fd, TEST_FD);
293 
294     /* prime mock stack for poll to indicate data is ready */
295     will_return (__wrap_poll, POLLIN);
296     will_return (__wrap_poll, 0);
297     will_return (__wrap_poll, 1);
298 
299     /* mock stack required to extract GIStream & read data */
300     will_return (__wrap_g_io_stream_get_input_stream, TEST_CONNECTION);
301     will_return (__wrap_g_input_stream_read, read_size);
302     will_return (__wrap_g_input_stream_read, buf);
303 
304     ret = tcti_tabrmd_read (tcti_ctx, resp, resp_size, timeout);
305     assert_int_equal (ret, TSS2_TCTI_RC_TRY_AGAIN);
306 }
307 static void
tcti_tabrmd_read_success(void ** state)308 tcti_tabrmd_read_success (void **state)
309 {
310     int ret;
311     uint8_t resp [TPM2_MAX_RESPONSE_SIZE] = { 0, };
312     uint8_t buf [TPM2_MAX_RESPONSE_SIZE] = { 0, };
313     size_t resp_size = sizeof (resp);
314     uint32_t timeout = TSS2_TCTI_TIMEOUT_BLOCK;
315     TSS2_TCTI_TABRMD_CONTEXT *tcti_ctx = (TSS2_TCTI_TABRMD_CONTEXT*)*state;
316 
317     /* prime mock stack for poll to indicate data is ready */
318     will_return (__wrap_poll, POLLIN);
319     will_return (__wrap_poll, 0);
320     will_return (__wrap_poll, 1);
321     /* mock stack required to extract the fd from the GSocketConnection */
322     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
323     will_return (__wrap_g_socket_get_fd, TEST_FD);
324 
325     /* mock stack required to extract GIStream & read data */
326     will_return (__wrap_g_io_stream_get_input_stream, TEST_CONNECTION);
327     will_return (__wrap_g_input_stream_read, resp_size);
328     will_return (__wrap_g_input_stream_read, buf);
329 
330     ret = tcti_tabrmd_read (tcti_ctx, resp, resp_size, timeout);
331     assert_int_equal (ret, TSS2_RC_SUCCESS);
332 }
333 static void
tcti_tabrmd_receive_null_context(void ** state)334 tcti_tabrmd_receive_null_context (void **state)
335 {
336     TSS2_RC rc;
337     UNUSED_PARAM(state);
338 
339     rc = tss2_tcti_tabrmd_receive (NULL, NULL, NULL, TSS2_TCTI_TIMEOUT_BLOCK);
340     assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
341 }
342 /*
343  * This test ensures that when passed a non-zero value in the 'size' param
344  * and a NULL response buffer the receive function will return the
345  * appropriate RC (this seems overly restrictive).
346  */
347 static void
tcti_tabrmd_receive_null_response(void ** state)348 tcti_tabrmd_receive_null_response (void **state)
349 {
350     TSS2_RC rc;
351     UNUSED_PARAM(state);
352     TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)1;
353     size_t size = 1;
354 
355     rc = tss2_tcti_tabrmd_receive (ctx, &size, NULL, TSS2_TCTI_TIMEOUT_BLOCK);
356     assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
357 }
358 /*
359  * Test that required checks are done on the MAGIC value in the context
360  * structure and that the appropriate RC is returned.
361  */
362 static void
tcti_tabrmd_receive_bad_magic(void ** state)363 tcti_tabrmd_receive_bad_magic (void **state)
364 {
365     TSS2_RC rc;
366     TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
367     TSS2_TCTI_CONTEXT_COMMON_V1 *common_ctx = (TSS2_TCTI_CONTEXT_COMMON_V1*)*state;
368     uint8_t buf[1] = { 0, };
369     size_t size = sizeof (buf);
370 
371     common_ctx->magic = 0;
372     rc = tss2_tcti_tabrmd_receive (ctx, &size, buf, TSS2_TCTI_TIMEOUT_BLOCK);
373     assert_int_equal (rc, TSS2_TCTI_RC_BAD_CONTEXT);
374 }
375 /* Same for the version field. */
376 static void
tcti_tabrmd_receive_bad_version(void ** state)377 tcti_tabrmd_receive_bad_version (void **state)
378 {
379     TSS2_RC rc;
380     TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
381     TSS2_TCTI_CONTEXT_COMMON_V1 *common_ctx = (TSS2_TCTI_CONTEXT_COMMON_V1*)*state;
382     uint8_t buf[1] = { 0, };
383     size_t size = sizeof (buf);
384 
385     common_ctx->version = 0;
386     rc = tss2_tcti_tabrmd_receive (ctx, &size, buf, TSS2_TCTI_TIMEOUT_BLOCK);
387     assert_int_equal (rc, TSS2_TCTI_RC_BAD_CONTEXT);
388 }
389 /*
390  * Test to be sure the 'receive' function is returning the right RC when
391  * the context is in the wrong state.
392  */
393 static void
tcti_tabrmd_receive_bad_state(void ** state)394 tcti_tabrmd_receive_bad_state (void **state)
395 {
396     TSS2_RC rc;
397     TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
398     uint8_t buf[1] = { 0, };
399     size_t size = sizeof (buf);
400 
401     rc = tss2_tcti_tabrmd_receive (ctx, &size, buf, TSS2_TCTI_TIMEOUT_BLOCK);
402     assert_int_equal (rc, TSS2_TCTI_RC_BAD_SEQUENCE);
403 }
404 /*
405  * Test that the 'receive' function returns the right RC when passed a
406  * invalid timeout value.
407  */
408 static void
tcti_tabrmd_receive_bad_timeout(void ** state)409 tcti_tabrmd_receive_bad_timeout (void **state)
410 {
411     TSS2_RC rc;
412     TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
413     uint8_t buf[1] = { 0, };
414     size_t size = sizeof (buf);
415 
416     rc = tss2_tcti_tabrmd_receive (ctx, &size, buf, -2);
417     assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
418 }
419 /*
420  * Test that the 'receive' funciton returns the rght RC when passed a
421  * buffer that is too small.
422  */
423 static void
tcti_tabrmd_receive_size_lt_header(void ** state)424 tcti_tabrmd_receive_size_lt_header (void **state)
425 {
426     TSS2_RC rc;
427     TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
428     uint8_t buf[1] = { 0, };
429     size_t size = sizeof (buf);
430 
431     rc = tss2_tcti_tabrmd_receive (ctx, &size, buf, TSS2_TCTI_TIMEOUT_BLOCK);
432     assert_int_equal (rc, TSS2_TCTI_RC_INSUFFICIENT_BUFFER);
433 }
434 /*
435  * Test that the 'receive' function handles errors returned by 'poll'
436  * correctly.
437  */
438 static void
tcti_tabrmd_receive_header_fail(void ** state)439 tcti_tabrmd_receive_header_fail (void **state)
440 {
441     TSS2_RC rc;
442     TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
443     size_t size = 0;
444 
445     /* mock stack required to extract the fd from the GSocketConnection */
446     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
447     will_return (__wrap_g_socket_get_fd, TEST_FD);
448 
449     /* prime mock stack for poll, will return 0 indicating timeout */
450     will_return (__wrap_poll, 0);
451     will_return (__wrap_poll, EINVAL);
452     will_return (__wrap_poll, -1);
453 
454     rc = tss2_tcti_tabrmd_receive (ctx, &size, NULL, TSS2_TCTI_TIMEOUT_BLOCK);
455     assert_int_equal (rc, TSS2_TCTI_RC_GENERAL_FAILURE);
456 }
457 /*
458  * This test causes the header to be read successfully, but the size field
459  * indicates a size < TPM_HEADER_SIZE which makes it impossible for us to
460  * get the rest of the buffer.
461  */
462 static void
tcti_tabrmd_receive_header_lt_expected(void ** state)463 tcti_tabrmd_receive_header_lt_expected (void **state)
464 {
465     TSS2_RC rc;
466     TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
467     uint8_t buf [TPM_HEADER_SIZE] = {
468         0x80, 0x02,
469         0x00, 0x00, 0x00, 0x01, /* invalid size < TPM_HEADER_SIZE */
470         0x00, 0x00, 0x00, 0x00,
471     };
472     size_t size = 0;
473 
474     /* mock stack required to extract the fd from the GSocketConnection */
475     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
476     will_return (__wrap_g_socket_get_fd, TEST_FD);
477     /* prime mock stack for poll to indicate data is ready */
478     will_return (__wrap_poll, POLLIN);
479     will_return (__wrap_poll, 0);
480     will_return (__wrap_poll, 1);
481     /* mock stack required to get 10 bytes back from the GInputStream */
482     will_return (__wrap_g_io_stream_get_input_stream, TEST_CONNECTION);
483     will_return (__wrap_g_input_stream_read, TPM_HEADER_SIZE);
484     will_return (__wrap_g_input_stream_read, buf);
485 
486     rc = tss2_tcti_tabrmd_receive (ctx, &size, NULL, TSS2_TCTI_TIMEOUT_BLOCK);
487     assert_int_equal (rc, TSS2_TCTI_RC_MALFORMED_RESPONSE);
488 }
489 /*
490  * This test covers a use case where the caller provides a NULL buffer to
491  * hold the response and a zero'd size parameter. This signals to the
492  * receive function that the caller wants to know how much space the
493  * response will require.
494  */
495 static void
tcti_tabrmd_receive_get_size(void ** state)496 tcti_tabrmd_receive_get_size (void **state)
497 {
498     TSS2_RC rc;
499     TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
500     uint8_t buf [TPM_HEADER_SIZE] = {
501         0x80, 0x02,
502         0x00, 0x00, 0x00, 0x0a, /* TPM_HEADER_SIZE -> resp is just header */
503         0x00, 0x00, 0x00, 0x00,
504     };
505     size_t size = 0;
506 
507     /* mock stack required to extract the fd from the GSocketConnection */
508     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
509     will_return (__wrap_g_socket_get_fd, TEST_FD);
510     /* prime mock stack for poll to indicate data is ready */
511     will_return (__wrap_poll, POLLIN);
512     will_return (__wrap_poll, 0);
513     will_return (__wrap_poll, 1);
514     /* mock stack required to get 10 bytes back from the GInputStream */
515     will_return (__wrap_g_io_stream_get_input_stream, TEST_CONNECTION);
516     will_return (__wrap_g_input_stream_read, TPM_HEADER_SIZE);
517     will_return (__wrap_g_input_stream_read, buf);
518 
519     rc = tss2_tcti_tabrmd_receive (ctx, &size, NULL, TSS2_TCTI_TIMEOUT_BLOCK);
520     assert_int_equal (rc, TSS2_RC_SUCCESS);
521     assert_int_equal (size, TPM_HEADER_SIZE);
522 }
523 /*
524  * This test ensures that a response from the TPM that is exactly 10
525  * bytes can be 'receive'd in a single call.
526  */
527 static void
tcti_tabrmd_receive_header_only(void ** state)528 tcti_tabrmd_receive_header_only (void **state)
529 {
530     TSS2_RC rc;
531     TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
532     uint8_t resp [TPM_HEADER_SIZE] = { 0, };
533     size_t resp_size = sizeof (resp);
534     uint8_t buf [TPM_HEADER_SIZE] = {
535         0x80, 0x02,
536         0x00, 0x00, 0x00, 0x0a, /* TPM_HEADER_SIZE -> resp is just header */
537         0x00, 0x00, 0x00, 0x00,
538     };
539 
540     /* mock stack required to extract the fd from the GSocketConnection */
541     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
542     will_return (__wrap_g_socket_get_fd, TEST_FD);
543     /* prime mock stack for poll to indicate data is ready */
544     will_return (__wrap_poll, POLLIN);
545     will_return (__wrap_poll, 0);
546     will_return (__wrap_poll, 1);
547     /* mock stack required to get 10 bytes back from the GInputStream */
548     will_return (__wrap_g_io_stream_get_input_stream, TEST_CONNECTION);
549     will_return (__wrap_g_input_stream_read, TPM_HEADER_SIZE);
550     will_return (__wrap_g_input_stream_read, buf);
551 
552     rc = tss2_tcti_tabrmd_receive (ctx, &resp_size, resp, TSS2_TCTI_TIMEOUT_BLOCK);
553     assert_int_equal (rc, TSS2_RC_SUCCESS);
554     assert_memory_equal (buf, resp, resp_size);
555 }
556 /*
557  * Receive response that is only a header in two reads. The first read will
558  * be a "short" read and we should get a response indicating that we need
559  * to try again.
560  */
561 #define FIRST_READ_SIZE 3
562 #define SECOND_READ_SIZE 7
563 static void
tcti_tabrmd_receive_header_only_retry(void ** state)564 tcti_tabrmd_receive_header_only_retry (void **state)
565 {
566     TSS2_RC rc;
567     TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
568     uint8_t resp [TPM_HEADER_SIZE] = { 0, };
569     size_t resp_size = sizeof (resp);
570     uint8_t buf [TPM_HEADER_SIZE] = {
571         0x80, 0x02,
572         0x00, 0x00, 0x00, 0x0a, /* TPM_HEADER_SIZE -> resp is just header */
573         0x00, 0x00, 0x00, 0x00,
574     };
575 
576     /* mock stack required to extract the fd from the GSocketConnection */
577     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
578     will_return (__wrap_g_socket_get_fd, TEST_FD);
579     /* prime mock stack for poll to indicate data is ready */
580     will_return (__wrap_poll, POLLIN);
581     will_return (__wrap_poll, 0);
582     will_return (__wrap_poll, 1);
583     /* mock stack required to get first bytes back from the GInputStream */
584     will_return (__wrap_g_io_stream_get_input_stream, TEST_CONNECTION);
585     will_return (__wrap_g_input_stream_read, FIRST_READ_SIZE);
586     will_return (__wrap_g_input_stream_read, buf);
587 
588     rc = tss2_tcti_tabrmd_receive (ctx, &resp_size, resp, TSS2_TCTI_TIMEOUT_BLOCK);
589     assert_int_equal (rc, TSS2_TCTI_RC_TRY_AGAIN);
590 
591     /* mock stack required to extract the fd from the GSocketConnection */
592     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
593     will_return (__wrap_g_socket_get_fd, TEST_FD);
594     /* prime mock stack for poll to indicate data is ready */
595     will_return (__wrap_poll, POLLIN);
596     will_return (__wrap_poll, 0);
597     will_return (__wrap_poll, 1);
598     /* mock stack required to get first bytes back from the GInputStream */
599     will_return (__wrap_g_io_stream_get_input_stream, TEST_CONNECTION);
600     will_return (__wrap_g_input_stream_read, SECOND_READ_SIZE);
601     will_return (__wrap_g_input_stream_read, &buf[FIRST_READ_SIZE]);
602 
603     rc = tss2_tcti_tabrmd_receive (ctx, &resp_size, resp, TSS2_TCTI_TIMEOUT_BLOCK);
604     assert_int_equal (rc, TSS2_RC_SUCCESS);
605     assert_memory_equal (buf, resp, resp_size);
606 }
607 /*
608  * This test implements a calling pattern referred to as "partial reads"
609  * in the system API implementation from tpm2-tss. It is also prescribed
610  * by the TCTI spec.
611  */
612 static void
tcti_tabrmd_receive_partial_reads(void ** state)613 tcti_tabrmd_receive_partial_reads (void **state)
614 {
615     TSS2_RC rc;
616     TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
617     uint8_t buf [] = {
618         0x80, 0x02,
619         0x00, 0x00, 0x00, 0x0e,
620         0xde, 0xad, 0xbe, 0xef,
621         0xca, 0xfe, 0xd0, 0x0d,
622     };
623     uint8_t resp [sizeof (buf)] = { 0, };
624     size_t resp_size = 0;
625 
626     /* mock stack required to extract the fd from the GSocketConnection */
627     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
628     will_return (__wrap_g_socket_get_fd, TEST_FD);
629     /* prime mock stack for poll to indicate data is ready */
630     will_return (__wrap_poll, POLLIN);
631     will_return (__wrap_poll, 0);
632     will_return (__wrap_poll, 1);
633     /* mock stack required to get 10 bytes back from the GInputStream */
634     will_return (__wrap_g_io_stream_get_input_stream, TEST_CONNECTION);
635     will_return (__wrap_g_input_stream_read, TPM_HEADER_SIZE);
636     will_return (__wrap_g_input_stream_read, buf);
637 
638     rc = tss2_tcti_tabrmd_receive (ctx,
639                                    &resp_size,
640                                    NULL,
641                                    TSS2_TCTI_TIMEOUT_BLOCK);
642     assert_int_equal (rc, TSS2_RC_SUCCESS);
643     assert_int_equal (resp_size, sizeof (buf));
644 
645     /* mock stack required to extract the fd from the GSocketConnection */
646     will_return (__wrap_g_socket_connection_get_socket, TEST_SOCKET);
647     will_return (__wrap_g_socket_get_fd, TEST_FD);
648     /* prime mock stack for poll to indicate data is ready */
649     will_return (__wrap_poll, POLLIN);
650     will_return (__wrap_poll, 0);
651     will_return (__wrap_poll, 1);
652     /* mock stack required to get 10 bytes back from the GInputStream */
653     will_return (__wrap_g_io_stream_get_input_stream, TEST_CONNECTION);
654     will_return (__wrap_g_input_stream_read, 4);
655     will_return (__wrap_g_input_stream_read, &buf[TPM_HEADER_SIZE]);
656 
657     rc = tss2_tcti_tabrmd_receive (ctx,
658                                    &resp_size,
659                                    resp,
660                                    TSS2_TCTI_TIMEOUT_BLOCK);
661     assert_int_equal (rc, TSS2_RC_SUCCESS);
662     assert_memory_equal (buf, resp, sizeof (buf));
663 }
664 
665 int
main(void)666 main (void)
667 {
668     const struct CMUnitTest tests[] = {
669         cmocka_unit_test (tcti_tabrmd_poll_fd_ready_pollin),
670         cmocka_unit_test (tcti_tabrmd_poll_fd_ready_pollpri),
671         cmocka_unit_test (tcti_tabrmd_poll_fd_ready_pollrdhup),
672         cmocka_unit_test (tcti_tabrmd_poll_timeout),
673         cmocka_unit_test (tcti_tabrmd_poll_error),
674         cmocka_unit_test_setup_teardown (tcti_tabrmd_read_poll_timeout,
675                                          tcti_tabrmd_setup,
676                                          tcti_tabrmd_teardown),
677         cmocka_unit_test_setup_teardown (tcti_tabrmd_read_poll_fail,
678                                          tcti_tabrmd_setup,
679                                          tcti_tabrmd_teardown),
680         cmocka_unit_test_setup_teardown (tcti_tabrmd_read_eof,
681                                          tcti_tabrmd_setup,
682                                          tcti_tabrmd_teardown),
683         cmocka_unit_test_setup_teardown (tcti_tabrmd_read_block_error,
684                                          tcti_tabrmd_setup,
685                                          tcti_tabrmd_teardown),
686         cmocka_unit_test_setup_teardown (tcti_tabrmd_read_short,
687                                          tcti_tabrmd_setup,
688                                          tcti_tabrmd_teardown),
689         cmocka_unit_test_setup_teardown (tcti_tabrmd_read_success,
690                                          tcti_tabrmd_setup,
691                                          tcti_tabrmd_teardown),
692         cmocka_unit_test (tcti_tabrmd_receive_null_context),
693         cmocka_unit_test (tcti_tabrmd_receive_null_response),
694         cmocka_unit_test_setup_teardown (tcti_tabrmd_receive_bad_magic,
695                                          tcti_tabrmd_setup,
696                                          tcti_tabrmd_teardown),
697         cmocka_unit_test_setup_teardown (tcti_tabrmd_receive_bad_version,
698                                          tcti_tabrmd_setup,
699                                          tcti_tabrmd_teardown),
700         cmocka_unit_test_setup_teardown (tcti_tabrmd_receive_bad_state,
701                                          tcti_tabrmd_setup,
702                                          tcti_tabrmd_teardown),
703         cmocka_unit_test_setup_teardown (tcti_tabrmd_receive_bad_timeout,
704                                          tcti_tabrmd_receive_setup,
705                                          tcti_tabrmd_teardown),
706         cmocka_unit_test_setup_teardown (tcti_tabrmd_receive_size_lt_header,
707                                          tcti_tabrmd_receive_setup,
708                                          tcti_tabrmd_teardown),
709         cmocka_unit_test_setup_teardown (tcti_tabrmd_receive_header_fail,
710                                          tcti_tabrmd_receive_setup,
711                                          tcti_tabrmd_teardown),
712         cmocka_unit_test_setup_teardown (tcti_tabrmd_receive_header_lt_expected,
713                                          tcti_tabrmd_receive_setup,
714                                          tcti_tabrmd_teardown),
715         cmocka_unit_test_setup_teardown (tcti_tabrmd_receive_get_size,
716                                          tcti_tabrmd_receive_setup,
717                                          tcti_tabrmd_teardown),
718         cmocka_unit_test_setup_teardown (tcti_tabrmd_receive_header_only,
719                                          tcti_tabrmd_receive_setup,
720                                          tcti_tabrmd_teardown),
721         cmocka_unit_test_setup_teardown (tcti_tabrmd_receive_header_only_retry,
722                                          tcti_tabrmd_receive_setup,
723                                          tcti_tabrmd_teardown),
724         cmocka_unit_test_setup_teardown (tcti_tabrmd_receive_partial_reads,
725                                          tcti_tabrmd_receive_setup,
726                                          tcti_tabrmd_teardown),
727     };
728     return cmocka_run_group_tests (tests, NULL, NULL);
729 }
730