blob: 283f78211c3a7bc09092085d12834c48571f93f3 [file] [log] [blame]
Thomas Gleixnerb886d83c2019-06-01 10:08:55 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * Copyright (C) 2004 IBM Corporation
Jarkko Sakkinena74f8b32015-10-11 12:26:58 +03004 * Copyright (C) 2015 Intel Corporation
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 *
6 * Authors:
7 * Leendert van Doorn <leendert@watson.ibm.com>
8 * Dave Safford <safford@watson.ibm.com>
9 * Reiner Sailer <sailer@watson.ibm.com>
10 * Kylene Hall <kjhall@us.ibm.com>
11 *
Kent Yoder8e81cc12007-08-22 14:01:04 -070012 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 *
14 * Device driver for TCG/TCPA TPM (trusted platform module).
Bruno E O Meneguele3b098252015-01-17 17:03:30 +010015 * Specifications at www.trustedcomputinggroup.org
Linus Torvalds1da177e2005-04-16 15:20:36 -070016 */
Christophe Ricardd2efee62016-05-04 21:06:22 +020017
18#ifndef __TPM_H__
19#define __TPM_H__
20
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070022#include <linux/delay.h>
Matthias Kaehlcked081d472007-05-08 00:32:02 -070023#include <linux/mutex.h>
Al Viro914e2632006-10-18 13:55:46 -040024#include <linux/sched.h>
Al Virobbc5b212005-11-01 15:14:05 +000025#include <linux/platform_device.h>
Andrew Morton276ad0c2006-03-25 03:07:35 -080026#include <linux/io.h>
Rajiv Andrade659aaf22009-02-02 15:23:44 -020027#include <linux/tpm.h>
Thiebaud Weksteenfd3ec362017-09-20 10:13:36 +020028#include <linux/tpm_eventlog.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
Azhar Shaikh5e572ca2017-06-18 19:17:59 -070030#ifdef CONFIG_X86
31#include <asm/intel-family.h>
32#endif
33
Roberto Sassu901615c2019-02-06 17:24:50 +010034#define TPM_MINOR 224 /* officially assigned */
35#define TPM_BUFSIZE 4096
36#define TPM_NUM_DEVICES 65536
37#define TPM_RETRY 50
Kent Yoder41ab9992012-06-07 13:47:14 -050038
Kylene Hall3122a882005-06-23 22:01:48 -070039enum tpm_timeout {
40 TPM_TIMEOUT = 5, /* msecs */
Hamza Attak9f3fc7b2017-08-14 19:09:16 +010041 TPM_TIMEOUT_RETRY = 100, /* msecs */
Nayna Jain59f5a6b2018-05-07 12:07:32 -040042 TPM_TIMEOUT_RANGE_US = 300, /* usecs */
Nayna Jain424eaf92018-05-16 01:51:25 -040043 TPM_TIMEOUT_POLL = 1, /* msecs */
44 TPM_TIMEOUT_USECS_MIN = 100, /* usecs */
45 TPM_TIMEOUT_USECS_MAX = 500 /* usecs */
Kylene Hall3122a882005-06-23 22:01:48 -070046};
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
48/* TPM addresses */
Kylene Hall3122a882005-06-23 22:01:48 -070049enum tpm_addr {
Kylene Jo Halldaacdfa2005-06-25 14:55:39 -070050 TPM_SUPERIO_ADDR = 0x2E,
Kylene Hall3122a882005-06-23 22:01:48 -070051 TPM_ADDR = 0x4E,
Kylene Hall3122a882005-06-23 22:01:48 -070052};
53
Duncan Laurie32d33b22013-03-17 14:56:39 -070054#define TPM_WARN_RETRY 0x800
Stefan Berger68d6e672011-11-11 12:57:04 -050055#define TPM_WARN_DOING_SELFTEST 0x802
Stefan Bergerbe405412012-01-17 22:07:30 -050056#define TPM_ERR_DEACTIVATED 0x6
57#define TPM_ERR_DISABLED 0x7
Jason Gunthorpec584af12012-11-21 13:54:33 -070058#define TPM_ERR_INVALID_POSTINIT 38
Stefan Bergerbe405412012-01-17 22:07:30 -050059
Roberto Sassu06e93272017-05-03 18:19:09 +020060#define TPM_TAG_RQU_COMMAND 193
Jason Gunthorpe000a07b2013-11-26 13:30:41 -070061
Jarkko Sakkinen6c4e79d2020-07-03 01:55:59 +030062/* TPM2 specific constants. */
63#define TPM2_SPACE_BUFFER_SIZE 16384 /* 16 kB */
64
Rajiv Andrade08837432009-02-02 15:23:43 -020065struct stclear_flags_t {
66 __be16 tag;
67 u8 deactivated;
68 u8 disableForceClear;
69 u8 physicalPresence;
70 u8 physicalPresenceLock;
71 u8 bGlobalLock;
Jason Gunthorpe348df8d2012-11-21 13:56:45 -070072} __packed;
Rajiv Andrade08837432009-02-02 15:23:43 -020073
Jarkko Sakkinenf2f58202019-09-02 07:27:33 -070074struct tpm1_version {
75 u8 major;
76 u8 minor;
77 u8 rev_major;
78 u8 rev_minor;
Jason Gunthorpe348df8d2012-11-21 13:56:45 -070079} __packed;
Rajiv Andrade08837432009-02-02 15:23:43 -020080
Jarkko Sakkinenf2f58202019-09-02 07:27:33 -070081struct tpm1_version2 {
82 __be16 tag;
83 struct tpm1_version version;
Jason Gunthorpe348df8d2012-11-21 13:56:45 -070084} __packed;
Rajiv Andrade08837432009-02-02 15:23:43 -020085
86struct timeout_t {
87 __be32 a;
88 __be32 b;
89 __be32 c;
90 __be32 d;
Jason Gunthorpe348df8d2012-11-21 13:56:45 -070091} __packed;
Rajiv Andrade08837432009-02-02 15:23:43 -020092
93struct duration_t {
94 __be32 tpm_short;
95 __be32 tpm_medium;
96 __be32 tpm_long;
Jason Gunthorpe348df8d2012-11-21 13:56:45 -070097} __packed;
Rajiv Andrade08837432009-02-02 15:23:43 -020098
99struct permanent_flags_t {
100 __be16 tag;
101 u8 disable;
102 u8 ownership;
103 u8 deactivated;
104 u8 readPubek;
105 u8 disableOwnerClear;
106 u8 allowMaintenance;
107 u8 physicalPresenceLifetimeLock;
108 u8 physicalPresenceHWEnable;
109 u8 physicalPresenceCMDEnable;
110 u8 CEKPUsed;
111 u8 TPMpost;
112 u8 TPMpostLock;
113 u8 FIPS;
114 u8 operator;
115 u8 enableRevokeEK;
116 u8 nvLocked;
117 u8 readSRKPub;
118 u8 tpmEstablished;
119 u8 maintenanceDone;
120 u8 disableFullDALogicInfo;
Jason Gunthorpe348df8d2012-11-21 13:56:45 -0700121} __packed;
Rajiv Andrade08837432009-02-02 15:23:43 -0200122
123typedef union {
124 struct permanent_flags_t perm_flags;
125 struct stclear_flags_t stclear_flags;
Stefan Bergera118cf22017-01-31 13:43:59 -0500126 __u8 owned;
Rajiv Andrade08837432009-02-02 15:23:43 -0200127 __be32 num_pcrs;
Jarkko Sakkinenf2f58202019-09-02 07:27:33 -0700128 struct tpm1_version version1;
129 struct tpm1_version2 version2;
Rajiv Andrade08837432009-02-02 15:23:43 -0200130 __be32 manufacturer_id;
131 struct timeout_t timeout;
132 struct duration_t duration;
133} cap_t;
134
Jason Gunthorpe000a07b2013-11-26 13:30:41 -0700135enum tpm_capabilities {
Jarkko Sakkinen84fda152016-09-19 23:22:09 +0300136 TPM_CAP_FLAG = 4,
137 TPM_CAP_PROP = 5,
138 TPM_CAP_VERSION_1_1 = 0x06,
139 TPM_CAP_VERSION_1_2 = 0x1A,
Jason Gunthorpe000a07b2013-11-26 13:30:41 -0700140};
141
142enum tpm_sub_capabilities {
Jarkko Sakkinen84fda152016-09-19 23:22:09 +0300143 TPM_CAP_PROP_PCR = 0x101,
144 TPM_CAP_PROP_MANUFACTURER = 0x103,
145 TPM_CAP_FLAG_PERM = 0x108,
146 TPM_CAP_FLAG_VOL = 0x109,
147 TPM_CAP_PROP_OWNER = 0x111,
148 TPM_CAP_PROP_TIS_TIMEOUT = 0x115,
149 TPM_CAP_PROP_TIS_DURATION = 0x120,
Jason Gunthorpe000a07b2013-11-26 13:30:41 -0700150};
151
Rajiv Andrade659aaf22009-02-02 15:23:44 -0200152
Kent Yoder41ab9992012-06-07 13:47:14 -0500153/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
154 * bytes, but 128 is still a relatively large number of random bytes and
155 * anything much bigger causes users of struct tpm_cmd_t to start getting
156 * compiler warnings about stack frame size. */
157#define TPM_MAX_RNG_DATA 128
158
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800159extern struct class *tpm_class;
James Bottomleyfdc915f2017-01-03 09:07:32 -0800160extern struct class *tpmrm_class;
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800161extern dev_t tpm_devt;
162extern const struct file_operations tpm_fops;
James Bottomleyfdc915f2017-01-03 09:07:32 -0800163extern const struct file_operations tpmrm_fops;
Stefan Berger15516782016-02-29 08:53:02 -0500164extern struct idr dev_nums_idr;
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800165
Jarkko Sakkinen47a6c282018-11-05 03:02:38 +0200166ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz);
Jarkko Sakkinend4abd952016-06-25 23:33:09 +0300167int tpm_get_timeouts(struct tpm_chip *);
Tomas Winklerb03c4372018-10-19 21:22:59 +0300168int tpm_auto_startup(struct tpm_chip *chip);
Tomas Winklerc82a3302018-10-19 21:22:57 +0300169
Tomas Winkler95adc6b2018-10-19 21:23:07 +0300170int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr);
Jason Gunthorpecae8b442016-07-12 11:41:49 -0600171int tpm1_auto_startup(struct tpm_chip *chip);
Tomas Winklerd4a317562018-10-19 21:22:56 +0300172int tpm1_do_selftest(struct tpm_chip *chip);
Tomas Winkler70a31992018-10-19 21:22:52 +0300173int tpm1_get_timeouts(struct tpm_chip *chip);
Tomas Winklerb2d6e6de2018-10-19 21:22:50 +0300174unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
Tomas Winkler95adc6b2018-10-19 21:23:07 +0300175int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash,
Tomas Winkler1ad66402018-10-19 21:22:53 +0300176 const char *log_msg);
Tomas Winkler95adc6b2018-10-19 21:23:07 +0300177int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf);
Tomas Winklerf4d916b2018-10-19 21:22:54 +0300178ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
179 const char *desc, size_t min_cap_length);
Tomas Winkler433d3902018-10-19 21:22:55 +0300180int tpm1_get_random(struct tpm_chip *chip, u8 *out, size_t max);
Nayna Jainfa4f99c2019-07-11 12:13:35 -0400181int tpm1_get_pcr_allocation(struct tpm_chip *chip);
Tomas Winklerd856c002018-10-19 21:22:51 +0300182unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
Jarkko Sakkinend4abd952016-06-25 23:33:09 +0300183int tpm_pm_suspend(struct device *dev);
184int tpm_pm_resume(struct device *dev);
Xiaoyan Zhangf84fdff2012-08-22 18:47:22 +0800185
Hamza Attak9f3fc7b2017-08-14 19:09:16 +0100186static inline void tpm_msleep(unsigned int delay_msec)
187{
Nayna Jain5ef924d2017-10-17 16:32:32 -0400188 usleep_range((delay_msec * 1000) - TPM_TIMEOUT_RANGE_US,
189 delay_msec * 1000);
Hamza Attak9f3fc7b2017-08-14 19:09:16 +0100190};
191
Jarkko Sakkinen47a6c282018-11-05 03:02:38 +0200192int tpm_chip_start(struct tpm_chip *chip);
193void tpm_chip_stop(struct tpm_chip *chip);
Stefan Bergerfc1d52b2018-06-26 07:06:15 -0400194struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip);
Jason Gunthorpe4e261952016-02-12 20:29:53 -0700195
Jarkko Sakkinend4abd952016-06-25 23:33:09 +0300196struct tpm_chip *tpm_chip_alloc(struct device *dev,
197 const struct tpm_class_ops *ops);
198struct tpm_chip *tpmm_chip_alloc(struct device *pdev,
199 const struct tpm_class_ops *ops);
200int tpm_chip_register(struct tpm_chip *chip);
201void tpm_chip_unregister(struct tpm_chip *chip);
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800202
Jason Gunthorpe062807f2016-04-18 13:26:13 -0400203void tpm_sysfs_add_device(struct tpm_chip *chip);
Jason Gunthorpeafdba322013-11-26 13:30:40 -0700204
Jason Gunthorpe000a07b2013-11-26 13:30:41 -0700205
Xiaoyan Zhangf84fdff2012-08-22 18:47:22 +0800206#ifdef CONFIG_ACPI
Jarkko Sakkinen9b774d52015-04-14 17:56:48 +0300207extern void tpm_add_ppi(struct tpm_chip *chip);
Xiaoyan Zhangf84fdff2012-08-22 18:47:22 +0800208#else
Jarkko Sakkinen9b774d52015-04-14 17:56:48 +0300209static inline void tpm_add_ppi(struct tpm_chip *chip)
Gang Wei1631cfb2012-10-09 17:35:22 +0800210{
211}
Xiaoyan Zhangf84fdff2012-08-22 18:47:22 +0800212#endif
Jarkko Sakkinen7a1d7e62014-12-12 11:46:38 -0800213
Tomas Winkler70a31992018-10-19 21:22:52 +0300214int tpm2_get_timeouts(struct tpm_chip *chip);
Roberto Sassu879b5892019-02-06 17:24:49 +0100215int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
216 struct tpm_digest *digest, u16 *digest_size_ptr);
Roberto Sassu0b6cf6b2019-02-06 17:24:52 +0100217int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
Roberto Sassuaa042472019-02-06 17:24:48 +0100218 struct tpm_digest *digests);
Jarkko Sakkinence63c052018-03-26 15:14:06 +0300219int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max);
Jarkko Sakkinen7a1d7e62014-12-12 11:46:38 -0800220ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,
221 u32 *value, const char *desc);
222
Nayna Jainfa4f99c2019-07-11 12:13:35 -0400223ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip);
Jason Gunthorpecae8b442016-07-12 11:41:49 -0600224int tpm2_auto_startup(struct tpm_chip *chip);
Jarkko Sakkinend4abd952016-06-25 23:33:09 +0300225void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
226unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
Jarkko Sakkinend4abd952016-06-25 23:33:09 +0300227int tpm2_probe(struct tpm_chip *chip);
Stefan Berger18b36702020-03-12 11:53:32 -0400228int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip);
Jarkko Sakkinen58472f52016-11-10 20:42:07 -0800229int tpm2_find_cc(struct tpm_chip *chip, u32 cc);
Jarkko Sakkinen6c4e79d2020-07-03 01:55:59 +0300230int tpm2_init_space(struct tpm_space *space, unsigned int buf_size);
James Bottomley4d578562017-01-31 15:47:31 -0800231void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space);
Jarkko Sakkinen304ff672018-11-04 16:15:49 +0200232void tpm2_flush_space(struct tpm_chip *chip);
Jarkko Sakkinenc3465a32018-11-03 03:04:56 +0200233int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd,
234 size_t cmdsiz);
235int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space, void *buf,
236 size_t *bufsiz);
Thiebaud Weksteenfd3ec362017-09-20 10:13:36 +0200237
Matthew Garrett805fa882020-01-02 13:55:18 -0800238void tpm_bios_log_setup(struct tpm_chip *chip);
Thiebaud Weksteenfd3ec362017-09-20 10:13:36 +0200239void tpm_bios_log_teardown(struct tpm_chip *chip);
Tadeusz Struk9e1b74a2018-09-10 10:18:33 -0700240int tpm_dev_common_init(void);
241void tpm_dev_common_exit(void);
Christophe Ricardd2efee62016-05-04 21:06:22 +0200242#endif