1 /* 2 * Copyright (C) 2004 IBM Corporation 3 * Authors: 4 * Leendert van Doorn <leendert@watson.ibm.com> 5 * Dave Safford <safford@watson.ibm.com> 6 * Reiner Sailer <sailer@watson.ibm.com> 7 * Kylene Hall <kjhall@us.ibm.com> 8 * 9 * Copyright (C) 2013 Obsidian Research Corp 10 * Jason Gunthorpe <jgunthorpe@obsidianresearch.com> 11 * 12 * sysfs filesystem inspection interface to the TPM 13 * 14 * This program is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU General Public License as 16 * published by the Free Software Foundation, version 2 of the 17 * License. 18 * 19 */ 20 #include <linux/device.h> 21 #include "tpm.h" 22 23 /* XXX for now this helper is duplicated in tpm-interface.c */ 24 static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd, 25 int len, const char *desc) 26 { 27 int err; 28 29 len = tpm_transmit(chip, (u8 *) cmd, len); 30 if (len < 0) 31 return len; 32 else if (len < TPM_HEADER_SIZE) 33 return -EFAULT; 34 35 err = be32_to_cpu(cmd->header.out.return_code); 36 if (err != 0 && desc) 37 dev_err(chip->dev, "A TPM error (%d) occurred %s\n", err, desc); 38 39 return err; 40 } 41 42 #define READ_PUBEK_RESULT_SIZE 314 43 #define TPM_ORD_READPUBEK cpu_to_be32(124) 44 static struct tpm_input_header tpm_readpubek_header = { 45 .tag = TPM_TAG_RQU_COMMAND, 46 .length = cpu_to_be32(30), 47 .ordinal = TPM_ORD_READPUBEK 48 }; 49 static ssize_t pubek_show(struct device *dev, struct device_attribute *attr, 50 char *buf) 51 { 52 u8 *data; 53 struct tpm_cmd_t tpm_cmd; 54 ssize_t err; 55 int i, rc; 56 char *str = buf; 57 58 struct tpm_chip *chip = dev_get_drvdata(dev); 59 60 tpm_cmd.header.in = tpm_readpubek_header; 61 err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, 62 "attempting to read the PUBEK"); 63 if (err) 64 goto out; 65 66 /* 67 ignore header 10 bytes 68 algorithm 32 bits (1 == RSA ) 69 encscheme 16 bits 70 sigscheme 16 bits 71 parameters (RSA 12->bytes: keybit, #primes, expbit) 72 keylenbytes 32 bits 73 256 byte modulus 74 ignore checksum 20 bytes 75 */ 76 data = tpm_cmd.params.readpubek_out_buffer; 77 str += 78 sprintf(str, 79 "Algorithm: %02X %02X %02X %02X\n" 80 "Encscheme: %02X %02X\n" 81 "Sigscheme: %02X %02X\n" 82 "Parameters: %02X %02X %02X %02X " 83 "%02X %02X %02X %02X " 84 "%02X %02X %02X %02X\n" 85 "Modulus length: %d\n" 86 "Modulus:\n", 87 data[0], data[1], data[2], data[3], 88 data[4], data[5], 89 data[6], data[7], 90 data[12], data[13], data[14], data[15], 91 data[16], data[17], data[18], data[19], 92 data[20], data[21], data[22], data[23], 93 be32_to_cpu(*((__be32 *) (data + 24)))); 94 95 for (i = 0; i < 256; i++) { 96 str += sprintf(str, "%02X ", data[i + 28]); 97 if ((i + 1) % 16 == 0) 98 str += sprintf(str, "\n"); 99 } 100 out: 101 rc = str - buf; 102 return rc; 103 } 104 static DEVICE_ATTR_RO(pubek); 105 106 static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr, 107 char *buf) 108 { 109 cap_t cap; 110 u8 digest[TPM_DIGEST_SIZE]; 111 ssize_t rc; 112 int i, j, num_pcrs; 113 char *str = buf; 114 struct tpm_chip *chip = dev_get_drvdata(dev); 115 116 rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap, 117 "attempting to determine the number of PCRS"); 118 if (rc) 119 return 0; 120 121 num_pcrs = be32_to_cpu(cap.num_pcrs); 122 for (i = 0; i < num_pcrs; i++) { 123 rc = tpm_pcr_read_dev(chip, i, digest); 124 if (rc) 125 break; 126 str += sprintf(str, "PCR-%02d: ", i); 127 for (j = 0; j < TPM_DIGEST_SIZE; j++) 128 str += sprintf(str, "%02X ", digest[j]); 129 str += sprintf(str, "\n"); 130 } 131 return str - buf; 132 } 133 static DEVICE_ATTR_RO(pcrs); 134 135 static ssize_t enabled_show(struct device *dev, struct device_attribute *attr, 136 char *buf) 137 { 138 cap_t cap; 139 ssize_t rc; 140 141 rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap, 142 "attempting to determine the permanent enabled state"); 143 if (rc) 144 return 0; 145 146 rc = sprintf(buf, "%d\n", !cap.perm_flags.disable); 147 return rc; 148 } 149 static DEVICE_ATTR_RO(enabled); 150 151 static ssize_t active_show(struct device *dev, struct device_attribute *attr, 152 char *buf) 153 { 154 cap_t cap; 155 ssize_t rc; 156 157 rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap, 158 "attempting to determine the permanent active state"); 159 if (rc) 160 return 0; 161 162 rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated); 163 return rc; 164 } 165 static DEVICE_ATTR_RO(active); 166 167 static ssize_t owned_show(struct device *dev, struct device_attribute *attr, 168 char *buf) 169 { 170 cap_t cap; 171 ssize_t rc; 172 173 rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap, 174 "attempting to determine the owner state"); 175 if (rc) 176 return 0; 177 178 rc = sprintf(buf, "%d\n", cap.owned); 179 return rc; 180 } 181 static DEVICE_ATTR_RO(owned); 182 183 static ssize_t temp_deactivated_show(struct device *dev, 184 struct device_attribute *attr, char *buf) 185 { 186 cap_t cap; 187 ssize_t rc; 188 189 rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap, 190 "attempting to determine the temporary state"); 191 if (rc) 192 return 0; 193 194 rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated); 195 return rc; 196 } 197 static DEVICE_ATTR_RO(temp_deactivated); 198 199 static ssize_t caps_show(struct device *dev, struct device_attribute *attr, 200 char *buf) 201 { 202 cap_t cap; 203 ssize_t rc; 204 char *str = buf; 205 206 rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap, 207 "attempting to determine the manufacturer"); 208 if (rc) 209 return 0; 210 str += sprintf(str, "Manufacturer: 0x%x\n", 211 be32_to_cpu(cap.manufacturer_id)); 212 213 /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */ 214 rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap, 215 "attempting to determine the 1.2 version"); 216 if (!rc) { 217 str += sprintf(str, 218 "TCG version: %d.%d\nFirmware version: %d.%d\n", 219 cap.tpm_version_1_2.Major, 220 cap.tpm_version_1_2.Minor, 221 cap.tpm_version_1_2.revMajor, 222 cap.tpm_version_1_2.revMinor); 223 } else { 224 /* Otherwise just use TPM_STRUCT_VER */ 225 rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap, 226 "attempting to determine the 1.1 version"); 227 if (rc) 228 return 0; 229 str += sprintf(str, 230 "TCG version: %d.%d\nFirmware version: %d.%d\n", 231 cap.tpm_version.Major, 232 cap.tpm_version.Minor, 233 cap.tpm_version.revMajor, 234 cap.tpm_version.revMinor); 235 } 236 237 return str - buf; 238 } 239 static DEVICE_ATTR_RO(caps); 240 241 static ssize_t cancel_store(struct device *dev, struct device_attribute *attr, 242 const char *buf, size_t count) 243 { 244 struct tpm_chip *chip = dev_get_drvdata(dev); 245 if (chip == NULL) 246 return 0; 247 248 chip->ops->cancel(chip); 249 return count; 250 } 251 static DEVICE_ATTR_WO(cancel); 252 253 static ssize_t durations_show(struct device *dev, struct device_attribute *attr, 254 char *buf) 255 { 256 struct tpm_chip *chip = dev_get_drvdata(dev); 257 258 if (chip->vendor.duration[TPM_LONG] == 0) 259 return 0; 260 261 return sprintf(buf, "%d %d %d [%s]\n", 262 jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]), 263 jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]), 264 jiffies_to_usecs(chip->vendor.duration[TPM_LONG]), 265 chip->vendor.duration_adjusted 266 ? "adjusted" : "original"); 267 } 268 static DEVICE_ATTR_RO(durations); 269 270 static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr, 271 char *buf) 272 { 273 struct tpm_chip *chip = dev_get_drvdata(dev); 274 275 return sprintf(buf, "%d %d %d %d [%s]\n", 276 jiffies_to_usecs(chip->vendor.timeout_a), 277 jiffies_to_usecs(chip->vendor.timeout_b), 278 jiffies_to_usecs(chip->vendor.timeout_c), 279 jiffies_to_usecs(chip->vendor.timeout_d), 280 chip->vendor.timeout_adjusted 281 ? "adjusted" : "original"); 282 } 283 static DEVICE_ATTR_RO(timeouts); 284 285 static struct attribute *tpm_dev_attrs[] = { 286 &dev_attr_pubek.attr, 287 &dev_attr_pcrs.attr, 288 &dev_attr_enabled.attr, 289 &dev_attr_active.attr, 290 &dev_attr_owned.attr, 291 &dev_attr_temp_deactivated.attr, 292 &dev_attr_caps.attr, 293 &dev_attr_cancel.attr, 294 &dev_attr_durations.attr, 295 &dev_attr_timeouts.attr, 296 NULL, 297 }; 298 299 static const struct attribute_group tpm_dev_group = { 300 .attrs = tpm_dev_attrs, 301 }; 302 303 int tpm_sysfs_add_device(struct tpm_chip *chip) 304 { 305 int err; 306 err = sysfs_create_group(&chip->dev->kobj, 307 &tpm_dev_group); 308 309 if (err) 310 dev_err(chip->dev, 311 "failed to create sysfs attributes, %d\n", err); 312 return err; 313 } 314 315 void tpm_sysfs_del_device(struct tpm_chip *chip) 316 { 317 sysfs_remove_group(&chip->dev->kobj, &tpm_dev_group); 318 } 319