123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- /* SPDX-License-Identifier: BSD-2-Clause */
- /*******************************************************************************
- * Copyright 2017, Fraunhofer SIT sponsored by Infineon Technologies AG
- * All rights reserved.
- *******************************************************************************/
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <stdbool.h>
- #include <stdlib.h>
- #include <string.h>
- #include "tss2_esys.h"
- #include "test-esys.h"
- #include "test-options.h"
- #include "context-util.h"
- #include "tss2-esys/esys_int.h"
- #define LOGMODULE test
- #include "util/log.h"
- /** Define a proxy tcti that returns yielded on every second invocation
- * thus the corresponding handling code in ESYS can be tested.
- * The first invocation will be Tss2_Sys_StartUp.
- */
- TSS2_RC
- (*transmit_hook) (const uint8_t *command_buffer, size_t command_size) = NULL;
- #define TCTI_PROXY_MAGIC 0x5250584f0a000000ULL /* 'PROXY\0\0\0' */
- #define TCTI_PROXY_VERSION 0x1
- enum state {
- forwarding,
- intercepting
- };
- typedef struct {
- uint64_t magic;
- uint32_t version;
- TSS2_TCTI_TRANSMIT_FCN transmit;
- TSS2_TCTI_RECEIVE_FCN receive;
- TSS2_RC (*finalize) (TSS2_TCTI_CONTEXT *tctiContext);
- TSS2_RC (*cancel) (TSS2_TCTI_CONTEXT *tctiContext);
- TSS2_RC (*getPollHandles) (TSS2_TCTI_CONTEXT *tctiContext,
- TSS2_TCTI_POLL_HANDLE *handles, size_t *num_handles);
- TSS2_RC (*setLocality) (TSS2_TCTI_CONTEXT *tctiContext, uint8_t locality);
- TSS2_TCTI_CONTEXT *tctiInner;
- enum state state;
- } TSS2_TCTI_CONTEXT_PROXY;
- static TSS2_TCTI_CONTEXT_PROXY*
- tcti_proxy_cast (TSS2_TCTI_CONTEXT *ctx)
- {
- TSS2_TCTI_CONTEXT_PROXY *ctxi = (TSS2_TCTI_CONTEXT_PROXY*)ctx;
- if (ctxi == NULL || ctxi->magic != TCTI_PROXY_MAGIC) {
- LOG_ERROR("Bad tcti passed.");
- return NULL;
- }
- return ctxi;
- }
- static TSS2_RC
- tcti_proxy_transmit(
- TSS2_TCTI_CONTEXT *tctiContext,
- size_t command_size,
- const uint8_t *command_buffer
- )
- {
- TSS2_RC rval;
- TSS2_TCTI_CONTEXT_PROXY *tcti_proxy = tcti_proxy_cast(tctiContext);
- if (tcti_proxy->state == intercepting) {
- return TSS2_RC_SUCCESS;
- }
- if (transmit_hook != NULL) {
- rval = transmit_hook(command_buffer, command_size);
- if (rval != TSS2_RC_SUCCESS) {
- LOG_ERROR("transmit hook requested error");
- return rval;
- }
- }
- rval = Tss2_Tcti_Transmit(tcti_proxy->tctiInner, command_size,
- command_buffer);
- if (rval != TSS2_RC_SUCCESS) {
- LOG_ERROR("Calling TCTI Transmit");
- return rval;
- }
- return rval;
- }
- uint8_t yielded_response[] = {
- 0x80, 0x01, /* TPM_ST_NO_SESSION */
- 0x00, 0x00, 0x00, 0x0A, /* Response Size 10 */
- 0x00, 0x00, 0x09, 0x08 /* TPM_RC_YIELDED */
- };
- static TSS2_RC
- tcti_proxy_receive(
- TSS2_TCTI_CONTEXT *tctiContext,
- size_t *response_size,
- uint8_t *response_buffer,
- int32_t timeout
- )
- {
- TSS2_RC rval;
- TSS2_TCTI_CONTEXT_PROXY *tcti_proxy = tcti_proxy_cast(tctiContext);
- if (tcti_proxy->state == intercepting) {
- *response_size = sizeof(yielded_response);
- if (response_buffer != NULL) {
- memcpy(response_buffer, &yielded_response[0], sizeof(yielded_response));
- tcti_proxy->state = forwarding;
- }
- return TSS2_RC_SUCCESS;
- }
- rval = Tss2_Tcti_Receive(tcti_proxy->tctiInner, response_size,
- response_buffer, timeout);
- if (rval != TSS2_RC_SUCCESS) {
- LOG_ERROR("Calling TCTI Transmit");
- return rval;
- }
- /* First read with response buffer == NULL is to get the size of the
- * response. The subsequent read needs to be forwarded also */
- if (response_buffer != NULL)
- tcti_proxy->state = intercepting;
- return rval;
- }
- static void
- tcti_proxy_finalize(
- TSS2_TCTI_CONTEXT *tctiContext)
- {
- memset(tctiContext, 0, sizeof(TSS2_TCTI_CONTEXT_PROXY));
- }
- static TSS2_RC
- tcti_proxy_initialize(
- TSS2_TCTI_CONTEXT *tctiContext,
- size_t *contextSize,
- TSS2_TCTI_CONTEXT *tctiInner)
- {
- TSS2_TCTI_CONTEXT_PROXY *tcti_proxy =
- (TSS2_TCTI_CONTEXT_PROXY*) tctiContext;
- if (tctiContext == NULL && contextSize == NULL) {
- return TSS2_TCTI_RC_BAD_VALUE;
- } else if (tctiContext == NULL) {
- *contextSize = sizeof(*tcti_proxy);
- return TSS2_RC_SUCCESS;
- }
- /* Init TCTI context */
- memset(tcti_proxy, 0, sizeof(*tcti_proxy));
- TSS2_TCTI_MAGIC (tctiContext) = TCTI_PROXY_MAGIC;
- TSS2_TCTI_VERSION (tctiContext) = TCTI_PROXY_VERSION;
- TSS2_TCTI_TRANSMIT (tctiContext) = tcti_proxy_transmit;
- TSS2_TCTI_RECEIVE (tctiContext) = tcti_proxy_receive;
- TSS2_TCTI_FINALIZE (tctiContext) = tcti_proxy_finalize;
- TSS2_TCTI_CANCEL (tctiContext) = NULL;
- TSS2_TCTI_GET_POLL_HANDLES (tctiContext) = NULL;
- TSS2_TCTI_SET_LOCALITY (tctiContext) = NULL;
- tcti_proxy->tctiInner = tctiInner;
- tcti_proxy->state = forwarding;
- return TSS2_RC_SUCCESS;
- }
- /**
- * This program is a template for integration tests (ones that use the TCTI
- * and the ESYS contexts / API directly). It does nothing more than parsing
- * command line options that allow the caller (likely a script) to specify
- * which TCTI to use for the test.
- */
- int
- main(int argc, char *argv[])
- {
- TSS2_RC rc;
- size_t tcti_size;
- TSS2_TCTI_CONTEXT *tcti_context;
- TSS2_TCTI_CONTEXT *tcti_inner;
- ESYS_CONTEXT *esys_context;
- TSS2_ABI_VERSION abiVersion =
- { TSSWG_INTEROP, TSS_SAPI_FIRST_FAMILY, TSS_SAPI_FIRST_LEVEL,
- TSS_SAPI_FIRST_VERSION };
- int ret;
- test_opts_t opts = {
- .tcti_type = TCTI_DEFAULT,
- .device_file = DEVICE_PATH_DEFAULT,
- .socket_address = HOSTNAME_DEFAULT,
- .socket_port = PORT_DEFAULT,
- };
- get_test_opts_from_env(&opts);
- if (sanity_check_test_opts(&opts) != 0) {
- LOG_ERROR("TPM Startup FAILED! Error in sanity check");
- exit(1);
- }
- tcti_inner = tcti_init_from_opts(&opts);
- if (tcti_inner == NULL) {
- LOG_ERROR("TPM Startup FAILED! Error tcti init");
- exit(1);
- }
- rc = tcti_proxy_initialize(NULL, &tcti_size, tcti_inner);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR("tcti initialization FAILED! Response Code : 0x%x", rc);
- return 1;
- }
- tcti_context = calloc(1, tcti_size);
- if (tcti_inner == NULL) {
- LOG_ERROR("TPM Startup FAILED! Error tcti init");
- exit(1);
- }
- rc = tcti_proxy_initialize(tcti_context, &tcti_size, tcti_inner);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR("tcti initialization FAILED! Response Code : 0x%x", rc);
- return 1;
- }
- rc = Esys_Initialize(&esys_context, tcti_context, &abiVersion);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR("Esys_Initialize FAILED! Response Code : 0x%x", rc);
- return 1;
- }
- rc = Esys_Startup(esys_context, TPM2_SU_CLEAR);
- if (rc != TSS2_RC_SUCCESS && rc != TPM2_RC_INITIALIZE) {
- LOG_ERROR("Esys_Startup FAILED! Response Code : 0x%x", rc);
- return 1;
- }
- rc = Esys_SetTimeout(esys_context, TSS2_TCTI_TIMEOUT_BLOCK);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR("Esys_SetTimeout FAILED! Response Code : 0x%x", rc);
- return 1;
- }
- ret = test_invoke_esys(esys_context);
- Esys_Finalize(&esys_context);
- tcti_teardown(tcti_inner);
- tcti_teardown(tcti_context);
- return ret;
- }
|