Skip to content

Commit e693eb0

Browse files
jarkkojsgregkh
authored andcommitted
tpm: Lazily flush the auth session
[ Upstream commit df745e2 ] Move the allocation of chip->auth to tpm2_start_auth_session() so that this field can be used as flag to tell whether auth session is active or not. Instead of flushing and reloading the auth session for every transaction separately, keep the session open unless /dev/tpm0 is used. Reported-by: Pengyu Ma <[email protected]> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219229 Cc: [email protected] # v6.10+ Fixes: 7ca110f ("tpm: Address !chip->auth in tpm_buf_append_hmac_session*()") Tested-by: Pengyu Ma <[email protected]> Tested-by: Stefan Berger <[email protected]> Reviewed-by: Stefan Berger <[email protected]> Signed-off-by: Jarkko Sakkinen <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent ddb0615 commit e693eb0

File tree

4 files changed

+44
-20
lines changed

4 files changed

+44
-20
lines changed

drivers/char/tpm/tpm-chip.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,16 @@ EXPORT_SYMBOL_GPL(tpm_chip_register);
674674
*/
675675
void tpm_chip_unregister(struct tpm_chip *chip)
676676
{
677+
#ifdef CONFIG_TCG_TPM2_HMAC
678+
int rc;
679+
680+
rc = tpm_try_get_ops(chip);
681+
if (!rc) {
682+
tpm2_end_auth_session(chip);
683+
tpm_put_ops(chip);
684+
}
685+
#endif
686+
677687
tpm_del_legacy_sysfs(chip);
678688
if (tpm_is_hwrng_enabled(chip))
679689
hwrng_unregister(&chip->hwrng);

drivers/char/tpm/tpm-dev-common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ static ssize_t tpm_dev_transmit(struct tpm_chip *chip, struct tpm_space *space,
2727
struct tpm_header *header = (void *)buf;
2828
ssize_t ret, len;
2929

30+
if (chip->flags & TPM_CHIP_FLAG_TPM2)
31+
tpm2_end_auth_session(chip);
32+
3033
ret = tpm2_prepare_space(chip, space, buf, bufsiz);
3134
/* If the command is not implemented by the TPM, synthesize a
3235
* response with a TPM2_RC_COMMAND_CODE return for user-space.

drivers/char/tpm/tpm-interface.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,10 +379,12 @@ int tpm_pm_suspend(struct device *dev)
379379

380380
rc = tpm_try_get_ops(chip);
381381
if (!rc) {
382-
if (chip->flags & TPM_CHIP_FLAG_TPM2)
382+
if (chip->flags & TPM_CHIP_FLAG_TPM2) {
383+
tpm2_end_auth_session(chip);
383384
tpm2_shutdown(chip, TPM2_SU_STATE);
384-
else
385+
} else {
385386
rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
387+
}
386388

387389
tpm_put_ops(chip);
388390
}

drivers/char/tpm/tpm2-sessions.c

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
333333
}
334334

335335
#ifdef CONFIG_TCG_TPM2_HMAC
336+
/* The first write to /dev/tpm{rm0} will flush the session. */
337+
attributes |= TPM2_SA_CONTINUE_SESSION;
338+
336339
/*
337340
* The Architecture Guide requires us to strip trailing zeros
338341
* before computing the HMAC
@@ -484,7 +487,8 @@ static void tpm2_KDFe(u8 z[EC_PT_SZ], const char *str, u8 *pt_u, u8 *pt_v,
484487
sha256_final(&sctx, out);
485488
}
486489

487-
static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip)
490+
static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip,
491+
struct tpm2_auth *auth)
488492
{
489493
struct crypto_kpp *kpp;
490494
struct kpp_request *req;
@@ -543,7 +547,7 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip)
543547
sg_set_buf(&s[0], chip->null_ec_key_x, EC_PT_SZ);
544548
sg_set_buf(&s[1], chip->null_ec_key_y, EC_PT_SZ);
545549
kpp_request_set_input(req, s, EC_PT_SZ*2);
546-
sg_init_one(d, chip->auth->salt, EC_PT_SZ);
550+
sg_init_one(d, auth->salt, EC_PT_SZ);
547551
kpp_request_set_output(req, d, EC_PT_SZ);
548552
crypto_kpp_compute_shared_secret(req);
549553
kpp_request_free(req);
@@ -554,8 +558,7 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip)
554558
* This works because KDFe fully consumes the secret before it
555559
* writes the salt
556560
*/
557-
tpm2_KDFe(chip->auth->salt, "SECRET", x, chip->null_ec_key_x,
558-
chip->auth->salt);
561+
tpm2_KDFe(auth->salt, "SECRET", x, chip->null_ec_key_x, auth->salt);
559562

560563
out:
561564
crypto_free_kpp(kpp);
@@ -853,7 +856,9 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
853856
if (rc)
854857
/* manually close the session if it wasn't consumed */
855858
tpm2_flush_context(chip, auth->handle);
856-
memzero_explicit(auth, sizeof(*auth));
859+
860+
kfree_sensitive(auth);
861+
chip->auth = NULL;
857862
} else {
858863
/* reset for next use */
859864
auth->session = TPM_HEADER_SIZE;
@@ -881,7 +886,8 @@ void tpm2_end_auth_session(struct tpm_chip *chip)
881886
return;
882887

883888
tpm2_flush_context(chip, auth->handle);
884-
memzero_explicit(auth, sizeof(*auth));
889+
kfree_sensitive(auth);
890+
chip->auth = NULL;
885891
}
886892
EXPORT_SYMBOL(tpm2_end_auth_session);
887893

@@ -962,16 +968,20 @@ static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key)
962968
*/
963969
int tpm2_start_auth_session(struct tpm_chip *chip)
964970
{
971+
struct tpm2_auth *auth;
965972
struct tpm_buf buf;
966-
struct tpm2_auth *auth = chip->auth;
967-
int rc;
968973
u32 null_key;
974+
int rc;
969975

970-
if (!auth) {
971-
dev_warn_once(&chip->dev, "auth session is not active\n");
976+
if (chip->auth) {
977+
dev_warn_once(&chip->dev, "auth session is active\n");
972978
return 0;
973979
}
974980

981+
auth = kzalloc(sizeof(*auth), GFP_KERNEL);
982+
if (!auth)
983+
return -ENOMEM;
984+
975985
rc = tpm2_load_null(chip, &null_key);
976986
if (rc)
977987
goto out;
@@ -992,7 +1002,7 @@ int tpm2_start_auth_session(struct tpm_chip *chip)
9921002
tpm_buf_append(&buf, auth->our_nonce, sizeof(auth->our_nonce));
9931003

9941004
/* append encrypted salt and squirrel away unencrypted in auth */
995-
tpm_buf_append_salt(&buf, chip);
1005+
tpm_buf_append_salt(&buf, chip, auth);
9961006
/* session type (HMAC, audit or policy) */
9971007
tpm_buf_append_u8(&buf, TPM2_SE_HMAC);
9981008

@@ -1014,10 +1024,13 @@ int tpm2_start_auth_session(struct tpm_chip *chip)
10141024

10151025
tpm_buf_destroy(&buf);
10161026

1017-
if (rc)
1018-
goto out;
1027+
if (rc == TPM2_RC_SUCCESS) {
1028+
chip->auth = auth;
1029+
return 0;
1030+
}
10191031

1020-
out:
1032+
out:
1033+
kfree_sensitive(auth);
10211034
return rc;
10221035
}
10231036
EXPORT_SYMBOL(tpm2_start_auth_session);
@@ -1367,10 +1380,6 @@ int tpm2_sessions_init(struct tpm_chip *chip)
13671380
return rc;
13681381
}
13691382

1370-
chip->auth = kmalloc(sizeof(*chip->auth), GFP_KERNEL);
1371-
if (!chip->auth)
1372-
return -ENOMEM;
1373-
13741383
return rc;
13751384
}
13761385
EXPORT_SYMBOL(tpm2_sessions_init);

0 commit comments

Comments
 (0)