Skip to content

Commit 64a7cfb

Browse files
Eric Biggersjarkkojs
authored andcommitted
tpm: Use HMAC-SHA256 library instead of open-coded HMAC
Now that there are easy-to-use HMAC-SHA256 library functions, use these in tpm2-sessions.c instead of open-coding the HMAC algorithm. Note that the new implementation correctly handles keys longer than 64 bytes (SHA256_BLOCK_SIZE), whereas the old implementation handled such keys incorrectly. But it doesn't appear that such keys were being used. Signed-off-by: Eric Biggers <ebiggers@kernel.org> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
1 parent 2c2615c commit 64a7cfb

1 file changed

Lines changed: 27 additions & 71 deletions

File tree

drivers/char/tpm/tpm2-sessions.c

Lines changed: 27 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@
6969
#include <linux/unaligned.h>
7070
#include <crypto/kpp.h>
7171
#include <crypto/ecdh.h>
72-
#include <crypto/hash.h>
73-
#include <crypto/hmac.h>
72+
#include <crypto/sha2.h>
7473
#include <crypto/utils.h>
7574

7675
/* maximum number of names the TPM must remember for authorization */
@@ -385,51 +384,6 @@ EXPORT_SYMBOL_GPL(tpm_buf_append_hmac_session);
385384
static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy,
386385
u32 *handle, u8 *name);
387386

388-
/*
389-
* It turns out the crypto hmac(sha256) is hard for us to consume
390-
* because it assumes a fixed key and the TPM seems to change the key
391-
* on every operation, so we weld the hmac init and final functions in
392-
* here to give it the same usage characteristics as a regular hash
393-
*/
394-
static void tpm2_hmac_init(struct sha256_ctx *sctx, u8 *key, u32 key_len)
395-
{
396-
u8 pad[SHA256_BLOCK_SIZE];
397-
int i;
398-
399-
sha256_init(sctx);
400-
for (i = 0; i < sizeof(pad); i++) {
401-
if (i < key_len)
402-
pad[i] = key[i];
403-
else
404-
pad[i] = 0;
405-
pad[i] ^= HMAC_IPAD_VALUE;
406-
}
407-
sha256_update(sctx, pad, sizeof(pad));
408-
}
409-
410-
static void tpm2_hmac_final(struct sha256_ctx *sctx, u8 *key, u32 key_len,
411-
u8 *out)
412-
{
413-
u8 pad[SHA256_BLOCK_SIZE];
414-
int i;
415-
416-
for (i = 0; i < sizeof(pad); i++) {
417-
if (i < key_len)
418-
pad[i] = key[i];
419-
else
420-
pad[i] = 0;
421-
pad[i] ^= HMAC_OPAD_VALUE;
422-
}
423-
424-
/* collect the final hash; use out as temporary storage */
425-
sha256_final(sctx, out);
426-
427-
sha256_init(sctx);
428-
sha256_update(sctx, pad, sizeof(pad));
429-
sha256_update(sctx, out, SHA256_DIGEST_SIZE);
430-
sha256_final(sctx, out);
431-
}
432-
433387
/*
434388
* assume hash sha256 and nonces u, v of size SHA256_DIGEST_SIZE but
435389
* otherwise standard tpm2_KDFa. Note output is in bytes not bits.
@@ -441,16 +395,16 @@ static void tpm2_KDFa(u8 *key, u32 key_len, const char *label, u8 *u,
441395
const __be32 bits = cpu_to_be32(bytes * 8);
442396

443397
while (bytes > 0) {
444-
struct sha256_ctx sctx;
398+
struct hmac_sha256_ctx hctx;
445399
__be32 c = cpu_to_be32(counter);
446400

447-
tpm2_hmac_init(&sctx, key, key_len);
448-
sha256_update(&sctx, (u8 *)&c, sizeof(c));
449-
sha256_update(&sctx, label, strlen(label)+1);
450-
sha256_update(&sctx, u, SHA256_DIGEST_SIZE);
451-
sha256_update(&sctx, v, SHA256_DIGEST_SIZE);
452-
sha256_update(&sctx, (u8 *)&bits, sizeof(bits));
453-
tpm2_hmac_final(&sctx, key, key_len, out);
401+
hmac_sha256_init_usingrawkey(&hctx, key, key_len);
402+
hmac_sha256_update(&hctx, (u8 *)&c, sizeof(c));
403+
hmac_sha256_update(&hctx, label, strlen(label) + 1);
404+
hmac_sha256_update(&hctx, u, SHA256_DIGEST_SIZE);
405+
hmac_sha256_update(&hctx, v, SHA256_DIGEST_SIZE);
406+
hmac_sha256_update(&hctx, (u8 *)&bits, sizeof(bits));
407+
hmac_sha256_final(&hctx, out);
454408

455409
bytes -= SHA256_DIGEST_SIZE;
456410
counter++;
@@ -594,6 +548,7 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
594548
u32 attrs;
595549
u8 cphash[SHA256_DIGEST_SIZE];
596550
struct sha256_ctx sctx;
551+
struct hmac_sha256_ctx hctx;
597552

598553
if (!auth)
599554
return;
@@ -705,14 +660,14 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
705660
sha256_final(&sctx, cphash);
706661

707662
/* now calculate the hmac */
708-
tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
709-
+ auth->passphrase_len);
710-
sha256_update(&sctx, cphash, sizeof(cphash));
711-
sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce));
712-
sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
713-
sha256_update(&sctx, &auth->attrs, 1);
714-
tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
715-
+ auth->passphrase_len, hmac);
663+
hmac_sha256_init_usingrawkey(&hctx, auth->session_key,
664+
sizeof(auth->session_key) +
665+
auth->passphrase_len);
666+
hmac_sha256_update(&hctx, cphash, sizeof(cphash));
667+
hmac_sha256_update(&hctx, auth->our_nonce, sizeof(auth->our_nonce));
668+
hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
669+
hmac_sha256_update(&hctx, &auth->attrs, 1);
670+
hmac_sha256_final(&hctx, hmac);
716671
}
717672
EXPORT_SYMBOL(tpm_buf_fill_hmac_session);
718673

