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 18 struct 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 32 static 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 85 out_buf: 86 tpm_buf_destroy(&tpm_buf); 87 out_ops: 88 tpm_put_ops(chip); 89 return str - buf; 90 } 91 static DEVICE_ATTR_RO(pubek); 92 93 static 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 } 126 static DEVICE_ATTR_RO(pcrs); 127 128 static 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); 144 out_ops: 145 tpm_put_ops(chip); 146 return rc; 147 } 148 static DEVICE_ATTR_RO(enabled); 149 150 static 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); 166 out_ops: 167 tpm_put_ops(chip); 168 return rc; 169 } 170 static DEVICE_ATTR_RO(active); 171 172 static 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); 188 out_ops: 189 tpm_put_ops(chip); 190 return rc; 191 } 192 static DEVICE_ATTR_RO(owned); 193 194 static 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); 210 out_ops: 211 tpm_put_ops(chip); 212 return rc; 213 } 214 static DEVICE_ATTR_RO(temp_deactivated); 215 216 static 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 ssize_t rc = 0; 221 char *str = buf; 222 cap_t cap; 223 224 if (tpm_try_get_ops(chip)) 225 return 0; 226 227 if (tpm1_getcap(chip, TPM_CAP_PROP_MANUFACTURER, &cap, 228 "attempting to determine the manufacturer", 229 sizeof(cap.manufacturer_id))) 230 goto out_ops; 231 232 str += sprintf(str, "Manufacturer: 0x%x\n", 233 be32_to_cpu(cap.manufacturer_id)); 234 235 /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */ 236 rc = tpm1_getcap(chip, TPM_CAP_VERSION_1_2, &cap, 237 "attempting to determine the 1.2 version", 238 sizeof(cap.tpm_version_1_2)); 239 if (!rc) { 240 str += sprintf(str, 241 "TCG version: %d.%d\nFirmware version: %d.%d\n", 242 cap.tpm_version_1_2.Major, 243 cap.tpm_version_1_2.Minor, 244 cap.tpm_version_1_2.revMajor, 245 cap.tpm_version_1_2.revMinor); 246 } else { 247 /* Otherwise just use TPM_STRUCT_VER */ 248 if (tpm1_getcap(chip, TPM_CAP_VERSION_1_1, &cap, 249 "attempting to determine the 1.1 version", 250 sizeof(cap.tpm_version))) 251 goto out_ops; 252 str += sprintf(str, 253 "TCG version: %d.%d\nFirmware version: %d.%d\n", 254 cap.tpm_version.Major, 255 cap.tpm_version.Minor, 256 cap.tpm_version.revMajor, 257 cap.tpm_version.revMinor); 258 } 259 rc = str - buf; 260 out_ops: 261 tpm_put_ops(chip); 262 return rc; 263 } 264 static DEVICE_ATTR_RO(caps); 265 266 static ssize_t cancel_store(struct device *dev, struct device_attribute *attr, 267 const char *buf, size_t count) 268 { 269 struct tpm_chip *chip = to_tpm_chip(dev); 270 271 if (tpm_try_get_ops(chip)) 272 return 0; 273 274 chip->ops->cancel(chip); 275 tpm_put_ops(chip); 276 return count; 277 } 278 static DEVICE_ATTR_WO(cancel); 279 280 static ssize_t durations_show(struct device *dev, struct device_attribute *attr, 281 char *buf) 282 { 283 struct tpm_chip *chip = to_tpm_chip(dev); 284 285 if (chip->duration[TPM_LONG] == 0) 286 return 0; 287 288 return sprintf(buf, "%d %d %d [%s]\n", 289 jiffies_to_usecs(chip->duration[TPM_SHORT]), 290 jiffies_to_usecs(chip->duration[TPM_MEDIUM]), 291 jiffies_to_usecs(chip->duration[TPM_LONG]), 292 chip->duration_adjusted 293 ? "adjusted" : "original"); 294 } 295 static DEVICE_ATTR_RO(durations); 296 297 static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr, 298 char *buf) 299 { 300 struct tpm_chip *chip = to_tpm_chip(dev); 301 302 return sprintf(buf, "%d %d %d %d [%s]\n", 303 jiffies_to_usecs(chip->timeout_a), 304 jiffies_to_usecs(chip->timeout_b), 305 jiffies_to_usecs(chip->timeout_c), 306 jiffies_to_usecs(chip->timeout_d), 307 chip->timeout_adjusted 308 ? "adjusted" : "original"); 309 } 310 static DEVICE_ATTR_RO(timeouts); 311 312 static struct attribute *tpm_dev_attrs[] = { 313 &dev_attr_pubek.attr, 314 &dev_attr_pcrs.attr, 315 &dev_attr_enabled.attr, 316 &dev_attr_active.attr, 317 &dev_attr_owned.attr, 318 &dev_attr_temp_deactivated.attr, 319 &dev_attr_caps.attr, 320 &dev_attr_cancel.attr, 321 &dev_attr_durations.attr, 322 &dev_attr_timeouts.attr, 323 NULL, 324 }; 325 326 static const struct attribute_group tpm_dev_group = { 327 .attrs = tpm_dev_attrs, 328 }; 329 330 void tpm_sysfs_add_device(struct tpm_chip *chip) 331 { 332 /* XXX: If you wish to remove this restriction, you must first update 333 * tpm_sysfs to explicitly lock chip->ops. 334 */ 335 if (chip->flags & TPM_CHIP_FLAG_TPM2) 336 return; 337 338 /* The sysfs routines rely on an implicit tpm_try_get_ops, device_del 339 * is called before ops is null'd and the sysfs core synchronizes this 340 * removal so that no callbacks are running or can run again 341 */ 342 WARN_ON(chip->groups_cnt != 0); 343 chip->groups[chip->groups_cnt++] = &tpm_dev_group; 344 } 345