From 80f87339fb73fd50b581b5927711e45e64279348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Th=C3=B6ni?= Date: Fri, 10 May 2024 23:16:37 +0200 Subject: [PATCH] ESYS: StartAuthSession bind auth trailing zeroes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When StartAuthSession is called with a bind entity with a auth value containing trailing zeroes, the HMAC or policy session computation of ESYS does not match the computation on the TPM2. The fix is to remove trailing zeroes from the auth value according to the specification (TPM2 Architecture, 19.6.5, Note 2) before computation of the session key. The fixed bug is especially tricky as a randomly generated auth value of the bind object can cause HMAC or policy session to fail occassionally. Signed-off-by: Stefan Thöni --- src/tss2-esys/api/Esys_StartAuthSession.c | 29 ++++++++++++++++------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/tss2-esys/api/Esys_StartAuthSession.c b/src/tss2-esys/api/Esys_StartAuthSession.c index 076760d0b..95b8bf7ed 100644 --- a/src/tss2-esys/api/Esys_StartAuthSession.c +++ b/src/tss2-esys/api/Esys_StartAuthSession.c @@ -458,8 +458,23 @@ Esys_StartAuthSession_Finish( size_t secret_size = 0; if (tpmKey != ESYS_TR_NONE) secret_size += keyHash_size; - if (bind != ESYS_TR_NONE && bindNode != NULL) - secret_size += bindNode->auth.size; + TPM2B_DIGEST bindNodeAuth = { + .buffer = { }, + .size = 0, + }; + if (bind != ESYS_TR_NONE && bindNode != NULL) { + /* + * TPM2.0 Architecture 19.6.5 Note 2 + * + * Remove tailing zeroes from the auth value + */ + bindNodeAuth.size = bindNode->auth.size; + while ((bindNodeAuth.size > 0) && + (bindNode->auth.buffer[bindNodeAuth.size - 1] == 0x00)) + bindNodeAuth.size--; + memcpy(&bindNodeAuth.buffer[0], &bindNode->auth.buffer[0], bindNodeAuth.size); + secret_size += bindNodeAuth.size; + } /* * A non null pointer for secret is required by the subsequent functions, * hence a malloc is called with size 1 if secret_size is zero. @@ -469,16 +484,14 @@ Esys_StartAuthSession_Finish( LOG_ERROR("Out of memory."); return TSS2_ESYS_RC_MEMORY; } - if (bind != ESYS_TR_NONE && bindNode != NULL - && bindNode->auth.size > 0) - memcpy(&secret[0], &bindNode->auth.buffer[0], bindNode->auth.size); + if (bindNodeAuth.size > 0) + memcpy(&secret[0], &bindNodeAuth.buffer[0], bindNodeAuth.size); if (tpmKey != ESYS_TR_NONE) - memcpy(&secret[(bind == ESYS_TR_NONE || bindNode == NULL) ? 0 - : bindNode->auth.size], + memcpy(&secret[bindNodeAuth.size], &esysContext->salt.buffer[0], keyHash_size); if (bind != ESYS_TR_NONE && bindNode != NULL) iesys_compute_bound_entity(&bindNode->rsrc.name, - &bindNode->auth, + &bindNodeAuth, &sessionHandleNode->rsrc.misc.rsrc_session.bound_entity); LOGBLOB_DEBUG(secret, secret_size, "ESYS Session Secret"); r = iesys_crypto_KDFa(&esysContext->crypto_backend, esysContext->in.StartAuthSession.authHash, secret,