From 0e43ce47169b14f29509031908fff5b15fff20e0 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 29 Oct 2026 14:29:06 -0700 Subject: [PATCH 1/2] client: bound and wipe the TPM key blob load readKeyBlob() checks each part of the key file against its destination before reading it, and every failure now returns an error with the file closed. wolfSSH_TPM_InitKey() refuses a key auth that does not fit the blob, and the key material is wiped once it is no longer needed. - reject a public size over pubAreaBuffer, a private part over key->priv - return BUFFER_E on a short read; parse errors go through exit - refuse a -K value longer than the auth buffer - wipe the key blob and session on return, the TPM key on cleanup Issue: F-8855, F-10558, F-10604, F-10601, F-10602, F-10603 --- examples/client/common.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/examples/client/common.c b/examples/client/common.c index d78f2fa56..6ab74f961 100644 --- a/examples/client/common.c +++ b/examples/client/common.c @@ -856,23 +856,33 @@ static int readKeyBlob(const char* filename, WOLFTPM2_KEYBLOB* key) if (bytes_read != sizeof(key->pub.size)) { printf("Read %zu, expected size marker of %zu bytes\n", bytes_read, sizeof(key->pub.size)); - goto exit; + rc = BUFFER_E; goto exit; } fileSz -= bytes_read; + if (sizeof(UINT16) + key->pub.size > sizeof(pubAreaBuffer)) { + printf("Public blob of %d bytes is too large\n", key->pub.size); + rc = BUFFER_E; goto exit; + } + bytes_read = WFREAD(NULL, pubAreaBuffer, 1, sizeof(UINT16) + key->pub.size, fp); if (bytes_read != sizeof(UINT16) + key->pub.size) { printf("Read %zu, expected public blob %zu bytes\n", bytes_read, sizeof(UINT16) + key->pub.size); - goto exit; + rc = BUFFER_E; goto exit; } fileSz -= bytes_read; /* Reminder bytes for private key part */ + if (fileSz > sizeof(key->priv)) { + printf("Private blob of %zu bytes is too large\n", fileSz); + rc = BUFFER_E; goto exit; + } + /* Decode the byte stream into a publicArea structure ready for use */ rc = TPM2_ParsePublic(&key->pub, pubAreaBuffer, (word32)sizeof(pubAreaBuffer), &pubAreaSize); - if (rc != 0) return rc; + if (rc != 0) goto exit; if (fileSz > 0) { printf("Reading the private part of the key\n"); @@ -880,7 +890,7 @@ static int readKeyBlob(const char* filename, WOLFTPM2_KEYBLOB* key) if (bytes_read != fileSz) { printf("Read %zu, expected private blob %zu bytes\n", bytes_read, fileSz); - goto exit; + rc = BUFFER_E; goto exit; } rc = 0; /* success */ } @@ -966,6 +976,11 @@ static int wolfSSH_TPM_InitKey(WOLFTPM2_DEV* dev, const char* name, } /* Use global auth if provided */ + if (rc == 0 && tpmKeyAuth != NULL && + XSTRLEN(tpmKeyAuth) > sizeof(tpmKeyBlob.handle.auth.buffer)) { + WLOG(WS_LOG_DEBUG, "TPM key auth is too long"); + rc = BUFFER_E; + } if (rc == 0 && tpmKeyAuth != NULL) { tpmKeyBlob.handle.auth.size = (word32)XSTRLEN(tpmKeyAuth); XMEMCPY(tpmKeyBlob.handle.auth.buffer, tpmKeyAuth, @@ -1015,6 +1030,10 @@ static int wolfSSH_TPM_InitKey(WOLFTPM2_DEV* dev, const char* name, wolfTPM2_UnloadHandle(dev, &endorse.handle); } + /* The blob holds the key auth; the session may hold auth data too. */ + wc_ForceZero(&tpmKeyBlob, sizeof(tpmKeyBlob)); + wc_ForceZero(&tpmSession, sizeof(tpmSession)); + WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_TPM_InitKey(), rc = %d", rc); return rc; } @@ -1024,6 +1043,7 @@ static void wolfSSH_TPM_Cleanup(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key) WLOG(WS_LOG_DEBUG, "Entering wolfSSH_TPM_Cleanup()"); if (key != NULL) { wolfTPM2_UnloadHandle(dev, &key->handle); + wc_ForceZero(key, sizeof(*key)); } if (dev != NULL) { From c7b0aa493c7f6955b00d38f794cfb50885ced04d Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 29 Oct 2026 14:29:06 -0700 Subject: [PATCH 2/2] client: load the built-in public key by default Without -i the client loads the built-in private key, so load its public half too and publickey auth with the default keys works. A -j file or a TPM key still supplies its own public key. Issue: F-13905 --- examples/client/client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/client/client.c b/examples/client/client.c index 35356dd42..8505fe97a 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1045,7 +1045,9 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args) } else #endif - if (pubKeyName) { + /* Without -i the built-in private key is loaded; a NULL name loads its + * public half. A TPM key fills in its own public key. */ + if (pubKeyName != NULL || privKeyName == NULL) { ret = ClientUsePubKey(pubKeyName, userEcc, NULL); } if (ret != 0) {