From 1e67ba45c9f05baef9e2a9c80956cefc2e42768d Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 5 Oct 2026 20:23:34 -0700 Subject: [PATCH] socket: make the swtpm transport and fwTPM server work on Windows --- .github/workflows/win-swtpm-test.yml | 87 +++++++++++++++++ examples/tls/tls_client.c | 4 +- examples/tls/tls_common.h | 14 +-- examples/tls/tls_server.c | 4 +- src/fwtpm/fwtpm_io.c | 14 +-- src/tpm2_swtpm.c | 134 ++++++++++++++++++--------- wolftpm/tpm2.h | 7 ++ wolftpm/tpm2_socket.h | 10 +- 8 files changed, 211 insertions(+), 63 deletions(-) create mode 100644 .github/workflows/win-swtpm-test.yml diff --git a/.github/workflows/win-swtpm-test.yml b/.github/workflows/win-swtpm-test.yml new file mode 100644 index 000000000..ecad739b2 --- /dev/null +++ b/.github/workflows/win-swtpm-test.yml @@ -0,0 +1,87 @@ +name: Windows swtpm Transport Test + +on: + push: + branches: [ 'master', 'main', 'release/**' ] + pull_request: + branches: [ '*' ] + types: [opened, synchronize, reopened, ready_for_review] + repository_dispatch: + types: [nightly-trigger] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + # The Visual Studio job in win-test.yml never compiles the socket + # transport, so nothing on Windows exercised it and it had drifted to the + # point of not working at all. The firmware TPM is software, so a runner + # with no TPM can still drive the transport end to end. + swtpm: + if: github.event_name != 'pull_request' || github.event.pull_request.draft == false + + runs-on: windows-latest + timeout-minutes: 45 + + defaults: + run: + shell: msys2 {0} + + steps: + - name: Checkout wolfTPM + uses: actions/checkout@v4 + + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: git make autoconf automake libtool + pacboy: toolchain:p + + - name: Build wolfSSL + run: | + set -e + git clone --quiet --depth 1 -b master \ + https://github.com/wolfSSL/wolfssl.git + cd wolfssl + ./autogen.sh + # The Windows certificate store is what drags in crypt32 and is not + # wanted here. Winsock is: wolfio really does call recv(). + ./configure --prefix="$PWD/../wolfssl-inst" --enable-wolftpm \ + --enable-pkcallbacks --enable-keygen \ + --disable-sys-ca-certs \ + CFLAGS="-DWC_RSA_NO_PADDING" LIBS="-lws2_32" + make + make install + + - name: Build wolfTPM + run: | + set -e + ./autogen.sh + ./configure --enable-fwtpm --enable-swtpm \ + --with-wolfcrypt="$PWD/wolfssl-inst" LIBS="-lws2_32" + # wolfTPM's own unit tests use POSIX setenv, which MinGW does not + # have, so a bare `make` stops before reaching these. + make src/fwtpm/fwtpm_server.exe examples/wrap/caps.exe + + - name: Talk to the firmware TPM over the socket transport + run: | + set -e + ./src/fwtpm/fwtpm_server.exe --port 2321 --platform-port 2322 \ + > fwtpm.log 2>&1 & + sleep 5 + cat fwtpm.log + # Reading capabilities needs the whole path to work: the handle has + # to survive being stored, Winsock has to be started, and a command + # has to go out and a response come back. Each of those has been + # broken on Windows. + ./examples/wrap/caps.exe | tee caps.log + grep -q "Mfg WOLF" caps.log + + - name: Collect logs on failure + if: failure() + run: | + tail -40 fwtpm.log 2>/dev/null || true + tail -40 caps.log 2>/dev/null || true diff --git a/examples/tls/tls_client.c b/examples/tls/tls_client.c index e3f84399e..0715b8b34 100644 --- a/examples/tls/tls_client.c +++ b/examples/tls/tls_client.c @@ -169,8 +169,8 @@ int TPM2_TLS_ClientArgs(void* userCtx, int argc, char *argv[]) /* initialize variables */ XMEMSET(&storageKey, 0, sizeof(storageKey)); XMEMSET(&sockIoCtx, 0, sizeof(sockIoCtx)); - sockIoCtx.fd = -1; - sockIoCtx.listenFd = -1; + sockIoCtx.fd = SOCKET_INVALID; + sockIoCtx.listenFd = SOCKET_INVALID; XMEMSET(&tpmCtx, 0, sizeof(tpmCtx)); #ifndef NO_RSA XMEMSET(&rsaKey, 0, sizeof(rsaKey)); diff --git a/examples/tls/tls_common.h b/examples/tls/tls_common.h index dfc03e175..ee46de680 100644 --- a/examples/tls/tls_common.h +++ b/examples/tls/tls_common.h @@ -228,7 +228,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; } @@ -270,7 +270,7 @@ static inline int SocketWaitClient(SockIoCbCtx* sockIoCtx) struct sockaddr_in clientAddr; XSOCKLENT size = sizeof(clientAddr); - if ((connd = accept(sockIoCtx->listenFd, (struct sockaddr*)&clientAddr, &size)) == -1) { + if ((connd = accept(sockIoCtx->listenFd, (struct sockaddr*)&clientAddr, &size)) == SOCKET_INVALID) { printf("ERROR: failed to accept the connection\n\n"); return -1; } @@ -307,7 +307,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; } @@ -350,13 +350,13 @@ static inline int SocketWaitData(SockIoCbCtx* sockIoCtx, int timeout_sec) static inline void CloseAndCleanupSocket(SockIoCbCtx* sockIoCtx) { - if (sockIoCtx->fd != -1) { + if (sockIoCtx->fd != SOCKET_INVALID) { CloseSocket(sockIoCtx->fd); - sockIoCtx->fd = -1; + sockIoCtx->fd = SOCKET_INVALID; } - if (sockIoCtx->listenFd != -1) { + if (sockIoCtx->listenFd != SOCKET_INVALID) { CloseSocket(sockIoCtx->listenFd); - sockIoCtx->listenFd = -1; + sockIoCtx->listenFd = SOCKET_INVALID; } } #else diff --git a/examples/tls/tls_server.c b/examples/tls/tls_server.c index 08d5c10dc..dad4c02ce 100644 --- a/examples/tls/tls_server.c +++ b/examples/tls/tls_server.c @@ -202,8 +202,8 @@ int TPM2_TLS_ServerArgs(void* userCtx, int argc, char *argv[]) /* initialize variables */ XMEMSET(&storageKey, 0, sizeof(storageKey)); XMEMSET(&sockIoCtx, 0, sizeof(sockIoCtx)); - sockIoCtx.fd = -1; - sockIoCtx.listenFd = -1; + sockIoCtx.fd = SOCKET_INVALID; + sockIoCtx.listenFd = SOCKET_INVALID; XMEMSET(&tpmCtx, 0, sizeof(tpmCtx)); #ifndef NO_RSA XMEMSET(&rsaKey, 0, sizeof(rsaKey)); diff --git a/src/fwtpm/fwtpm_io.c b/src/fwtpm/fwtpm_io.c index d1c3e4e31..f25584276 100644 --- a/src/fwtpm/fwtpm_io.c +++ b/src/fwtpm/fwtpm_io.c @@ -219,7 +219,7 @@ static int BuildErrorResponse(byte* rspBuf, UINT16 tag, TPM_RC rc) } /* --- Platform port handler --- */ -static int HandlePlatformCommand(FWTPM_CTX* ctx, int clientFd) +static int HandlePlatformCommand(FWTPM_CTX* ctx, SOCKET_T clientFd) { int rc; UINT32 cmd; @@ -319,7 +319,7 @@ static int HandlePlatformCommand(FWTPM_CTX* ctx, int clientFd) } /* --- Handle mssim signal on command port --- */ -static int HandleMssimSignal(FWTPM_CTX* ctx, int clientFd, UINT32 tssCmd) +static int HandleMssimSignal(FWTPM_CTX* ctx, SOCKET_T clientFd, UINT32 tssCmd) { UINT32 netVal; /* State-mutating signals (POWER_OFF/RESET) are rejected before reaching @@ -335,7 +335,7 @@ static int HandleMssimSignal(FWTPM_CTX* ctx, int clientFd, UINT32 tssCmd) /* --- Process and send TPM command response --- */ static int DispatchAndRespond(FWTPM_CTX* ctx, UINT32 cmdSize, int locality, - int clientFd, int isSwtpm) + SOCKET_T clientFd, int isSwtpm) { int rc; int rspSize = 0; @@ -445,7 +445,7 @@ static int IsMssimSignal(UINT32 cmd) /* --- Command port handler (auto-detects mssim vs swtpm protocol) --- * mssim: first 4 bytes are a small protocol command (1-21) * swtpm: first 4 bytes are raw TPM header (tag 0x8001/0x8002 + size) */ -static int HandleCommandConnection(FWTPM_CTX* ctx, int clientFd) +static int HandleCommandConnection(FWTPM_CTX* ctx, SOCKET_T clientFd) { int rc; UINT32 firstWord; @@ -670,7 +670,7 @@ int FWTPM_IO_ServerLoop(FWTPM_CTX* ctx) #ifndef WOLFTPM_FWTPM_TIS int rc = TPM_RC_SUCCESS; fd_set readFds; - int maxFd; + SOCKET_T maxFd; SOCKET_T cmdFds[FWTPM_MAX_COMMAND_CLIENTS]; SOCKET_T platFd = FWTPM_INVALID_FD; /* active platform client fd */ struct timeval tv; @@ -737,7 +737,9 @@ int FWTPM_IO_ServerLoop(FWTPM_CTX* ctx) tv.tv_sec = 30; tv.tv_usec = 0; - selRc = select(maxFd + 1, &readFds, NULL, NULL, &tv); + /* Windows ignores the first argument and its SOCKET does not fit an + * int; everywhere else it is the descriptor bound and does. */ + selRc = select((int)(maxFd + 1), &readFds, NULL, NULL, &tv); if (selRc < 0) { #ifdef _WIN32 if (WSAGetLastError() == WSAEINTR) continue; diff --git a/src/tpm2_swtpm.c b/src/tpm2_swtpm.c index bfa2ddee9..1022e2174 100644 --- a/src/tpm2_swtpm.c +++ b/src/tpm2_swtpm.c @@ -105,6 +105,39 @@ #endif #endif +/* How the transport reaches its descriptor. Everywhere except Windows a + * socket is a file descriptor and the ordinary calls work on it. A Winsock + * SOCKET is not a CRT descriptor: read(), write() and close() do not accept + * one, it is unsigned so a negative test never fires, and the invalid value + * is INVALID_SOCKET rather than -1. UART mode really does use a descriptor, + * so it keeps the POSIX calls on every platform. */ +#if defined(_WIN32) && !defined(WOLFTPM_SWTPM_UART) + typedef uintptr_t SWTPM_FD_T; + #define SWTPM_FD_INVALID ((uintptr_t)INVALID_SOCKET) + #define SWTPM_FD_IS_VALID(fd) ((fd) != SWTPM_FD_INVALID) + #define SWTPM_READ(fd, p, n) recv((SOCKET)(fd), (p), (int)(n), 0) + #define SWTPM_WRITE(fd, p, n) send((SOCKET)(fd), (p), (int)(n), 0) + #define SWTPM_CLOSE(fd) closesocket((SOCKET)(fd)) + /* Winsock does not set errno; a transfer that fails leaves whatever was + * there before, so the retry decision has to come from Winsock. */ + #define SWTPM_SHOULD_RETRY() (WSAGetLastError() == WSAEINTR) +#else + typedef int SWTPM_FD_T; + #define SWTPM_FD_INVALID (-1) + #define SWTPM_FD_IS_VALID(fd) ((fd) >= 0) + #define SWTPM_READ(fd, p, n) read((fd), (p), (n)) + #define SWTPM_WRITE(fd, p, n) write((fd), (p), (n)) + #define SWTPM_CLOSE(fd) close(fd) + #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || EWOULDBLOCK != EAGAIN) + #define SWTPM_SHOULD_RETRY() \ + (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) + #elif defined(EAGAIN) + #define SWTPM_SHOULD_RETRY() (errno == EINTR || errno == EAGAIN) + #else + #define SWTPM_SHOULD_RETRY() (errno == EINTR) + #endif +#endif + static TPM_RC SwTpmTransmit(TPM2_CTX* ctx, const void* buffer, ssize_t bufSz) { TPM_RC rc = TPM_RC_SUCCESS; @@ -112,7 +145,8 @@ static TPM_RC SwTpmTransmit(TPM2_CTX* ctx, const void* buffer, ssize_t bufSz) const char* ptr; ssize_t remaining; - if (ctx == NULL || ctx->tcpCtx.fd < 0 || buffer == NULL || bufSz <= 0) { + if (ctx == NULL || !SWTPM_FD_IS_VALID(ctx->tcpCtx.fd) || + buffer == NULL || bufSz <= 0) { return BAD_FUNC_ARG; } @@ -124,24 +158,17 @@ static TPM_RC SwTpmTransmit(TPM2_CTX* ctx, const void* buffer, ssize_t bufSz) /* a dead peer must return an error, not raise SIGPIPE */ wrc = send(ctx->tcpCtx.fd, ptr, remaining, MSG_NOSIGNAL); #else - wrc = write(ctx->tcpCtx.fd, ptr, remaining); + wrc = SWTPM_WRITE(ctx->tcpCtx.fd, ptr, remaining); #endif if (wrc < 0) { - /* Retry on EINTR (signal). EAGAIN/EWOULDBLOCK shouldn't normally - * happen on the default blocking fd, but treat them as transient. */ - if (errno == EINTR - #ifdef EAGAIN - || errno == EAGAIN - #endif - #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || EWOULDBLOCK != EAGAIN) - || errno == EWOULDBLOCK - #endif - ) { + /* Retry a signal, and the transient would-block cases that a + * blocking descriptor should not produce but sometimes does. */ + if (SWTPM_SHOULD_RETRY()) { continue; } #ifdef WOLFTPM_DEBUG_VERBOSE printf("Failed to send the TPM command to fd %d, got errno %d =" - "%s\n", ctx->tcpCtx.fd, errno, strerror(errno)); + "%s\n", (int)ctx->tcpCtx.fd, errno, strerror(errno)); #endif rc = TPM_RC_FAILURE; break; @@ -173,27 +200,19 @@ static TPM_RC SwTpmReceive(TPM2_CTX* ctx, void* buffer, size_t rxSz) } #endif - if (ctx == NULL || ctx->tcpCtx.fd < 0 || buffer == NULL) { + if (ctx == NULL || !SWTPM_FD_IS_VALID(ctx->tcpCtx.fd) || buffer == NULL) { return BAD_FUNC_ARG; } while (bytes_remaining > 0) { - wrc = read(ctx->tcpCtx.fd, ptr, bytes_remaining); + wrc = SWTPM_READ(ctx->tcpCtx.fd, ptr, bytes_remaining); if (wrc < 0) { - /* Retry on EINTR; treat EAGAIN/EWOULDBLOCK as transient too. */ - if (errno == EINTR - #ifdef EAGAIN - || errno == EAGAIN - #endif - #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || EWOULDBLOCK != EAGAIN) - || errno == EWOULDBLOCK - #endif - ) { + if (SWTPM_SHOULD_RETRY()) { continue; } #ifdef DEBUG_WOLFTPM printf("Failed to read from TPM socket %d, got errno %d" - " = %s\n", ctx->tcpCtx.fd, errno, strerror(errno)); + " = %s\n", (int)ctx->tcpCtx.fd, errno, strerror(errno)); #endif rc = TPM_RC_FAILURE; break; @@ -238,7 +257,9 @@ static TPM_RC SwTpmReceive(TPM2_CTX* ctx, void* buffer, size_t rxSz) static TPM_RC SwTpmConnect(TPM2_CTX* ctx, const char* host, const char* port) { TPM_RC rc = TPM_RC_FAILURE; - int fd = -1; + /* Must be the width of the field it ends up in: narrowing a Windows + * SOCKET into an int here would undo the widening in the context. */ + SWTPM_FD_T fd = SWTPM_FD_INVALID; #ifdef WOLFTPM_SWTPM_UART /* UART transport: open serial device with termios */ @@ -413,11 +434,35 @@ static TPM_RC SwTpmConnect(TPM2_CTX* ctx, const char* host, const char* port) int sockOpt = 1; struct addrinfo hints; struct addrinfo *result, *rp; +#ifdef _WIN32 + static int wsaStarted = 0; + WSADATA wsd; +#endif if (ctx == NULL) { return BAD_FUNC_ARG; } +#ifdef _WIN32 + /* Nothing may call a socket function before Winsock is started, and this + * transport is usually the first thing in the process to do so: a TLS + * example reaches its TPM here before it opens a socket of its own. + * + * Started once and deliberately never matched with WSACleanup: the + * library has no teardown hook that runs after the last connection, and + * a cleanup on disconnect would pull Winsock out from under a caller + * that is still using sockets of its own. Winsock is released when the + * process exits. The flag is not synchronized, so a caller that first + * connects from two threads at once should serialize that. */ + if (!wsaStarted) { + if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) { + fprintf(stderr, "WSAStartup failed\n"); + return rc; + } + wsaStarted = 1; + } +#endif + XMEMSET(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; @@ -430,11 +475,11 @@ static TPM_RC SwTpmConnect(TPM2_CTX* ctx, const char* host, const char* port) for (rp = result; rp != NULL; rp = rp->ai_next) { fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - if (fd == -1) + if (!SWTPM_FD_IS_VALID(fd)) continue; if (connect(fd, rp->ai_addr, rp->ai_addrlen) == -1) { - close(fd); + SWTPM_CLOSE(fd); } else { break; @@ -448,12 +493,13 @@ static TPM_RC SwTpmConnect(TPM2_CTX* ctx, const char* host, const char* port) (void)fcntl(fd, F_SETFD, FD_CLOEXEC); #endif #ifdef SO_NOSIGPIPE - (void)setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &sockOpt, - sizeof(sockOpt)); + (void)setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, + (const char*)&sockOpt, sizeof(sockOpt)); #endif #ifdef TCP_NODELAY - (void)setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &sockOpt, - sizeof(sockOpt)); + /* Winsock takes a char* here where POSIX takes a void*. */ + (void)setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, + (const char*)&sockOpt, sizeof(sockOpt)); #endif ctx->tcpCtx.fd = fd; rc = TPM_RC_SUCCESS; @@ -473,7 +519,7 @@ static TPM_RC SwTpmDisconnect(TPM2_CTX* ctx) TPM_RC rc = TPM_RC_SUCCESS; uint32_t tss_cmd; - if (ctx == NULL || ctx->tcpCtx.fd < 0) { + if (ctx == NULL || !SWTPM_FD_IS_VALID(ctx->tcpCtx.fd)) { return BAD_FUNC_ARG; } @@ -489,20 +535,20 @@ static TPM_RC SwTpmDisconnect(TPM2_CTX* ctx) #ifdef WOLFTPM_SWTPM_UART /* Keep the port open unless SESSION_END fails. */ if (rc != TPM_RC_SUCCESS) { - close(ctx->tcpCtx.fd); - ctx->tcpCtx.fd = -1; + SWTPM_CLOSE(ctx->tcpCtx.fd); + ctx->tcpCtx.fd = SWTPM_FD_INVALID; } #else - if (0 != close(ctx->tcpCtx.fd)) { + if (0 != SWTPM_CLOSE(ctx->tcpCtx.fd)) { rc = TPM_RC_FAILURE; #ifdef WOLFTPM_DEBUG_VERBOSE printf("Failed to close fd %d, got errno %d =" - "%s\n", ctx->tcpCtx.fd, errno, strerror(errno)); + "%s\n", (int)ctx->tcpCtx.fd, errno, strerror(errno)); #endif } - ctx->tcpCtx.fd = -1; + ctx->tcpCtx.fd = SWTPM_FD_INVALID; #endif return rc; @@ -540,7 +586,7 @@ int TPM2_SWTPM_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet) return BAD_FUNC_ARG; } - if (ctx->tcpCtx.fd < 0) { + if (!SWTPM_FD_IS_VALID(ctx->tcpCtx.fd)) { #ifndef NO_GETENV envVal = getenv("TPM2_SWTPM_HOST"); if (envVal != NULL && envVal[0] != '\0') @@ -628,7 +674,7 @@ int TPM2_SWTPM_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet) #endif #ifdef WOLFTPM_SWTPM_UART - if (ctx->tcpCtx.fd >= 0) { + if (SWTPM_FD_IS_VALID(ctx->tcpCtx.fd)) { TPM_RC rc_disconnect = SwTpmDisconnect(ctx); if (rc == TPM_RC_SUCCESS) { rc = rc_disconnect; @@ -636,7 +682,7 @@ int TPM2_SWTPM_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet) } #else /* Reconnect after a transport failure. */ - if (rc != TPM_RC_SUCCESS && ctx->tcpCtx.fd >= 0) { + if (rc != TPM_RC_SUCCESS && SWTPM_FD_IS_VALID(ctx->tcpCtx.fd)) { (void)SwTpmDisconnect(ctx); } #endif @@ -646,10 +692,10 @@ int TPM2_SWTPM_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet) void TPM2_SwtpmClose(TPM2_CTX* ctx) { - if (ctx != NULL && ctx->tcpCtx.fd >= 0) { + if (ctx != NULL && SWTPM_FD_IS_VALID(ctx->tcpCtx.fd)) { #ifdef WOLFTPM_SWTPM_UART - close(ctx->tcpCtx.fd); - ctx->tcpCtx.fd = -1; + SWTPM_CLOSE(ctx->tcpCtx.fd); + ctx->tcpCtx.fd = SWTPM_FD_INVALID; #else (void)SwTpmDisconnect(ctx); #endif diff --git a/wolftpm/tpm2.h b/wolftpm/tpm2.h index 08d17278b..b497bf857 100644 --- a/wolftpm/tpm2.h +++ b/wolftpm/tpm2.h @@ -2189,7 +2189,14 @@ struct TPM2_CTX; #ifdef WOLFTPM_SWTPM struct wolfTPM_tcpContext { +#if defined(_WIN32) && !defined(WOLFTPM_SWTPM_UART) + /* A Winsock SOCKET is an unsigned pointer-width handle, which an int + * truncates on a 64 bit build. Spelled without the socket headers so + * this one stays out of the public include path. */ + uintptr_t fd; +#else int fd; +#endif }; #endif /* WOLFTPM_SWTPM */ diff --git a/wolftpm/tpm2_socket.h b/wolftpm/tpm2_socket.h index ebeeaaa47..e0ef6b3f6 100644 --- a/wolftpm/tpm2_socket.h +++ b/wolftpm/tpm2_socket.h @@ -33,9 +33,11 @@ #define SOCKET_T SOCKET - /* TODO: HACKY for win32 */ + /* SOCKET is an unsigned UINT_PTR, so the sentinel is all bits set and is + * 64 bit wide on a 64 bit build; a literal 0xFFFFFFFF is a different + * value there and matches no socket. */ #undef SOCKET_INVALID - #define SOCKET_INVALID 0xFFFFFFFF + #define SOCKET_INVALID INVALID_SOCKET #elif defined(WOLFTPM_ZEPHYR) #include @@ -47,6 +49,10 @@ #define SOCKET_T int #endif +#ifndef SOCKET_INVALID + #define SOCKET_INVALID ((SOCKET_T)-1) +#endif + #ifdef USE_WINDOWS_API #ifndef CloseSocket #define CloseSocket(s) closesocket(s)