linux/drivers/char/tpm/tpm-sysfs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2004 IBM Corporation
   4 * Authors:
   5 * Leendert van Doorn <leendert@watson.ibm.com>
   6 * Dave Safford <safford@watson.ibm.com>
   7 * Reiner Sailer <sailer@watson.ibm.com>
   8 * Kylene Hall <kjhall@us.ibm.com>
   9 *
  10 * Copyright (C) 2013 Obsidian Research Corp
  11 * Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
  12 *
  13 * sysfs filesystem inspection interface to the TPM
  14 */
  15#include <linux/device.h>
  16#include "tpm.h"
  17
  18struct tpm_readpubek_out {
  19        u8 algorithm[4];
  20        u8 encscheme[2];
  21        u8 sigscheme[2];
  22        __be32 paramsize;
  23        u8 parameters[12];
  24        __be32 keysize;
  25        u8 modulus[256];
  26        u8 checksum[20];
  27} __packed;
  28
  29#define READ_PUBEK_RESULT_MIN_BODY_SIZE (28 + 256)
  30#define TPM_ORD_READPUBEK 124
  31
  32static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
  33                          char *buf)
  34{
  35        struct tpm_buf tpm_buf;
  36        struct tpm_readpubek_out *out;
  37        int i;
  38        char *str = buf;
  39        struct tpm_chip *chip = to_tpm_chip(dev);
  40        char anti_replay[20];
  41
  42        memset(&anti_replay, 0, sizeof(anti_replay));
  43
  44        if (tpm_try_get_ops(chip))
  45                return 0;
  46
  47        if (tpm_buf_init(&tpm_buf, TPM_TAG_RQU_COMMAND, TPM_ORD_READPUBEK))
  48                goto out_ops;
  49
  50        tpm_buf_append(&tpm_buf, anti_replay, sizeof(anti_replay));
  51
  52        if (tpm_transmit_cmd(chip, &tpm_buf, READ_PUBEK_RESULT_MIN_BODY_SIZE,
  53                             "attempting to read the PUBEK"))
  54                goto out_buf;
  55
  56        out = (struct tpm_readpubek_out *)&tpm_buf.data[10];
  57        str +=
  58            sprintf(str,
  59                    "Algorithm: %02X %02X %02X %02X\n"
  60                    "Encscheme: %02X %02X\n"
  61                    "Sigscheme: %02X %02X\n"
  62                    "Parameters: %02X %02X %02X %02X "
  63                    "%02X %02X %02X %02X "
  64                    "%02X %02X %02X %02X\n"
  65                    "Modulus length: %d\n"
  66                    "Modulus:\n",
  67                    out->algorithm[0], out->algorithm[1], out->algorithm[2],
  68                    out->algorithm[3],
  69                    out->encscheme[0], out->encscheme[1],
  70                    out->sigscheme[0], out->sigscheme[1],
  71                    out->parameters[0], out->parameters[1],
  72                    out->parameters[2], out->parameters[3],
  73                    out->parameters[4], out->parameters[5],
  74                    out->parameters[6], out->parameters[7],
  75                    out->parameters[8], out->parameters[9],
  76                    out->parameters[10], out->parameters[11],
  77                    be32_to_cpu(out->keysize));
  78
  79        for (i = 0; i < 256; i++) {
  80                str += sprintf(str, "%02X ", out->modulus[i]);
  81                if ((i + 1) % 16 == 0)
  82                        str += sprintf(str, "\n");
  83        }
  84
  85out_buf:
  86        tpm_buf_destroy(&tpm_buf);
  87out_ops:
  88        tpm_put_ops(chip);
  89        return str - buf;
  90}
  91static DEVICE_ATTR_RO(pubek);
  92
  93static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr,
  94                         char *buf)
  95{
  96        cap_t cap;
  97        u8 digest[TPM_DIGEST_SIZE];
  98        u32 i, j, num_pcrs;
  99        char *str = buf;
 100        struct tpm_chip *chip = to_tpm_chip(dev);
 101
 102        if (tpm_try_get_ops(chip))
 103                return 0;
 104
 105        if (tpm1_getcap(chip, TPM_CAP_PROP_PCR, &cap,
 106                        "attempting to determine the number of PCRS",
 107                        sizeof(cap.num_pcrs))) {
 108                tpm_put_ops(chip);
 109                return 0;
 110        }
 111
 112        num_pcrs = be32_to_cpu(cap.num_pcrs);
 113        for (i = 0; i < num_pcrs; i++) {
 114                if (tpm1_pcr_read(chip, i, digest)) {
 115                        str = buf;
 116                        break;
 117                }
 118                str += sprintf(str, "PCR-%02d: ", i);
 119                for (j = 0; j < TPM_DIGEST_SIZE; j++)
 120                        str += sprintf(str, "%02X ", digest[j]);
 121                str += sprintf(str, "\n");
 122        }
 123        tpm_put_ops(chip);
 124        return str - buf;
 125}
 126static DEVICE_ATTR_RO(pcrs);
 127
 128static ssize_t enabled_show(struct device *dev, struct device_attribute *attr,
 129                     char *buf)
 130{
 131        struct tpm_chip *chip = to_tpm_chip(dev);
 132        ssize_t rc = 0;
 133        cap_t cap;
 134
 135        if (tpm_try_get_ops(chip))
 136                return 0;
 137
 138        if (tpm1_getcap(chip, TPM_CAP_FLAG_PERM, &cap,
 139                        "attempting to determine the permanent enabled state",
 140                        sizeof(cap.perm_flags)))
 141                goto out_ops;
 142
 143        rc = sprintf(buf, "%d\n", !cap.perm_flags.disable);
 144out_ops:
 145        tpm_put_ops(chip);
 146        return rc;
 147}
 148static DEVICE_ATTR_RO(enabled);
 149
 150static ssize_t active_show(struct device *dev, struct device_attribute *attr,
 151                    char *buf)
 152{
 153        struct tpm_chip *chip = to_tpm_chip(dev);
 154        ssize_t rc = 0;
 155        cap_t cap;
 156
 157        if (tpm_try_get_ops(chip))
 158                return 0;
 159
 160        if (tpm1_getcap(chip, TPM_CAP_FLAG_PERM, &cap,
 161                        "attempting to determine the permanent active state",
 162                        sizeof(cap.perm_flags)))
 163                goto out_ops;
 164
 165        rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated);
 166out_ops:
 167        tpm_put_ops(chip);
 168        return rc;
 169}
 170static DEVICE_ATTR_RO(active);
 171
 172static ssize_t owned_show(struct device *dev, struct device_attribute *attr,
 173                          char *buf)
 174{
 175        struct tpm_chip *chip = to_tpm_chip(dev);
 176        ssize_t rc = 0;
 177        cap_t cap;
 178
 179        if (tpm_try_get_ops(chip))
 180                return 0;
 181
 182        if (tpm1_getcap(to_tpm_chip(dev), TPM_CAP_PROP_OWNER, &cap,
 183                        "attempting to determine the owner state",
 184                        sizeof(cap.owned)))
 185                goto out_ops;
 186
 187        rc = sprintf(buf, "%d\n", cap.owned);
 188out_ops:
 189        tpm_put_ops(chip);
 190        return rc;
 191}
 192static DEVICE_ATTR_RO(owned);
 193
 194static ssize_t temp_deactivated_show(struct device *dev,
 195                                     struct device_attribute *attr, char *buf)
 196{
 197        struct tpm_chip *chip = to_tpm_chip(dev);
 198        ssize_t rc = 0;
 199        cap_t cap;
 200
 201        if (tpm_try_get_ops(chip))
 202                return 0;
 203
 204        if (tpm1_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_VOL, &cap,
 205                        "attempting to determine the temporary state",
 206                        sizeof(cap.stclear_flags)))
 207                goto out_ops;
 208
 209        rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated);
 210out_ops:
 211        tpm_put_ops(chip);
 212        return rc;
 213}
 214static DEVICE_ATTR_RO(temp_deactivated);
 215
 216static ssize_t caps_show(struct device *dev, struct device_attribute *attr,
 217                         char *buf)
 218{
 219        struct tpm_chip *chip = to_tpm_chip(dev);
 220        struct tpm1_version *version;
 221        ssize_t rc = 0;
 222        char *str = buf;
 223        cap_t cap;
 224
 225        if (tpm_try_get_ops(chip))
 226                return 0;
 227
 228        if (tpm1_getcap(chip, TPM_CAP_PROP_MANUFACTURER, &cap,
 229                        "attempting to determine the manufacturer",
 230                        sizeof(cap.manufacturer_id)))
 231                goto out_ops;
 232
 233        str += sprintf(str, "Manufacturer: 0x%x\n",
 234                       be32_to_cpu(cap.manufacturer_id));
 235
 236        /* TPM 1.2 */
 237        if (!tpm1_getcap(chip, TPM_CAP_VERSION_1_2, &cap,
 238                         "attempting to determine the 1.2 version",
 239                         sizeof(cap.version2))) {
 240                version = &cap.version2.version;
 241                goto out_print;
 242        }
 243
 244        /* TPM 1.1 */
 245        if (tpm1_getcap(chip, TPM_CAP_VERSION_1_1, &cap,
 246                        "attempting to determine the 1.1 version",
 247                        sizeof(cap.version1))) {
 248                goto out_ops;
 249        }
 250
 251        version = &cap.version1;
 252
 253out_print:
 254        str += sprintf(str,
 255                       "TCG version: %d.%d\nFirmware version: %d.%d\n",
 256                       version->major, version->minor,
 257                       version->rev_major, version->rev_minor);
 258
 259        rc = str - buf;
 260
 261out_ops:
 262        tpm_put_ops(chip);
 263        return rc;
 264}
 265static DEVICE_ATTR_RO(caps);
 266
 267static ssize_t cancel_store(struct device *dev, struct device_attribute *attr,
 268                            const char *buf, size_t count)
 269{
 270        struct tpm_chip *chip = to_tpm_chip(dev);
 271
 272        if (tpm_try_get_ops(chip))
 273                return 0;
 274
 275        chip->ops->cancel(chip);
 276        tpm_put_ops(chip);
 277        return count;
 278}
 279static DEVICE_ATTR_WO(cancel);
 280
 281static ssize_t durations_show(struct device *dev, struct device_attribute *attr,
 282                              char *buf)
 283{
 284        struct tpm_chip *chip = to_tpm_chip(dev);
 285
 286        if (chip->duration[TPM_LONG] == 0)
 287                return 0;
 288
 289        return sprintf(buf, "%d %d %d [%s]\n",
 290                       jiffies_to_usecs(chip->duration[TPM_SHORT]),
 291                       jiffies_to_usecs(chip->duration[TPM_MEDIUM]),
 292                       jiffies_to_usecs(chip->duration[TPM_LONG]),
 293                       chip->duration_adjusted
 294                       ? "adjusted" : "original");
 295}
 296static DEVICE_ATTR_RO(durations);
 297
 298static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr,
 299                             char *buf)
 300{
 301        struct tpm_chip *chip = to_tpm_chip(dev);
 302
 303        return sprintf(buf, "%d %d %d %d [%s]\n",
 304                       jiffies_to_usecs(chip->timeout_a),
 305                       jiffies_to_usecs(chip->timeout_b),
 306                       jiffies_to_usecs(chip->timeout_c),
 307                       jiffies_to_usecs(chip->timeout_d),
 308                       chip->timeout_adjusted
 309                       ? "adjusted" : "original");
 310}
 311static DEVICE_ATTR_RO(timeouts);
 312
 313static ssize_t tpm_version_major_show(struct device *dev,
 314                                  struct device_attribute *attr, char *buf)
 315{
 316        struct tpm_chip *chip = to_tpm_chip(dev);
 317
 318        return sprintf(buf, "%s\n", chip->flags & TPM_CHIP_FLAG_TPM2
 319                       ? "2" : "1");
 320}
 321static DEVICE_ATTR_RO(tpm_version_major);
 322
 323static struct attribute *tpm1_dev_attrs[] = {
 324        &dev_attr_pubek.attr,
 325        &dev_attr_pcrs.attr,
 326        &dev_attr_enabled.attr,
 327        &dev_attr_active.attr,
 328        &dev_attr_owned.attr,
 329        &dev_attr_temp_deactivated.attr,
 330        &dev_attr_caps.attr,
 331        &dev_attr_cancel.attr,
 332        &dev_attr_durations.attr,
 333        &dev_attr_timeouts.attr,
 334        &dev_attr_tpm_version_major.attr,
 335        NULL,
 336};
 337
 338static struct attribute *tpm2_dev_attrs[] = {
 339        &dev_attr_tpm_version_major.attr,
 340        NULL
 341};
 342
 343static const struct attribute_group tpm1_dev_group = {
 344        .attrs = tpm1_dev_attrs,
 345};
 346
 347static const struct attribute_group tpm2_dev_group = {
 348        .attrs = tpm2_dev_attrs,
 349};
 350
 351void tpm_sysfs_add_device(struct tpm_chip *chip)
 352{
 353        WARN_ON(chip->groups_cnt != 0);
 354        if (chip->flags & TPM_CHIP_FLAG_TPM2)
 355                chip->groups[chip->groups_cnt++] = &tpm2_dev_group;
 356        else
 357                chip->groups[chip->groups_cnt++] = &tpm1_dev_group;
 358}
 359