Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2004 IBM Corporation
0004  * Authors:
0005  * Leendert van Doorn <leendert@watson.ibm.com>
0006  * Dave Safford <safford@watson.ibm.com>
0007  * Reiner Sailer <sailer@watson.ibm.com>
0008  * Kylene Hall <kjhall@us.ibm.com>
0009  *
0010  * Copyright (C) 2013 Obsidian Research Corp
0011  * Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
0012  *
0013  * sysfs filesystem inspection interface to the TPM
0014  */
0015 #include <linux/device.h>
0016 #include "tpm.h"
0017 
0018 struct tpm_readpubek_out {
0019     u8 algorithm[4];
0020     u8 encscheme[2];
0021     u8 sigscheme[2];
0022     __be32 paramsize;
0023     u8 parameters[12];
0024     __be32 keysize;
0025     u8 modulus[256];
0026     u8 checksum[20];
0027 } __packed;
0028 
0029 #define READ_PUBEK_RESULT_MIN_BODY_SIZE (28 + 256)
0030 #define TPM_ORD_READPUBEK 124
0031 
0032 static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
0033               char *buf)
0034 {
0035     struct tpm_buf tpm_buf;
0036     struct tpm_readpubek_out *out;
0037     int i;
0038     char *str = buf;
0039     struct tpm_chip *chip = to_tpm_chip(dev);
0040     char anti_replay[20];
0041 
0042     memset(&anti_replay, 0, sizeof(anti_replay));
0043 
0044     if (tpm_try_get_ops(chip))
0045         return 0;
0046 
0047     if (tpm_buf_init(&tpm_buf, TPM_TAG_RQU_COMMAND, TPM_ORD_READPUBEK))
0048         goto out_ops;
0049 
0050     tpm_buf_append(&tpm_buf, anti_replay, sizeof(anti_replay));
0051 
0052     if (tpm_transmit_cmd(chip, &tpm_buf, READ_PUBEK_RESULT_MIN_BODY_SIZE,
0053                  "attempting to read the PUBEK"))
0054         goto out_buf;
0055 
0056     out = (struct tpm_readpubek_out *)&tpm_buf.data[10];
0057     str +=
0058         sprintf(str,
0059             "Algorithm: %4ph\n"
0060             "Encscheme: %2ph\n"
0061             "Sigscheme: %2ph\n"
0062             "Parameters: %12ph\n"
0063             "Modulus length: %d\n"
0064             "Modulus:\n",
0065             out->algorithm,
0066             out->encscheme,
0067             out->sigscheme,
0068             out->parameters,
0069             be32_to_cpu(out->keysize));
0070 
0071     for (i = 0; i < 256; i += 16)
0072         str += sprintf(str, "%16ph\n", &out->modulus[i]);
0073 
0074 out_buf:
0075     tpm_buf_destroy(&tpm_buf);
0076 out_ops:
0077     tpm_put_ops(chip);
0078     return str - buf;
0079 }
0080 static DEVICE_ATTR_RO(pubek);
0081 
0082 static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr,
0083              char *buf)
0084 {
0085     cap_t cap;
0086     u8 digest[TPM_DIGEST_SIZE];
0087     u32 i, j, num_pcrs;
0088     char *str = buf;
0089     struct tpm_chip *chip = to_tpm_chip(dev);
0090 
0091     if (tpm_try_get_ops(chip))
0092         return 0;
0093 
0094     if (tpm1_getcap(chip, TPM_CAP_PROP_PCR, &cap,
0095             "attempting to determine the number of PCRS",
0096             sizeof(cap.num_pcrs))) {
0097         tpm_put_ops(chip);
0098         return 0;
0099     }
0100 
0101     num_pcrs = be32_to_cpu(cap.num_pcrs);
0102     for (i = 0; i < num_pcrs; i++) {
0103         if (tpm1_pcr_read(chip, i, digest)) {
0104             str = buf;
0105             break;
0106         }
0107         str += sprintf(str, "PCR-%02d: ", i);
0108         for (j = 0; j < TPM_DIGEST_SIZE; j++)
0109             str += sprintf(str, "%02X ", digest[j]);
0110         str += sprintf(str, "\n");
0111     }
0112     tpm_put_ops(chip);
0113     return str - buf;
0114 }
0115 static DEVICE_ATTR_RO(pcrs);
0116 
0117 static ssize_t enabled_show(struct device *dev, struct device_attribute *attr,
0118              char *buf)
0119 {
0120     struct tpm_chip *chip = to_tpm_chip(dev);
0121     ssize_t rc = 0;
0122     cap_t cap;
0123 
0124     if (tpm_try_get_ops(chip))
0125         return 0;
0126 
0127     if (tpm1_getcap(chip, TPM_CAP_FLAG_PERM, &cap,
0128             "attempting to determine the permanent enabled state",
0129             sizeof(cap.perm_flags)))
0130         goto out_ops;
0131 
0132     rc = sprintf(buf, "%d\n", !cap.perm_flags.disable);
0133 out_ops:
0134     tpm_put_ops(chip);
0135     return rc;
0136 }
0137 static DEVICE_ATTR_RO(enabled);
0138 
0139 static ssize_t active_show(struct device *dev, struct device_attribute *attr,
0140             char *buf)
0141 {
0142     struct tpm_chip *chip = to_tpm_chip(dev);
0143     ssize_t rc = 0;
0144     cap_t cap;
0145 
0146     if (tpm_try_get_ops(chip))
0147         return 0;
0148 
0149     if (tpm1_getcap(chip, TPM_CAP_FLAG_PERM, &cap,
0150             "attempting to determine the permanent active state",
0151             sizeof(cap.perm_flags)))
0152         goto out_ops;
0153 
0154     rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated);
0155 out_ops:
0156     tpm_put_ops(chip);
0157     return rc;
0158 }
0159 static DEVICE_ATTR_RO(active);
0160 
0161 static ssize_t owned_show(struct device *dev, struct device_attribute *attr,
0162               char *buf)
0163 {
0164     struct tpm_chip *chip = to_tpm_chip(dev);
0165     ssize_t rc = 0;
0166     cap_t cap;
0167 
0168     if (tpm_try_get_ops(chip))
0169         return 0;
0170 
0171     if (tpm1_getcap(to_tpm_chip(dev), TPM_CAP_PROP_OWNER, &cap,
0172             "attempting to determine the owner state",
0173             sizeof(cap.owned)))
0174         goto out_ops;
0175 
0176     rc = sprintf(buf, "%d\n", cap.owned);
0177 out_ops:
0178     tpm_put_ops(chip);
0179     return rc;
0180 }
0181 static DEVICE_ATTR_RO(owned);
0182 
0183 static ssize_t temp_deactivated_show(struct device *dev,
0184                      struct device_attribute *attr, char *buf)
0185 {
0186     struct tpm_chip *chip = to_tpm_chip(dev);
0187     ssize_t rc = 0;
0188     cap_t cap;
0189 
0190     if (tpm_try_get_ops(chip))
0191         return 0;
0192 
0193     if (tpm1_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_VOL, &cap,
0194             "attempting to determine the temporary state",
0195             sizeof(cap.stclear_flags)))
0196         goto out_ops;
0197 
0198     rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated);
0199 out_ops:
0200     tpm_put_ops(chip);
0201     return rc;
0202 }
0203 static DEVICE_ATTR_RO(temp_deactivated);
0204 
0205 static ssize_t caps_show(struct device *dev, struct device_attribute *attr,
0206              char *buf)
0207 {
0208     struct tpm_chip *chip = to_tpm_chip(dev);
0209     struct tpm1_version *version;
0210     ssize_t rc = 0;
0211     char *str = buf;
0212     cap_t cap;
0213 
0214     if (tpm_try_get_ops(chip))
0215         return 0;
0216 
0217     if (tpm1_getcap(chip, TPM_CAP_PROP_MANUFACTURER, &cap,
0218             "attempting to determine the manufacturer",
0219             sizeof(cap.manufacturer_id)))
0220         goto out_ops;
0221 
0222     str += sprintf(str, "Manufacturer: 0x%x\n",
0223                be32_to_cpu(cap.manufacturer_id));
0224 
0225     /* TPM 1.2 */
0226     if (!tpm1_getcap(chip, TPM_CAP_VERSION_1_2, &cap,
0227              "attempting to determine the 1.2 version",
0228              sizeof(cap.version2))) {
0229         version = &cap.version2.version;
0230         goto out_print;
0231     }
0232 
0233     /* TPM 1.1 */
0234     if (tpm1_getcap(chip, TPM_CAP_VERSION_1_1, &cap,
0235             "attempting to determine the 1.1 version",
0236             sizeof(cap.version1))) {
0237         goto out_ops;
0238     }
0239 
0240     version = &cap.version1;
0241 
0242 out_print:
0243     str += sprintf(str,
0244                "TCG version: %d.%d\nFirmware version: %d.%d\n",
0245                version->major, version->minor,
0246                version->rev_major, version->rev_minor);
0247 
0248     rc = str - buf;
0249 
0250 out_ops:
0251     tpm_put_ops(chip);
0252     return rc;
0253 }
0254 static DEVICE_ATTR_RO(caps);
0255 
0256 static ssize_t cancel_store(struct device *dev, struct device_attribute *attr,
0257                 const char *buf, size_t count)
0258 {
0259     struct tpm_chip *chip = to_tpm_chip(dev);
0260 
0261     if (tpm_try_get_ops(chip))
0262         return 0;
0263 
0264     chip->ops->cancel(chip);
0265     tpm_put_ops(chip);
0266     return count;
0267 }
0268 static DEVICE_ATTR_WO(cancel);
0269 
0270 static ssize_t durations_show(struct device *dev, struct device_attribute *attr,
0271                   char *buf)
0272 {
0273     struct tpm_chip *chip = to_tpm_chip(dev);
0274 
0275     if (chip->duration[TPM_LONG] == 0)
0276         return 0;
0277 
0278     return sprintf(buf, "%d %d %d [%s]\n",
0279                jiffies_to_usecs(chip->duration[TPM_SHORT]),
0280                jiffies_to_usecs(chip->duration[TPM_MEDIUM]),
0281                jiffies_to_usecs(chip->duration[TPM_LONG]),
0282                chip->duration_adjusted
0283                ? "adjusted" : "original");
0284 }
0285 static DEVICE_ATTR_RO(durations);
0286 
0287 static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr,
0288                  char *buf)
0289 {
0290     struct tpm_chip *chip = to_tpm_chip(dev);
0291 
0292     return sprintf(buf, "%d %d %d %d [%s]\n",
0293                jiffies_to_usecs(chip->timeout_a),
0294                jiffies_to_usecs(chip->timeout_b),
0295                jiffies_to_usecs(chip->timeout_c),
0296                jiffies_to_usecs(chip->timeout_d),
0297                chip->timeout_adjusted
0298                ? "adjusted" : "original");
0299 }
0300 static DEVICE_ATTR_RO(timeouts);
0301 
0302 static ssize_t tpm_version_major_show(struct device *dev,
0303                   struct device_attribute *attr, char *buf)
0304 {
0305     struct tpm_chip *chip = to_tpm_chip(dev);
0306 
0307     return sprintf(buf, "%s\n", chip->flags & TPM_CHIP_FLAG_TPM2
0308                ? "2" : "1");
0309 }
0310 static DEVICE_ATTR_RO(tpm_version_major);
0311 
0312 static struct attribute *tpm1_dev_attrs[] = {
0313     &dev_attr_pubek.attr,
0314     &dev_attr_pcrs.attr,
0315     &dev_attr_enabled.attr,
0316     &dev_attr_active.attr,
0317     &dev_attr_owned.attr,
0318     &dev_attr_temp_deactivated.attr,
0319     &dev_attr_caps.attr,
0320     &dev_attr_cancel.attr,
0321     &dev_attr_durations.attr,
0322     &dev_attr_timeouts.attr,
0323     &dev_attr_tpm_version_major.attr,
0324     NULL,
0325 };
0326 
0327 static struct attribute *tpm2_dev_attrs[] = {
0328     &dev_attr_tpm_version_major.attr,
0329     NULL
0330 };
0331 
0332 static const struct attribute_group tpm1_dev_group = {
0333     .attrs = tpm1_dev_attrs,
0334 };
0335 
0336 static const struct attribute_group tpm2_dev_group = {
0337     .attrs = tpm2_dev_attrs,
0338 };
0339 
0340 struct tpm_pcr_attr {
0341     int alg_id;
0342     int pcr;
0343     struct device_attribute attr;
0344 };
0345 
0346 #define to_tpm_pcr_attr(a) container_of(a, struct tpm_pcr_attr, attr)
0347 
0348 static ssize_t pcr_value_show(struct device *dev,
0349                   struct device_attribute *attr,
0350                   char *buf)
0351 {
0352     struct tpm_pcr_attr *ha = to_tpm_pcr_attr(attr);
0353     struct tpm_chip *chip = to_tpm_chip(dev);
0354     struct tpm_digest digest;
0355     int i;
0356     int digest_size = 0;
0357     int rc;
0358     char *str = buf;
0359 
0360     for (i = 0; i < chip->nr_allocated_banks; i++)
0361         if (ha->alg_id == chip->allocated_banks[i].alg_id)
0362             digest_size = chip->allocated_banks[i].digest_size;
0363     /* should never happen */
0364     if (!digest_size)
0365         return -EINVAL;
0366 
0367     digest.alg_id = ha->alg_id;
0368     rc = tpm_pcr_read(chip, ha->pcr, &digest);
0369     if (rc)
0370         return rc;
0371     for (i = 0; i < digest_size; i++)
0372         str += sprintf(str, "%02X", digest.digest[i]);
0373     str += sprintf(str, "\n");
0374 
0375     return str - buf;
0376 }
0377 
0378 /*
0379  * The following set of defines represents all the magic to build
0380  * the per hash attribute groups for displaying each bank of PCRs.
0381  * The only slight problem with this approach is that every PCR is
0382  * hard coded to be present, so you don't know if an PCR is missing
0383  * until a cat of the file returns -EINVAL
0384  *
0385  * Also note you must ignore checkpatch warnings in this macro
0386  * code. This is deep macro magic that checkpatch.pl doesn't
0387  * understand.
0388  */
0389 
0390 /* Note, this must match TPM2_PLATFORM_PCR which is fixed at 24. */
0391 #define _TPM_HELPER(_alg, _hash, F) \
0392     F(_alg, _hash, 0)       \
0393     F(_alg, _hash, 1)       \
0394     F(_alg, _hash, 2)       \
0395     F(_alg, _hash, 3)       \
0396     F(_alg, _hash, 4)       \
0397     F(_alg, _hash, 5)       \
0398     F(_alg, _hash, 6)       \
0399     F(_alg, _hash, 7)       \
0400     F(_alg, _hash, 8)       \
0401     F(_alg, _hash, 9)       \
0402     F(_alg, _hash, 10)      \
0403     F(_alg, _hash, 11)      \
0404     F(_alg, _hash, 12)      \
0405     F(_alg, _hash, 13)      \
0406     F(_alg, _hash, 14)      \
0407     F(_alg, _hash, 15)      \
0408     F(_alg, _hash, 16)      \
0409     F(_alg, _hash, 17)      \
0410     F(_alg, _hash, 18)      \
0411     F(_alg, _hash, 19)      \
0412     F(_alg, _hash, 20)      \
0413     F(_alg, _hash, 21)      \
0414     F(_alg, _hash, 22)      \
0415     F(_alg, _hash, 23)
0416 
0417 /* ignore checkpatch warning about trailing ; in macro. */
0418 #define PCR_ATTR(_alg, _hash, _pcr)                \
0419     static struct tpm_pcr_attr dev_attr_pcr_##_hash##_##_pcr = {    \
0420         .alg_id = _alg,                    \
0421         .pcr = _pcr,                       \
0422         .attr = {                      \
0423             .attr = {                  \
0424                 .name = __stringify(_pcr),     \
0425                 .mode = 0444               \
0426             },                     \
0427             .show = pcr_value_show             \
0428         }                          \
0429     };
0430 
0431 #define PCR_ATTRS(_alg, _hash)          \
0432     _TPM_HELPER(_alg, _hash, PCR_ATTR)
0433 
0434 /* ignore checkpatch warning about trailing , in macro. */
0435 #define PCR_ATTR_VAL(_alg, _hash, _pcr)     \
0436     &dev_attr_pcr_##_hash##_##_pcr.attr.attr,
0437 
0438 #define PCR_ATTR_GROUP_ARRAY(_alg, _hash)              \
0439     static struct attribute *pcr_group_attrs_##_hash[] = { \
0440         _TPM_HELPER(_alg, _hash, PCR_ATTR_VAL)         \
0441         NULL                           \
0442     }
0443 
0444 #define PCR_ATTR_GROUP(_alg, _hash)             \
0445     static struct attribute_group pcr_group_##_hash = { \
0446         .name = "pcr-" __stringify(_hash),      \
0447         .attrs = pcr_group_attrs_##_hash        \
0448     }
0449 
0450 #define PCR_ATTR_BUILD(_alg, _hash)    \
0451     PCR_ATTRS(_alg, _hash)         \
0452     PCR_ATTR_GROUP_ARRAY(_alg, _hash); \
0453     PCR_ATTR_GROUP(_alg, _hash)
0454 /*
0455  * End of macro structure to build an attribute group containing 24
0456  * PCR value files for each supported hash algorithm
0457  */
0458 
0459 /*
0460  * The next set of macros implements the cleverness for each hash to
0461  * build a static attribute group called pcr_group_<hash> which can be
0462  * added to chip->groups[].
0463  *
0464  * The first argument is the TPM algorithm id and the second is the
0465  * hash used as both the suffix and the group name.  Note: the group
0466  * name is a directory in the top level tpm class with the name
0467  * pcr-<hash>, so it must not clash with any other names already
0468  * in the sysfs directory.
0469  */
0470 PCR_ATTR_BUILD(TPM_ALG_SHA1, sha1);
0471 PCR_ATTR_BUILD(TPM_ALG_SHA256, sha256);
0472 PCR_ATTR_BUILD(TPM_ALG_SHA384, sha384);
0473 PCR_ATTR_BUILD(TPM_ALG_SHA512, sha512);
0474 PCR_ATTR_BUILD(TPM_ALG_SM3_256, sm3);
0475 
0476 
0477 void tpm_sysfs_add_device(struct tpm_chip *chip)
0478 {
0479     int i;
0480 
0481     WARN_ON(chip->groups_cnt != 0);
0482 
0483     if (tpm_is_firmware_upgrade(chip))
0484         return;
0485 
0486     if (chip->flags & TPM_CHIP_FLAG_TPM2)
0487         chip->groups[chip->groups_cnt++] = &tpm2_dev_group;
0488     else
0489         chip->groups[chip->groups_cnt++] = &tpm1_dev_group;
0490 
0491     /* add one group for each bank hash */
0492     for (i = 0; i < chip->nr_allocated_banks; i++) {
0493         switch (chip->allocated_banks[i].alg_id) {
0494         case TPM_ALG_SHA1:
0495             chip->groups[chip->groups_cnt++] = &pcr_group_sha1;
0496             break;
0497         case TPM_ALG_SHA256:
0498             chip->groups[chip->groups_cnt++] = &pcr_group_sha256;
0499             break;
0500         case TPM_ALG_SHA384:
0501             chip->groups[chip->groups_cnt++] = &pcr_group_sha384;
0502             break;
0503         case TPM_ALG_SHA512:
0504             chip->groups[chip->groups_cnt++] = &pcr_group_sha512;
0505             break;
0506         case TPM_ALG_SM3_256:
0507             chip->groups[chip->groups_cnt++] = &pcr_group_sm3;
0508             break;
0509         default:
0510             /*
0511              * If triggers, send a patch to add both a
0512              * PCR_ATTR_BUILD() macro above for the
0513              * missing algorithm as well as an additional
0514              * case in this switch statement.
0515              */
0516             dev_err(&chip->dev,
0517                 "TPM with unsupported bank algorithm 0x%04x",
0518                 chip->allocated_banks[i].alg_id);
0519             break;
0520         }
0521     }
0522 
0523     /*
0524      * This will only trigger if someone has added an additional
0525      * hash to the tpm_algorithms enum without incrementing
0526      * TPM_MAX_HASHES.
0527      */
0528     WARN_ON(chip->groups_cnt > TPM_MAX_HASHES + 1);
0529 }