/* SPDX-License-Identifier: BSD-2-Clause */
/***********************************************************************
 * Copyright (c) 2017-2018, Intel Corporation
 *
 * All rights reserved.
 ***********************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <poll.h>

#include <setjmp.h>
#include <cmocka.h>

#include "tss2_mu.h"
#include "tss2_tcti_device.h"

#include "tss2-tcti/tcti-common.h"
#include "tss2-tcti/tcti-device.h"

/*
 * Size of the TPM2 buffer used in these tests. In some cases this will be
 * the command sent (transmit tests) and in others it's used as the response
 * buffer returned by the TCTI. The only field used by the TCTI is the size
 * field.
 */
#define BUF_SIZE 20
static uint8_t tpm2_buf [BUF_SIZE] = {
    0x80, 0x02, /* TAG */
    0x00, 0x00, 0x00, 0x14, /* size (BUF_SIZE) */
    0x00, 0x00, 0x00, 0x00, /* rc (success) */
    0xde, 0xad, 0xbe, 0xef, /* junk data */
    0xca, 0xfe, 0xba, 0xbe,
    0xfe, 0xef
};
int
__real_open(const char *pathname, int flags, ...);
/* wrap function for open required to test init */
int
__wrap_open(const char *pathname, int flags, ...)
{
    const char* pathname_prefix_dev = "/dev";
    if (strncmp(pathname, pathname_prefix_dev, strlen(pathname_prefix_dev)) == 0) {
        return mock_type (int);
    } else {
        /* only mock opening of device files as the open() syscall is needed
           for code coverage reports as well */
        return __real_open(pathname, flags);
    }
}
/**
 * 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);
}
/* Test the failure of opening a specified device file */
static void
tcti_device_init_conf_fail (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);
    errno = ENOENT; /* No such file or directory */
    will_return (__wrap_open, -1);
    ret = Tss2_Tcti_Device_Init (ctx, &tcti_size, "/dev/nonexistent");
    assert_true (ret == TSS2_TCTI_RC_IO_ERROR);

    free(ctx);
}
/* Test the device file recognition if no config string was specified */
static void
tcti_device_init_conf_default_fail (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);
    errno = EACCES; /* Permission denied */
    will_return (__wrap_open, -1);
    will_return (__wrap_open, -1);
    ret = Tss2_Tcti_Device_Init (ctx, &tcti_size, NULL);
    assert_true (ret == TSS2_TCTI_RC_IO_ERROR);

    free(ctx);
}

/* Test the device file recognition if no config string was specified */
static void
tcti_device_init_conf_default_success (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);
    will_return (__wrap_open, 3);
    will_return (__wrap_write, 12);
    will_return (__wrap_write, tpm2_buf);
    will_return (__wrap_poll, 1);
    will_return (__wrap_read, 10);
    will_return (__wrap_read, tpm2_buf);
    will_return (__wrap_poll, 1);
    will_return (__wrap_read, 8);
    will_return (__wrap_read, tpm2_buf);
    ret = Tss2_Tcti_Device_Init (ctx, &tcti_size, NULL);
    assert_true (ret == TSS2_RC_SUCCESS);

    free(ctx);
}

/* 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)
{
    ssize_t ret = mock_type (ssize_t);
    uint8_t *buf_out = mock_type (uint8_t*);

    memcpy (buf_out, buffer, ret);
    return ret;
}

int
__wrap_poll (struct pollfd *fds, nfds_t nfds, int timeout)
{
    int ret = mock_type (int);

    fds->revents = fds->events;
    return ret;
}

/* 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);
    will_return (__wrap_open, 3);
    will_return (__wrap_write, 12);
    will_return (__wrap_write, tpm2_buf);
    will_return (__wrap_poll, 1);
    will_return (__wrap_read, 10);
    will_return (__wrap_read, tpm2_buf);
    will_return (__wrap_poll, 1);
    will_return (__wrap_read, 0);
    will_return (__wrap_read, tpm2_buf);
    will_return (__wrap_open, 3);
    ret = Tss2_Tcti_Device_Init (ctx, &tcti_size, "/dev/null");
    assert_true (ret == TSS2_RC_SUCCESS);

    *state = ctx;
    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;

}
/*
 * This test ensures that the GetPollHandles function in the device TCTI
 * returns the expected value. Since this TCTI does not support async I/O
 * on account of limitations in the kernel it just returns the
 * NOT_IMPLEMENTED response code.
 */
