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 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 253 out_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 261 out_ops: 262 tpm_put_ops(chip); 263 return rc; 264 } 265 static DEVICE_ATTR_RO(caps); 266 267 static 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 } 279 static DEVICE_ATTR_WO(cancel); 280 281 static 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 } 296 static DEVICE_ATTR_RO(durations); 297 298 static 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 } 311 static DEVICE_ATTR_RO(timeouts); 312 313 static struct attribute *tpm_dev_attrs[] = { 314 &dev_attr_pubek.attr, 315 &dev_attr_pcrs.attr, 316 &dev_attr_enabled.attr, 317 &dev_attr_active.attr, 318 &dev_attr_owned.attr, 319 &dev_attr_temp_deactivated.attr, 320 &dev_attr_caps.attr, 321 &dev_attr_cancel.attr, 322 &dev_attr_durations.attr, 323 &dev_attr_timeouts.attr, 324 NULL, 325 }; 326 327 static const struct attribute_group tpm_dev_group = { 328 .attrs = tpm_dev_attrs, 329 }; 330 331 void tpm_sysfs_add_device(struct tpm_chip *chip) 332 { 333 if (chip->flags & TPM_CHIP_FLAG_TPM2) 334 return; 335 336 WARN_ON(chip->groups_cnt != 0); 337 chip->groups[chip->groups_cnt++] = &tpm_dev_group; 338 } 339