diff options
author | John Andersen <john.s.andersen@intel.com> | 2019-01-16 12:58:36 -0800 |
---|---|---|
committer | Tadeusz Struk <tadeusz.struk@intel.com> | 2019-02-27 10:12:03 -0800 |
commit | 443455b885c5e51aaeab691ebba31090a8809d68 (patch) | |
tree | 1c958729ab80c203921d80ffccfea8c1732919fd | |
parent | 3a493816c210f005ffbc6cfb26a7617a3e5b081c (diff) | |
download | tpm2-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.am | 17 | ||||
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | configure.ac | 21 | ||||
-rw-r--r-- | test/fuzz/tcti/tcti-fuzzing.c | 274 | ||||
-rw-r--r-- | test/fuzz/tcti/tcti-fuzzing.h | 33 | ||||
-rw-r--r-- | test/fuzz/tcti/tss2_tcti_fuzzing.h | 24 | ||||
-rw-r--r-- | test/integration/sapi-context-util.c | 52 | ||||
-rw-r--r-- | test/integration/sapi-test-options.c | 6 | ||||
-rw-r--r-- | test/integration/test-options.h | 1 |
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; |