static void
tcti_device_get_poll_handles_test (void **state)
{
    TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
    size_t num_handles = 5;
    TSS2_TCTI_POLL_HANDLE handles [5] = { 0 };
    TSS2_RC rc;

    rc = Tss2_Tcti_GetPollHandles (ctx, handles, &num_handles);
    assert_int_equal (rc, TSS2_RC_SUCCESS);
    assert_int_equal (num_handles, 1);
}
/*
 */
static void
tcti_device_receive_null_size_test (void **state)
{
    TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
    TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
    TSS2_RC rc;

    /* Keep state machine check in `receive` from returning error. */
    tcti_common->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_success (void **state)
{
    TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
    TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
    TSS2_RC rc;
    /* output buffer for response */
    uint8_t buf_out [BUF_SIZE + 5] = { 0 };
    size_t size = BUF_SIZE + 5;

    /* Keep state machine check in `receive` from returning error. */
    tcti_common->state = TCTI_STATE_RECEIVE;
    will_return (__wrap_poll, 1);
    will_return (__wrap_read, BUF_SIZE);
    will_return (__wrap_read, tpm2_buf);
    rc = Tss2_Tcti_Receive (ctx,
                            &size,
                            buf_out,
                            TSS2_TCTI_TIMEOUT_BLOCK);
    assert_true (rc == TSS2_RC_SUCCESS);
    assert_int_equal (BUF_SIZE, size);
    assert_memory_equal (tpm2_buf, buf_out, size);
}
/*
 * Ensure that when the 'read' results in an EOF, we get a response code
 * indicating as much. EOF happens if / when the device driver kills our
 * connection.
 */
static void
tcti_device_receive_eof_test (void **state)
{
    TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
    TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
    TSS2_RC rc;
    /* output buffer for response */
    uint8_t buf_out [BUF_SIZE + 5] = { 0 };
    size_t size = BUF_SIZE + 5;

    /* Keep state machine check in `receive` from returning error. */
    tcti_common->state = TCTI_STATE_RECEIVE;
    will_return (__wrap_poll, 1);
    will_return (__wrap_read, 0);
    will_return (__wrap_read, tpm2_buf);
    rc = Tss2_Tcti_Receive (ctx,
                            &size,
                            buf_out,
                            TSS2_TCTI_TIMEOUT_BLOCK);
    assert_int_equal (rc, TSS2_TCTI_RC_NO_CONNECTION);
}
/*
 * This is a weird test: The device TCTI can't read the header for the
 * response buffer separately from the body. This means it can't know the size
 * of the response before reading the whole thing. In the event that the caller
 * provides a buffer that isn't large enough to hold the full response the TCTI
 * will just read as much data as the buffer will hold. Subsequent interactions
 * with the kernel driver will likely result in an error.
 */
static void
tcti_device_receive_buffer_lt_response (void **state)
{
    TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
    TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
    TSS2_RC rc;
    uint8_t buf_out [BUF_SIZE] = { 0 };
    /* set size to lt the size in the header of the TPM2 response buffer */
    size_t size = BUF_SIZE - 1;
    size_t small_size = TPM_HEADER_SIZE + 1;

    /* Keep state machine check in `receive` from returning error. */
    tcti_common->state = TCTI_STATE_RECEIVE;
    will_return (__wrap_poll, 1);
    will_return (__wrap_read, size);
    will_return (__wrap_read, tpm2_buf);
    rc = Tss2_Tcti_Receive (ctx,
                            &small_size,
                            buf_out,
                            TSS2_TCTI_TIMEOUT_BLOCK);
    assert_int_equal (rc, TSS2_TCTI_RC_GENERAL_FAILURE);
}
/*
 * 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)
{
    TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
    TSS2_RC rc;
    /* output buffer for response */
    uint8_t buf_out [BUF_SIZE] = { 0 };

    will_return (__wrap_write, BUF_SIZE);
    will_return (__wrap_write, buf_out);
    rc = Tss2_Tcti_Transmit (ctx,
                             BUF_SIZE,
                             tpm2_buf);
    assert_true (rc == TSS2_RC_SUCCESS);
    assert_memory_equal (tpm2_buf, buf_out, BUF_SIZE);
}
/*
 * A test case for a successful poll
 */
