Skip to content

Commit 2c2615c

Browse files
Eric Biggersjarkkojs
authored andcommitted
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>
1 parent 4bddf45 commit 2c2615c

2 files changed

Lines changed: 4 additions & 3 deletions

File tree

drivers/char/tpm/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ config TCG_TPM2_HMAC
3333
select CRYPTO_ECDH
3434
select CRYPTO_LIB_AESCFB
3535
select CRYPTO_LIB_SHA256
36+
select CRYPTO_LIB_UTILS
3637
help
3738
Setting this causes us to deploy a scheme which uses request
3839
and response HMACs in addition to encryption for

drivers/char/tpm/tpm2-sessions.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
#include <crypto/ecdh.h>
7272
#include <crypto/hash.h>
7373
#include <crypto/hmac.h>
74+
#include <crypto/utils.h>
7475

7576
/* maximum number of names the TPM must remember for authorization */
7677
#define AUTH_MAX_NAMES 3
@@ -829,12 +830,11 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
829830
/* we're done with the rphash, so put our idea of the hmac there */
830831
tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
831832
+ auth->passphrase_len, rphash);
832-
if (memcmp(rphash, &buf->data[offset_s], SHA256_DIGEST_SIZE) == 0) {
833-
rc = 0;
834-
} else {
833+
if (crypto_memneq(rphash, &buf->data[offset_s], SHA256_DIGEST_SIZE)) {
835834
dev_err(&chip->dev, "TPM: HMAC check failed\n");
836835
goto out;
837836
}
837+
rc = 0;
838838

839839
/* now do response decryption */
840840
if (auth->attrs & TPM2_SA_ENCRYPT) {

0 commit comments

Comments
 (0)