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 #define READ_PUBEK_RESULT_SIZE 314 24 #define READ_PUBEK_RESULT_MIN_BODY_SIZE (28 + 256) 25 #define TPM_ORD_READPUBEK 124 26 static const struct tpm_input_header tpm_readpubek_header = { 27 .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND), 28 .length = cpu_to_be32(30), 29 .ordinal = cpu_to_be32(TPM_ORD_READPUBEK) 30 }; 31 static ssize_t pubek_show(struct device *dev, struct device_attribute *attr, 32 char *buf) 33 { 34 u8 *data; 35 struct tpm_cmd_t tpm_cmd; 36 ssize_t err; 37 int i, rc; 38 char *str = buf; 39 struct tpm_chip *chip = to_tpm_chip(dev); 40 41 memset(&tpm_cmd, 0, sizeof(tpm_cmd)); 42 43 tpm_cmd.header.in = tpm_readpubek_header; 44 err = tpm_transmit_cmd(chip, NULL, &tpm_cmd, READ_PUBEK_RESULT_SIZE, 45 READ_PUBEK_RESULT_MIN_BODY_SIZE, 0, 46 "attempting to read the PUBEK"); 47 if (err) 48 goto out; 49 50 /* 51 ignore header 10 bytes 52 algorithm 32 bits (1 == RSA ) 53 encscheme 16 bits 54 sigscheme 16 bits 55 parameters (RSA 12->bytes: keybit, #primes, expbit) 56 keylenbytes 32 bits 57 256 byte modulus 58 ignore checksum 20 bytes 59 */ 60 data = tpm_cmd.params.readpubek_out_buffer; 61 str += 62 sprintf(str, 63 "Algorithm: %02X %02X %02X %02X\n" 64 "Encscheme: %02X %02X\n" 65 "Sigscheme: %02X %02X\n" 66 "Parameters: %02X %02X %02X %02X " 67 "%02X %02X %02X %02X " 68 "%02X %02X %02X %02X\n" 69 "Modulus length: %d\n" 70 "Modulus:\n", 71 data[0], data[1], data[2], data[3], 72 data[4], data[5], 73 data[6], data[7], 74 data[12], data[13], data[14], data[15], 75 data[16], data[17], data[18], data[19], 76 data[20], data[21], data[22], data[23], 77 be32_to_cpu(*((__be32 *) (data + 24)))); 78 79 for (i = 0; i < 256; i++) { 80 str += sprintf(str, "%02X ", data[i + 28]); 81 if ((i + 1) % 16 == 0) 82 str += sprintf(str, "\n"); 83 } 84 out: 85 rc = str - buf; 86 return rc; 87 } 88 static DEVICE_ATTR_RO(pubek); 89 90 static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr, 91 char *buf) 92 { 93 cap_t cap; 94 u8 digest[TPM_DIGEST_SIZE]; 95 ssize_t rc; 96 int i, j, num_pcrs; 97 char *str = buf; 98 struct tpm_chip *chip = to_tpm_chip(dev); 99 100 rc = tpm_getcap(chip, TPM_CAP_PROP_PCR, &cap, 101 "attempting to determine the number of PCRS", 102 sizeof(cap.num_pcrs)); 103 if (rc) 104 return 0; 105 106 num_pcrs = be32_to_cpu(cap.num_pcrs); 107 for (i = 0; i < num_pcrs; i++) { 108 rc = tpm_pcr_read_dev(chip, i, digest); 109 if (rc) 110 break; 111 str += sprintf(str, "PCR-%02d: ", i); 112 for (j = 0; j < TPM_DIGEST_SIZE; j++) 113 str += sprintf(str, "%02X ", digest[j]); 114 str += sprintf(str, "\n"); 115 } 116 return str - buf; 117 } 118 static DEVICE_ATTR_RO(pcrs); 119 120 static ssize_t enabled_show(struct device *dev, struct device_attribute *attr, 121 char *buf) 122 { 123 cap_t cap; 124 ssize_t rc; 125 126 rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_PERM, &cap, 127 "attempting to determine the permanent enabled state", 128 sizeof(cap.perm_flags)); 129 if (rc) 130 return 0; 131 132 rc = sprintf(buf, "%d\n", !cap.perm_flags.disable); 133 return rc; 134 } 135 static DEVICE_ATTR_RO(enabled); 136 137 static ssize_t active_show(struct device *dev, struct device_attribute *attr, 138 char *buf) 139 { 140 cap_t cap; 141 ssize_t rc; 142 143 rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_PERM, &cap, 144 "attempting to determine the permanent active state", 145 sizeof(cap.perm_flags)); 146 if (rc) 147 return 0; 148 149 rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated); 150 return rc; 151 } 152 static DEVICE_ATTR_RO(active); 153 154 static ssize_t owned_show(struct device *dev, struct device_attribute *attr, 155 char *buf) 156 { 157 cap_t cap; 158 ssize_t rc; 159 160 rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_PROP_OWNER, &cap, 161 "attempting to determine the owner state", 162 sizeof(cap.owned)); 163 if (rc) 164 return 0; 165 166 rc = sprintf(buf, "%d\n", cap.owned); 167 return rc; 168 } 169 static DEVICE_ATTR_RO(owned); 170 171 static ssize_t temp_deactivated_show(struct device *dev, 172 struct device_attribute *attr, char *buf) 173 { 174 cap_t cap; 175 ssize_t rc; 176 177 rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_VOL, &cap, 178 "attempting to determine the temporary state", 179 sizeof(cap.stclear_flags)); 180 if (rc) 181 return 0; 182 183 rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated); 184 return rc; 185 } 186 static DEVICE_ATTR_RO(temp_deactivated); 187 188 static ssize_t caps_show(struct device *dev, struct device_attribute *attr, 189 char *buf) 190 { 191 struct tpm_chip *chip = to_tpm_chip(dev); 192 cap_t cap; 193 ssize_t rc; 194 char *str = buf; 195 196 rc = tpm_getcap(chip, TPM_CAP_PROP_MANUFACTURER, &cap, 197 "attempting to determine the manufacturer", 198 sizeof(cap.manufacturer_id)); 199 if (rc) 200 return 0; 201 str += sprintf(str, "Manufacturer: 0x%x\n", 202 be32_to_cpu(cap.manufacturer_id)); 203 204 /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */ 205 rc = tpm_getcap(chip, TPM_CAP_VERSION_1_2, &cap, 206 "attempting to determine the 1.2 version", 207 sizeof(cap.tpm_version_1_2)); 208 if (!rc) { 209 str += sprintf(str, 210 "TCG version: %d.%d\nFirmware version: %d.%d\n", 211 cap.tpm_version_1_2.Major, 212 cap.tpm_version_1_2.Minor, 213 cap.tpm_version_1_2.revMajor, 214 cap.tpm_version_1_2.revMinor); 215 } else { 216 /* Otherwise just use TPM_STRUCT_VER */ 217 rc = tpm_getcap(chip, TPM_CAP_VERSION_1_1, &cap, 218 "attempting to determine the 1.1 version", 219 sizeof(cap.tpm_version)); 220 if (rc) 221 return 0; 222 str += sprintf(str, 223 "TCG version: %d.%d\nFirmware version: %d.%d\n", 224 cap.tpm_version.Major, 225 cap.tpm_version.Minor, 226 cap.tpm_version.revMajor, 227 cap.tpm_version.revMinor); 228 } 229 230 return str - buf; 231 } 232 static DEVICE_ATTR_RO(caps); 233 234 static ssize_t cancel_store(struct device *dev, struct device_attribute *attr, 235 const char *buf, size_t count) 236 { 237 struct tpm_chip *chip = to_tpm_chip(dev); 238 if (chip == NULL) 239 return 0; 240 241 chip->ops->cancel(chip); 242 return count; 243 } 244 static DEVICE_ATTR_WO(cancel); 245 246 static ssize_t durations_show(struct device *dev, struct device_attribute *attr, 247 char *buf) 248 { 249 struct tpm_chip *chip = to_tpm_chip(dev); 250 251 if (chip->duration[TPM_LONG] == 0) 252 return 0; 253 254 return sprintf(buf, "%d %d %d [%s]\n", 255 jiffies_to_usecs(chip->duration[TPM_SHORT]), 256 jiffies_to_usecs(chip->duration[TPM_MEDIUM]), 257 jiffies_to_usecs(chip->duration[TPM_LONG]), 258 chip->duration_adjusted 259 ? "adjusted" : "original"); 260 } 261 static DEVICE_ATTR_RO(durations); 262 263 static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr, 264 char *buf) 265 { 266 struct tpm_chip *chip = to_tpm_chip(dev); 267 268 return sprintf(buf, "%d %d %d %d [%s]\n", 269 jiffies_to_usecs(chip->timeout_a), 270 jiffies_to_usecs(chip->timeout_b), 271 jiffies_to_usecs(chip->timeout_c), 272 jiffies_to_usecs(chip->timeout_d), 273 chip->timeout_adjusted 274 ? "adjusted" : "original"); 275 } 276 static DEVICE_ATTR_RO(timeouts); 277 278 static struct attribute *tpm_dev_attrs[] = { 279 &dev_attr_pubek.attr, 280 &dev_attr_pcrs.attr, 281 &dev_attr_enabled.attr, 282 &dev_attr_active.attr, 283 &dev_attr_owned.attr, 284 &dev_attr_temp_deactivated.attr, 285 &dev_attr_caps.attr, 286 &dev_attr_cancel.attr, 287 &dev_attr_durations.attr, 288 &dev_attr_timeouts.attr, 289 NULL, 290 }; 291 292 static const struct attribute_group tpm_dev_group = { 293 .attrs = tpm_dev_attrs, 294 }; 295 296 void tpm_sysfs_add_device(struct tpm_chip *chip) 297 { 298 /* XXX: If you wish to remove this restriction, you must first update 299 * tpm_sysfs to explicitly lock chip->ops. 300 */ 301 if (chip->flags & TPM_CHIP_FLAG_TPM2) 302 return; 303 304 /* The sysfs routines rely on an implicit tpm_try_get_ops, device_del 305 * is called before ops is null'd and the sysfs core synchronizes this 306 * removal so that no callbacks are running or can run again 307 */ 308 WARN_ON(chip->groups_cnt != 0); 309 chip->groups[chip->groups_cnt++] = &tpm_dev_group; 310 } 311