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