Skip to content

Commit 1854909

Browse files
committed
More fenrir/skoll review feedback
1 parent fd02c4f commit 1854909

File tree

7 files changed

+136
-31
lines changed

7 files changed

+136
-31
lines changed

Makefile.am

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ DISTCLEANFILES+= aminclude.am
2828
# make sure we pass the correct flags to distcheck
2929
# SWTPM_PORT can be set via --with-swtpm-port during configure
3030
# Use @SWTPM_PORT@ substitution from configure.ac
31-
AM_DISTCHECK_CONFIGURE_FLAGS = --enable-swtpm @DISTCHECK_SWTPM_PORT_FLAG@
31+
# Explicitly disable fwtpm during distcheck — fwtpm_server requires
32+
# optional wolfSSL features (WOLFSSL_KEY_GEN, WC_RSA_NO_PADDING) that
33+
# distcheck runners can't guarantee. Restores pre-auto-enable behavior.
34+
AM_DISTCHECK_CONFIGURE_FLAGS = --enable-swtpm --disable-fwtpm @DISTCHECK_SWTPM_PORT_FLAG@
3235

3336
exampledir = $(docdir)/example
3437
dist_example_DATA=

configure.ac

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,31 @@ then
311311
then
312312
AC_MSG_ERROR([fwTPM requires wolfCrypt. Do not use --disable-wolfcrypt with --enable-fwtpm.])
313313
fi
314+
# Probe wolfSSL for optional RSA features required by fwTPM's RSA key
315+
# paths. These aren't hard errors — ECC-only fwTPM works without them —
316+
# so emit warnings rather than failing configure.
317+
AC_MSG_CHECKING([wolfSSL for WOLFSSL_KEY_GEN (needed for RSA CreatePrimary)])
318+
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
319+
#include <wolfssl/options.h>
320+
#ifndef WOLFSSL_KEY_GEN
321+
#error WOLFSSL_KEY_GEN not defined
322+
#endif
323+
int main(void){return 0;}
324+
]])],
325+
[AC_MSG_RESULT([yes])],
326+
[AC_MSG_RESULT([no])
327+
AC_MSG_WARN([fwTPM: wolfSSL lacks WOLFSSL_KEY_GEN — RSA CreatePrimary will fail at runtime. Rebuild wolfSSL with --enable-keygen or use --disable-fwtpm.])])
328+
AC_MSG_CHECKING([wolfSSL for WC_RSA_NO_PADDING (needed for RSA_Encrypt/Decrypt)])
329+
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
330+
#include <wolfssl/options.h>
331+
#ifndef WC_RSA_NO_PADDING
332+
#error WC_RSA_NO_PADDING not defined
333+
#endif
334+
int main(void){return 0;}
335+
]])],
336+
[AC_MSG_RESULT([yes])],
337+
[AC_MSG_RESULT([no])
338+
AC_MSG_WARN([fwTPM: wolfSSL lacks WC_RSA_NO_PADDING — raw RSA operations will return TPM_RC_SCHEME. Rebuild wolfSSL with CFLAGS="-DWC_RSA_NO_PADDING".])])
314339
# WOLFTPM_FWTPM is added to options.h (via OPTION_FLAGS) but NOT to AM_CFLAGS.
315340
# It gates server-specific code in tpm2_packet.c/tpm2_param_enc.c and is set
316341
# as a compile flag only for the fwtpm_server target in src/fwtpm/include.am.

src/tpm2_crypto.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ int TPM2_KDFe(
329329

330330
#ifndef WOLFTPM2_NO_WOLFCRYPT
331331

332-
#ifndef NO_AES
332+
#if !defined(NO_AES) && defined(WOLFSSL_AES_CFB)
333333

334334
int TPM2_AesCfbEncrypt(
335335
const byte* key, int keySz,
@@ -359,6 +359,8 @@ int TPM2_AesCfbEncrypt(
359359
rc = wc_AesCfbEncrypt(&aes, data, data, dataSz);
360360
}
361361
wc_AesFree(&aes);
362+
/* Wipe residual key material from the stack Aes object. */
363+
TPM2_ForceZero(&aes, sizeof(aes));
362364
}
363365
return rc;
364366
}
@@ -391,11 +393,13 @@ int TPM2_AesCfbDecrypt(
391393
rc = wc_AesCfbDecrypt(&aes, data, data, dataSz);
392394
}
393395
wc_AesFree(&aes);
396+
/* Wipe residual key material from the stack Aes object. */
397+
TPM2_ForceZero(&aes, sizeof(aes));
394398
}
395399
return rc;
396400
}
397401