static void
tcti_device_poll_success (void **state)
{
    TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
    TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
    TSS2_RC rc;
    /* output buffer for response */
    uint8_t buf_out [BUF_SIZE] = { 0 };
    size_t size = BUF_SIZE;

    /* Keep state machine check in `receive` from returning error. */
    tcti_common->state = TCTI_STATE_RECEIVE;
    will_return (__wrap_poll, 1);
    will_return (__wrap_read, BUF_SIZE);
    will_return (__wrap_read, tpm2_buf);

    rc = Tss2_Tcti_Receive (ctx,
                            &size,
                            buf_out,
                            TSS2_TCTI_TIMEOUT_BLOCK);

    assert_true (rc == TSS2_RC_SUCCESS);
    assert_int_equal (BUF_SIZE, size);
    assert_memory_equal (tpm2_buf, buf_out, size);
}
/*
 * A test case for poll timeout
 */
static void
tcti_device_poll_timeout (void **state)
{
    TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
    TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
    TSS2_RC rc;
    /* output buffer for response */
    uint8_t buf_out [BUF_SIZE] = { 0 };
    size_t size = BUF_SIZE;

    /* Keep state machine check in `receive` from returning error. */
    tcti_common->state = TCTI_STATE_RECEIVE;
    will_return (__wrap_poll, 0);

    rc = Tss2_Tcti_Receive (ctx,
                            &size,
                            buf_out,
                            TSS2_TCTI_TIMEOUT_BLOCK);

    assert_true (rc == TSS2_TCTI_RC_TRY_AGAIN);
}
/*
 * A test case for poll io-error
 */
static void
tcti_device_poll_io_error (void **state)
{
    TSS2_TCTI_CONTEXT *ctx = (TSS2_TCTI_CONTEXT*)*state;
    TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_common_context_cast (ctx);
    TSS2_RC rc;
    /* output buffer for response */
    uint8_t buf_out [BUF_SIZE] = { 0 };
    size_t size = BUF_SIZE;

    /* Keep state machine check in `receive` from returning error. */
    tcti_common->state = TCTI_STATE_RECEIVE;
    will_return (__wrap_poll, -1);

    rc = Tss2_Tcti_Receive (ctx,
                            &size,
                            buf_out,
                            TSS2_TCTI_TIMEOUT_BLOCK);

    assert_true (rc == TSS2_TCTI_RC_IO_ERROR);
}

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(tcti_device_init_conf_fail),
        cmocka_unit_test(tcti_device_init_conf_default_fail),
        cmocka_unit_test(tcti_device_init_conf_default_success),
        cmocka_unit_test_setup_teardown (tcti_device_get_poll_handles_test,
                                         tcti_device_setup,
                                         tcti_device_teardown),
        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_success,
                                         tcti_device_setup,
                                         tcti_device_teardown),
        cmocka_unit_test_setup_teardown (tcti_device_receive_eof_test,
                                         tcti_device_setup,
                                         tcti_device_teardown),
        cmocka_unit_test_setup_teardown (tcti_device_receive_buffer_lt_response,
                                         tcti_device_setup,
                                         tcti_device_teardown),
        cmocka_unit_test_setup_teardown (tcti_device_transmit_success,
                                         tcti_device_setup,
                                         tcti_device_teardown),
        cmocka_unit_test_setup_teardown (tcti_device_poll_success,
                                         tcti_device_setup,
                                         tcti_device_teardown),
        cmocka_unit_test_setup_teardown (tcti_device_poll_timeout,
                                         tcti_device_setup,
                                         tcti_device_teardown),
        cmocka_unit_test_setup_teardown (tcti_device_poll_io_error,
                                         tcti_device_setup,
                                         tcti_device_teardown),
    };
    return cmocka_run_group_tests (tests, NULL, NULL);
}
