aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Andersen <john.s.andersen@intel.com>2019-01-16 12:58:36 -0800
committerTadeusz Struk <tadeusz.struk@intel.com>2019-02-27 10:12:03 -0800
commit443455b885c5e51aaeab691ebba31090a8809d68 (patch)
tree1c958729ab80c203921d80ffccfea8c1732919fd
parent3a493816c210f005ffbc6cfb26a7617a3e5b081c (diff)
downloadtpm2-tss-443455b885c5e51aaeab691ebba31090a8809d68.tar.gz
test: fuzz: Added fuzzing TCTI
* Created a test/fuzz/tcti/ directory which contains a TCTI to be used for fuzz testing. * Added ifdefs to sapi helpers and test-options in integration tests to enable static linking to a single TCTI. * Added configure.ac options to build fuzzing TCTI. * Added Makefile-fuzz.am used to build fuzzing TCTI. Signed-off-by: John Andersen <john.s.andersen@intel.com>
-rw-r--r--Makefile-fuzz.am17
-rw-r--r--Makefile.am3
-rw-r--r--configure.ac21
-rw-r--r--test/fuzz/tcti/tcti-fuzzing.c274
-rw-r--r--test/fuzz/tcti/tcti-fuzzing.h33
-rw-r--r--test/fuzz/tcti/tss2_tcti_fuzzing.h24
-rw-r--r--test/integration/sapi-context-util.c52
-rw-r--r--test/integration/sapi-test-options.c6
-rw-r--r--test/integration/test-options.h1
9 files changed, 430 insertions, 1 deletions
diff --git a/Makefile-fuzz.am b/Makefile-fuzz.am
new file mode 100644
index 00000000..b7b917f0
--- /dev/null
+++ b/Makefile-fuzz.am
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: BSD-2
+# Copyright (c) 2019 Intel Corporation
+# All rights reserved.
+
+INCLUDE_DIRS += -I$(srcdir)/test/fuzz/tcti
+
+# tcti library used for fuzzing
+if ENABLE_TCTI_FUZZING
+libtss2_tcti_fuzzing = test/fuzz/tcti/libtss2-tcti-fuzzing.la
+noinst_LTLIBRARIES += $(libtss2_tcti_fuzzing)
+
+test_fuzz_tcti_libtss2_tcti_fuzzing_la_CFLAGS = $(AM_CFLAGS)
+test_fuzz_tcti_libtss2_tcti_fuzzing_la_LIBADD = $(libtss2_mu) $(libutil)
+test_fuzz_tcti_libtss2_tcti_fuzzing_la_SOURCES = \
+ src/tss2-tcti/tcti-common.c src/tss2-tcti/tcti-common.h \
+ test/fuzz/tcti/tcti-fuzzing.c test/fuzz/tcti/tcti-fuzzing.h
+endif # ENABLE_TCTI_FUZZING
diff --git a/Makefile.am b/Makefile.am
index f57bf34b..522179f8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -157,6 +157,9 @@ include src_vars.mk
# Add test definitions
include Makefile-test.am
+# Add fuzz definitions
+include Makefile-fuzz.am
+
### Distribution files ###
# Add udev rule
udevrules_DATA = dist/tpm-udev.rules
diff --git a/configure.ac b/configure.ac
index d9695318..51b11eee 100644
--- a/configure.ac
+++ b/configure.ac
@@ -138,6 +138,8 @@ AC_ARG_ENABLE([tcti-device],
[enable_tcti_device=$enableval],
[enable_tcti_device=yes])
AM_CONDITIONAL([ENABLE_TCTI_DEVICE], [test "x$enable_tcti_device" != xno])
+AS_IF([test "x$enable_tcti_device" = "xyes"],
+ AC_DEFINE([TCTI_DEVICE],[1], [TCTI FOR DEV TPM]))
AC_ARG_ENABLE([tcti-mssim],
[AS_HELP_STRING([--enable-tcti-mssim],
@@ -148,6 +150,15 @@ AM_CONDITIONAL([ENABLE_TCTI_MSSIM], [test "x$enable_tcti_mssim" != xno])
AS_IF([test "x$enable_tcti_mssim" = "xyes"],
AC_DEFINE([TCTI_MSSIM],[1], [TCTI FOR MS SIMULATOR]))
+AC_ARG_ENABLE([tcti-fuzzing],
+ [AS_HELP_STRING([--enable-tcti-fuzzing],
+ [build the tcti-fuzzing module (default is no)])],
+ [enable_tcti_fuzzing=$enableval],
+ [enable_tcti_fuzzing=no])
+AM_CONDITIONAL([ENABLE_TCTI_FUZZING], [test "x$enable_tcti_fuzzing" != xno])
+AS_IF([test "x$enable_tcti_fuzzing" = "xyes"],
+ AC_DEFINE([TCTI_FUZZING],[1], [TCTI FOR FUZZING]))
+
#
# udev
#
@@ -327,7 +338,15 @@ AC_OUTPUT
AM_COND_IF([ENABLE_TCTI_DEVICE], [],
[AM_COND_IF([ENABLE_TCTI_MSSIM], [],
- [AC_MSG_WARN("No build-in TCTI module enabled")])])
+ [AM_COND_IF([ENABLE_TCTI_FUZZING], [],
+ [AC_MSG_WARN("No build-in TCTI module enabled")])])])
+
+AM_COND_IF([ENABLE_TCTI_FUZZING], [
+ AM_COND_IF([ENABLE_TCTI_DEVICE],
+ AC_MSG_ERROR("Fuzzing TCTI is meant to be built as the only TCTI"), [])
+ AM_COND_IF([ENABLE_TCTI_MSSIM],
+ AC_MSG_ERROR("Fuzzing TCTI is meant to be built as the only TCTI"), [])
+ ], [])
AC_MSG_RESULT([
$PACKAGE_NAME $VERSION
diff --git a/test/fuzz/tcti/tcti-fuzzing.c b/test/fuzz/tcti/tcti-fuzzing.c
new file mode 100644
index 00000000..c60e3bdd
--- /dev/null
+++ b/test/fuzz/tcti/tcti-fuzzing.c
@@ -0,0 +1,274 @@
+/* SPDX-License-Identifier: BSD-2 */
+/*
+ * Copyright (c) 2018 Intel Corporation
+ * All rights reserved.
+ */
+
+#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 *curr = NULL;
+ size_t size = 0U;
+ size_t i = 0U;
+ void *dest;
+ size_t length = 0U;
+ size_t combined = 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) {
+ length = va_arg (ap, size_t);
+ dest = va_arg (ap, void *);
+ if (size > (combined + length)) {
+ curr = &data[combined];
+ combined += length;
+ memcpy (dest, curr, 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;
+}
diff --git a/test/fuzz/tcti/tcti-fuzzing.h b/test/fuzz/tcti/tcti-fuzzing.h
new file mode 100644
index 00000000..d4018679
--- /dev/null
+++ b/test/fuzz/tcti/tcti-fuzzing.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: BSD-2 */
+/*
+ * Copyright (c) 2018 Intel Corporation
+ * All rights reserved.
+ */
+
+#ifndef TCTI_FUZZING_H
+#define TCTI_FUZZING_H
+
+#include <limits.h>
+
+#include "tss2-tcti/tcti-common.h"
+#include "util/io.h"
+#include "tss2-sys/sysapi_util.h"
+
+#define TCTI_FUZZING_MAGIC 0x66757a7a696e6700ULL
+
+typedef struct {
+ TSS2_TCTI_COMMON_CONTEXT common;
+ const uint8_t *data;
+ size_t size;
+} TSS2_TCTI_FUZZING_CONTEXT;
+
+TSS2_TCTI_FUZZING_CONTEXT*
+tcti_fuzzing_context_cast (TSS2_TCTI_CONTEXT *tcti_ctx);
+
+int
+fuzz_fill (
+ TSS2_SYS_CONTEXT *sysContext,
+ size_t count,
+ ...);
+
+#endif /* TCTI_FUZZING_H */
diff --git a/test/fuzz/tcti/tss2_tcti_fuzzing.h b/test/fuzz/tcti/tss2_tcti_fuzzing.h
new file mode 100644
index 00000000..3491b492
--- /dev/null
+++ b/test/fuzz/tcti/tss2_tcti_fuzzing.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: BSD-2 */
+/*
+ * Copyright (c) 2018, Intel Corporation
+ * All rights reserved.
+ */
+#ifndef TSS2_TCTI_FUZZING_H
+#define TSS2_TCTI_FUZZING_H
+
+#include "tss2_tcti.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+TSS2_RC Tss2_Tcti_Fuzzing_Init (
+ TSS2_TCTI_CONTEXT *tcti_ctx,
+ size_t *size,
+ const char *conf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TSS2_TCTI_FUZZING_H */
diff --git a/test/integration/sapi-context-util.c b/test/integration/sapi-context-util.c
index 78893796..0dd08fe6 100644
--- a/test/integration/sapi-context-util.c
+++ b/test/integration/sapi-context-util.c
@@ -9,13 +9,18 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <config.h>
#include "tss2_tcti_device.h"
#include "tss2_tcti_mssim.h"
+#ifdef TCTI_FUZZING
+#include "tss2_tcti_fuzzing.h"
+#endif /* TCTI_FUZZING */
#include "context-util.h"
#include "tss2-tcti/tcti-mssim.h"
+#ifdef TCTI_DEVICE
/*
* Initialize a TSS2_TCTI_CONTEXT for the device TCTI.
*/
@@ -48,7 +53,9 @@ tcti_device_init(char const *device_path)
}
return tcti_ctx;
}
+#endif /* TCTI_DEVICE */
+#ifdef TCTI_MSSIM
/*
* Initialize a socket TCTI instance using the provided options structure.
* The hostname and port are the only configuration options used.
@@ -84,6 +91,43 @@ tcti_socket_init(char const *host, uint16_t port)
}
return tcti_ctx;
}
+#endif /* TCTI_MSSIM */
+
+#ifdef TCTI_FUZZING
+/*
+ * Initialize a fuzzing TCTI instance using the provided options structure.
+ * The fuzzing_lengths.log file is the only configuration option used.
+ * The caller is returned a TCTI context structure that is allocated by this
+ * function. This structure must be freed by the caller.
+ */
+TSS2_TCTI_CONTEXT *
+tcti_fuzzing_init()
+{
+ size_t size;
+ TSS2_RC rc;
+ TSS2_TCTI_CONTEXT *tcti_ctx;
+
+ rc = Tss2_Tcti_Fuzzing_Init(NULL, &size, NULL);
+ if (rc != TSS2_RC_SUCCESS) {
+ fprintf(stderr, "Faled to get allocation size for tcti context: "
+ "0x%x\n", rc);
+ return NULL;
+ }
+ tcti_ctx = (TSS2_TCTI_CONTEXT *) calloc(1, size);
+ if (tcti_ctx == NULL) {
+ fprintf(stderr, "Allocation for tcti context failed: %s\n",
+ strerror(errno));
+ return NULL;
+ }
+ rc = Tss2_Tcti_Fuzzing_Init(tcti_ctx, &size, NULL);
+ if (rc != TSS2_RC_SUCCESS) {
+ fprintf(stderr, "Failed to initialize tcti context: 0x%x\n", rc);
+ free(tcti_ctx);
+ return NULL;
+ }
+ return tcti_ctx;
+}
+#endif /* TCTI_FUZZING */
/*
* Initialize a SAPI context using the TCTI context provided by the caller.
@@ -147,10 +191,18 @@ TSS2_TCTI_CONTEXT *
tcti_init_from_opts(test_opts_t * options)
{
switch (options->tcti_type) {
+#ifdef TCTI_DEVICE
case DEVICE_TCTI:
return tcti_device_init(options->device_file);
+#endif /* TCTI_DEVICE */
+#ifdef TCTI_MSSIM
case SOCKET_TCTI:
return tcti_socket_init(options->socket_address, options->socket_port);
+#endif /* TCTI_MSSIM */
+#ifdef TCTI_FUZZING
+ case FUZZING_TCTI:
+ return tcti_fuzzing_init();
+#endif /* TCTI_FUZZING */
default:
return NULL;
}
diff --git a/test/integration/sapi-test-options.c b/test/integration/sapi-test-options.c
index 47ef02ba..3f249619 100644
--- a/test/integration/sapi-test-options.c
+++ b/test/integration/sapi-test-options.c
@@ -32,6 +32,10 @@ tcti_map_entry_t tcti_map_table[] = {
.type = SOCKET_TCTI,
},
{
+ .name = "fuzzing",
+ .type = FUZZING_TCTI,
+ },
+ {
.name = "unknown",
.type = UNKNOWN_TCTI,
},
@@ -86,6 +90,8 @@ sanity_check_test_opts(test_opts_t * opts)
return 1;
}
break;
+ case FUZZING_TCTI:
+ break;
default:
fprintf(stderr, "unknown TCTI type, check env\n");
return 1;
diff --git a/test/integration/test-options.h b/test/integration/test-options.h
index 49228ae4..a67bbd57 100644
--- a/test/integration/test-options.h
+++ b/test/integration/test-options.h
@@ -30,6 +30,7 @@ typedef enum {
UNKNOWN_TCTI,
DEVICE_TCTI,
SOCKET_TCTI,
+ FUZZING_TCTI,
N_TCTI,
} TCTI_TYPE;