1 /* 2 * Copyright (C) 2004 IBM Corporation 3 * 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 * Maintained by: <tpmdd-devel@lists.sourceforge.net> 11 * 12 * Device driver for TCG/TCPA TPM (trusted platform module). 13 * Specifications at www.trustedcomputinggroup.org 14 * 15 * This program is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU General Public License as 17 * published by the Free Software Foundation, version 2 of the 18 * License. 19 * 20 */ 21 #include <linux/module.h> 22 #include <linux/delay.h> 23 #include <linux/fs.h> 24 #include <linux/mutex.h> 25 #include <linux/sched.h> 26 #include <linux/miscdevice.h> 27 #include <linux/platform_device.h> 28 #include <linux/io.h> 29 #include <linux/tpm.h> 30 31 enum tpm_timeout { 32 TPM_TIMEOUT = 5, /* msecs */ 33 }; 34 35 /* TPM addresses */ 36 enum tpm_addr { 37 TPM_SUPERIO_ADDR = 0x2E, 38 TPM_ADDR = 0x4E, 39 }; 40 41 extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr, 42 char *); 43 extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr, 44 char *); 45 extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr, 46 char *); 47 extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr, 48 char *); 49 extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr, 50 const char *, size_t); 51 extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr, 52 char *); 53 extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr, 54 char *); 55 extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr, 56 char *); 57 extern ssize_t tpm_show_temp_deactivated(struct device *, 58 struct device_attribute *attr, char *); 59 60 struct tpm_chip; 61 62 struct tpm_vendor_specific { 63 const u8 req_complete_mask; 64 const u8 req_complete_val; 65 const u8 req_canceled; 66 void __iomem *iobase; /* ioremapped address */ 67 unsigned long base; /* TPM base address */ 68 69 int irq; 70 71 int region_size; 72 int have_region; 73 74 int (*recv) (struct tpm_chip *, u8 *, size_t); 75 int (*send) (struct tpm_chip *, u8 *, size_t); 76 void (*cancel) (struct tpm_chip *); 77 u8 (*status) (struct tpm_chip *); 78 void (*release) (struct device *); 79 struct miscdevice miscdev; 80 struct attribute_group *attr_group; 81 struct list_head list; 82 int locality; 83 unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */ 84 unsigned long duration[3]; /* jiffies */ 85 86 wait_queue_head_t read_queue; 87 wait_queue_head_t int_queue; 88 }; 89 90 struct tpm_chip { 91 struct device *dev; /* Device stuff */ 92 93 int dev_num; /* /dev/tpm# */ 94 unsigned long is_open; /* only one allowed */ 95 int time_expired; 96 97 /* Data passed to and from the tpm via the read/write calls */ 98 u8 *data_buffer; 99 atomic_t data_pending; 100 struct mutex buffer_mutex; 101 102 struct timer_list user_read_timer; /* user needs to claim result */ 103 struct work_struct work; 104 struct mutex tpm_mutex; /* tpm is processing */ 105 106 struct tpm_vendor_specific vendor; 107 108 struct dentry **bios_dir; 109 110 struct list_head list; 111 void (*release) (struct device *); 112 }; 113 114 #define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor) 115 116 static inline void tpm_chip_put(struct tpm_chip *chip) 117 { 118 module_put(chip->dev->driver->owner); 119 } 120 121 static inline int tpm_read_index(int base, int index) 122 { 123 outb(index, base); 124 return inb(base+1) & 0xFF; 125 } 126 127 static inline void tpm_write_index(int base, int index, int value) 128 { 129 outb(index, base); 130 outb(value & 0xFF, base+1); 131 } 132 struct tpm_input_header { 133 __be16 tag; 134 __be32 length; 135 __be32 ordinal; 136 }__attribute__((packed)); 137 138 struct tpm_output_header { 139 __be16 tag; 140 __be32 length; 141 __be32 return_code; 142 }__attribute__((packed)); 143 144 struct stclear_flags_t { 145 __be16 tag; 146 u8 deactivated; 147 u8 disableForceClear; 148 u8 physicalPresence; 149 u8 physicalPresenceLock; 150 u8 bGlobalLock; 151 }__attribute__((packed)); 152 153 struct tpm_version_t { 154 u8 Major; 155 u8 Minor; 156 u8 revMajor; 157 u8 revMinor; 158 }__attribute__((packed)); 159 160 struct tpm_version_1_2_t { 161 __be16 tag; 162 u8 Major; 163 u8 Minor; 164 u8 revMajor; 165 u8 revMinor; 166 }__attribute__((packed)); 167 168 struct timeout_t { 169 __be32 a; 170 __be32 b; 171 __be32 c; 172 __be32 d; 173 }__attribute__((packed)); 174 175 struct duration_t { 176 __be32 tpm_short; 177 __be32 tpm_medium; 178 __be32 tpm_long; 179 }__attribute__((packed)); 180 181 struct permanent_flags_t { 182 __be16 tag; 183 u8 disable; 184 u8 ownership; 185 u8 deactivated; 186 u8 readPubek; 187 u8 disableOwnerClear; 188 u8 allowMaintenance; 189 u8 physicalPresenceLifetimeLock; 190 u8 physicalPresenceHWEnable; 191 u8 physicalPresenceCMDEnable; 192 u8 CEKPUsed; 193 u8 TPMpost; 194 u8 TPMpostLock; 195 u8 FIPS; 196 u8 operator; 197 u8 enableRevokeEK; 198 u8 nvLocked; 199 u8 readSRKPub; 200 u8 tpmEstablished; 201 u8 maintenanceDone; 202 u8 disableFullDALogicInfo; 203 }__attribute__((packed)); 204 205 typedef union { 206 struct permanent_flags_t perm_flags; 207 struct stclear_flags_t stclear_flags; 208 bool owned; 209 __be32 num_pcrs; 210 struct tpm_version_t tpm_version; 211 struct tpm_version_1_2_t tpm_version_1_2; 212 __be32 manufacturer_id; 213 struct timeout_t timeout; 214 struct duration_t duration; 215 } cap_t; 216 217 struct tpm_getcap_params_in { 218 __be32 cap; 219 __be32 subcap_size; 220 __be32 subcap; 221 }__attribute__((packed)); 222 223 struct tpm_getcap_params_out { 224 __be32 cap_size; 225 cap_t cap; 226 }__attribute__((packed)); 227 228 struct tpm_readpubek_params_out { 229 u8 algorithm[4]; 230 u8 encscheme[2]; 231 u8 sigscheme[2]; 232 __be32 paramsize; 233 u8 parameters[12]; /*assuming RSA*/ 234 __be32 keysize; 235 u8 modulus[256]; 236 u8 checksum[20]; 237 }__attribute__((packed)); 238 239 typedef union { 240 struct tpm_input_header in; 241 struct tpm_output_header out; 242 } tpm_cmd_header; 243 244 #define TPM_DIGEST_SIZE 20 245 struct tpm_pcrread_out { 246 u8 pcr_result[TPM_DIGEST_SIZE]; 247 }__attribute__((packed)); 248 249 struct tpm_pcrread_in { 250 __be32 pcr_idx; 251 }__attribute__((packed)); 252 253 struct tpm_pcrextend_in { 254 __be32 pcr_idx; 255 u8 hash[TPM_DIGEST_SIZE]; 256 }__attribute__((packed)); 257 258 typedef union { 259 struct tpm_getcap_params_out getcap_out; 260 struct tpm_readpubek_params_out readpubek_out; 261 u8 readpubek_out_buffer[sizeof(struct tpm_readpubek_params_out)]; 262 struct tpm_getcap_params_in getcap_in; 263 struct tpm_pcrread_in pcrread_in; 264 struct tpm_pcrread_out pcrread_out; 265 struct tpm_pcrextend_in pcrextend_in; 266 } tpm_cmd_params; 267 268 struct tpm_cmd_t { 269 tpm_cmd_header header; 270 tpm_cmd_params params; 271 }__attribute__((packed)); 272 273 ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *); 274 275 extern void tpm_get_timeouts(struct tpm_chip *); 276 extern void tpm_gen_interrupt(struct tpm_chip *); 277 extern void tpm_continue_selftest(struct tpm_chip *); 278 extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32); 279 extern struct tpm_chip* tpm_register_hardware(struct device *, 280 const struct tpm_vendor_specific *); 281 extern int tpm_open(struct inode *, struct file *); 282 extern int tpm_release(struct inode *, struct file *); 283 extern void tpm_dev_vendor_release(struct tpm_chip *); 284 extern ssize_t tpm_write(struct file *, const char __user *, size_t, 285 loff_t *); 286 extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); 287 extern void tpm_remove_hardware(struct device *); 288 extern int tpm_pm_suspend(struct device *, pm_message_t); 289 extern int tpm_pm_resume(struct device *); 290 291 #ifdef CONFIG_ACPI 292 extern struct dentry ** tpm_bios_log_setup(char *); 293 extern void tpm_bios_log_teardown(struct dentry **); 294 #else 295 static inline struct dentry ** tpm_bios_log_setup(char *name) 296 { 297 return NULL; 298 } 299 static inline void tpm_bios_log_teardown(struct dentry **dir) 300 { 301 } 302 #endif 303