diff options
| author | Kylene Jo Hall <kjhall@us.ibm.com> | 2006-04-22 05:37:05 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-22 12:19:53 -0400 |
| commit | beed53a1aaeaae4eb93297c23f1598a726716adf (patch) | |
| tree | ca2debde55f2320cae3c83d1be90fc07961d5050 | |
| parent | 3c2f606a098b07f053904ec8b8f4d0e101c28b35 (diff) | |
[PATCH] tpm: reorganize sysfs files
Many of the sysfs files were calling the TPM_GetCapability command with array.
Since for 1.2 more sysfs files of this type are coming I am generalizing the
array so there can be one array and the unique parts can be filled in just
before the command is called.
Signed-off-by: Kylene Hall <kjhall@us.ibm.com>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | drivers/char/tpm/tpm.c | 145 |
1 files changed, 86 insertions, 59 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 379c5d465579..187bcdaf7bf6 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
| @@ -119,17 +119,57 @@ out: | |||
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | #define TPM_DIGEST_SIZE 20 | 121 | #define TPM_DIGEST_SIZE 20 |
| 122 | #define CAP_PCR_RESULT_SIZE 18 | 122 | #define TPM_ERROR_SIZE 10 |
| 123 | static const u8 cap_pcr[] = { | 123 | #define TPM_RET_CODE_IDX 6 |
| 124 | #define TPM_GET_CAP_RET_SIZE_IDX 10 | ||
| 125 | #define TPM_GET_CAP_RET_UINT32_1_IDX 14 | ||
| 126 | #define TPM_GET_CAP_RET_UINT32_2_IDX 18 | ||
| 127 | #define TPM_GET_CAP_RET_UINT32_3_IDX 22 | ||
| 128 | #define TPM_GET_CAP_RET_UINT32_4_IDX 26 | ||
| 129 | |||
| 130 | #define TPM_CAP_IDX 13 | ||
| 131 | #define TPM_CAP_SUBCAP_IDX 21 | ||
| 132 | |||
| 133 | enum tpm_capabilities { | ||
| 134 | TPM_CAP_PROP = 5, | ||
| 135 | }; | ||
| 136 | |||
| 137 | enum tpm_sub_capabilities { | ||
| 138 | TPM_CAP_PROP_PCR = 0x1, | ||
| 139 | TPM_CAP_PROP_MANUFACTURER = 0x3, | ||
| 140 | }; | ||
| 141 | |||
| 142 | /* | ||
| 143 | * This is a semi generic GetCapability command for use | ||
| 144 | * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG | ||
| 145 | * and their associated sub_capabilities. | ||
| 146 | */ | ||
| 147 | |||
| 148 | static const u8 tpm_cap[] = { | ||
| 124 | 0, 193, /* TPM_TAG_RQU_COMMAND */ | 149 | 0, 193, /* TPM_TAG_RQU_COMMAND */ |
| 125 | 0, 0, 0, 22, /* length */ | 150 | 0, 0, 0, 22, /* length */ |
| 126 | 0, 0, 0, 101, /* TPM_ORD_GetCapability */ | 151 | 0, 0, 0, 101, /* TPM_ORD_GetCapability */ |
| 127 | 0, 0, 0, 5, | 152 | 0, 0, 0, 0, /* TPM_CAP_<TYPE> */ |
| 128 | 0, 0, 0, 4, | 153 | 0, 0, 0, 4, /* TPM_CAP_SUB_<TYPE> size */ |
| 129 | 0, 0, 1, 1 | 154 | 0, 0, 1, 0 /* TPM_CAP_SUB_<TYPE> */ |
| 130 | }; | 155 | }; |
| 131 | 156 | ||
| 132 | #define READ_PCR_RESULT_SIZE 30 | 157 | static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len, |
| 158 | char *desc) | ||
| 159 | { | ||
| 160 | int err; | ||
| 161 | |||
| 162 | len = tpm_transmit(chip, data, len); | ||
| 163 | if (len < 0) | ||
| 164 | return len; | ||
| 165 | if (len == TPM_ERROR_SIZE) { | ||
| 166 | err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))); | ||
| 167 | dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc); | ||
| 168 | return err; | ||
| 169 | } | ||
| 170 | return 0; | ||
| 171 | } | ||
| 172 | |||
| 133 | static const u8 pcrread[] = { | 173 | static const u8 pcrread[] = { |
| 134 | 0, 193, /* TPM_TAG_RQU_COMMAND */ | 174 | 0, 193, /* TPM_TAG_RQU_COMMAND */ |
| 135 | 0, 0, 0, 14, /* length */ | 175 | 0, 0, 0, 14, /* length */ |
| @@ -140,8 +180,8 @@ static const u8 pcrread[] = { | |||
| 140 | ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, | 180 | ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, |
| 141 | char *buf) | 181 | char *buf) |
| 142 | { | 182 | { |
| 143 | u8 data[READ_PCR_RESULT_SIZE]; | 183 | u8 data[30]; |
| 144 | ssize_t len; | 184 | ssize_t rc; |
| 145 | int i, j, num_pcrs; | 185 | int i, j, num_pcrs; |
| 146 | __be32 index; | 186 | __be32 index; |
| 147 | char *str = buf; | 187 | char *str = buf; |
| @@ -150,29 +190,24 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, | |||
| 150 | if (chip == NULL) | 190 | if (chip == NULL) |
| 151 | return -ENODEV; | 191 | return -ENODEV; |
| 152 | 192 | ||
| 153 | memcpy(data, cap_pcr, sizeof(cap_pcr)); | 193 | memcpy(data, tpm_cap, sizeof(tpm_cap)); |
| 154 | if ((len = tpm_transmit(chip, data, sizeof(data))) | 194 | data[TPM_CAP_IDX] = TPM_CAP_PROP; |
| 155 | < CAP_PCR_RESULT_SIZE) { | 195 | data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR; |
| 156 | dev_dbg(chip->dev, "A TPM error (%d) occurred " | 196 | |
| 157 | "attempting to determine the number of PCRS\n", | 197 | rc = transmit_cmd(chip, data, sizeof(data), |
| 158 | be32_to_cpu(*((__be32 *) (data + 6)))); | 198 | "attempting to determine the number of PCRS"); |
| 199 | if (rc) | ||
| 159 | return 0; | 200 | return 0; |
| 160 | } | ||
| 161 | 201 | ||
| 162 | num_pcrs = be32_to_cpu(*((__be32 *) (data + 14))); | 202 | num_pcrs = be32_to_cpu(*((__be32 *) (data + 14))); |
| 163 | |||
| 164 | for (i = 0; i < num_pcrs; i++) { | 203 | for (i = 0; i < num_pcrs; i++) { |
| 165 | memcpy(data, pcrread, sizeof(pcrread)); | 204 | memcpy(data, pcrread, sizeof(pcrread)); |
| 166 | index = cpu_to_be32(i); | 205 | index = cpu_to_be32(i); |
| 167 | memcpy(data + 10, &index, 4); | 206 | memcpy(data + 10, &index, 4); |
| 168 | if ((len = tpm_transmit(chip, data, sizeof(data))) | 207 | rc = transmit_cmd(chip, data, sizeof(data), |
| 169 | < READ_PCR_RESULT_SIZE){ | 208 | "attempting to read a PCR"); |
| 170 | dev_dbg(chip->dev, "A TPM error (%d) occurred" | 209 | if (rc) |
| 171 | " attempting to read PCR %d of %d\n", | ||
| 172 | be32_to_cpu(*((__be32 *) (data + 6))), | ||
| 173 | i, num_pcrs); | ||
| 174 | goto out; | 210 | goto out; |
| 175 | } | ||
| 176 | str += sprintf(str, "PCR-%02d: ", i); | 211 | str += sprintf(str, "PCR-%02d: ", i); |
| 177 | for (j = 0; j < TPM_DIGEST_SIZE; j++) | 212 | for (j = 0; j < TPM_DIGEST_SIZE; j++) |
| 178 | str += sprintf(str, "%02X ", *(data + 10 + j)); | 213 | str += sprintf(str, "%02X ", *(data + 10 + j)); |
| @@ -194,7 +229,7 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, | |||
| 194 | char *buf) | 229 | char *buf) |
| 195 | { | 230 | { |
| 196 | u8 *data; | 231 | u8 *data; |
| 197 | ssize_t len; | 232 | ssize_t err; |
| 198 | int i, rc; | 233 | int i, rc; |
| 199 | char *str = buf; | 234 | char *str = buf; |
| 200 | 235 | ||
| @@ -208,14 +243,10 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, | |||
| 208 | 243 | ||
| 209 | memcpy(data, readpubek, sizeof(readpubek)); | 244 | memcpy(data, readpubek, sizeof(readpubek)); |
| 210 | 245 | ||
| 211 | if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) < | 246 | err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE, |
| 212 | READ_PUBEK_RESULT_SIZE) { | 247 | "attempting to read the PUBEK"); |
| 213 | dev_dbg(chip->dev, "A TPM error (%d) occurred " | 248 | if (err) |
| 214 | "attempting to read the PUBEK\n", | ||
| 215 | be32_to_cpu(*((__be32 *) (data + 6)))); | ||
| 216 | rc = 0; | ||
| 217 | goto out; | 249 | goto out; |
| 218 | } | ||
| 219 | 250 | ||
| 220 | /* | 251 | /* |
| 221 | ignore header 10 bytes | 252 | ignore header 10 bytes |
| @@ -245,63 +276,59 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, | |||
| 245 | if ((i + 1) % 16 == 0) | 276 | if ((i + 1) % 16 == 0) |
| 246 | str += sprintf(str, "\n"); | 277 | str += sprintf(str, "\n"); |
| 247 | } | 278 | } |
| 248 | rc = str - buf; | ||
| 249 | out: | 279 | out: |
| 280 | rc = str - buf; | ||
| 250 | kfree(data); | 281 | kfree(data); |
| 251 | return rc; | 282 | return rc; |
| 252 | } | 283 | } |
| 253 | EXPORT_SYMBOL_GPL(tpm_show_pubek); | 284 | EXPORT_SYMBOL_GPL(tpm_show_pubek); |
| 254 | 285 | ||
| 255 | #define CAP_VER_RESULT_SIZE 18 | 286 | #define CAP_VERSION_1_1 6 |
| 287 | #define CAP_VERSION_IDX 13 | ||
| 256 | static const u8 cap_version[] = { | 288 | static const u8 cap_version[] = { |
| 257 | 0, 193, /* TPM_TAG_RQU_COMMAND */ | 289 | 0, 193, /* TPM_TAG_RQU_COMMAND */ |
| 258 | 0, 0, 0, 18, /* length */ | 290 | 0, 0, 0, 18, /* length */ |
| 259 | 0, 0, 0, 101, /* TPM_ORD_GetCapability */ | 291 | 0, 0, 0, 101, /* TPM_ORD_GetCapability */ |
| 260 | 0, 0, 0, 6, | 292 | 0, 0, 0, 0, |
| 261 | 0, 0, 0, 0 | 293 | 0, 0, 0, 0 |
| 262 | }; | 294 | }; |
| 263 | 295 | ||
| 264 | #define CAP_MANUFACTURER_RESULT_SIZE 18 | ||
| 265 | static const u8 cap_manufacturer[] = { | ||
| 266 | 0, 193, /* TPM_TAG_RQU_COMMAND */ | ||
| 267 | 0, 0, 0, 22, /* length */ | ||
| 268 | 0, 0, 0, 101, /* TPM_ORD_GetCapability */ | ||
| 269 | 0, 0, 0, 5, | ||
| 270 | 0, 0, 0, 4, | ||
| 271 | 0, 0, 1, 3 | ||
| 272 | }; | ||
| 273 | |||
| 274 | ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, | 296 | ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, |
| 275 | char *buf) | 297 | char *buf) |
| 276 | { | 298 | { |
| 277 | u8 data[sizeof(cap_manufacturer)]; | 299 | u8 data[30]; |
| 278 | ssize_t len; | 300 | ssize_t rc; |
| 279 | char *str = buf; | 301 | char *str = buf; |
| 280 | 302 | ||
| 281 | struct tpm_chip *chip = dev_get_drvdata(dev); | 303 | struct tpm_chip *chip = dev_get_drvdata(dev); |
| 282 | if (chip == NULL) | 304 | if (chip == NULL) |
| 283 | return -ENODEV; | 305 | return -ENODEV; |
| 284 | 306 | ||
| 285 | memcpy(data, cap_manufacturer, sizeof(cap_manufacturer)); | 307 | memcpy(data, tpm_cap, sizeof(tpm_cap)); |
| 308 | data[TPM_CAP_IDX] = TPM_CAP_PROP; | ||
| 309 | data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER; | ||
| 286 | 310 | ||
| 287 | if ((len = tpm_transmit(chip, data, sizeof(data))) < | 311 | rc = transmit_cmd(chip, data, sizeof(data), |
| 288 | CAP_MANUFACTURER_RESULT_SIZE) | 312 | "attempting to determine the manufacturer"); |
| 289 | return len; | 313 | if (rc) |
| 314 | return 0; | ||
| 290 | 315 | ||
| 291 | str += sprintf(str, "Manufacturer: 0x%x\n", | 316 | str += sprintf(str, "Manufacturer: 0x%x\n", |
| 292 | be32_to_cpu(*((__be32 *) (data + 14)))); | 317 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)))); |
| 293 | 318 | ||
| 294 | memcpy(data, cap_version, sizeof(cap_version)); | 319 | memcpy(data, cap_version, sizeof(cap_version)); |
| 320 | data[CAP_VERSION_IDX] = CAP_VERSION_1_1; | ||
| 321 | rc = transmit_cmd(chip, data, sizeof(data), | ||
| 322 | "attempting to determine the 1.1 version"); | ||
| 323 | if (rc) | ||
| 324 | goto out; | ||
| 295 | 325 | ||
| 296 | if ((len = tpm_transmit(chip, data, sizeof(data))) < | 326 | str += sprintf(str, |
| 297 | CAP_VER_RESULT_SIZE) | 327 | "TCG version: %d.%d\nFirmware version: %d.%d\n", |
| 298 | return len; | 328 | (int) data[14], (int) data[15], (int) data[16], |
| 299 | 329 | (int) data[17]); | |
| 300 | str += | ||
| 301 | sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n", | ||
| 302 | (int) data[14], (int) data[15], (int) data[16], | ||
| 303 | (int) data[17]); | ||
| 304 | 330 | ||
| 331 | out: | ||
| 305 | return str - buf; | 332 | return str - buf; |
| 306 | } | 333 | } |
| 307 | EXPORT_SYMBOL_GPL(tpm_show_caps); | 334 | EXPORT_SYMBOL_GPL(tpm_show_caps); |