@@ -752,6 +707,7 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
752707
u8 rphash[SHA256_DIGEST_SIZE];
753708
u32 attrs, cc;
754709
struct sha256_ctx sctx;
710+
struct hmac_sha256_ctx hctx;
755711
u16 tag = be16_to_cpu(head->tag);
756712
int parm_len, len, i, handles;
757713

@@ -821,15 +777,15 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
821777
sha256_final(&sctx, rphash);
822778

823779
/* now calculate the hmac */
824-
tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
825-
+ auth->passphrase_len);
826-
sha256_update(&sctx, rphash, sizeof(rphash));
827-
sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
828-
sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce));
829-
sha256_update(&sctx, &auth->attrs, 1);
780+
hmac_sha256_init_usingrawkey(&hctx, auth->session_key,
781+
sizeof(auth->session_key) +
782+
auth->passphrase_len);
783+
hmac_sha256_update(&hctx, rphash, sizeof(rphash));
784+
hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
785+
hmac_sha256_update(&hctx, auth->our_nonce, sizeof(auth->our_nonce));
786+
hmac_sha256_update(&hctx, &auth->attrs, 1);
830787
/* we're done with the rphash, so put our idea of the hmac there */
831-
tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
832-
+ auth->passphrase_len, rphash);
788+
hmac_sha256_final(&hctx, rphash);
833789
if (crypto_memneq(rphash, &buf->data[offset_s], SHA256_DIGEST_SIZE)) {
834790
dev_err(&chip->dev, "TPM: HMAC check failed\n");
835791
goto out;

0 commit comments

Comments
 (0)