tpm.h 8.6 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 34 35 36
enum tpm_const {
	TPM_MINOR = 224,	/* officially assigned */
	TPM_BUFSIZE = 4096,
	TPM_NUM_DEVICES = 256,
};

37 38 39
enum tpm_timeout {
	TPM_TIMEOUT = 5,	/* msecs */
};
L
Linus Torvalds 已提交
40 41

/* TPM addresses */
42
enum tpm_addr {
43
	TPM_SUPERIO_ADDR = 0x2E,
44 45 46
	TPM_ADDR = 0x4E,
};

47
#define TPM_WARN_DOING_SELFTEST 0x802
48 49
#define TPM_ERR_DEACTIVATED     0x6
#define TPM_ERR_DISABLED        0x7
50
#define TPM_ERR_INVALID_POSTINIT 38
51

R
Rajiv Andrade 已提交
52
#define TPM_HEADER_SIZE		10
53 54 55 56 57 58
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 *);
59 60
extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr,
				char *);
61 62
extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
				const char *, size_t);
63 64 65 66 67 68 69 70
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 *);
71 72
extern ssize_t tpm_show_durations(struct device *,
				  struct device_attribute *attr, char *);
73 74
extern ssize_t tpm_show_timeouts(struct device *,
				 struct device_attribute *attr, char *);
L
Linus Torvalds 已提交
75 76 77 78

struct tpm_chip;

struct tpm_vendor_specific {
79 80 81
	const u8 req_complete_mask;
	const u8 req_complete_val;
	const u8 req_canceled;
82 83 84
	void __iomem *iobase;		/* ioremapped address */
	unsigned long base;		/* TPM base address */

85
	int irq;
86
	int probed_irq;
87

88 89
	int region_size;
	int have_region;
L
Linus Torvalds 已提交
90 91 92 93

	int (*recv) (struct tpm_chip *, u8 *, size_t);
	int (*send) (struct tpm_chip *, u8 *, size_t);
	void (*cancel) (struct tpm_chip *);
94
	u8 (*status) (struct tpm_chip *);
95
	void (*release) (struct device *);
L
Linus Torvalds 已提交
96
	struct miscdevice miscdev;
97
	struct attribute_group *attr_group;
98 99
	struct list_head list;
	int locality;
100
	unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */
101
	bool timeout_adjusted;
102
	unsigned long duration[3]; /* jiffies */
103
	bool duration_adjusted;
104
	void *data;
105 106 107

	wait_queue_head_t read_queue;
	wait_queue_head_t int_queue;
L
Linus Torvalds 已提交
108 109
};

S
Stefan Berger 已提交
110 111
#define TPM_VID_INTEL    0x8086

L
Linus Torvalds 已提交
112
struct tpm_chip {
113
	struct device *dev;	/* Device stuff */
L
Linus Torvalds 已提交
114 115

	int dev_num;		/* /dev/tpm# */
116
	unsigned long is_open;	/* only one allowed */
L
Linus Torvalds 已提交
117 118 119 120 121
	int time_expired;

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

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

K
Kylene Jo Hall 已提交
128
	struct tpm_vendor_specific vendor;
L
Linus Torvalds 已提交
129

130 131
	struct dentry **bios_dir;

L
Linus Torvalds 已提交
132
	struct list_head list;
133
	void (*release) (struct device *);
L
Linus Torvalds 已提交
134 135
};

136 137
#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)

M
Mimi Zohar 已提交
138 139 140 141 142
static inline void tpm_chip_put(struct tpm_chip *chip)
{
	module_put(chip->dev->driver->owner);
}

143
static inline int tpm_read_index(int base, int index)
L
Linus Torvalds 已提交
144
{
145 146
	outb(index, base);
	return inb(base+1) & 0xFF;
L
Linus Torvalds 已提交
147 148
}

149
static inline void tpm_write_index(int base, int index, int value)
L
Linus Torvalds 已提交
150
{
151 152
	outb(index, base);
	outb(value & 0xFF, base+1);
L
Linus Torvalds 已提交
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 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
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 已提交
254
	__be32	paramsize;
255 256 257 258 259 260 261 262 263 264 265
	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 已提交
266 267 268 269 270 271 272 273 274 275 276 277 278 279
#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));

280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
 * bytes, but 128 is still a relatively large number of random bytes and
 * anything much bigger causes users of struct tpm_cmd_t to start getting
 * compiler warnings about stack frame size. */
#define TPM_MAX_RNG_DATA	128

struct tpm_getrandom_out {
	__be32 rng_data_len;
	u8     rng_data[TPM_MAX_RNG_DATA];
}__attribute__((packed));

struct tpm_getrandom_in {
	__be32 num_bytes;
}__attribute__((packed));

295 296 297 298
struct tpm_startup_in {
	__be16	startup_type;
} __packed;

299 300 301 302 303
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 已提交
304 305 306
	struct	tpm_pcrread_in	pcrread_in;
	struct	tpm_pcrread_out	pcrread_out;
	struct	tpm_pcrextend_in pcrextend_in;
307 308
	struct	tpm_getrandom_in getrandom_in;
	struct	tpm_getrandom_out getrandom_out;
309
	struct tpm_startup_in startup_in;
310 311 312 313 314 315 316 317
} 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 已提交
318

319
extern int tpm_get_timeouts(struct tpm_chip *);
320
extern void tpm_gen_interrupt(struct tpm_chip *);
321
extern int tpm_do_selftest(struct tpm_chip *);
322
extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
323 324
extern struct tpm_chip* tpm_register_hardware(struct device *,
				 const struct tpm_vendor_specific *);
L
Linus Torvalds 已提交
325 326
extern int tpm_open(struct inode *, struct file *);
extern int tpm_release(struct inode *, struct file *);
327
extern void tpm_dev_vendor_release(struct tpm_chip *);
L
Linus Torvalds 已提交
328 329 330
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 *);
331
extern void tpm_remove_hardware(struct device *);
332
extern int tpm_pm_suspend(struct device *);
333
extern int tpm_pm_resume(struct device *);
334 335
extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long,
			     wait_queue_head_t *);
336 337

#ifdef CONFIG_ACPI
338 339
extern int tpm_add_ppi(struct kobject *);
extern void tpm_remove_ppi(struct kobject *);
340
#else
341
static inline int tpm_add_ppi(struct kobject *parent)
342 343 344
{
	return 0;
}
345 346 347 348

static inline void tpm_remove_ppi(struct kobject *parent)
{
}
349
#endif