tpm.h 8.4 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 50
#define TPM_ERR_DEACTIVATED     0x6
#define TPM_ERR_DISABLED        0x7

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

struct tpm_chip;

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

84
	int irq;
85
	int probed_irq;
86

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

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

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

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

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

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

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

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

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

129 130
	struct dentry **bios_dir;

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

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

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

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

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

279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
/* 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));

294 295 296 297 298
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 已提交
299 300 301
	struct	tpm_pcrread_in	pcrread_in;
	struct	tpm_pcrread_out	pcrread_out;
	struct	tpm_pcrextend_in pcrextend_in;
302 303
	struct	tpm_getrandom_in getrandom_in;
	struct	tpm_getrandom_out getrandom_out;
304 305 306 307 308 309 310 311
} 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 已提交
312

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

#ifdef CONFIG_ACPI
332 333
extern int tpm_add_ppi(struct kobject *);
extern void tpm_remove_ppi(struct kobject *);
334
#else
335
static inline int tpm_add_ppi(struct kobject *parent)
336 337 338
{
	return 0;
}
339 340 341 342

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