blob: f19f08517463a179dc443d34e9ad251a48aeab80 [file] [log] [blame]
/* SPDX-License-Identifier: BSD-2-Clause */
/*******************************************************************************
* Copyright 2019, Intel Corporation
*
* All rights reserved.
******************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdarg.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <setjmp.h>
#include <cmocka.h>
#include "tss2_sys.h"
#include "sysapi_util.h"
#include "tss2-tcti/tcti-common.h"
#define LOGMODULE test
#include "util/log.h"
/**
* Test calls Tss2_Sys_Execute() many times after receiving TPM2_RC_RETRY
*/
const uint8_t ok_response[] = {
0x80, 0x01, /* TPM_ST_NO_SESSION */
0x00, 0x00, 0x00, 0x2C, /* Response Size 10 + 2 + 32 */
0x00, 0x00, 0x00, 0x00, /* TPM_RC_SUCCESS */
0x00, 0x20, /* size of buffer */
0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef,
};
const uint8_t retry_response[] = {
0x80, 0x01, /* TPM_ST_NO_SESSION */
0x00, 0x00, 0x00, 0x0A, /* Response Size 10 */
0x00, 0x00, 0x09, 0x22 /* TPM2_RC_RETRY */
};
static TSS2_RC
tcti_transmit(
TSS2_TCTI_CONTEXT *tctiContext,
size_t size,
uint8_t const *command)
{
TSS2_RC r = 0;
tpm_header_t hdr;
LOG_DEBUG ("%s: transmiting %zu bytes", __func__, size);
r = header_unmarshal (command, &hdr);
if (r)
return r;
LOG_DEBUG ("%s request_hdr.tag = %x", __func__, hdr.tag);
LOG_DEBUG ("%s request_hdr.size = %x", __func__, hdr.size);
LOG_DEBUG ("%s request_hdr.code = %x", __func__, hdr.code);
if (hdr.tag != TPM2_ST_NO_SESSIONS || hdr.size != 0xC || hdr.code != 0x17B)
return TSS2_TCTI_RC_BAD_VALUE;
return r;
}
#define NUM_OF_RETRIES 4
static TSS2_RC
tcti_receive(
TSS2_TCTI_CONTEXT *tctiContext,
size_t *size,
uint8_t *response,
int32_t timeout)
{
static int i;
LOG_DEBUG ("%s: receiving response, size %zu, buff %p",
__func__, sizeof(ok_response), response);
if (response == NULL) {
*size = sizeof(ok_response);
return TPM2_RC_SUCCESS;
}
if (i++ < NUM_OF_RETRIES) {
LOG_DEBUG ("%s: return RC_RETRY", __func__);
memcpy(response, retry_response, sizeof(retry_response));
*size = sizeof(retry_response);
return TPM2_RC_SUCCESS;
}
memcpy(response, ok_response, sizeof(ok_response));
*size = sizeof(ok_response);
return TPM2_RC_SUCCESS;
}
static TSS2_ABI_VERSION ver = TSS2_ABI_VERSION_CURRENT;
static TSS2_TCTI_CONTEXT_COMMON_V1 _tcti_v1_ctx;
static int
setup(void **state)
{
TSS2_SYS_CONTEXT *sys_ctx;
TSS2_TCTI_CONTEXT *tcti_ctx = (TSS2_TCTI_CONTEXT *) &_tcti_v1_ctx;
UINT32 size_ctx;
TSS2_RC r;
size_ctx = Tss2_Sys_GetContextSize(0);
sys_ctx = calloc (1, size_ctx);
assert_non_null (sys_ctx);
_tcti_v1_ctx.version = 1;
_tcti_v1_ctx.transmit = tcti_transmit;
_tcti_v1_ctx.receive = tcti_receive;
r = Tss2_Sys_Initialize(sys_ctx, size_ctx, tcti_ctx, &ver);
assert_int_equal (r, TSS2_RC_SUCCESS);
*state = sys_ctx;
return 0;
}
static int
teardown(void **state)
{
TSS2_SYS_CONTEXT *sys_ctx = (TSS2_SYS_CONTEXT *)*state;
if (sys_ctx)
free (sys_ctx);
return 0;
}
static void
test_resubmit(void **state)
{
TSS2_RC r = 0;
TSS2_SYS_CONTEXT *sys_ctx = (TSS2_SYS_CONTEXT *)*state;
int ctr = 0;
r = Tss2_Sys_GetRandom_Prepare(sys_ctx, 32);
assert_int_equal(r, TSS2_RC_SUCCESS);
do {
r = Tss2_Sys_Execute(sys_ctx);
} while (r == TPM2_RC_RETRY && ctr++ < 10);
assert_int_equal(r, TSS2_RC_SUCCESS);
assert_int_equal(ctr, NUM_OF_RETRIES);
return;
}
int
main(int argc, char *argv[])
{
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(test_resubmit, setup, teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}