tpm.h 7.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9
/*
 * Copyright (C) 2004 IBM Corporation
 *
 * Authors:
 * Leendert van Doorn <leendert@watson.ibm.com>
 * Dave Safford <safford@watson.ibm.com>
 * Reiner Sailer <sailer@watson.ibm.com>
 * Kylene Hall <kjhall@us.ibm.com>
 *
K
Kent Yoder 已提交
10
 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
L
Linus Torvalds 已提交
11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * Device driver for TCG/TCPA TPM (trusted platform module).
 * Specifications at www.trustedcomputinggroup.org	 
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, version 2 of the
 * License.
 * 
 */
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/fs.h>
24
#include <linux/mutex.h>
25
#include <linux/sched.h>
L
Linus Torvalds 已提交
26
#include <linux/miscdevice.h>
27
#include <linux/platform_device.h>
A
Andrew Morton 已提交
28
#include <linux/io.h>
R
Rajiv Andrade 已提交
29
#include <linux/tpm.h>
L
Linus Torvalds 已提交
30

31 32 33
enum tpm_timeout {
	TPM_TIMEOUT = 5,	/* msecs */
};
L
Linus Torvalds 已提交
34 35

/* TPM addresses */
36
enum tpm_addr {
37
	TPM_SUPERIO_ADDR = 0x2E,
38 39 40
	TPM_ADDR = 0x4E,
};

41 42 43 44 45 46
extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
				char *);
extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr,
				char *);
extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
				char *);
47 48
extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr,
				char *);
49 50
extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
				const char *, size_t);
51 52 53 54 55 56 57 58
extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr,
				char *);
extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr,
				char *);
extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr,
				char *);
extern ssize_t tpm_show_temp_deactivated(struct device *,
					 struct device_attribute *attr, char *);
59 60
extern ssize_t tpm_show_durations(struct device *,
				  struct device_attribute *attr, char *);
61 62
extern ssize_t tpm_show_timeouts(struct device *,
				 struct device_attribute *attr, char *);
L
Linus Torvalds 已提交
63 64 65 66

struct tpm_chip;

struct tpm_vendor_specific {
67 68 69
	const u8 req_complete_mask;
	const u8 req_complete_val;
	const u8 req_canceled;
70 71 72
	void __iomem *iobase;		/* ioremapped address */
	unsigned long base;		/* TPM base address */

73
	int irq;
74
	int probed_irq;
75

76 77
	int region_size;
	int have_region;
L
Linus Torvalds 已提交
78 79 80 81

	int (*recv) (struct tpm_chip *, u8 *, size_t);
	int (*send) (struct tpm_chip *, u8 *, size_t);
	void (*cancel) (struct tpm_chip *);
82
	u8 (*status) (struct tpm_chip *);
83
	void (*release) (struct device *);
L
Linus Torvalds 已提交
84
	struct miscdevice miscdev;
85
	struct attribute_group *attr_group;
86 87
	struct list_head list;
	int locality;
88
	unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */
89
	bool timeout_adjusted;
90
	unsigned long duration[3]; /* jiffies */
91
	bool duration_adjusted;
92 93 94

	wait_queue_head_t read_queue;
	wait_queue_head_t int_queue;
L
Linus Torvalds 已提交
95 96 97
};

struct tpm_chip {
98
	struct device *dev;	/* Device stuff */
L
Linus Torvalds 已提交
99 100

	int dev_num;		/* /dev/tpm# */
101
	unsigned long is_open;	/* only one allowed */
L
Linus Torvalds 已提交
102 103 104 105 106
	int time_expired;

	/* Data passed to and from the tpm via the read/write calls */
	u8 *data_buffer;
	atomic_t data_pending;
107
	struct mutex buffer_mutex;
L
Linus Torvalds 已提交
108 109

	struct timer_list user_read_timer;	/* user needs to claim result */
K
Kylene Jo Hall 已提交
110
	struct work_struct work;
111
	struct mutex tpm_mutex;	/* tpm is processing */
L
Linus Torvalds 已提交
112

K
Kylene Jo Hall 已提交
113
	struct tpm_vendor_specific vendor;
L
Linus Torvalds 已提交
114

115 116
	struct dentry **bios_dir;

L
Linus Torvalds 已提交
117
	struct list_head list;
118
	void (*release) (struct device *);
L
Linus Torvalds 已提交
119 120
};

121 122
#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)

M
Mimi Zohar 已提交
123 124 125 126 127
static inline void tpm_chip_put(struct tpm_chip *chip)
{
	module_put(chip->dev->driver->owner);
}

128
static inline int tpm_read_index(int base, int index)
L
Linus Torvalds 已提交
129
{
130 131
	outb(index, base);
	return inb(base+1) & 0xFF;
L
Linus Torvalds 已提交
132 133
}

134
static inline void tpm_write_index(int base, int index, int value)
L
Linus Torvalds 已提交
135
{
136 137
	outb(index, base);
	outb(value & 0xFF, base+1);
L
Linus Torvalds 已提交
138
}
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
struct tpm_input_header {
	__be16	tag;
	__be32	length;
	__be32	ordinal;
}__attribute__((packed));

struct tpm_output_header {
	__be16	tag;
	__be32	length;
	__be32	return_code;
}__attribute__((packed));

struct	stclear_flags_t {
	__be16	tag;
	u8	deactivated;
	u8	disableForceClear;
	u8	physicalPresence;
	u8	physicalPresenceLock;
	u8	bGlobalLock;
}__attribute__((packed));

