blob: 14c950947929bb22963fcc553a08db6fd263bc93 [file] [log] [blame]
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <setjmp.h>
#include <cmocka.h>
#include "tss2_mu.h"
#include "tss2_tcti_device.h"
#include "tcti/tcti.h"
/**
* When passed all NULL values ensure that we get back the expected RC
* indicating bad values.
*/
static void
tcti_device_init_all_null_test (void **state)
{
TSS2_RC rc;
rc = Tss2_Tcti_Device_Init (NULL, NULL, NULL);
assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE);
}
/* Determine the size of a TCTI context structure. Requires calling the
* initialization function for the device TCTI with the first parameter
* (the TCTI context) NULL.
*/
static void
tcti_device_init_size_test (void **state)
{
size_t tcti_size = 0;
TSS2_RC ret = TSS2_RC_SUCCESS;
ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL);
assert_int_equal (ret, TSS2_RC_SUCCESS);
}
/* wrap functions for read & write required to test receive / transmit */
ssize_t
__wrap_read (int fd, void *buf, size_t count)
{
ssize_t ret = mock_type (ssize_t);
uint8_t *buf_in = mock_type (uint8_t*);
memcpy (buf, buf_in, ret);
return ret;
}
ssize_t
__wrap_write (int fd, const void *buffer, size_t buffer_size)
{
return mock_type (ssize_t);
}
typedef struct {
TSS2_TCTI_CONTEXT *ctx;
uint8_t *buffer;
size_t buffer_size;
size_t data_size;
} data_t;
/* Setup functions to create the context for the device TCTI */
static int
tcti_device_setup (void **state)
{
size_t tcti_size = 0;
TSS2_RC ret = TSS2_RC_SUCCESS;
TSS2_TCTI_CONTEXT *ctx = NULL;
ret = Tss2_Tcti_Device_Init (NULL, &tcti_size, NULL);
assert_true (ret == TSS2_RC_SUCCESS);
ctx = calloc (1, tcti_size);
assert_non_null (ctx);
ret = Tss2_Tcti_Device_Init (ctx, 0, "/dev/null");
assert_true (ret == TSS2_RC_SUCCESS);
*state = ctx;
return 0;
}
static int
tcti_device_setup_with_command (void **state)
{
TSS2_RC rc;
data_t *data;
size_t index = 0;
data = malloc (sizeof (data_t));
assert_non_null (data);
tcti_device_setup ((void**)&data->ctx);
data->buffer_size = 1024;
data->data_size = 512;
data->buffer = malloc (data->buffer_size);
rc = Tss2_MU_TPM2_ST_Marshal (TPM2_ST_NO_SESSIONS, data->buffer, data->buffer_size, &index);
assert_true (rc == TSS2_RC_SUCCESS);
rc = Tss2_MU_UINT32_Marshal (data->data_size, data->buffer, data->buffer_size, &index);
assert_true (rc == TSS2_RC_SUCCESS);
rc = Tss2_MU_TPM2_CC_Marshal (TPM2_CC_Create, data->buffer, data->buffer_size, &index);
assert_true (rc == TSS2_RC_SUCCESS);
*state = data;
return 0;
}
static int
tcti_device_teardown (void **state)
{
TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
Tss2_Tcti_Finalize (ctx);
free (ctx);
return 0;
}
static int
tcti_device_teardown_with_data (void **state)
{
data_t *data = *state;
tcti_device_teardown ((void**)&data->ctx);
free (data);
return 0;
}
/*
*/
static void
tcti_device_receive_null_size_test (void **state)
{
TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (ctx);
TSS2_RC rc;
/* Keep state machine check in `receive` from returning error. */
tcti_intel->state = TCTI_STATE_RECEIVE;
rc = Tss2_Tcti_Receive (ctx,
NULL, /* NULL 'size' parameter */
NULL,
TSS2_TCTI_TIMEOUT_BLOCK);
assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
rc = Tss2_Tcti_Receive (ctx,
NULL, /* NULL 'size' parameter */
(uint8_t*)1, /* non-NULL buffer */
TSS2_TCTI_TIMEOUT_BLOCK);
assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
}
/*
* A test case for a successful call to the receive function. This requires
* that the context and the command buffer be valid (including the size
* field being set appropriately). The result should be an RC indicating
* success and the size parameter be updated to reflect the size of the
* data received.
*/
static void
tcti_device_receive_one_call_success (void **state)
{
data_t *data = *state;
TSS2_RC rc;
TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (data->ctx);
/* Keep state machine check in `receive` from returning error. */
tcti_intel->state = TCTI_STATE_RECEIVE;
will_return (__wrap_read, TPM_HEADER_SIZE);
will_return (__wrap_read, data->buffer);
will_return (__wrap_read, data->data_size - TPM_HEADER_SIZE);
will_return (__wrap_read, &data->buffer [TPM_HEADER_SIZE]);
rc = Tss2_Tcti_Receive (data->ctx,
&data->buffer_size,
data->buffer,
TSS2_TCTI_TIMEOUT_BLOCK);
assert_true (rc == TSS2_RC_SUCCESS);
assert_int_equal (data->data_size, data->buffer_size);
}
static void
tcti_device_receive_two_call_success (void **state)
{
data_t *data = *state;
TSS2_RC rc;
TSS2_TCTI_CONTEXT_INTEL *tcti_intel = tcti_context_intel_cast (data->ctx);
size_t size = 0;
/* Keep state machine check in `receive` from returning error. */
tcti_intel->state = TCTI_STATE_RECEIVE;
will_return (__wrap_read, TPM_HEADER_SIZE);
will_return (__wrap_read, data->buffer);
will_return (__wrap_read, data->data_size - TPM_HEADER_SIZE);
will_return (__wrap_read, &data->buffer [TPM_HEADER_SIZE]);
rc = Tss2_Tcti_Receive (data->ctx,
&size,
NULL,
TSS2_TCTI_TIMEOUT_BLOCK);
printf ("got size: %zd", size);
assert_int_equal (size, data->data_size);
assert_int_equal (rc, TSS2_RC_SUCCESS);
rc = Tss2_Tcti_Receive (data->ctx,
&data->buffer_size,
data->buffer,
TSS2_TCTI_TIMEOUT_BLOCK);
assert_true (rc == TSS2_RC_SUCCESS);
}
/*
* A test case for a successful call to the transmit function. This requires
* that the context and the cmmand buffer be valid. The only indication of
* success is the RC.
*/
static void
tcti_device_transmit_success (void **state)
{
data_t *data = *state;
TSS2_RC rc;
will_return (__wrap_write, data->buffer_size);
rc = Tss2_Tcti_Transmit (data->ctx,
data->buffer_size,
data->buffer);
assert_true (rc == TSS2_RC_SUCCESS);
}
int
main(int argc, char* argv[])
{
const struct CMUnitTest tests[] = {
cmocka_unit_test (tcti_device_init_all_null_test),
cmocka_unit_test(tcti_device_init_size_test),
cmocka_unit_test_setup_teardown (tcti_device_receive_null_size_test,
tcti_device_setup,
tcti_device_teardown),
cmocka_unit_test_setup_teardown (tcti_device_receive_one_call_success,
tcti_device_setup_with_command,
tcti_device_teardown),
cmocka_unit_test_setup_teardown (tcti_device_receive_two_call_success,
tcti_device_setup_with_command,
tcti_device_teardown_with_data),
cmocka_unit_test_setup_teardown (tcti_device_transmit_success,
tcti_device_setup_with_command,
tcti_device_teardown_with_data),
};
return cmocka_run_group_tests (tests, NULL, NULL);
}