Skip to content

fwTPM: parameter-encryption key leaves out the authValue when the session isn't bound to the authorized entity #648

Open

Description

@AlexLaroche

In an HMAC session that is not bound to the object it authorizes (an unbound session, or one bound or salted to another object), fwTPM builds the parameter-encryption key from the session key alone. TPM 2.0 Part 1 ("Parameter Encryption", the symmetric key is sessionKey || authValue of the entity the session authorizes) and tpm2-tss include the authorized entity's authValue. FwBuildParamEncKey only appends bindAuth, and only when the session is bound to that same entity. The client and fwTPM then disagree on the key, so an encrypted response decrypts to garbage on the client, and an encrypted command parameter decrypts to garbage in fwTPM.

Effect. tpm2-pkcs11 unseals its token's wrapping key under such a session, gets 64 bytes of garbage, and every C_Login fails ("Expected internal wrapping key in base 16 format").

Reproduction (ESYS).

  1. Create a keyed-hash sealed object with userAuth = "pass" under an owner primary, and load it.
  2. Call Esys_TR_SetAuth(seal, "pass").
  3. Start an unbound, unsalted HMAC session with sym = AES-128-CFB and SHA-256, and set DECRYPT|ENCRYPT|CONTINUESESSION on it.
  4. Esys_Unseal(e, seal, session, ...), then compare the result with the sealed data.

The same steps with a session salted and bound to the parent behave the same way.

                                   fwTPM master    swtpm 0.10.2
Unseal (password session)          same: yes       same: yes
Unseal (unbound, encrypted)        same: NO        same: yes
Unseal (salted+bound, encrypted)   same: NO        same: yes

Suggested fix. When the session isn't bound to the authorized entity, append that entity's authValue, looked up with FwLookupEntityAuth. With this change the encrypted unseals return the sealed data, and tpm2-pkcs11's test suite passes on fwTPM.

diff --git a/src/fwtpm/fwtpm_command.c b/src/fwtpm/fwtpm_command.c
index c4091f3..f5f8b03 100644
--- a/src/fwtpm/fwtpm_command.c
+++ b/src/fwtpm/fwtpm_command.c
@@ -525,10 +525,21 @@ static int FwBuildParamEncKey(FWTPM_CTX* ctx, FWTPM_Session* sess,
     if (sz < 0 || sz > keyBufMax)
         return TPM_RC_FAILURE;
     XMEMCPY(keyBuf, sess->sessionKey.buffer, sz);
-    if (FwSessionIsBoundToEntity(ctx, sess, authHandle) &&
-            sess->bindAuth.size > 0 && sz + sess->bindAuth.size <= keyBufMax) {
-        XMEMCPY(keyBuf + sz, sess->bindAuth.buffer, sess->bindAuth.size);
-        sz += sess->bindAuth.size;
+    if (FwSessionIsBoundToEntity(ctx, sess, authHandle)) {
+        if (sess->bindAuth.size > 0 && sz + sess->bindAuth.size <= keyBufMax) {
+            XMEMCPY(keyBuf + sz, sess->bindAuth.buffer, sess->bindAuth.size);
+            sz += sess->bindAuth.size;
+        }
+    }
+    else if (authHandle != 0) {
+        const byte* entityAuth = NULL;
+        int entityAuthSz = 0;
+        FwLookupEntityAuth(ctx, authHandle, &entityAuth, &entityAuthSz);
+        if (entityAuth != NULL && entityAuthSz > 0 &&
+                sz + entityAuthSz <= keyBufMax) {
+            XMEMCPY(keyBuf + sz, entityAuth, entityAuthSz);
+            sz += entityAuthSz;
+        }
     }
     *keyBufSz = sz;
     return 0;

Environment

  • wolfTPM master at d7f73b5 (also seen in v4.2.0), fwTPM built with ./configure --enable-fwtpm-only --enable-swtpm on wolfSSL v5.9.4-stable (--enable-wolftpm --enable-pkcallbacks --enable-keygen).
  • fwtpm_server --port 2341 --platform-port 2342, reached through the tpm2-tss 4.2.0 swtpm TCTI (swtpm:host=127.0.0.1,port=2341).
  • For comparison, the same program against swtpm 0.10.2 (libtpms).
  • Found while running tpm2-pkcs11 on fwTPM.

Activity

  1. dgarske commented on Oct 28, 2026

    @dgarske
    Member

    Hi @AlexLaroche thank you for all the reports. Can you review and try out the fixes in #656 ?
    Thanks, David Garske, wolfSSL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions