Hi,
Round #2. O_EXCL patches will be postponed to 6.19 as they need some restructuring. E.g., there's in-between series regression breaking the user space as lack of O_EXCL flag handling causes obviously unconditional O_EXCL. As per Chris' feedback, commands fail because it is based on Google's a non-standard proprietary TPM alike implementation. And the issue is not PC Client Profile specific. "typical profiles" are fine when they become "typical profiles". The null key can be verified with vendor certificate tied keys, and there's challenge-response process using them for certifying any other key by a remote party. Performance hit on generation aside, if really starting to cut hairs null keys are the most secure option, and it's a non-debatable fact: they have shortest expiration times as seed changes per power cycle. Based on this TCG_TPM2_HMAC is disabled from defconfig exactly for the sake of the performance issues. BR, Jarkko -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQRE6pSOnaBC00OEHEIaerohdGur0gUCaOiYuAAKCRAaerohdGur 0rcQAPwM2bZ9euY6uvH+bJO73UFcqRmQZGLloqx4FAM92893rAEA1PHznYNj/8MO 58yt99PE4DK7XSamSemcDL/OHXmgvQI= =ZbHp -----END PGP SIGNATURE----- Merge tag 'tpmdd-next-v6.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd Pull tpm updates from Jarkko Sakkinen: - Disable TCG_TPM2_HMAC from defconfig It causes performance issues, and breaks some atypical configurations. - simplify code using the new crypto library - misc fixes and cleanups * tag 'tpmdd-next-v6.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: tpm: Prevent local DOS via tpm/tpm0/ppi/*operations tpm: use a map for tpm2_calc_ordinal_duration() tpm_tis: Fix incorrect arguments in tpm_tis_probe_irq_single tpm: Use HMAC-SHA256 library instead of open-coded HMAC tpm: Compare HMAC values in constant time tpm: Disable TPM2_TCG_HMAC by default
This commit is contained in:
commit
84d4e8b613
|
@ -29,10 +29,11 @@ if TCG_TPM
|
|||
|
||||
config TCG_TPM2_HMAC
|
||||
bool "Use HMAC and encrypted transactions on the TPM bus"
|
||||
default X86_64
|
||||
default n
|
||||
select CRYPTO_ECDH
|
||||
select CRYPTO_LIB_AESCFB
|
||||
select CRYPTO_LIB_SHA256
|
||||
select CRYPTO_LIB_UTILS
|
||||
help
|
||||
Setting this causes us to deploy a scheme which uses request
|
||||
and response HMACs in addition to encryption for
|
||||
|
|
|
@ -52,7 +52,7 @@ MODULE_PARM_DESC(suspend_pcr,
|
|||
unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
|
||||
{
|
||||
if (chip->flags & TPM_CHIP_FLAG_TPM2)
|
||||
return tpm2_calc_ordinal_duration(chip, ordinal);
|
||||
return tpm2_calc_ordinal_duration(ordinal);
|
||||
else
|
||||
return tpm1_calc_ordinal_duration(chip, ordinal);
|
||||
}
|
||||
|
|
|
@ -299,7 +299,7 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,
|
|||
ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip);
|
||||
int tpm2_auto_startup(struct tpm_chip *chip);
|
||||
void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
|
||||
unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
|
||||
unsigned long tpm2_calc_ordinal_duration(u32 ordinal);
|
||||
int tpm2_probe(struct tpm_chip *chip);
|
||||
int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip);
|
||||
int tpm2_find_cc(struct tpm_chip *chip, u32 cc);
|
||||
|
|
|
@ -28,120 +28,57 @@ static struct tpm2_hash tpm2_hash_map[] = {
|
|||
|
||||
int tpm2_get_timeouts(struct tpm_chip *chip)
|
||||
{
|
||||
/* Fixed timeouts for TPM2 */
|
||||
chip->timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
|
||||
chip->timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B);
|
||||
chip->timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C);
|
||||
chip->timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D);
|
||||
|
||||
/* PTP spec timeouts */
|
||||
chip->duration[TPM_SHORT] = msecs_to_jiffies(TPM2_DURATION_SHORT);
|
||||
chip->duration[TPM_MEDIUM] = msecs_to_jiffies(TPM2_DURATION_MEDIUM);
|
||||
chip->duration[TPM_LONG] = msecs_to_jiffies(TPM2_DURATION_LONG);
|
||||
|
||||
/* Key creation commands long timeouts */
|
||||
chip->duration[TPM_LONG_LONG] =
|
||||
msecs_to_jiffies(TPM2_DURATION_LONG_LONG);
|
||||
|
||||
chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* tpm2_ordinal_duration_index() - returns an index to the chip duration table
|
||||
* @ordinal: TPM command ordinal.
|
||||
*
|
||||
* The function returns an index to the chip duration table
|
||||
* (enum tpm_duration), that describes the maximum amount of
|
||||
* time the chip could take to return the result for a particular ordinal.
|
||||
*
|
||||
* The values of the MEDIUM, and LONG durations are taken
|
||||
* from the PC Client Profile (PTP) specification (750, 2000 msec)
|
||||
*
|
||||
* LONG_LONG is for commands that generates keys which empirically takes
|
||||
* a longer time on some systems.
|
||||
*
|
||||
* Return:
|
||||
* * TPM_MEDIUM
|
||||
* * TPM_LONG
|
||||
* * TPM_LONG_LONG
|
||||
* * TPM_UNDEFINED
|
||||
/*
|
||||
* Contains the maximum durations in milliseconds for TPM2 commands.
|
||||
*/
|
||||
static u8 tpm2_ordinal_duration_index(u32 ordinal)
|
||||
{
|
||||
switch (ordinal) {
|
||||
/* Startup */
|
||||
case TPM2_CC_STARTUP: /* 144 */
|
||||
return TPM_MEDIUM;
|
||||
|
||||
case TPM2_CC_SELF_TEST: /* 143 */
|
||||
return TPM_LONG;
|
||||
|
||||
case TPM2_CC_GET_RANDOM: /* 17B */
|
||||
return TPM_LONG;
|
||||
|
||||
case TPM2_CC_SEQUENCE_UPDATE: /* 15C */
|
||||
return TPM_MEDIUM;
|
||||
case TPM2_CC_SEQUENCE_COMPLETE: /* 13E */
|
||||
return TPM_MEDIUM;
|
||||
case TPM2_CC_EVENT_SEQUENCE_COMPLETE: /* 185 */
|
||||
return TPM_MEDIUM;
|
||||
case TPM2_CC_HASH_SEQUENCE_START: /* 186 */
|
||||
return TPM_MEDIUM;
|
||||
|
||||
case TPM2_CC_VERIFY_SIGNATURE: /* 177 */
|
||||
return TPM_LONG_LONG;
|
||||
|
||||
case TPM2_CC_PCR_EXTEND: /* 182 */
|
||||
return TPM_MEDIUM;
|
||||
|
||||
case TPM2_CC_HIERARCHY_CONTROL: /* 121 */
|
||||
return TPM_LONG;
|
||||
case TPM2_CC_HIERARCHY_CHANGE_AUTH: /* 129 */
|
||||
return TPM_LONG;
|
||||
|
||||
case TPM2_CC_GET_CAPABILITY: /* 17A */
|
||||
return TPM_MEDIUM;
|
||||
|
||||
case TPM2_CC_NV_READ: /* 14E */
|
||||
return TPM_LONG;
|
||||
|
||||
case TPM2_CC_CREATE_PRIMARY: /* 131 */
|
||||
return TPM_LONG_LONG;
|
||||
case TPM2_CC_CREATE: /* 153 */
|
||||
return TPM_LONG_LONG;
|
||||
case TPM2_CC_CREATE_LOADED: /* 191 */
|
||||
return TPM_LONG_LONG;
|
||||
|
||||
default:
|
||||
return TPM_UNDEFINED;
|
||||
}
|
||||
}
|
||||
static const struct {
|
||||
unsigned long ordinal;
|
||||
unsigned long duration;
|
||||
} tpm2_ordinal_duration_map[] = {
|
||||
{TPM2_CC_STARTUP, 750},
|
||||
{TPM2_CC_SELF_TEST, 3000},
|
||||
{TPM2_CC_GET_RANDOM, 2000},
|
||||
{TPM2_CC_SEQUENCE_UPDATE, 750},
|
||||
{TPM2_CC_SEQUENCE_COMPLETE, 750},
|
||||
{TPM2_CC_EVENT_SEQUENCE_COMPLETE, 750},
|
||||
{TPM2_CC_HASH_SEQUENCE_START, 750},
|
||||
{TPM2_CC_VERIFY_SIGNATURE, 30000},
|
||||
{TPM2_CC_PCR_EXTEND, 750},
|
||||
{TPM2_CC_HIERARCHY_CONTROL, 2000},
|
||||
{TPM2_CC_HIERARCHY_CHANGE_AUTH, 2000},
|
||||
{TPM2_CC_GET_CAPABILITY, 750},
|
||||
{TPM2_CC_NV_READ, 2000},
|
||||
{TPM2_CC_CREATE_PRIMARY, 30000},
|
||||
{TPM2_CC_CREATE, 30000},
|
||||
{TPM2_CC_CREATE_LOADED, 30000},
|
||||
};
|
||||
|
||||
/**
|
||||
* tpm2_calc_ordinal_duration() - calculate the maximum command duration
|
||||
* @chip: TPM chip to use.
|
||||
* tpm2_calc_ordinal_duration() - Calculate the maximum command duration
|
||||
* @ordinal: TPM command ordinal.
|
||||
*
|
||||
* The function returns the maximum amount of time the chip could take
|
||||
* to return the result for a particular ordinal in jiffies.
|
||||
*
|
||||
* Return: A maximal duration time for an ordinal in jiffies.
|
||||
* Returns the maximum amount of time the chip is expected by kernel to
|
||||
* take in jiffies.
|
||||
*/
|
||||
unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
|
||||
unsigned long tpm2_calc_ordinal_duration(u32 ordinal)
|
||||
{
|
||||
unsigned int index;
|
||||
int i;
|
||||
|
||||
index = tpm2_ordinal_duration_index(ordinal);
|
||||
for (i = 0; i < ARRAY_SIZE(tpm2_ordinal_duration_map); i++)
|
||||
if (ordinal == tpm2_ordinal_duration_map[i].ordinal)
|
||||
return msecs_to_jiffies(tpm2_ordinal_duration_map[i].duration);
|
||||
|
||||
if (index != TPM_UNDEFINED)
|
||||
return chip->duration[index];
|
||||
else
|
||||
return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
|
||||
return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
struct tpm2_pcr_read_out {
|
||||
__be32 update_cnt;
|
||||
__be32 pcr_selects_cnt;
|
||||
|
|
|
@ -69,8 +69,8 @@
|
|||
#include <linux/unaligned.h>
|
||||
#include <crypto/kpp.h>
|
||||
#include <crypto/ecdh.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <crypto/hmac.h>
|
||||
#include <crypto/sha2.h>
|
||||
#include <crypto/utils.h>
|
||||
|
||||
/* maximum number of names the TPM must remember for authorization */
|
||||
#define AUTH_MAX_NAMES 3
|
||||
|
@ -384,51 +384,6 @@ EXPORT_SYMBOL_GPL(tpm_buf_append_hmac_session);
|
|||
static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy,
|
||||
u32 *handle, u8 *name);
|
||||
|
||||
/*
|
||||
* It turns out the crypto hmac(sha256) is hard for us to consume
|
||||
* because it assumes a fixed key and the TPM seems to change the key
|
||||
* on every operation, so we weld the hmac init and final functions in
|
||||
* here to give it the same usage characteristics as a regular hash
|
||||
*/
|
||||
static void tpm2_hmac_init(struct sha256_ctx *sctx, u8 *key, u32 key_len)
|
||||
{
|
||||
u8 pad[SHA256_BLOCK_SIZE];
|
||||
int i;
|
||||
|
||||
sha256_init(sctx);
|
||||
for (i = 0; i < sizeof(pad); i++) {
|
||||
if (i < key_len)
|
||||
pad[i] = key[i];
|
||||
else
|
||||
pad[i] = 0;
|
||||
pad[i] ^= HMAC_IPAD_VALUE;
|
||||
}
|
||||
sha256_update(sctx, pad, sizeof(pad));
|
||||
}
|
||||
|
||||
static void tpm2_hmac_final(struct sha256_ctx *sctx, u8 *key, u32 key_len,
|
||||
u8 *out)
|
||||
{
|
||||
u8 pad[SHA256_BLOCK_SIZE];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(pad); i++) {
|
||||
if (i < key_len)
|
||||
pad[i] = key[i];
|
||||
else
|
||||
pad[i] = 0;
|
||||
pad[i] ^= HMAC_OPAD_VALUE;
|
||||
}
|
||||
|
||||
/* collect the final hash; use out as temporary storage */
|
||||
sha256_final(sctx, out);
|
||||
|
||||
sha256_init(sctx);
|
||||
sha256_update(sctx, pad, sizeof(pad));
|
||||
sha256_update(sctx, out, SHA256_DIGEST_SIZE);
|
||||
sha256_final(sctx, out);
|
||||
}
|
||||
|
||||
/*
|
||||
* assume hash sha256 and nonces u, v of size SHA256_DIGEST_SIZE but
|
||||
* otherwise standard tpm2_KDFa. Note output is in bytes not bits.
|
||||
|
@ -440,16 +395,16 @@ static void tpm2_KDFa(u8 *key, u32 key_len, const char *label, u8 *u,
|
|||
const __be32 bits = cpu_to_be32(bytes * 8);
|
||||
|
||||
while (bytes > 0) {
|
||||
struct sha256_ctx sctx;
|
||||
struct hmac_sha256_ctx hctx;
|
||||
__be32 c = cpu_to_be32(counter);
|
||||
|
||||
tpm2_hmac_init(&sctx, key, key_len);
|
||||
sha256_update(&sctx, (u8 *)&c, sizeof(c));
|
||||
sha256_update(&sctx, label, strlen(label)+1);
|
||||
sha256_update(&sctx, u, SHA256_DIGEST_SIZE);
|
||||
sha256_update(&sctx, v, SHA256_DIGEST_SIZE);
|
||||
sha256_update(&sctx, (u8 *)&bits, sizeof(bits));
|
||||
tpm2_hmac_final(&sctx, key, key_len, out);
|
||||
hmac_sha256_init_usingrawkey(&hctx, key, key_len);
|
||||
hmac_sha256_update(&hctx, (u8 *)&c, sizeof(c));
|
||||
hmac_sha256_update(&hctx, label, strlen(label) + 1);
|
||||
hmac_sha256_update(&hctx, u, SHA256_DIGEST_SIZE);
|
||||
hmac_sha256_update(&hctx, v, SHA256_DIGEST_SIZE);
|
||||
hmac_sha256_update(&hctx, (u8 *)&bits, sizeof(bits));
|
||||
hmac_sha256_final(&hctx, out);
|
||||
|
||||
bytes -= SHA256_DIGEST_SIZE;
|
||||
counter++;
|
||||
|
@ -593,6 +548,7 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
|
|||
u32 attrs;
|
||||
u8 cphash[SHA256_DIGEST_SIZE];
|
||||
struct sha256_ctx sctx;
|
||||
struct hmac_sha256_ctx hctx;
|
||||
|
||||
if (!auth)
|
||||
return;
|
||||
|
@ -704,14 +660,14 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
|
|||
sha256_final(&sctx, cphash);
|
||||
|
||||
/* now calculate the hmac */
|
||||
tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
|
||||
+ auth->passphrase_len);
|
||||
sha256_update(&sctx, cphash, sizeof(cphash));
|
||||
sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce));
|
||||
sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
|
||||
sha256_update(&sctx, &auth->attrs, 1);
|
||||
tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
|
||||
+ auth->passphrase_len, hmac);
|
||||
hmac_sha256_init_usingrawkey(&hctx, auth->session_key,
|
||||
sizeof(auth->session_key) +
|
||||
auth->passphrase_len);
|
||||
hmac_sha256_update(&hctx, cphash, sizeof(cphash));
|
||||
hmac_sha256_update(&hctx, auth->our_nonce, sizeof(auth->our_nonce));
|
||||
hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
|
||||
hmac_sha256_update(&hctx, &auth->attrs, 1);
|
||||
hmac_sha256_final(&hctx, hmac);
|
||||
}
|
||||
EXPORT_SYMBOL(tpm_buf_fill_hmac_session);
|
||||
|
||||
|
@ -751,6 +707,7 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
|
|||
u8 rphash[SHA256_DIGEST_SIZE];
|
||||
u32 attrs, cc;
|
||||
struct sha256_ctx sctx;
|
||||
struct hmac_sha256_ctx hctx;
|
||||
u16 tag = be16_to_cpu(head->tag);
|
||||
int parm_len, len, i, handles;
|
||||
|
||||
|
@ -820,21 +777,20 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
|
|||
sha256_final(&sctx, rphash);
|
||||
|
||||
/* now calculate the hmac */
|
||||
tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
|
||||
+ auth->passphrase_len);
|
||||
sha256_update(&sctx, rphash, sizeof(rphash));
|
||||
sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
|
||||
sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce));
|
||||
sha256_update(&sctx, &auth->attrs, 1);
|
||||
hmac_sha256_init_usingrawkey(&hctx, auth->session_key,
|
||||
sizeof(auth->session_key) +
|
||||
auth->passphrase_len);
|
||||
hmac_sha256_update(&hctx, rphash, sizeof(rphash));
|
||||
hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
|
||||
hmac_sha256_update(&hctx, auth->our_nonce, sizeof(auth->our_nonce));
|
||||
hmac_sha256_update(&hctx, &auth->attrs, 1);
|
||||
/* 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 {
|
||||
hmac_sha256_final(&hctx, rphash);
|
||||
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) {
|
||||
|
|
|
@ -33,6 +33,20 @@ static const guid_t tpm_ppi_guid =
|
|||
GUID_INIT(0x3DDDFAA6, 0x361B, 0x4EB4,
|
||||
0xA4, 0x24, 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53);
|
||||
|
||||
static const char * const tpm_ppi_info[] = {
|
||||
"Not implemented",
|
||||
"BIOS only",
|
||||
"Blocked for OS by system firmware",
|
||||
"User required",
|
||||
"User not required",
|
||||
};
|
||||
|
||||
/* A spinlock to protect access to the cache from concurrent reads */
|
||||
static DEFINE_MUTEX(tpm_ppi_lock);
|
||||
|
||||
static u32 ppi_operations_cache[PPI_VS_REQ_END + 1];
|
||||
static bool ppi_cache_populated;
|
||||
|
||||
static bool tpm_ppi_req_has_parameter(u64 req)
|
||||
{
|
||||
return req == 23;
|
||||
|
@ -277,8 +291,7 @@ cleanup:
|
|||
return status;
|
||||
}
|
||||
|
||||
static ssize_t show_ppi_operations(acpi_handle dev_handle, char *buf, u32 start,
|
||||
u32 end)
|
||||
static ssize_t cache_ppi_operations(acpi_handle dev_handle, char *buf)
|
||||
{
|
||||
int i;
|
||||
u32 ret;
|
||||
|
@ -286,34 +299,22 @@ static ssize_t show_ppi_operations(acpi_handle dev_handle, char *buf, u32 start,
|
|||
union acpi_object *obj, tmp;
|
||||
union acpi_object argv = ACPI_INIT_DSM_ARGV4(1, &tmp);
|
||||
|
||||
static char *info[] = {
|
||||
"Not implemented",
|
||||
"BIOS only",
|
||||
"Blocked for OS by BIOS",
|
||||
"User required",
|
||||
"User not required",
|
||||
};
|
||||
|
||||
if (!acpi_check_dsm(dev_handle, &tpm_ppi_guid, TPM_PPI_REVISION_ID_1,
|
||||
1 << TPM_PPI_FN_GETOPR))
|
||||
return -EPERM;
|
||||
|
||||
tmp.integer.type = ACPI_TYPE_INTEGER;
|
||||
for (i = start; i <= end; i++) {
|
||||
for (i = 0; i <= PPI_VS_REQ_END; i++) {
|
||||
tmp.integer.value = i;
|
||||
obj = tpm_eval_dsm(dev_handle, TPM_PPI_FN_GETOPR,
|
||||
ACPI_TYPE_INTEGER, &argv,
|
||||
TPM_PPI_REVISION_ID_1);
|
||||
if (!obj) {
|
||||
if (!obj)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
ret = obj->integer.value;
|
||||
ACPI_FREE(obj);
|
||||
}
|
||||
|
||||
if (ret > 0 && ret < ARRAY_SIZE(info))
|
||||
len += sysfs_emit_at(buf, len, "%d %d: %s\n",
|
||||
i, ret, info[ret]);
|
||||
ret = obj->integer.value;
|
||||
ppi_operations_cache[i] = ret;
|
||||
ACPI_FREE(obj);
|
||||
}
|
||||
|
||||
return len;
|
||||
|
@ -324,9 +325,30 @@ static ssize_t tpm_show_ppi_tcg_operations(struct device *dev,
|
|||
char *buf)
|
||||
{
|
||||
struct tpm_chip *chip = to_tpm_chip(dev);
|
||||
ssize_t len = 0;
|
||||
u32 ret;
|
||||
int i;
|
||||
|
||||
return show_ppi_operations(chip->acpi_dev_handle, buf, 0,
|
||||
PPI_TPM_REQ_MAX);
|
||||
mutex_lock(&tpm_ppi_lock);
|
||||
if (!ppi_cache_populated) {
|
||||
len = cache_ppi_operations(chip->acpi_dev_handle, buf);
|
||||
if (len < 0) {
|
||||
mutex_unlock(&tpm_ppi_lock);
|
||||
return len;
|
||||
}
|
||||
|
||||
ppi_cache_populated = true;
|
||||
}
|
||||
|
||||
for (i = 0; i <= PPI_TPM_REQ_MAX; i++) {
|
||||
ret = ppi_operations_cache[i];
|
||||
if (ret >= 0 && ret < ARRAY_SIZE(tpm_ppi_info))
|
||||
len += sysfs_emit_at(buf, len, "%d %d: %s\n",
|
||||
i, ret, tpm_ppi_info[ret]);
|
||||
}
|
||||
mutex_unlock(&tpm_ppi_lock);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t tpm_show_ppi_vs_operations(struct device *dev,
|
||||
|
@ -334,9 +356,30 @@ static ssize_t tpm_show_ppi_vs_operations(struct device *dev,
|
|||
char *buf)
|
||||
{
|
||||
struct tpm_chip *chip = to_tpm_chip(dev);
|
||||
ssize_t len = 0;
|
||||
u32 ret;
|
||||
int i;
|
||||
|
||||
return show_ppi_operations(chip->acpi_dev_handle, buf, PPI_VS_REQ_START,
|
||||
PPI_VS_REQ_END);
|
||||
mutex_lock(&tpm_ppi_lock);
|
||||
if (!ppi_cache_populated) {
|
||||
len = cache_ppi_operations(chip->acpi_dev_handle, buf);
|
||||
if (len < 0) {
|
||||
mutex_unlock(&tpm_ppi_lock);
|
||||
return len;
|
||||
}
|
||||
|
||||
ppi_cache_populated = true;
|
||||
}
|
||||
|
||||
for (i = PPI_VS_REQ_START; i <= PPI_VS_REQ_END; i++) {
|
||||
ret = ppi_operations_cache[i];
|
||||
if (ret >= 0 && ret < ARRAY_SIZE(tpm_ppi_info))
|
||||
len += sysfs_emit_at(buf, len, "%d %d: %s\n",
|
||||
i, ret, tpm_ppi_info[ret]);
|
||||
}
|
||||
mutex_unlock(&tpm_ppi_lock);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(version, S_IRUGO, tpm_show_ppi_version, NULL);
|
||||
|
|
|
@ -978,8 +978,8 @@ restore_irqs:
|
|||
* will call disable_irq which undoes all of the above.
|
||||
*/
|
||||
if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
|
||||
tpm_tis_write8(priv, original_int_vec,
|
||||
TPM_INT_VECTOR(priv->locality));
|
||||
tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality),
|
||||
original_int_vec);
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -228,10 +228,11 @@ enum tpm2_timeouts {
|
|||
TPM2_TIMEOUT_B = 4000,
|
||||
TPM2_TIMEOUT_C = 200,
|
||||
TPM2_TIMEOUT_D = 30,
|
||||
};
|
||||
|
||||
enum tpm2_durations {
|
||||
TPM2_DURATION_SHORT = 20,
|
||||
TPM2_DURATION_MEDIUM = 750,
|
||||
TPM2_DURATION_LONG = 2000,
|
||||
TPM2_DURATION_LONG_LONG = 300000,
|
||||
TPM2_DURATION_DEFAULT = 120000,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue