summaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm/tpm2-sessions.c
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@kernel.org>2025-08-01 14:24:21 -0700
committerJarkko Sakkinen <jarkko@kernel.org>2025-10-10 08:21:45 +0300
commit2c2615c8423890b5ef8e0a186b65607ef5fdeda1 (patch)
tree5c5a8a6c0aaa04ae71f0d0cb5501d1215070a0c6 /drivers/char/tpm/tpm2-sessions.c
parenttpm: Disable TPM2_TCG_HMAC by default (diff)
downloadlinux-2c2615c8423890b5ef8e0a186b65607ef5fdeda1.tar.gz
linux-2c2615c8423890b5ef8e0a186b65607ef5fdeda1.zip
tpm: Compare HMAC values in constant time
In tpm_buf_check_hmac_response(), compare the HMAC values in constant time using crypto_memneq() instead of in variable time using memcmp(). This is worthwhile to follow best practices and to be consistent with MAC comparisons elsewhere in the kernel. However, in this driver the side channel seems to have been benign: the HMAC input data is guaranteed to always be unique, which makes the usual MAC forgery via timing side channel not possible. Specifically, the HMAC input data in tpm_buf_check_hmac_response() includes the "our_nonce" field, which was generated by the kernel earlier, remains under the control of the kernel, and is unique for each call to tpm_buf_check_hmac_response(). Signed-off-by: Eric Biggers <ebiggers@kernel.org> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Diffstat (limited to '')
-rw-r--r--drivers/char/tpm/tpm2-sessions.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c
index bdb119453dfb..5fbd62ee5090 100644
--- a/drivers/char/tpm/tpm2-sessions.c
+++ b/drivers/char/tpm/tpm2-sessions.c
@@ -71,6 +71,7 @@
#include <crypto/ecdh.h>
#include <crypto/hash.h>
#include <crypto/hmac.h>
+#include <crypto/utils.h>
/* maximum number of names the TPM must remember for authorization */
#define AUTH_MAX_NAMES 3
@@ -829,12 +830,11 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
/* we're done with the rphash, so put our idea of the hmac there */
tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
+ auth->passphrase_len, rphash);
- if (memcmp(rphash, &buf->data[offset_s], SHA256_DIGEST_SIZE) == 0) {
- rc = 0;
- } else {
+ if (crypto_memneq(rphash, &buf->data[offset_s], SHA256_DIGEST_SIZE)) {
dev_err(&chip->dev, "TPM: HMAC check failed\n");
goto out;
}
+ rc = 0;
/* now do response decryption */
if (auth->attrs & TPM2_SA_ENCRYPT) {