Repository navigation
fwTPM: parameter-encryption key leaves out the authValue when the session isn't bound to the authorized entity #648
Description
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).
- Create a keyed-hash sealed object with
userAuth = "pass"under an owner primary, and load it. - Call
Esys_TR_SetAuth(seal, "pass"). - Start an unbound, unsalted HMAC session with
sym = AES-128-CFBand SHA-256, and setDECRYPT|ENCRYPT|CONTINUESESSIONon it. 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
masterat d7f73b5 (also seen in v4.2.0), fwTPM built with./configure --enable-fwtpm-only --enable-swtpmon 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.0swtpmTCTI (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
dgarske commentedon Oct 28, 2026
Hi @AlexLaroche thank you for all the reports. Can you review and try out the fixes in #656 ?
Thanks, David Garske, wolfSSL
test: run tpm2-pkcs11 over more software TPMs, and on its FAPI store