From 0fb03c12b1339b3cae88d9c0aa1bda0819d04114 Mon Sep 17 00:00:00 2001 From: Elms Date: Tue, 6 Oct 2020 10:08:32 -0700 Subject: [PATCH] compiling with minGW - mingw visibility fix --- configure.ac | 19 +++ examples/tls/tls_common.h | 253 +++++++++++++++++++++++++++++++++++++- src/include.am | 6 +- src/tpm2.c | 3 + wolftpm/include.am | 1 + wolftpm/visibility.h | 3 +- 6 files changed, 279 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index d02bcef..6c41a13 100644 --- a/configure.ac +++ b/configure.ac @@ -196,6 +196,23 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_SWTPM" fi +# Windows TBS device Support +AC_ARG_ENABLE([winapi], + [AS_HELP_STRING([--enable-winapi],[Enable use of TPM through Windows driver (default: disabled)])], + [ ENABLED_WINAPI=$enableval ], + [ ENABLED_WINAPI=no ] + ) + +if test "x$ENABLED_WINAPI" = "xyes" +then + if test "x$ENABLED_DEVTPM" = "xyes" -o "x$ENABLED_SWTPM" = "xyes" + then + AC_MSG_ERROR([Cannot enable swtpm or devtpm with windows API]) + fi + + AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_WINAPI" +fi + # STM ST33 Support AC_ARG_ENABLE([st33],, @@ -336,6 +353,7 @@ AM_CONDITIONAL([BUILD_MICROCHIP], [test "x$ENABLED_MICROCHIP" = "xyes"]) AM_CONDITIONAL([BUILD_INFINEON], [test "x$ENABLED_INFINEON" = "xyes"]) AM_CONDITIONAL([BUILD_DEVTPM], [test "x$ENABLED_DEVTPM" = "xyes"]) AM_CONDITIONAL([BUILD_SWTPM], [test "x$ENABLED_SWTPM" = "xyes"]) +AM_CONDITIONAL([BUILD_WINAPI], [test "x$ENABLED_WINAPI" = "xyes"]) AM_CONDITIONAL([BUILD_NUVOTON], [test "x$ENABLED_NUVOTON" = "xyes"]) AM_CONDITIONAL([BUILD_CHECKWAITSTATE], [test "x$ENABLED_CHECKWAITSTATE" = "xyes"]) AM_CONDITIONAL([BUILD_AUTODETECT], [test "x$ENABLED_AUTODETECT" = "xyes"]) @@ -455,6 +473,7 @@ echo " * Advanced IO: $ENABLED_ADVIO" echo " * I2C: $ENABLED_I2C" echo " * Linux kernel TPM device: $ENABLED_DEVTPM" echo " * SWTPM: $ENABLED_SWTPM" +echo " * WINAPI: $ENABLED_WINAPI" echo " * TIS/SPI Check Wait State: $ENABLED_CHECKWAITSTATE" echo " * Infineon SLB9670 $ENABLED_INFINEON" diff --git a/examples/tls/tls_common.h b/examples/tls/tls_common.h index 09b0c1e..c2bb3a5 100644 --- a/examples/tls/tls_common.h +++ b/examples/tls/tls_common.h @@ -33,6 +33,13 @@ #include #include +#include + +/* TODO: HACKY for win32 */ +#ifdef WIN32 +#undef SOCKET_INVALID +#define SOCKET_INVALID 0xFFFFFFFF +#endif #include @@ -86,11 +93,15 @@ /******************************************************************************/ typedef struct SockIoCbCtx { - int listenFd; - int fd; + SOCKET_T listenFd; + SOCKET_T fd; } SockIoCbCtx; + + #ifndef WOLFSSL_USER_IO +#ifndef USE_WOLFSSL_IO + /* socket includes */ #include #include @@ -221,7 +232,7 @@ static inline int SetupSocketAndListen(SockIoCbCtx* sockIoCtx, word32 port) /* Create a socket that uses an Internet IPv4 address, * Sets the socket to be stream based (TCP), * 0 means choose the default protocol. */ - if ((sockIoCtx->listenFd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + if ((sockIoCtx->listenFd = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_INVALID) { printf("ERROR: failed to create the socket\n"); return -1; } @@ -285,7 +296,7 @@ static inline int SetupSocketAndConnect(SockIoCbCtx* sockIoCtx, const char* host /* Create a socket that uses an Internet IPv4 address, * Sets the socket to be stream based (TCP), * 0 means choose the default protocol. */ - if ((sockIoCtx->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + if ((sockIoCtx->fd = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_INVALID) { printf("ERROR: failed to create the socket\n"); return -1; } @@ -311,6 +322,240 @@ static inline void CloseAndCleanupSocket(SockIoCbCtx* sockIoCtx) sockIoCtx->listenFd = -1; } } +#else /* USE_WOLFSSL_IO */ + +/* Copied from wolfSSL server.c */ +static WC_INLINE int wolfIO_LastError(void) +{ +#ifdef USE_WINDOWS_API + return WSAGetLastError(); +#elif defined(EBSNET) + return xn_getlasterror(); +#else + return errno; +#endif +} + +static inline int SockIORecv(WOLFSSL* ssl, char* buff, int sz, void* ctx) +{ + SockIoCbCtx* sockCtx = (SockIoCbCtx*)ctx; + int recvd; + int err; + + (void)ssl; + + /* Receive message from socket */ + if ((recvd = wolfIO_Send(sockCtx->fd, buff, sz, 0)) == -1) { + /* error encountered. Be responsible and report it in wolfSSL terms */ + + err = wolfIO_LastError(); + printf("IO RECEIVE ERROR: "); + switch (err) { + case SOCKET_EWOULDBLOCK: + if (wolfSSL_get_using_nonblock(ssl)) { + printf("would block\n"); + return WOLFSSL_CBIO_ERR_WANT_READ; + } + else { + printf("socket timeout\n"); + return WOLFSSL_CBIO_ERR_TIMEOUT; + } + case SOCKET_ECONNRESET: + printf("connection reset\n"); + return WOLFSSL_CBIO_ERR_CONN_RST; + case SOCKET_EINTR: + printf("socket interrupted\n"); + return WOLFSSL_CBIO_ERR_ISR; + case SOCKET_ECONNREFUSED: + printf("connection refused\n"); + return WOLFSSL_CBIO_ERR_WANT_READ; + case SOCKET_ECONNABORTED: + printf("connection aborted\n"); + return WOLFSSL_CBIO_ERR_CONN_CLOSE; + default: + printf("general error\n"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + } + else if (recvd == 0) { + printf("Connection closed\n"); + return WOLFSSL_CBIO_ERR_CONN_CLOSE; + } + +#ifdef TLS_BENCH_MODE + { + const double zeroVal = 0.0; + if (XMEMCMP(&benchStart, &zeroVal, sizeof(double)) == 0) { + benchStart = gettime_secs(1); + } + } +#endif + +#ifdef DEBUG_WOLFTPM + /* successful receive */ + printf("SockIORecv: received %d bytes from %d\n", sz, sockCtx->fd); +#endif + + return recvd; +} + + +static inline int SockIOSend(WOLFSSL* ssl, char* buff, int sz, void* ctx) +{ + SockIoCbCtx* sockCtx = (SockIoCbCtx*)ctx; + int sent; + int err; + + (void)ssl; + + /* Receive message from socket */ + if ((sent = (int)wolfIO_Send(sockCtx->fd, buff, sz, 0)) == -1) { + /* error encountered. Be responsible and report it in wolfSSL terms */ + + err = wolfIO_LastError(); + printf("IO SEND ERROR: "); + switch (err) { + case SOCKET_EWOULDBLOCK: + printf("would block\n"); + return WOLFSSL_CBIO_ERR_WANT_READ; + case SOCKET_ECONNRESET: + printf("connection reset\n"); + return WOLFSSL_CBIO_ERR_CONN_RST; + case SOCKET_EINTR: + printf("socket interrupted\n"); + return WOLFSSL_CBIO_ERR_ISR; + case SOCKET_EPIPE: + printf("socket EPIPE\n"); + return WOLFSSL_CBIO_ERR_CONN_CLOSE; + default: + printf("general error\n"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + } + else if (sent == 0) { + printf("Connection closed\n"); + return 0; + } + +#ifdef DEBUG_WOLFTPM + /* successful send */ + printf("SockIOSend: sent %d bytes to %d\n", sz, sockCtx->fd); +#endif + + return sent; +} + +static inline int SetupSocketAndListen(SockIoCbCtx* sockIoCtx, word32 port) +{ + struct sockaddr_in servAddr; + int optval = 1; + + /* Setup server address */ + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_port = htons(port); + servAddr.sin_addr.s_addr = INADDR_ANY; + + /* Create a socket that uses an Internet IPv4 address, + * Sets the socket to be stream based (TCP), + * 0 means choose the default protocol. */ + if ((sockIoCtx->listenFd = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_INVALID) { + printf("ERROR: failed to create the socket\n"); + return -1; + } + + #if defined(SO_REUSEADDR) && !defined(WIN32) + /* allow reuse */ + if (setsockopt(sockIoCtx->listenFd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) { + printf("setsockopt SO_REUSEADDR failed\n"); + return -1; + } + #else + (void)optval; + #endif + + /* Connect to the server */ + if (bind(sockIoCtx->listenFd, (struct sockaddr*)&servAddr, + sizeof(servAddr)) == -1) { + printf("ERROR: failed to bind\n"); + return -1; + } + + if (listen(sockIoCtx->listenFd, 5) != 0) { + printf("ERROR: failed to listen\n"); + return -1; + } + + return 0; +} + +static inline int SocketWaitClient(SockIoCbCtx* sockIoCtx) +{ + int connd; + struct sockaddr_in clientAddr; + int size = sizeof(clientAddr); + + if ((connd = accept(sockIoCtx->listenFd, (struct sockaddr*)&clientAddr, &size)) == -1) { + printf("ERROR: failed to accept the connection\n\n"); + return -1; + } + sockIoCtx->fd = connd; + return 0; +} + +static inline int SetupSocketAndConnect(SockIoCbCtx* sockIoCtx, const char* host, + word32 port) +{ + struct sockaddr_in servAddr; + struct hostent* entry; + + /* Setup server address */ + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_port = htons(port); + + /* Resolve host */ + entry = gethostbyname(host); + if (entry) { + XMEMCPY(&servAddr.sin_addr.s_addr, entry->h_addr_list[0], + entry->h_length); + } + else { + servAddr.sin_addr.s_addr = inet_addr(host); + } + + /* Create a socket that uses an Internet IPv4 address, + * Sets the socket to be stream based (TCP), + * 0 means choose the default protocol. */ + if ((sockIoCtx->fd = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_INVALID) { + printf("ERROR: failed to create the socket\n"); + return -1; + } + + /* Connect to the server */ + if (connect(sockIoCtx->fd, (struct sockaddr*)&servAddr, + sizeof(servAddr)) == -1) { + printf("ERROR: failed to connect\n"); + return -1; + } + + return 0; +} + +static inline void CloseAndCleanupSocket(SockIoCbCtx* sockIoCtx) +{ + + if (sockIoCtx->fd != SOCKET_INVALID) { + CloseSocket(sockIoCtx->fd); + sockIoCtx->fd = SOCKET_INVALID; + } + if (sockIoCtx->listenFd != SOCKET_INVALID) { + CloseSocket(sockIoCtx->listenFd); + sockIoCtx->listenFd = SOCKET_INVALID; + } +} + +#endif /* ! USE_WOLFSSL_IO */ #else /* Provide you own socket implementation code */ int SockIORecv(WOLFSSL* ssl, char* buff, int sz, void* ctx); diff --git a/src/include.am b/src/include.am index 5d02551..22efee3 100644 --- a/src/include.am +++ b/src/include.am @@ -17,8 +17,12 @@ endif if BUILD_SWTPM src_libwolftpm_la_SOURCES += src/tpm2_swtpm.c endif +if BUILD_WINAPI +src_libwolftpm_la_SOURCES += src/tpm2_winapi.c +src_libwolftpm_la_EXTRAS = -I/mingw64/x86_64-w64-mingw32/include/ +endif -src_libwolftpm_la_CFLAGS = -DBUILDING_WOLFTPM $(AM_CFLAGS) +src_libwolftpm_la_CFLAGS = $(src_libwolftpm_la_EXTRAS) -DBUILDING_WOLFTPM $(AM_CFLAGS) src_libwolftpm_la_CPPFLAGS = -DBUILDING_WOLFTPM $(AM_CPPFLAGS) src_libwolftpm_la_LDFLAGS = ${AM_LDFLAGS} -no-undefined -version-info ${WOLFTPM_LIBRARY_VERSION} diff --git a/src/tpm2.c b/src/tpm2.c index 404b8d5..9eacb52 100644 --- a/src/tpm2.c +++ b/src/tpm2.c @@ -25,6 +25,7 @@ #include #include #include +#include #include /******************************************************************************/ @@ -40,6 +41,8 @@ static volatile int gWolfCryptRefCount = 0; #define INTERNAL_SEND_COMMAND TPM2_LINUX_SendCommand #elif defined(WOLFTPM_SWTPM) #define INTERNAL_SEND_COMMAND TPM2_SWTPM_SendCommand +#elif defined(WOLFTPM_WINAPI) +#define INTERNAL_SEND_COMMAND TPM2_WinApi_SendCommand #else #define INTERNAL_SEND_COMMAND TPM2_TIS_SendCommand #endif diff --git a/wolftpm/include.am b/wolftpm/include.am index 8204f25..b0a0eba 100644 --- a/wolftpm/include.am +++ b/wolftpm/include.am @@ -10,6 +10,7 @@ nobase_include_HEADERS+= \ wolftpm/tpm2_wrap.h \ wolftpm/tpm2_linux.h \ wolftpm/tpm2_swtpm.h \ + wolftpm/tpm2_winapi.h \ wolftpm/tpm2_param_enc.h \ wolftpm/version.h \ wolftpm/visibility.h \ diff --git a/wolftpm/visibility.h b/wolftpm/visibility.h index 463952c..2e1447a 100644 --- a/wolftpm/visibility.h +++ b/wolftpm/visibility.h @@ -31,7 +31,8 @@ */ #if defined(BUILDING_WOLFTPM) - #if defined(_MSC_VER) || defined(__CYGWIN__) + #if defined(_MSC_VER) || defined(__CYGWIN__) || \ + defined(__MINGW32__) || defined(__MINGW64__) #ifdef _WINDLL #define WOLFTPM_API __declspec(dllexport) #else