398-
#endif /* !NO_AES */
402+
#endif /* !NO_AES && WOLFSSL_AES_CFB */
399403

400404
#ifndef NO_HMAC
401405

@@ -441,6 +445,8 @@ int TPM2_HmacCompute(
441445
rc = wc_HmacFinal(&hmac, digest);
442446
}
443447
wc_HmacFree(&hmac);
448+
/* Wipe residual key material from the stack Hmac object. */
449+
TPM2_ForceZero(&hmac, sizeof(hmac));
444450
}
445451
if (rc == 0 && digestSz != NULL) {
446452
*digestSz = (word32)dSz;

src/tpm2_param_enc.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@
5757
/* --- Param Enc/Dec Functions -- */
5858
/******************************************************************************/
5959

60-
/* Maximum XOR mask size: RSA 2048 private key blob is ~1250 bytes */
60+
/* Maximum XOR mask size. RSA-2048 inSensitive parameter blobs on Create can
61+
* exceed MAX_DIGEST_BUFFER (1024), so leave headroom to ~1250 bytes. Keep
62+
* stack usage bounded by switching to heap under WOLFTPM_SMALL_STACK. */
6163
#ifndef TPM2_XOR_MASK_MAX
62-
#define TPM2_XOR_MASK_MAX 1500
64+
#define TPM2_XOR_MASK_MAX 1280
6365
#endif
6466

6567
/* XOR parameter encryption/decryption (shared by client and fwTPM).
@@ -73,14 +75,23 @@ int TPM2_ParamEnc_XOR(
7375
BYTE *paramData, UINT32 paramSz)
7476
{
7577
int rc;
76-
BYTE mask[TPM2_XOR_MASK_MAX];
7778
UINT32 i;
79+
#ifdef WOLFTPM_SMALL_STACK
80+
BYTE *mask = (BYTE*)XMALLOC(TPM2_XOR_MASK_MAX, NULL,
81+
DYNAMIC_TYPE_TMP_BUFFER);
82+
if (mask == NULL) {
83+
return MEMORY_E;
84+
}
85+
#else
86+
BYTE mask[TPM2_XOR_MASK_MAX];
87+
#endif
7888

79-
if (paramSz > sizeof(mask)) {
80-
return BUFFER_E;
89+
if (paramSz > TPM2_XOR_MASK_MAX) {
90+
rc = BUFFER_E;
91+
goto out;
8192
}
8293

83-
XMEMSET(mask, 0, sizeof(mask));
94+
XMEMSET(mask, 0, TPM2_XOR_MASK_MAX);
8495
rc = TPM2_KDFa_ex(authHash, keyIn, keyInSz, "XOR",
8596
nonceA, nonceASz, nonceB, nonceBSz, mask, paramSz);
8697
if ((UINT32)rc == paramSz) {
@@ -96,7 +107,11 @@ int TPM2_ParamEnc_XOR(
96107
rc = TPM_RC_FAILURE;
97108
}
98109

99-
TPM2_ForceZero(mask, sizeof(mask));
110+
TPM2_ForceZero(mask, TPM2_XOR_MASK_MAX);
111+
out:
112+
#ifdef WOLFTPM_SMALL_STACK
113+
XFREE(mask, NULL, DYNAMIC_TYPE_TMP_BUFFER);
114+
#endif
100115
return rc;
101116
}
102117

src/tpm2_swtpm.c

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,18 @@
6565
#include <fcntl.h>
6666
#include <termios.h>
6767
#include <sys/stat.h>
68+
#include <time.h>
6869
#ifndef O_CLOEXEC
6970
#define O_CLOEXEC 0
7071
#endif
7172
#ifndef O_NOFOLLOW
7273
#define O_NOFOLLOW 0
7374
#endif
75+
/* Cumulative wall-clock timeout for SwTpmReceive. Defends against trickle
76+
* senders that repeatedly reset the per-read VMIN/VTIME timer. */
77+
#ifndef WOLFTPM_SWTPM_UART_RX_TIMEOUT_SECS
78+
#define WOLFTPM_SWTPM_UART_RX_TIMEOUT_SECS 30
79+
#endif
7480
#endif
7581

7682
#include <wolftpm/tpm2_socket.h>
@@ -133,6 +139,13 @@ static TPM_RC SwTpmReceive(TPM2_CTX* ctx, void* buffer, size_t rxSz)
133139
ssize_t wrc = 0;
134140
size_t bytes_remaining = rxSz;
135141
char* ptr = (char*)buffer;
142+
#if defined(WOLFTPM_SWTPM_UART) && defined(CLOCK_MONOTONIC)
143+
struct timespec start, now;
144+
int haveStart = 0;
145+
if (clock_gettime(CLOCK_MONOTONIC, &start) == 0) {
146+
haveStart = 1;
147+
}
148+
#endif
136149

137150
if (ctx == NULL || ctx->tcpCtx.fd < 0 || buffer == NULL) {
138151
return BAD_FUNC_ARG;
@@ -161,6 +174,23 @@ static TPM_RC SwTpmReceive(TPM2_CTX* ctx, void* buffer, size_t rxSz)
161174
printf("TPM socket received %zd waiting for %zu more\n",
162175
wrc, bytes_remaining);
163176
#endif
177+
178+
#if defined(WOLFTPM_SWTPM_UART) && defined(CLOCK_MONOTONIC)
179+
/* Enforce cumulative timeout so a trickle sender cannot reset
180+
* VMIN/VTIME indefinitely. */
181+
if (haveStart && bytes_remaining > 0 &&
182+
clock_gettime(CLOCK_MONOTONIC, &now) == 0 &&
183+
(now.tv_sec - start.tv_sec) >
184+
WOLFTPM_SWTPM_UART_RX_TIMEOUT_SECS) {
185+
#ifdef DEBUG_WOLFTPM
186+
printf("SwTpmReceive: cumulative UART timeout after %lds "
187+
"(%zu bytes remaining)\n",
188+
(long)(now.tv_sec - start.tv_sec), bytes_remaining);
189+
#endif
190+
rc = TPM_RC_FAILURE;
191+
break;
192+
}
193+
#endif
164194
}
165195

166196
return rc;
@@ -233,8 +263,14 @@ static TPM_RC SwTpmConnect(TPM2_CTX* ctx, const char* host, const char* port)
233263
#endif
234264
default: baud = B115200; break;
235265
}
236-
cfsetospeed(&tty, baud);
237-
cfsetispeed(&tty, baud);
266+
if (cfsetospeed(&tty, baud) != 0 || cfsetispeed(&tty, baud) != 0) {
267+
#ifdef DEBUG_WOLFTPM
268+
printf("Failed to set UART baud rate %d: %s\n",
269+
baudInt, strerror(errno));
270+
#endif
271+
close(fd);
272+
return TPM_RC_FAILURE;
273+
}
238274

