Commit ec288bd3 authored by Marcin Obara's avatar Marcin Obara Committed by Linus Torvalds

tpm: increase size of internal TPM response buffers

This patch increases size of driver internal response buffers.  Some TPM
responses defined in TCG TPM Specification Version 1.2 Revision 103 have
increased size and do not fit previously defined buffers.  Some TPM
responses do not have fixed size, so bigger response buffers have to be
allocated.  200B buffers should be enough.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: default avatarMarcin Obara <marcin_obara@users.sourceforge.net>
Cc: Marcel Selhorst <tpm@selhorst.net>
Cc: Kylene Jo Hall <kjhall@us.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 3bd60464
...@@ -580,91 +580,133 @@ void tpm_continue_selftest(struct tpm_chip *chip) ...@@ -580,91 +580,133 @@ void tpm_continue_selftest(struct tpm_chip *chip)
} }
EXPORT_SYMBOL_GPL(tpm_continue_selftest); EXPORT_SYMBOL_GPL(tpm_continue_selftest);
#define TPM_INTERNAL_RESULT_SIZE 200
ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr, ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
char *buf) char *buf)
{ {
u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)]; u8 *data;
ssize_t rc; ssize_t rc;
struct tpm_chip *chip = dev_get_drvdata(dev); struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL) if (chip == NULL)
return -ENODEV; return -ENODEV;
data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
if (!data)
return -ENOMEM;
memcpy(data, tpm_cap, sizeof(tpm_cap)); memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_FLAG; data[TPM_CAP_IDX] = TPM_CAP_FLAG;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
rc = transmit_cmd(chip, data, sizeof(data), rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
"attemtping to determine the permanent state"); "attemtping to determine the permanent enabled state");
if (rc) if (rc) {
kfree(data);
return 0; return 0;
return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]); }
rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
kfree(data);
return rc;
} }
EXPORT_SYMBOL_GPL(tpm_show_enabled); EXPORT_SYMBOL_GPL(tpm_show_enabled);
ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr, ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
char *buf) char *buf)
{ {
u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)]; u8 *data;
ssize_t rc; ssize_t rc;
struct tpm_chip *chip = dev_get_drvdata(dev); struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL) if (chip == NULL)
return -ENODEV; return -ENODEV;
data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
if (!data)
return -ENOMEM;
memcpy(data, tpm_cap, sizeof(tpm_cap)); memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_FLAG; data[TPM_CAP_IDX] = TPM_CAP_FLAG;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
rc = transmit_cmd(chip, data, sizeof(data), rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
"attemtping to determine the permanent state"); "attemtping to determine the permanent active state");
if (rc) if (rc) {
kfree(data);
return 0; return 0;
return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]); }
rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
kfree(data);
return rc;
} }
EXPORT_SYMBOL_GPL(tpm_show_active); EXPORT_SYMBOL_GPL(tpm_show_active);
ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr, ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
char *buf) char *buf)
{ {
u8 data[sizeof(tpm_cap)]; u8 *data;
ssize_t rc; ssize_t rc;
struct tpm_chip *chip = dev_get_drvdata(dev); struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL) if (chip == NULL)
return -ENODEV; return -ENODEV;
data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
if (!data)
return -ENOMEM;
memcpy(data, tpm_cap, sizeof(tpm_cap)); memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_IDX] = TPM_CAP_PROP;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
rc = transmit_cmd(chip, data, sizeof(data), rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
"attempting to determine the owner state"); "attempting to determine the owner state");
if (rc) if (rc) {
kfree(data);
return 0; return 0;
return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]); }
rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
kfree(data);
return rc;
} }
EXPORT_SYMBOL_GPL(tpm_show_owned); EXPORT_SYMBOL_GPL(tpm_show_owned);
ssize_t tpm_show_temp_deactivated(struct device * dev, ssize_t tpm_show_temp_deactivated(struct device * dev,
struct device_attribute * attr, char *buf) struct device_attribute * attr, char *buf)
{ {
u8 data[sizeof(tpm_cap)]; u8 *data;
ssize_t rc; ssize_t rc;
struct tpm_chip *chip = dev_get_drvdata(dev); struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL) if (chip == NULL)
return -ENODEV; return -ENODEV;
data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
if (!data)
return -ENOMEM;
memcpy(data, tpm_cap, sizeof(tpm_cap)); memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_FLAG; data[TPM_CAP_IDX] = TPM_CAP_FLAG;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
rc = transmit_cmd(chip, data, sizeof(data), rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
"attempting to determine the temporary state"); "attempting to determine the temporary state");
if (rc) if (rc) {
kfree(data);
return 0; return 0;
return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]); }
rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
kfree(data);
return rc;
} }
EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated); EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
...@@ -678,7 +720,7 @@ static const u8 pcrread[] = { ...@@ -678,7 +720,7 @@ static const u8 pcrread[] = {
ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)]; u8 *data;
ssize_t rc; ssize_t rc;
int i, j, num_pcrs; int i, j, num_pcrs;
__be32 index; __be32 index;
...@@ -688,21 +730,27 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, ...@@ -688,21 +730,27 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
if (chip == NULL) if (chip == NULL)
return -ENODEV; return -ENODEV;
data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
if (!data)
return -ENOMEM;
memcpy(data, tpm_cap, sizeof(tpm_cap)); memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_IDX] = TPM_CAP_PROP;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
rc = transmit_cmd(chip, data, sizeof(data), rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
"attempting to determine the number of PCRS"); "attempting to determine the number of PCRS");
if (rc) if (rc) {
kfree(data);
return 0; return 0;
}
num_pcrs = be32_to_cpu(*((__be32 *) (data + 14))); num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
for (i = 0; i < num_pcrs; i++) { for (i = 0; i < num_pcrs; i++) {
memcpy(data, pcrread, sizeof(pcrread)); memcpy(data, pcrread, sizeof(pcrread));
index = cpu_to_be32(i); index = cpu_to_be32(i);
memcpy(data + 10, &index, 4); memcpy(data + 10, &index, 4);
rc = transmit_cmd(chip, data, sizeof(data), rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
"attempting to read a PCR"); "attempting to read a PCR");
if (rc) if (rc)
goto out; goto out;
...@@ -712,6 +760,7 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, ...@@ -712,6 +760,7 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
str += sprintf(str, "\n"); str += sprintf(str, "\n");
} }
out: out:
kfree(data);
return str - buf; return str - buf;
} }
EXPORT_SYMBOL_GPL(tpm_show_pcrs); EXPORT_SYMBOL_GPL(tpm_show_pcrs);
...@@ -795,7 +844,7 @@ static const u8 cap_version[] = { ...@@ -795,7 +844,7 @@ static const u8 cap_version[] = {
ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)]; u8 *data;
ssize_t rc; ssize_t rc;
char *str = buf; char *str = buf;
...@@ -803,21 +852,27 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, ...@@ -803,21 +852,27 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
if (chip == NULL) if (chip == NULL)
return -ENODEV; return -ENODEV;
data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
if (!data)
return -ENOMEM;
memcpy(data, tpm_cap, sizeof(tpm_cap)); memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_IDX] = TPM_CAP_PROP;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
rc = transmit_cmd(chip, data, sizeof(data), rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
"attempting to determine the manufacturer"); "attempting to determine the manufacturer");
if (rc) if (rc) {
kfree(data);
return 0; return 0;
}
str += sprintf(str, "Manufacturer: 0x%x\n", str += sprintf(str, "Manufacturer: 0x%x\n",
be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)))); be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
memcpy(data, cap_version, sizeof(cap_version)); memcpy(data, cap_version, sizeof(cap_version));
data[CAP_VERSION_IDX] = CAP_VERSION_1_1; data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
rc = transmit_cmd(chip, data, sizeof(data), rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
"attempting to determine the 1.1 version"); "attempting to determine the 1.1 version");
if (rc) if (rc)
goto out; goto out;
...@@ -828,6 +883,7 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, ...@@ -828,6 +883,7 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
(int) data[17]); (int) data[17]);
out: out:
kfree(data);
return str - buf; return str - buf;
} }
EXPORT_SYMBOL_GPL(tpm_show_caps); EXPORT_SYMBOL_GPL(tpm_show_caps);
...@@ -835,7 +891,7 @@ EXPORT_SYMBOL_GPL(tpm_show_caps); ...@@ -835,7 +891,7 @@ EXPORT_SYMBOL_GPL(tpm_show_caps);
ssize_t tpm_show_caps_1_2(struct device * dev, ssize_t tpm_show_caps_1_2(struct device * dev,
struct device_attribute * attr, char *buf) struct device_attribute * attr, char *buf)
{ {
u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)]; u8 *data;
ssize_t len; ssize_t len;
char *str = buf; char *str = buf;
...@@ -843,15 +899,20 @@ ssize_t tpm_show_caps_1_2(struct device * dev, ...@@ -843,15 +899,20 @@ ssize_t tpm_show_caps_1_2(struct device * dev,
if (chip == NULL) if (chip == NULL)
return -ENODEV; return -ENODEV;
data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
if (!data)
return -ENOMEM;
memcpy(data, tpm_cap, sizeof(tpm_cap)); memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_IDX] = TPM_CAP_PROP;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
if ((len = tpm_transmit(chip, data, sizeof(data))) <= len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE);
TPM_ERROR_SIZE) { if (len <= TPM_ERROR_SIZE) {
dev_dbg(chip->dev, "A TPM error (%d) occurred " dev_dbg(chip->dev, "A TPM error (%d) occurred "
"attempting to determine the manufacturer\n", "attempting to determine the manufacturer\n",
be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)))); be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
kfree(data);
return 0; return 0;
} }
...@@ -861,8 +922,8 @@ ssize_t tpm_show_caps_1_2(struct device * dev, ...@@ -861,8 +922,8 @@ ssize_t tpm_show_caps_1_2(struct device * dev,
memcpy(data, cap_version, sizeof(cap_version)); memcpy(data, cap_version, sizeof(cap_version));
data[CAP_VERSION_IDX] = CAP_VERSION_1_2; data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
if ((len = tpm_transmit(chip, data, sizeof(data))) <= len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE);
TPM_ERROR_SIZE) { if (len <= TPM_ERROR_SIZE) {
dev_err(chip->dev, "A TPM error (%d) occurred " dev_err(chip->dev, "A TPM error (%d) occurred "
"attempting to determine the 1.2 version\n", "attempting to determine the 1.2 version\n",
be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)))); be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
...@@ -874,6 +935,7 @@ ssize_t tpm_show_caps_1_2(struct device * dev, ...@@ -874,6 +935,7 @@ ssize_t tpm_show_caps_1_2(struct device * dev,
(int) data[19]); (int) data[19]);
out: out:
kfree(data);
return str - buf; return str - buf;
} }
EXPORT_SYMBOL_GPL(tpm_show_caps_1_2); EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment