You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
7.3 KiB
279 lines
7.3 KiB
/* SPDX-License-Identifier: BSD-2-Clause */
|
|
/*
|
|
* Copyright (c) 2018 Intel Corporation
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <sys/time.h>
|
|
#include <inttypes.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
|
#include "tss2_mu.h"
|
|
#include "tss2_tcti_fuzzing.h"
|
|
|
|
#include "tcti-fuzzing.h"
|
|
#include "tss2-tcti/tcti-common.h"
|
|
#include "util/key-value-parse.h"
|
|
#define LOGMODULE tcti
|
|
#include "util/log.h"
|
|
|
|
/*
|
|
* Using the data and size fields of the fuzzing TCTI memcpy the data into the
|
|
* structures given via va_list. Caller will pass the sysContext and number of
|
|
* arguments that follow. Following the count of arguments caller should pass
|
|
* the sizeof the next argument, which shall be a pointer to the structure to be
|
|
* filled.
|
|
*
|
|
* Example:
|
|
*
|
|
* TPMI_DH_OBJECT keyA = {0};
|
|
* TPM2B_ECC_POINT inQsB = {0};
|
|
* TPM2B_ECC_POINT inQeB = {0};
|
|
* TPMI_ECC_KEY_EXCHANGE inScheme = {0};
|
|
* UINT16 counter = {0};
|
|
*
|
|
* ret = fuzz_fill (
|
|
* sysContext,
|
|
* 10,
|
|
* sizeof (keyA), &keyA,
|
|
* sizeof (inQsB), &inQsB,
|
|
* sizeof (inQeB), &inQeB,
|
|
* sizeof (inScheme), &inScheme,
|
|
* sizeof (counter), &counter
|
|
* );
|
|
* if (ret) {
|
|
* ... handle failure
|
|
* }
|
|
*/
|
|
int
|
|
fuzz_fill (
|
|
TSS2_SYS_CONTEXT *sysContext,
|
|
size_t count,
|
|
...)
|
|
{
|
|
va_list ap;
|
|
const uint8_t *data = NULL;
|
|
const uint8_t *pointer_into_data = NULL;
|
|
size_t size = 0U;
|
|
size_t i = 0U;
|
|
void *copy_into_type;
|
|
size_t copy_into_length = 0U;
|
|
size_t data_used = 0U;
|
|
_TSS2_SYS_CONTEXT_BLOB *ctx = NULL;
|
|
TSS2_TCTI_FUZZING_CONTEXT *tcti_fuzzing = NULL;
|
|
|
|
ctx = syscontext_cast (sysContext);
|
|
tcti_fuzzing = tcti_fuzzing_context_cast (ctx->tctiContext);
|
|
data = tcti_fuzzing->data;
|
|
size = tcti_fuzzing->size;
|
|
|
|
va_start (ap, count);
|
|
|
|
for (i = 0U; i < (count / 2); ++i) {
|
|
copy_into_length = va_arg (ap, size_t);
|
|
copy_into_type = va_arg (ap, void *);
|
|
if (size > (data_used + copy_into_length)) {
|
|
pointer_into_data = &data[data_used];
|
|
data_used += copy_into_length;
|
|
memcpy (copy_into_type, pointer_into_data, copy_into_length);
|
|
}
|
|
}
|
|
|
|
va_end (ap);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* This function wraps the "up-cast" of the opaque TCTI context type to the
|
|
* type for the fuzzing TCTI context. The only safeguard we have to ensure this
|
|
* operation is possible is the magic number in the fuzzing TCTI context.
|
|
* If passed a NULL context, or the magic number check fails, this function
|
|
* will return NULL.
|
|
*/
|
|
TSS2_TCTI_FUZZING_CONTEXT*
|
|
tcti_fuzzing_context_cast (TSS2_TCTI_CONTEXT *tcti_ctx)
|
|
{
|
|
if (tcti_ctx != NULL && TSS2_TCTI_MAGIC (tcti_ctx) == TCTI_FUZZING_MAGIC) {
|
|
return (TSS2_TCTI_FUZZING_CONTEXT*)tcti_ctx;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* This function down-casts the fuzzing TCTI context to the common context
|
|
* defined in the tcti-common module.
|
|
*/
|
|
TSS2_TCTI_COMMON_CONTEXT*
|
|
tcti_fuzzing_down_cast (TSS2_TCTI_FUZZING_CONTEXT *tcti_fuzzing)
|
|
{
|
|
if (tcti_fuzzing == NULL) {
|
|
return NULL;
|
|
}
|
|
return &tcti_fuzzing->common;
|
|
}
|
|
|
|
TSS2_RC
|
|
tcti_fuzzing_transmit (
|
|
TSS2_TCTI_CONTEXT *tcti_ctx,
|
|
size_t size,
|
|
const uint8_t *cmd_buf)
|
|
{
|
|
(void) tcti_ctx;
|
|
(void) size;
|
|
(void) cmd_buf;
|
|
((TSS2_TCTI_FUZZING_CONTEXT*) tcti_ctx)->common.state = TCTI_STATE_RECEIVE;
|
|
return TSS2_RC_SUCCESS;
|
|
}
|
|
|
|
TSS2_RC
|
|
tcti_fuzzing_cancel (
|
|
TSS2_TCTI_CONTEXT *tcti_ctx)
|
|
{
|
|
(void) tcti_ctx;
|
|
return TSS2_RC_SUCCESS;
|
|
}
|
|
|
|
TSS2_RC
|
|
tcti_fuzzing_set_locality (
|
|
TSS2_TCTI_CONTEXT *tcti_ctx,
|
|
uint8_t locality)
|
|
{
|
|
(void) tcti_ctx;
|
|
(void) locality;
|
|
return TSS2_RC_SUCCESS;
|
|
}
|
|
|
|
TSS2_RC
|
|
tcti_fuzzing_get_poll_handles (
|
|
TSS2_TCTI_CONTEXT *tcti_ctx,
|
|
TSS2_TCTI_POLL_HANDLE *handles,
|
|
size_t *num_handles)
|
|
{
|
|
(void)(tcti_ctx);
|
|
(void)(handles);
|
|
(void)(num_handles);
|
|
return TSS2_TCTI_RC_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
void
|
|
tcti_fuzzing_finalize(
|
|
TSS2_TCTI_CONTEXT *tcti_ctx)
|
|
{
|
|
(void)(tcti_ctx);
|
|
}
|
|
|
|
TSS2_RC
|
|
tcti_fuzzing_receive (
|
|
TSS2_TCTI_CONTEXT *tcti_ctx,
|
|
size_t *response_size,
|
|
unsigned char *response_buffer,
|
|
int32_t timeout)
|
|
{
|
|
TSS2_TCTI_FUZZING_CONTEXT *tcti_fuzzing = tcti_fuzzing_context_cast (tcti_ctx);
|
|
TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_fuzzing_down_cast (tcti_fuzzing);
|
|
TSS2_RC rc;
|
|
|
|
rc = tcti_common_receive_checks (tcti_common, response_size);
|
|
if (rc != TSS2_RC_SUCCESS) {
|
|
return rc;
|
|
}
|
|
if (timeout != TSS2_TCTI_TIMEOUT_BLOCK) {
|
|
LOG_WARNING ("The underlying IPC mechanism does not support "
|
|
"asynchronous I/O. The 'timeout' parameter must be "
|
|
"TSS2_TCTI_TIMEOUT_BLOCK");
|
|
return TSS2_TCTI_RC_BAD_VALUE;
|
|
}
|
|
if (response_buffer == NULL) {
|
|
LOG_DEBUG ("Caller queried for size but linux kernel doesn't allow this. "
|
|
"Returning 4k which is the max size for a response buffer.");
|
|
*response_size = tcti_fuzzing->size;
|
|
return TSS2_RC_SUCCESS;
|
|
}
|
|
if (*response_size < tcti_fuzzing->size) {
|
|
LOG_INFO ("Caller provided buffer that *may* not be large enough to "
|
|
"hold the response buffer.");
|
|
}
|
|
|
|
/* Receive the TPM response. */
|
|
*response_size = tcti_fuzzing->size;
|
|
tcti_common->header.size = 0;
|
|
tcti_common->state = TCTI_STATE_TRANSMIT;
|
|
memcpy(response_buffer, tcti_fuzzing->data, *response_size);
|
|
|
|
return rc;
|
|
}
|
|
|
|
void
|
|
tcti_fuzzing_init_context_data (
|
|
TSS2_TCTI_COMMON_CONTEXT *tcti_common)
|
|
{
|
|
TSS2_TCTI_MAGIC (tcti_common) = TCTI_FUZZING_MAGIC;
|
|
TSS2_TCTI_VERSION (tcti_common) = TCTI_VERSION;
|
|
TSS2_TCTI_TRANSMIT (tcti_common) = tcti_fuzzing_transmit;
|
|
TSS2_TCTI_RECEIVE (tcti_common) = tcti_fuzzing_receive;
|
|
TSS2_TCTI_FINALIZE (tcti_common) = tcti_fuzzing_finalize;
|
|
TSS2_TCTI_CANCEL (tcti_common) = tcti_fuzzing_cancel;
|
|
TSS2_TCTI_GET_POLL_HANDLES (tcti_common) = tcti_fuzzing_get_poll_handles;
|
|
TSS2_TCTI_SET_LOCALITY (tcti_common) = tcti_fuzzing_set_locality;
|
|
TSS2_TCTI_MAKE_STICKY (tcti_common) = tcti_make_sticky_not_implemented;
|
|
tcti_common->state = TCTI_STATE_TRANSMIT;
|
|
tcti_common->locality = 3;
|
|
memset (&tcti_common->header, 0, sizeof (tcti_common->header));
|
|
}
|
|
|
|
/*
|
|
* This is an implementation of the standard TCTI initialization function for
|
|
* this module.
|
|
*/
|
|
TSS2_RC
|
|
Tss2_Tcti_Fuzzing_Init (
|
|
TSS2_TCTI_CONTEXT *tcti_ctx,
|
|
size_t *size,
|
|
const char *conf)
|
|
{
|
|
(void) conf;
|
|
|
|
if (size == NULL) {
|
|
return TSS2_TCTI_RC_BAD_VALUE;
|
|
}
|
|
if (tcti_ctx == NULL) {
|
|
*size = sizeof (TSS2_TCTI_FUZZING_CONTEXT);
|
|
return TSS2_RC_SUCCESS;
|
|
}
|
|
if (*size != sizeof (TSS2_TCTI_FUZZING_CONTEXT)) {
|
|
return TSS2_TCTI_RC_BAD_VALUE;
|
|
}
|
|
|
|
tcti_fuzzing_init_context_data (
|
|
&(((TSS2_TCTI_FUZZING_CONTEXT*) tcti_ctx)->common));
|
|
|
|
return TSS2_RC_SUCCESS;
|
|
}
|
|
|
|
/* public info structure */
|
|
const TSS2_TCTI_INFO tss2_tcti_info = {
|
|
.version = TCTI_VERSION,
|
|
.name = "tcti-fuzzing",
|
|
.description = "TCTI module for fuzzing the System API.",
|
|
.config_help = "Takes no configuration.",
|
|
.init = Tss2_Tcti_Fuzzing_Init,
|
|
};
|
|
|
|
const TSS2_TCTI_INFO*
|
|
Tss2_Tcti_Info (void)
|
|
{
|
|
return &tss2_tcti_info;
|
|
}
|