239275
/* 8N1: 8 data bits, no parity, 1 stop bit */
240276
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
@@ -381,10 +417,15 @@ static TPM_RC SwTpmDisconnect(TPM2_CTX* ctx)
381417
#endif
382418

383419
#ifdef WOLFTPM_SWTPM_UART
384-
/* UART: keep the port open for the next command.
420+
/* UART: on success, keep the port open for the next command.
385421
* The SESSION_END tells the server the command sequence is done.
386-
* Final cleanup of the UART FD is handled in TPM2_SwtpmCloseUART. */
387-
(void)ctx;
422+
* Final cleanup of the UART FD is handled in TPM2_SwtpmCloseUART.
423+
* On SESSION_END write failure, close and reset the fd so the next
424+
* command reconnects instead of reusing a broken connection. */
425+
if (rc != TPM_RC_SUCCESS) {
426+
close(ctx->tcpCtx.fd);
427+
ctx->tcpCtx.fd = -1;
428+
}
388429
#else
389430
if (0 != close(ctx->tcpCtx.fd)) {
390431
rc = TPM_RC_FAILURE;

src/tpm2_wrap.c

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,12 +1723,14 @@ int wolfTPM2_SetAuthHandle(WOLFTPM2_DEV* dev, int index,
17231723
TPM2_PrintBin(session->name.name, session->name.size);
17241724
TPM2_PrintBin(handle->name.name, handle->name.size);
17251725
#endif
1726-
session->policyAuth = handle->policyAuth;
1726+
/* Validate bounds before any session-state mutation so the
1727+
* session isn't left inconsistent on BUFFER_E. */
17271728
if (authDigestSz <= 0 ||
17281729
(handle->auth.size + authDigestSz) >
17291730
(int)sizeof(session->auth.buffer)) {
17301731
return BUFFER_E;
17311732
}
1733+
session->policyAuth = handle->policyAuth;
17321734
session->auth.size = authDigestSz + handle->auth.size;
17331735
XMEMCPY(&session->auth.buffer[authDigestSz], handle->auth.buffer,
17341736
handle->auth.size);
@@ -1862,16 +1864,19 @@ int wolfTPM2_SetSessionHandle(WOLFTPM2_DEV* dev, int index,
18621864

18631865
/* Set password handle unless TPM session is available */
18641866
if (tpmSession) {
1865-
session->sessionHandle = tpmSession->handle.hndl;
1866-
1867-
session->auth.size = tpmSession->handle.auth.size;
1868-
if (session->auth.size > sizeof(session->auth.buffer)) {
1867+
/* Validate bounds before mutating session state so the session
1868+
* isn't left inconsistent on BUFFER_E. */
1869+
if (tpmSession->handle.auth.size > sizeof(session->auth.buffer)) {
18691870
#ifdef DEBUG_WOLFTPM
18701871
printf("SetSessionHandle: auth size %d exceeds buffer %d\n",
1871-
session->auth.size, (int)sizeof(session->auth.buffer));
1872+
tpmSession->handle.auth.size,
1873+
(int)sizeof(session->auth.buffer));
18721874
#endif
18731875
return BUFFER_E;
18741876
}
1877+
1878+
session->sessionHandle = tpmSession->handle.hndl;
1879+
session->auth.size = tpmSession->handle.auth.size;
18751880
XMEMCPY(session->auth.buffer, tpmSession->handle.auth.buffer,
18761881
session->auth.size);
18771882

@@ -9249,14 +9254,20 @@ int wolfTPM2_SetIdentityAuth(WOLFTPM2_DEV* dev, WOLFTPM2_HANDLE* handle,
92499254
wc_HashFree(&hash_ctx, hashType);
92509255
}
92519256

9252-
/* Hash Final truncate to 16 bytes */
9253-
/* Use 16-byte for auth when accessing key */
9254-
handle->auth.size = 16;
9255-
XMEMCPY(handle->auth.buffer, &digest[16], 16);
9256-
#ifdef DEBUG_WOLFTPM
9257-
printf("Handle 0x%x, Auth %d\n", handle->hndl, handle->auth.size);
9258-
TPM2_PrintBin(handle->auth.buffer, handle->auth.size);
9259-
#endif
9257+
/* Only copy digest to handle auth when hashing succeeded — otherwise
9258+
* `digest` contains uninitialized stack data. */
9259+
if (rc == 0) {
9260+
/* Hash Final truncate to 16 bytes — use 16-byte auth for key access */
9261+
handle->auth.size = 16;
9262+
XMEMCPY(handle->auth.buffer, &digest[16], 16);
9263+
#ifdef DEBUG_WOLFTPM
9264+
printf("Handle 0x%x, Auth %d\n", handle->hndl, handle->auth.size);
9265+
TPM2_PrintBin(handle->auth.buffer, handle->auth.size);
9266+
#endif
9267+
}
9268+
else {
9269+
handle->auth.size = 0;
9270+
}
92609271

92619272
TPM2_ForceZero(digest, sizeof(digest));
92629273
TPM2_ForceZero(serialNum, sizeof(serialNum));

wolftpm/tpm2_crypto.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,9 @@ WOLFTPM_API int TPM2_KDFe(
144144

145145
/* --- Crypto Primitive Wrappers --- */
146146

147-
#ifndef NO_AES
147+
#ifndef WOLFTPM2_NO_WOLFCRYPT
148+
149+
#if !defined(NO_AES) && defined(WOLFSSL_AES_CFB)
148150
/*!
149151
\ingroup TPM2_Crypto
150152
\brief AES-CFB one-shot encrypt (in-place).
@@ -184,7 +186,7 @@ WOLFTPM_API int TPM2_AesCfbDecrypt(
184186
const byte* key, int keySz,
185187
const byte* iv,
186188
byte* data, word32 dataSz);
187-
#endif /* !NO_AES */
189+
#endif /* !NO_AES && WOLFSSL_AES_CFB */
188190

189191
#ifndef NO_HMAC
190192
/*!
@@ -264,6 +266,8 @@ WOLFTPM_API int TPM2_HashCompute(
264266
const byte* data, word32 dataSz,
265267
byte* digest, word32* digestSz);
266268

269+
#endif /* !WOLFTPM2_NO_WOLFCRYPT */
270+
267271
#ifdef __cplusplus
268272
} /* extern "C" */
269273
#endif

0 commit comments

Comments
 (0)