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