struct	tpm_version_t {
	u8	Major;
	u8	Minor;
	u8	revMajor;
	u8	revMinor;
}__attribute__((packed));

struct	tpm_version_1_2_t {
	__be16	tag;
	u8	Major;
	u8	Minor;
	u8	revMajor;
	u8	revMinor;
}__attribute__((packed));

struct	timeout_t {
	__be32	a;
	__be32	b;
	__be32	c;
	__be32	d;
}__attribute__((packed));

struct duration_t {
	__be32	tpm_short;
	__be32	tpm_medium;
	__be32	tpm_long;
}__attribute__((packed));

struct permanent_flags_t {
	__be16	tag;
	u8	disable;
	u8	ownership;
	u8	deactivated;
	u8	readPubek;
	u8	disableOwnerClear;
	u8	allowMaintenance;
	u8	physicalPresenceLifetimeLock;
	u8	physicalPresenceHWEnable;
	u8	physicalPresenceCMDEnable;
	u8	CEKPUsed;
	u8	TPMpost;
	u8	TPMpostLock;
	u8	FIPS;
	u8	operator;
	u8	enableRevokeEK;
	u8	nvLocked;
	u8	readSRKPub;
	u8	tpmEstablished;
	u8	maintenanceDone;
	u8	disableFullDALogicInfo;
}__attribute__((packed));

typedef union {
	struct	permanent_flags_t perm_flags;
	struct	stclear_flags_t	stclear_flags;
	bool	owned;
	__be32	num_pcrs;
	struct	tpm_version_t	tpm_version;
	struct	tpm_version_1_2_t tpm_version_1_2;
	__be32	manufacturer_id;
	struct timeout_t  timeout;
	struct duration_t duration;
} cap_t;

struct	tpm_getcap_params_in {
	__be32	cap;
	__be32	subcap_size;
	__be32	subcap;
}__attribute__((packed));

struct	tpm_getcap_params_out {
	__be32	cap_size;
	cap_t	cap;
}__attribute__((packed));

struct	tpm_readpubek_params_out {
	u8	algorithm[4];
	u8	encscheme[2];
	u8	sigscheme[2];
R
Rajiv Andrade 已提交
239
	__be32	paramsize;
240 241 242 243 244 245 246 247 248 249 250
	u8	parameters[12]; /*assuming RSA*/
	__be32	keysize;
	u8	modulus[256];
	u8	checksum[20];
}__attribute__((packed));

typedef union {
	struct	tpm_input_header in;
	struct	tpm_output_header out;
} tpm_cmd_header;

R
Rajiv Andrade 已提交
251 252 253 254 255 256 257 258 259 260 261 262 263 264
#define TPM_DIGEST_SIZE 20
struct tpm_pcrread_out {
	u8	pcr_result[TPM_DIGEST_SIZE];
}__attribute__((packed));

struct tpm_pcrread_in {
	__be32	pcr_idx;
}__attribute__((packed));

struct tpm_pcrextend_in {
	__be32	pcr_idx;
	u8	hash[TPM_DIGEST_SIZE];
}__attribute__((packed));

265 266 267 268 269
typedef union {
	struct	tpm_getcap_params_out getcap_out;
	struct	tpm_readpubek_params_out readpubek_out;
	u8	readpubek_out_buffer[sizeof(struct tpm_readpubek_params_out)];
	struct	tpm_getcap_params_in getcap_in;
R
Rajiv Andrade 已提交
270 271 272
	struct	tpm_pcrread_in	pcrread_in;
	struct	tpm_pcrread_out	pcrread_out;
	struct	tpm_pcrextend_in pcrextend_in;
273 274 275 276 277 278 279 280
} tpm_cmd_params;

struct tpm_cmd_t {
	tpm_cmd_header	header;
	tpm_cmd_params	params;
}__attribute__((packed));

ssize_t	tpm_getcap(struct device *, __be32, cap_t *, const char *);
L
Linus Torvalds 已提交
281

282
extern int tpm_get_timeouts(struct tpm_chip *);
283
extern void tpm_gen_interrupt(struct tpm_chip *);
S
Stefan Berger 已提交
284
extern int tpm_continue_selftest(struct tpm_chip *);
285
extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
286 287
extern struct tpm_chip* tpm_register_hardware(struct device *,
				 const struct tpm_vendor_specific *);
L
Linus Torvalds 已提交
288 289
extern int tpm_open(struct inode *, struct file *);
extern int tpm_release(struct inode *, struct file *);
290
extern void tpm_dev_vendor_release(struct tpm_chip *);
L
Linus Torvalds 已提交
291 292 293
extern ssize_t tpm_write(struct file *, const char __user *, size_t,
			 loff_t *);
extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
294
extern void tpm_remove_hardware(struct device *);
295 296
extern int tpm_pm_suspend(struct device *, pm_message_t);
extern int tpm_pm_resume(struct device *);
297 298 299 300 301

#ifdef CONFIG_ACPI
extern struct dentry ** tpm_bios_log_setup(char *);
extern void tpm_bios_log_teardown(struct dentry **);
#else
302
static inline struct dentry ** tpm_bios_log_setup(char *name)
303 304 305 306 307 308 309
{
	return NULL;
}
static inline void tpm_bios_log_teardown(struct dentry **dir)
{
}
#endif