Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 1 | #include <inttypes.h> |
Philip Tricca | 09a5bcd | 2016-03-21 13:20:19 -0700 | [diff] [blame] | 2 | #include <stdbool.h> |
Philip Tricca | a7d2e2c | 2016-11-17 14:47:21 -0800 | [diff] [blame] | 3 | #include <stdio.h> |
Philip Tricca | 910f17c | 2018-03-15 12:38:37 -0700 | [diff] [blame] | 4 | #include <string.h> |
Philip Tricca | a7d2e2c | 2016-11-17 14:47:21 -0800 | [diff] [blame] | 5 | |
Philip Tricca | 09a5bcd | 2016-03-21 13:20:19 -0700 | [diff] [blame] | 6 | #include <setjmp.h> |
| 7 | #include <cmocka.h> |
Philip Tricca | b194be9 | 2016-03-15 13:27:09 -0700 | [diff] [blame] | 8 | |
Philip Tricca | 8ffd3c4 | 2018-03-09 16:27:24 -0800 | [diff] [blame] | 9 | #include "tss2_mu.h" |
| 10 | #include "tss2_tcti_device.h" |
Philip Tricca | b8584ac | 2018-03-10 17:02:30 -0800 | [diff] [blame] | 11 | #include "tss2-tcti/tcti.h" |
Philip Tricca | a7d2e2c | 2016-11-17 14:47:21 -0800 | [diff] [blame] | 12 | |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 13 | /* |
| 14 | * Size of the TPM2 buffer used in these tests. In some cases this will be |
| 15 | * the command sent (transmit tests) and in others it's used as the response |
| 16 | * buffer returned by the TCTI. The only field used by the TCTI is the size |
| 17 | * field. |
| 18 | */ |
| 19 | #define BUF_SIZE 20 |
| 20 | static uint8_t tpm2_buf [BUF_SIZE] = { |
| 21 | 0x80, 0x02, /* TAG */ |
| 22 | 0x00, 0x00, 0x00, 0x14, /* size (BUF_SIZE) */ |
| 23 | 0x00, 0x00, 0x00, 0x00, /* rc (success) */ |
| 24 | 0xde, 0xad, 0xbe, 0xef, /* junk data */ |
| 25 | 0xca, 0xfe, 0xba, 0xbe, |
| 26 | 0xfe, 0xef |
| 27 | }; |
Philip Tricca | 467d63b | 2016-11-17 18:56:41 -0800 | [diff] [blame] | 28 | /** |
| 29 | * When passed all NULL values ensure that we get back the expected RC |
| 30 | * indicating bad values. |
| 31 | */ |
| 32 | static void |
| 33 | tcti_device_init_all_null_test (void **state) |
| 34 | { |
| 35 | TSS2_RC rc; |
| 36 | |
Philip Tricca | 1ae4cff | 2018-01-19 14:41:57 -0800 | [diff] [blame] | 37 | rc = Tss2_Tcti_Device_Init (NULL, NULL, NULL); |
Philip Tricca | 467d63b | 2016-11-17 18:56:41 -0800 | [diff] [blame] | 38 | assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE); |
| 39 | } |
Philip Tricca | b194be9 | 2016-03-15 13:27:09 -0700 | [diff] [blame] | 40 | /* Determine the size of a TCTI context structure. Requires calling the |
| 41 | * initialization function for the device TCTI with the first parameter |
| 42 | * (the TCTI context) NULL. |
| 43 | */ |
Philip Tricca | ae884f5 | 2016-11-17 14:54:56 -0800 | [diff] [blame] | 44 | static void |
| 45 | tcti_device_init_size_test (void **state) |
Philip Tricca | b194be9 | 2016-03-15 13:27:09 -0700 | [diff] [blame] | 46 | { |
Philip Tricca | b194be9 | 2016-03-15 13:27:09 -0700 | [diff] [blame] | 47 | size_t tcti_size = 0; |
| 48 | TSS2_RC ret = TSS2_RC_SUCCESS; |
| 49 | |
Philip Tricca | 1ae4cff | 2018-01-19 14:41:57 -0800 | [diff] [blame] | 50 | ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL); |
Philip Tricca | ae884f5 | 2016-11-17 14:54:56 -0800 | [diff] [blame] | 51 | assert_int_equal (ret, TSS2_RC_SUCCESS); |
Philip Tricca | b194be9 | 2016-03-15 13:27:09 -0700 | [diff] [blame] | 52 | } |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 53 | /* wrap functions for read & write required to test receive / transmit */ |
| 54 | ssize_t |
Philip Tricca | 7a10ee3 | 2018-03-06 12:48:39 -0800 | [diff] [blame] | 55 | __wrap_read (int fd, void *buf, size_t count) |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 56 | { |
Philip Tricca | 7a10ee3 | 2018-03-06 12:48:39 -0800 | [diff] [blame] | 57 | ssize_t ret = mock_type (ssize_t); |
| 58 | uint8_t *buf_in = mock_type (uint8_t*); |
| 59 | |
| 60 | memcpy (buf, buf_in, ret); |
| 61 | return ret; |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 62 | } |
| 63 | ssize_t |
| 64 | __wrap_write (int fd, const void *buffer, size_t buffer_size) |
| 65 | { |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 66 | ssize_t ret = mock_type (ssize_t); |
| 67 | uint8_t *buf_out = mock_type (uint8_t*); |
| 68 | |
| 69 | memcpy (buf_out, buffer, ret); |
| 70 | return ret; |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 71 | } |
| 72 | |
| 73 | typedef struct { |
| 74 | TSS2_TCTI_CONTEXT *ctx; |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 75 | size_t buffer_size; |
| 76 | size_t data_size; |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 77 | uint8_t buffer [TPM_HEADER_SIZE * 2]; |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 78 | } data_t; |
| 79 | /* Setup functions to create the context for the device TCTI */ |
Philip Tricca | 25789b2 | 2018-03-07 15:23:47 -0800 | [diff] [blame] | 80 | static int |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 81 | tcti_device_setup (void **state) |
| 82 | { |
| 83 | size_t tcti_size = 0; |
| 84 | TSS2_RC ret = TSS2_RC_SUCCESS; |
| 85 | TSS2_TCTI_CONTEXT *ctx = NULL; |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 86 | |
Philip Tricca | 1ae4cff | 2018-01-19 14:41:57 -0800 | [diff] [blame] | 87 | ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL); |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 88 | assert_true (ret == TSS2_RC_SUCCESS); |
| 89 | ctx = calloc (1, tcti_size); |
| 90 | assert_non_null (ctx); |
Philip Tricca | 1ae4cff | 2018-01-19 14:41:57 -0800 | [diff] [blame] | 91 | ret = Tss2_Tcti_Device_Init (ctx, 0, "/dev/null"); |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 92 | assert_true (ret == TSS2_RC_SUCCESS); |
Philip Tricca | 25789b2 | 2018-03-07 15:23:47 -0800 | [diff] [blame] | 93 | |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 94 | *state = ctx; |
Philip Tricca | 25789b2 | 2018-03-07 15:23:47 -0800 | [diff] [blame] | 95 | return 0; |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 96 | } |
| 97 | |
Tadeusz Struk | 2147c49 | 2017-08-09 13:40:31 -0700 | [diff] [blame] | 98 | static int |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 99 | tcti_device_teardown (void **state) |
| 100 | { |
Philip Tricca | 25789b2 | 2018-03-07 15:23:47 -0800 | [diff] [blame] | 101 | TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state; |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 102 | |
Andreas Fuchs | 930b5c1 | 2017-11-20 11:28:57 +0100 | [diff] [blame] | 103 | Tss2_Tcti_Finalize (ctx); |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 104 | free (ctx); |
Philip Tricca | 25789b2 | 2018-03-07 15:23:47 -0800 | [diff] [blame] | 105 | |
Tadeusz Struk | 2147c49 | 2017-08-09 13:40:31 -0700 | [diff] [blame] | 106 | return 0; |
Philip Tricca | 25789b2 | 2018-03-07 15:23:47 -0800 | [diff] [blame] | 107 | |
| 108 | } |
Philip Tricca | 25789b2 | 2018-03-07 15:23:47 -0800 | [diff] [blame] | 109 | /* |
| 110 | */ |
| 111 | static void |
| 112 | tcti_device_receive_null_size_test (void **state) |
| 113 | { |
| 114 | TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state; |
| 115 | TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (ctx); |
| 116 | TSS2_RC rc; |
| 117 | |
| 118 | /* Keep state machine check in `receive` from returning error. */ |
| 119 | tcti_intel->state = TCTI_STATE_RECEIVE; |
| 120 | rc = Tss2_Tcti_Receive (ctx, |
| 121 | NULL, /* NULL 'size' parameter */ |
| 122 | NULL, |
| 123 | TSS2_TCTI_TIMEOUT_BLOCK); |
| 124 | assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE); |
| 125 | rc = Tss2_Tcti_Receive (ctx, |
| 126 | NULL, /* NULL 'size' parameter */ |
| 127 | (uint8_t*)1, /* non-NULL buffer */ |
| 128 | TSS2_TCTI_TIMEOUT_BLOCK); |
| 129 | assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE); |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 130 | } |
| 131 | /* |
| 132 | * A test case for a successful call to the receive function. This requires |
| 133 | * that the context and the command buffer be valid (including the size |
| 134 | * field being set appropriately). The result should be an RC indicating |
| 135 | * success and the size parameter be updated to reflect the size of the |
| 136 | * data received. |
| 137 | */ |
| 138 | static void |
Philip Tricca | 7a10ee3 | 2018-03-06 12:48:39 -0800 | [diff] [blame] | 139 | tcti_device_receive_one_call_success (void **state) |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 140 | { |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 141 | TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state; |
| 142 | TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (ctx); |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 143 | TSS2_RC rc; |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 144 | /* output buffer for response */ |
| 145 | uint8_t buf_out [BUF_SIZE + 5] = { 0 }; |
| 146 | size_t size = BUF_SIZE + 5; |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 147 | |
Philip Tricca | fa14abe | 2018-03-05 21:14:54 -0800 | [diff] [blame] | 148 | /* Keep state machine check in `receive` from returning error. */ |
| 149 | tcti_intel->state = TCTI_STATE_RECEIVE; |
Philip Tricca | 7a10ee3 | 2018-03-06 12:48:39 -0800 | [diff] [blame] | 150 | will_return (__wrap_read, TPM_HEADER_SIZE); |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 151 | will_return (__wrap_read, tpm2_buf); |
| 152 | will_return (__wrap_read, BUF_SIZE - TPM_HEADER_SIZE); |
| 153 | will_return (__wrap_read, &tpm2_buf [TPM_HEADER_SIZE]); |
| 154 | rc = Tss2_Tcti_Receive (ctx, |
| 155 | &size, |
| 156 | buf_out, |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 157 | TSS2_TCTI_TIMEOUT_BLOCK); |
| 158 | assert_true (rc == TSS2_RC_SUCCESS); |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 159 | assert_int_equal (BUF_SIZE, size); |
| 160 | assert_memory_equal (tpm2_buf, buf_out, size); |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 161 | } |
Philip Tricca | 7a10ee3 | 2018-03-06 12:48:39 -0800 | [diff] [blame] | 162 | static void |
| 163 | tcti_device_receive_two_call_success (void **state) |
| 164 | { |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 165 | TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state; |
| 166 | TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (ctx); |
Philip Tricca | 7a10ee3 | 2018-03-06 12:48:39 -0800 | [diff] [blame] | 167 | TSS2_RC rc; |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 168 | /* output buffer for response */ |
| 169 | uint8_t buf_out [BUF_SIZE + 5] = { 0 }; |
Philip Tricca | 7a10ee3 | 2018-03-06 12:48:39 -0800 | [diff] [blame] | 170 | size_t size = 0; |
| 171 | |
| 172 | /* Keep state machine check in `receive` from returning error. */ |
| 173 | tcti_intel->state = TCTI_STATE_RECEIVE; |
| 174 | will_return (__wrap_read, TPM_HEADER_SIZE); |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 175 | will_return (__wrap_read, tpm2_buf); |
| 176 | will_return (__wrap_read, BUF_SIZE - TPM_HEADER_SIZE); |
| 177 | will_return (__wrap_read, &tpm2_buf [TPM_HEADER_SIZE]); |
| 178 | rc = Tss2_Tcti_Receive (ctx, |
Philip Tricca | 7a10ee3 | 2018-03-06 12:48:39 -0800 | [diff] [blame] | 179 | &size, |
| 180 | NULL, |
| 181 | TSS2_TCTI_TIMEOUT_BLOCK); |
Philip Tricca | 7a10ee3 | 2018-03-06 12:48:39 -0800 | [diff] [blame] | 182 | assert_int_equal (rc, TSS2_RC_SUCCESS); |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 183 | assert_int_equal (size, BUF_SIZE); |
| 184 | assert_true (size < BUF_SIZE + 5); |
| 185 | rc = Tss2_Tcti_Receive (ctx, |
| 186 | &size, |
| 187 | buf_out, |
Philip Tricca | 7a10ee3 | 2018-03-06 12:48:39 -0800 | [diff] [blame] | 188 | TSS2_TCTI_TIMEOUT_BLOCK); |
| 189 | assert_true (rc == TSS2_RC_SUCCESS); |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 190 | assert_int_equal (size, BUF_SIZE); |
| 191 | assert_memory_equal (tpm2_buf, buf_out, size); |
Philip Tricca | 7a10ee3 | 2018-03-06 12:48:39 -0800 | [diff] [blame] | 192 | } |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 193 | /* |
| 194 | * A test case for a successful call to the transmit function. This requires |
| 195 | * that the context and the cmmand buffer be valid. The only indication of |
| 196 | * success is the RC. |
| 197 | */ |
| 198 | static void |
| 199 | tcti_device_transmit_success (void **state) |
| 200 | { |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 201 | TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state; |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 202 | TSS2_RC rc; |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 203 | /* output buffer for response */ |
| 204 | uint8_t buf_out [BUF_SIZE] = { 0 }; |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 205 | |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 206 | will_return (__wrap_write, BUF_SIZE); |
| 207 | will_return (__wrap_write, buf_out); |
| 208 | rc = Tss2_Tcti_Transmit (ctx, |
| 209 | BUF_SIZE, |
| 210 | tpm2_buf); |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 211 | assert_true (rc == TSS2_RC_SUCCESS); |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 212 | assert_memory_equal (tpm2_buf, buf_out, BUF_SIZE); |
Philip Tricca | 8e5afda | 2017-03-14 09:29:54 -0700 | [diff] [blame] | 213 | } |
Philip Tricca | a7d2e2c | 2016-11-17 14:47:21 -0800 | [diff] [blame] | 214 | |
Philip Tricca | a7d2e2c | 2016-11-17 14:47:21 -0800 | [diff] [blame] | 215 | int |
| 216 | main(int argc, char* argv[]) |
| 217 | { |
Tadeusz Struk | 2147c49 | 2017-08-09 13:40:31 -0700 | [diff] [blame] | 218 | const struct CMUnitTest tests[] = { |
| 219 | cmocka_unit_test (tcti_device_init_all_null_test), |
| 220 | cmocka_unit_test(tcti_device_init_size_test), |
Philip Tricca | 25789b2 | 2018-03-07 15:23:47 -0800 | [diff] [blame] | 221 | cmocka_unit_test_setup_teardown (tcti_device_receive_null_size_test, |
| 222 | tcti_device_setup, |
| 223 | tcti_device_teardown), |
Philip Tricca | 7a10ee3 | 2018-03-06 12:48:39 -0800 | [diff] [blame] | 224 | cmocka_unit_test_setup_teardown (tcti_device_receive_one_call_success, |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 225 | tcti_device_setup, |
| 226 | tcti_device_teardown), |
Philip Tricca | 7a10ee3 | 2018-03-06 12:48:39 -0800 | [diff] [blame] | 227 | cmocka_unit_test_setup_teardown (tcti_device_receive_two_call_success, |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 228 | tcti_device_setup, |
| 229 | tcti_device_teardown), |
Tadeusz Struk | 2147c49 | 2017-08-09 13:40:31 -0700 | [diff] [blame] | 230 | cmocka_unit_test_setup_teardown (tcti_device_transmit_success, |
Philip Tricca | 0b87044 | 2018-03-26 14:27:28 -0700 | [diff] [blame^] | 231 | tcti_device_setup, |
| 232 | tcti_device_teardown), |
Philip Tricca | a7d2e2c | 2016-11-17 14:47:21 -0800 | [diff] [blame] | 233 | }; |
Tadeusz Struk | 2147c49 | 2017-08-09 13:40:31 -0700 | [diff] [blame] | 234 | return cmocka_run_group_tests (tests, NULL, NULL); |
Philip Tricca | a7d2e2c | 2016-11-17 14:47:21 -0800 | [diff] [blame] | 235 | } |