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