15e124724SVadim Bendebury /* 28732b070SChe-liang Chiou * Copyright (c) 2013 The Chromium OS Authors. 3be6c1529SReinhard Pfau * Coypright (c) 2013 Guntermann & Drunck GmbH 45e124724SVadim Bendebury * 51a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 65e124724SVadim Bendebury */ 75e124724SVadim Bendebury 88732b070SChe-liang Chiou #ifndef __TPM_H 98732b070SChe-liang Chiou #define __TPM_H 105e124724SVadim Bendebury 118732b070SChe-liang Chiou #include <tis.h> 125e124724SVadim Bendebury 135e124724SVadim Bendebury /* 148732b070SChe-liang Chiou * Here is a partial implementation of TPM commands. Please consult TCG Main 158732b070SChe-liang Chiou * Specification for definitions of TPM commands. 165e124724SVadim Bendebury */ 175e124724SVadim Bendebury 18f255d31fSSimon Glass #define TPM_HEADER_SIZE 10 19f255d31fSSimon Glass 20f255d31fSSimon Glass enum tpm_duration { 21f255d31fSSimon Glass TPM_SHORT = 0, 22f255d31fSSimon Glass TPM_MEDIUM = 1, 23f255d31fSSimon Glass TPM_LONG = 2, 24f255d31fSSimon Glass TPM_UNDEFINED, 25f255d31fSSimon Glass 26f255d31fSSimon Glass TPM_DURATION_COUNT, 27f255d31fSSimon Glass }; 28f255d31fSSimon Glass 298732b070SChe-liang Chiou enum tpm_startup_type { 308732b070SChe-liang Chiou TPM_ST_CLEAR = 0x0001, 318732b070SChe-liang Chiou TPM_ST_STATE = 0x0002, 328732b070SChe-liang Chiou TPM_ST_DEACTIVATED = 0x0003, 338732b070SChe-liang Chiou }; 348732b070SChe-liang Chiou 358732b070SChe-liang Chiou enum tpm_physical_presence { 368732b070SChe-liang Chiou TPM_PHYSICAL_PRESENCE_HW_DISABLE = 0x0200, 378732b070SChe-liang Chiou TPM_PHYSICAL_PRESENCE_CMD_DISABLE = 0x0100, 388732b070SChe-liang Chiou TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK = 0x0080, 398732b070SChe-liang Chiou TPM_PHYSICAL_PRESENCE_HW_ENABLE = 0x0040, 408732b070SChe-liang Chiou TPM_PHYSICAL_PRESENCE_CMD_ENABLE = 0x0020, 418732b070SChe-liang Chiou TPM_PHYSICAL_PRESENCE_NOTPRESENT = 0x0010, 428732b070SChe-liang Chiou TPM_PHYSICAL_PRESENCE_PRESENT = 0x0008, 438732b070SChe-liang Chiou TPM_PHYSICAL_PRESENCE_LOCK = 0x0004, 448732b070SChe-liang Chiou }; 458732b070SChe-liang Chiou 468732b070SChe-liang Chiou enum tpm_nv_index { 478732b070SChe-liang Chiou TPM_NV_INDEX_LOCK = 0xffffffff, 488732b070SChe-liang Chiou TPM_NV_INDEX_0 = 0x00000000, 498732b070SChe-liang Chiou TPM_NV_INDEX_DIR = 0x10000001, 508732b070SChe-liang Chiou }; 518732b070SChe-liang Chiou 528732b070SChe-liang Chiou /** 53be6c1529SReinhard Pfau * TPM return codes as defined in the TCG Main specification 54be6c1529SReinhard Pfau * (TPM Main Part 2 Structures; Specification version 1.2) 55be6c1529SReinhard Pfau */ 56be6c1529SReinhard Pfau enum tpm_return_code { 57be6c1529SReinhard Pfau TPM_BASE = 0x00000000, 58be6c1529SReinhard Pfau TPM_NON_FATAL = 0x00000800, 59be6c1529SReinhard Pfau TPM_SUCCESS = TPM_BASE, 60be6c1529SReinhard Pfau /* TPM-defined fatal error codes */ 61be6c1529SReinhard Pfau TPM_AUTHFAIL = TPM_BASE + 1, 62be6c1529SReinhard Pfau TPM_BADINDEX = TPM_BASE + 2, 63be6c1529SReinhard Pfau TPM_BAD_PARAMETER = TPM_BASE + 3, 64be6c1529SReinhard Pfau TPM_AUDITFAILURE = TPM_BASE + 4, 65be6c1529SReinhard Pfau TPM_CLEAR_DISABLED = TPM_BASE + 5, 66be6c1529SReinhard Pfau TPM_DEACTIVATED = TPM_BASE + 6, 67be6c1529SReinhard Pfau TPM_DISABLED = TPM_BASE + 7, 68be6c1529SReinhard Pfau TPM_DISABLED_CMD = TPM_BASE + 8, 69be6c1529SReinhard Pfau TPM_FAIL = TPM_BASE + 9, 70be6c1529SReinhard Pfau TPM_BAD_ORDINAL = TPM_BASE + 10, 71be6c1529SReinhard Pfau TPM_INSTALL_DISABLED = TPM_BASE + 11, 72be6c1529SReinhard Pfau TPM_INVALID_KEYHANDLE = TPM_BASE + 12, 73be6c1529SReinhard Pfau TPM_KEYNOTFOUND = TPM_BASE + 13, 74be6c1529SReinhard Pfau TPM_INAPPROPRIATE_ENC = TPM_BASE + 14, 75be6c1529SReinhard Pfau TPM_MIGRATE_FAIL = TPM_BASE + 15, 76be6c1529SReinhard Pfau TPM_INVALID_PCR_INFO = TPM_BASE + 16, 77be6c1529SReinhard Pfau TPM_NOSPACE = TPM_BASE + 17, 78be6c1529SReinhard Pfau TPM_NOSRK = TPM_BASE + 18, 79be6c1529SReinhard Pfau TPM_NOTSEALED_BLOB = TPM_BASE + 19, 80be6c1529SReinhard Pfau TPM_OWNER_SET = TPM_BASE + 20, 81be6c1529SReinhard Pfau TPM_RESOURCES = TPM_BASE + 21, 82be6c1529SReinhard Pfau TPM_SHORTRANDOM = TPM_BASE + 22, 83be6c1529SReinhard Pfau TPM_SIZE = TPM_BASE + 23, 84be6c1529SReinhard Pfau TPM_WRONGPCRVAL = TPM_BASE + 24, 85be6c1529SReinhard Pfau TPM_BAD_PARAM_SIZE = TPM_BASE + 25, 86be6c1529SReinhard Pfau TPM_SHA_THREAD = TPM_BASE + 26, 87be6c1529SReinhard Pfau TPM_SHA_ERROR = TPM_BASE + 27, 88be6c1529SReinhard Pfau TPM_FAILEDSELFTEST = TPM_BASE + 28, 89be6c1529SReinhard Pfau TPM_AUTH2FAIL = TPM_BASE + 29, 90be6c1529SReinhard Pfau TPM_BADTAG = TPM_BASE + 30, 91be6c1529SReinhard Pfau TPM_IOERROR = TPM_BASE + 31, 92be6c1529SReinhard Pfau TPM_ENCRYPT_ERROR = TPM_BASE + 32, 93be6c1529SReinhard Pfau TPM_DECRYPT_ERROR = TPM_BASE + 33, 94be6c1529SReinhard Pfau TPM_INVALID_AUTHHANDLE = TPM_BASE + 34, 95be6c1529SReinhard Pfau TPM_NO_ENDORSEMENT = TPM_BASE + 35, 96be6c1529SReinhard Pfau TPM_INVALID_KEYUSAGE = TPM_BASE + 36, 97be6c1529SReinhard Pfau TPM_WRONG_ENTITYTYPE = TPM_BASE + 37, 98be6c1529SReinhard Pfau TPM_INVALID_POSTINIT = TPM_BASE + 38, 99be6c1529SReinhard Pfau TPM_INAPPROPRIATE_SIG = TPM_BASE + 39, 100be6c1529SReinhard Pfau TPM_BAD_KEY_PROPERTY = TPM_BASE + 40, 101be6c1529SReinhard Pfau TPM_BAD_MIGRATION = TPM_BASE + 41, 102be6c1529SReinhard Pfau TPM_BAD_SCHEME = TPM_BASE + 42, 103be6c1529SReinhard Pfau TPM_BAD_DATASIZE = TPM_BASE + 43, 104be6c1529SReinhard Pfau TPM_BAD_MODE = TPM_BASE + 44, 105be6c1529SReinhard Pfau TPM_BAD_PRESENCE = TPM_BASE + 45, 106be6c1529SReinhard Pfau TPM_BAD_VERSION = TPM_BASE + 46, 107be6c1529SReinhard Pfau TPM_NO_WRAP_TRANSPORT = TPM_BASE + 47, 108be6c1529SReinhard Pfau TPM_AUDITFAIL_UNSUCCESSFUL = TPM_BASE + 48, 109be6c1529SReinhard Pfau TPM_AUDITFAIL_SUCCESSFUL = TPM_BASE + 49, 110be6c1529SReinhard Pfau TPM_NOTRESETABLE = TPM_BASE + 50, 111be6c1529SReinhard Pfau TPM_NOTLOCAL = TPM_BASE + 51, 112be6c1529SReinhard Pfau TPM_BAD_TYPE = TPM_BASE + 52, 113be6c1529SReinhard Pfau TPM_INVALID_RESOURCE = TPM_BASE + 53, 114be6c1529SReinhard Pfau TPM_NOTFIPS = TPM_BASE + 54, 115be6c1529SReinhard Pfau TPM_INVALID_FAMILY = TPM_BASE + 55, 116be6c1529SReinhard Pfau TPM_NO_NV_PERMISSION = TPM_BASE + 56, 117be6c1529SReinhard Pfau TPM_REQUIRES_SIGN = TPM_BASE + 57, 118be6c1529SReinhard Pfau TPM_KEY_NOTSUPPORTED = TPM_BASE + 58, 119be6c1529SReinhard Pfau TPM_AUTH_CONFLICT = TPM_BASE + 59, 120be6c1529SReinhard Pfau TPM_AREA_LOCKED = TPM_BASE + 60, 121be6c1529SReinhard Pfau TPM_BAD_LOCALITY = TPM_BASE + 61, 122be6c1529SReinhard Pfau TPM_READ_ONLY = TPM_BASE + 62, 123be6c1529SReinhard Pfau TPM_PER_NOWRITE = TPM_BASE + 63, 124be6c1529SReinhard Pfau TPM_FAMILY_COUNT = TPM_BASE + 64, 125be6c1529SReinhard Pfau TPM_WRITE_LOCKED = TPM_BASE + 65, 126be6c1529SReinhard Pfau TPM_BAD_ATTRIBUTES = TPM_BASE + 66, 127be6c1529SReinhard Pfau TPM_INVALID_STRUCTURE = TPM_BASE + 67, 128be6c1529SReinhard Pfau TPM_KEY_OWNER_CONTROL = TPM_BASE + 68, 129be6c1529SReinhard Pfau TPM_BAD_COUNTER = TPM_BASE + 69, 130be6c1529SReinhard Pfau TPM_NOT_FULLWRITE = TPM_BASE + 70, 131be6c1529SReinhard Pfau TPM_CONTEXT_GAP = TPM_BASE + 71, 132be6c1529SReinhard Pfau TPM_MAXNVWRITES = TPM_BASE + 72, 133be6c1529SReinhard Pfau TPM_NOOPERATOR = TPM_BASE + 73, 134be6c1529SReinhard Pfau TPM_RESOURCEMISSING = TPM_BASE + 74, 135be6c1529SReinhard Pfau TPM_DELEGATE_LOCK = TPM_BASE + 75, 136be6c1529SReinhard Pfau TPM_DELEGATE_FAMILY = TPM_BASE + 76, 137be6c1529SReinhard Pfau TPM_DELEGATE_ADMIN = TPM_BASE + 77, 138be6c1529SReinhard Pfau TPM_TRANSPORT_NOTEXCLUSIVE = TPM_BASE + 78, 139be6c1529SReinhard Pfau TPM_OWNER_CONTROL = TPM_BASE + 79, 140be6c1529SReinhard Pfau TPM_DAA_RESOURCES = TPM_BASE + 80, 141be6c1529SReinhard Pfau TPM_DAA_INPUT_DATA0 = TPM_BASE + 81, 142be6c1529SReinhard Pfau TPM_DAA_INPUT_DATA1 = TPM_BASE + 82, 143be6c1529SReinhard Pfau TPM_DAA_ISSUER_SETTINGS = TPM_BASE + 83, 144be6c1529SReinhard Pfau TPM_DAA_TPM_SETTINGS = TPM_BASE + 84, 145be6c1529SReinhard Pfau TPM_DAA_STAGE = TPM_BASE + 85, 146be6c1529SReinhard Pfau TPM_DAA_ISSUER_VALIDITY = TPM_BASE + 86, 147be6c1529SReinhard Pfau TPM_DAA_WRONG_W = TPM_BASE + 87, 148be6c1529SReinhard Pfau TPM_BAD_HANDLE = TPM_BASE + 88, 149be6c1529SReinhard Pfau TPM_BAD_DELEGATE = TPM_BASE + 89, 150be6c1529SReinhard Pfau TPM_BADCONTEXT = TPM_BASE + 90, 151be6c1529SReinhard Pfau TPM_TOOMANYCONTEXTS = TPM_BASE + 91, 152be6c1529SReinhard Pfau TPM_MA_TICKET_SIGNATURE = TPM_BASE + 92, 153be6c1529SReinhard Pfau TPM_MA_DESTINATION = TPM_BASE + 93, 154be6c1529SReinhard Pfau TPM_MA_SOURCE = TPM_BASE + 94, 155be6c1529SReinhard Pfau TPM_MA_AUTHORITY = TPM_BASE + 95, 156be6c1529SReinhard Pfau TPM_PERMANENTEK = TPM_BASE + 97, 157be6c1529SReinhard Pfau TPM_BAD_SIGNATURE = TPM_BASE + 98, 158be6c1529SReinhard Pfau TPM_NOCONTEXTSPACE = TPM_BASE + 99, 159be6c1529SReinhard Pfau /* TPM-defined non-fatal errors */ 160be6c1529SReinhard Pfau TPM_RETRY = TPM_BASE + TPM_NON_FATAL, 161be6c1529SReinhard Pfau TPM_NEEDS_SELFTEST = TPM_BASE + TPM_NON_FATAL + 1, 162be6c1529SReinhard Pfau TPM_DOING_SELFTEST = TPM_BASE + TPM_NON_FATAL + 2, 163be6c1529SReinhard Pfau TPM_DEFEND_LOCK_RUNNING = TPM_BASE + TPM_NON_FATAL + 3, 164be6c1529SReinhard Pfau }; 165be6c1529SReinhard Pfau 166f255d31fSSimon Glass #ifdef CONFIG_DM_TPM 167f255d31fSSimon Glass 168f255d31fSSimon Glass /* Max buffer size supported by our tpm */ 169f255d31fSSimon Glass #define TPM_DEV_BUFSIZE 1260 170f255d31fSSimon Glass 171f255d31fSSimon Glass /** 172f255d31fSSimon Glass * struct tpm_chip_priv - Information about a TPM, stored by the uclass 173f255d31fSSimon Glass * 174f255d31fSSimon Glass * These values must be set up by the device's probe() method before 175f255d31fSSimon Glass * communcation is attempted. If the device has an xfer() method, this is 176f255d31fSSimon Glass * not needed. There is no need to set up @buf. 177f255d31fSSimon Glass * 178f255d31fSSimon Glass * @duration_ms: Length of each duration type in milliseconds 179f255d31fSSimon Glass * @retry_time_ms: Time to wait before retrying receive 180f255d31fSSimon Glass */ 181f255d31fSSimon Glass struct tpm_chip_priv { 182f255d31fSSimon Glass uint duration_ms[TPM_DURATION_COUNT]; 183f255d31fSSimon Glass uint retry_time_ms; 184f255d31fSSimon Glass u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)]; /* Max buffer size + addr */ 185f255d31fSSimon Glass }; 186f255d31fSSimon Glass 187f255d31fSSimon Glass /** 188f255d31fSSimon Glass * struct tpm_ops - low-level TPM operations 189f255d31fSSimon Glass * 190f255d31fSSimon Glass * These are designed to avoid loops and delays in the driver itself. These 191f255d31fSSimon Glass * should be handled in the uclass. 192f255d31fSSimon Glass * 193f255d31fSSimon Glass * In gneral you should implement everything except xfer(). Where you need 194f255d31fSSimon Glass * complete control of the transfer, then xfer() can be provided and will 195f255d31fSSimon Glass * override the other methods. 196f255d31fSSimon Glass * 197f255d31fSSimon Glass * This interface is for low-level TPM access. It does not understand the 198f255d31fSSimon Glass * concept of localities or the various TPM messages. That interface is 199f255d31fSSimon Glass * defined in the functions later on in this file, but they all translate 200f255d31fSSimon Glass * to bytes which are sent and received. 201f255d31fSSimon Glass */ 202f255d31fSSimon Glass struct tpm_ops { 203f255d31fSSimon Glass /** 204f255d31fSSimon Glass * open() - Request access to locality 0 for the caller 205f255d31fSSimon Glass * 206f255d31fSSimon Glass * After all commands have been completed the caller should call 207f255d31fSSimon Glass * close(). 208f255d31fSSimon Glass * 209f255d31fSSimon Glass * @dev: Device to close 210f255d31fSSimon Glass * @return 0 ok OK, -ve on error 211f255d31fSSimon Glass */ 212f255d31fSSimon Glass int (*open)(struct udevice *dev); 213f255d31fSSimon Glass 214f255d31fSSimon Glass /** 215f255d31fSSimon Glass * close() - Close the current session 216f255d31fSSimon Glass * 217f255d31fSSimon Glass * Releasing the locked locality. Returns 0 on success, -ve 1 on 218f255d31fSSimon Glass * failure (in case lock removal did not succeed). 219f255d31fSSimon Glass * 220f255d31fSSimon Glass * @dev: Device to close 221f255d31fSSimon Glass * @return 0 ok OK, -ve on error 222f255d31fSSimon Glass */ 223f255d31fSSimon Glass int (*close)(struct udevice *dev); 224f255d31fSSimon Glass 225f255d31fSSimon Glass /** 226f255d31fSSimon Glass * get_desc() - Get a text description of the TPM 227f255d31fSSimon Glass * 228f255d31fSSimon Glass * @dev: Device to check 229f255d31fSSimon Glass * @buf: Buffer to put the string 230f255d31fSSimon Glass * @size: Maximum size of buffer 231f255d31fSSimon Glass * @return length of string, or -ENOSPC it no space 232f255d31fSSimon Glass */ 233f255d31fSSimon Glass int (*get_desc)(struct udevice *dev, char *buf, int size); 234f255d31fSSimon Glass 235f255d31fSSimon Glass /** 236f255d31fSSimon Glass * send() - send data to the TPM 237f255d31fSSimon Glass * 238f255d31fSSimon Glass * @dev: Device to talk to 239f255d31fSSimon Glass * @sendbuf: Buffer of the data to send 240f255d31fSSimon Glass * @send_size: Size of the data to send 241f255d31fSSimon Glass * 242f255d31fSSimon Glass * Returns 0 on success or -ve on failure. 243f255d31fSSimon Glass */ 244f255d31fSSimon Glass int (*send)(struct udevice *dev, const uint8_t *sendbuf, 245f255d31fSSimon Glass size_t send_size); 246f255d31fSSimon Glass 247f255d31fSSimon Glass /** 248f255d31fSSimon Glass * recv() - receive a response from the TPM 249f255d31fSSimon Glass * 250f255d31fSSimon Glass * @dev: Device to talk to 251f255d31fSSimon Glass * @recvbuf: Buffer to save the response to 252f255d31fSSimon Glass * @max_size: Maximum number of bytes to receive 253f255d31fSSimon Glass * 254f255d31fSSimon Glass * Returns number of bytes received on success, -EAGAIN if the TPM 255f255d31fSSimon Glass * response is not ready, -EINTR if cancelled, or other -ve value on 256f255d31fSSimon Glass * failure. 257f255d31fSSimon Glass */ 258f255d31fSSimon Glass int (*recv)(struct udevice *dev, uint8_t *recvbuf, size_t max_size); 259f255d31fSSimon Glass 260f255d31fSSimon Glass /** 261f255d31fSSimon Glass * cleanup() - clean up after an operation in progress 262f255d31fSSimon Glass * 263f255d31fSSimon Glass * This is called if receiving times out. The TPM may need to abort 264f255d31fSSimon Glass * the current transaction if it did not complete, and make itself 265f255d31fSSimon Glass * ready for another. 266f255d31fSSimon Glass * 267f255d31fSSimon Glass * @dev: Device to talk to 268f255d31fSSimon Glass */ 269f255d31fSSimon Glass int (*cleanup)(struct udevice *dev); 270f255d31fSSimon Glass 271f255d31fSSimon Glass /** 272f255d31fSSimon Glass * xfer() - send data to the TPM and get response 273f255d31fSSimon Glass * 274f255d31fSSimon Glass * This method is optional. If it exists it is used in preference 275f255d31fSSimon Glass * to send(), recv() and cleanup(). It should handle all aspects of 276f255d31fSSimon Glass * TPM communication for a single transfer. 277f255d31fSSimon Glass * 278f255d31fSSimon Glass * @dev: Device to talk to 279f255d31fSSimon Glass * @sendbuf: Buffer of the data to send 280f255d31fSSimon Glass * @send_size: Size of the data to send 281f255d31fSSimon Glass * @recvbuf: Buffer to save the response to 282f255d31fSSimon Glass * @recv_size: Pointer to the size of the response buffer 283f255d31fSSimon Glass * 284f255d31fSSimon Glass * Returns 0 on success (and places the number of response bytes at 285f255d31fSSimon Glass * recv_size) or -ve on failure. 286f255d31fSSimon Glass */ 287f255d31fSSimon Glass int (*xfer)(struct udevice *dev, const uint8_t *sendbuf, 288f255d31fSSimon Glass size_t send_size, uint8_t *recvbuf, size_t *recv_size); 289f255d31fSSimon Glass }; 290f255d31fSSimon Glass 291f255d31fSSimon Glass #define tpm_get_ops(dev) ((struct tpm_ops *)device_get_ops(dev)) 292f255d31fSSimon Glass 293f255d31fSSimon Glass /** 294f255d31fSSimon Glass * tpm_open() - Request access to locality 0 for the caller 295f255d31fSSimon Glass * 296f255d31fSSimon Glass * After all commands have been completed the caller is supposed to 297f255d31fSSimon Glass * call tpm_close(). 298f255d31fSSimon Glass * 299f255d31fSSimon Glass * Returns 0 on success, -ve on failure. 300f255d31fSSimon Glass */ 301f255d31fSSimon Glass int tpm_open(struct udevice *dev); 302f255d31fSSimon Glass 303f255d31fSSimon Glass /** 304f255d31fSSimon Glass * tpm_close() - Close the current session 305f255d31fSSimon Glass * 306f255d31fSSimon Glass * Releasing the locked locality. Returns 0 on success, -ve 1 on 307f255d31fSSimon Glass * failure (in case lock removal did not succeed). 308f255d31fSSimon Glass */ 309f255d31fSSimon Glass int tpm_close(struct udevice *dev); 310f255d31fSSimon Glass 311f255d31fSSimon Glass /** 312f255d31fSSimon Glass * tpm_get_desc() - Get a text description of the TPM 313f255d31fSSimon Glass * 314f255d31fSSimon Glass * @dev: Device to check 315f255d31fSSimon Glass * @buf: Buffer to put the string 316f255d31fSSimon Glass * @size: Maximum size of buffer 317f255d31fSSimon Glass * @return length of string, or -ENOSPC it no space 318f255d31fSSimon Glass */ 319f255d31fSSimon Glass int tpm_get_desc(struct udevice *dev, char *buf, int size); 320f255d31fSSimon Glass 321f255d31fSSimon Glass /** 322f255d31fSSimon Glass * tpm_xfer() - send data to the TPM and get response 323f255d31fSSimon Glass * 324f255d31fSSimon Glass * This first uses the device's send() method to send the bytes. Then it calls 325f255d31fSSimon Glass * recv() to get the reply. If recv() returns -EAGAIN then it will delay a 326f255d31fSSimon Glass * short time and then call recv() again. 327f255d31fSSimon Glass * 328f255d31fSSimon Glass * Regardless of whether recv() completes successfully, it will then call 329f255d31fSSimon Glass * cleanup() to finish the transaction. 330f255d31fSSimon Glass * 331f255d31fSSimon Glass * Note that the outgoing data is inspected to determine command type 332f255d31fSSimon Glass * (ordinal) and a timeout is used for that command type. 333f255d31fSSimon Glass * 334f255d31fSSimon Glass * @sendbuf - buffer of the data to send 335f255d31fSSimon Glass * @send_size size of the data to send 336f255d31fSSimon Glass * @recvbuf - memory to save the response to 337f255d31fSSimon Glass * @recv_len - pointer to the size of the response buffer 338f255d31fSSimon Glass * 339f255d31fSSimon Glass * Returns 0 on success (and places the number of response bytes at 340f255d31fSSimon Glass * recv_len) or -ve on failure. 341f255d31fSSimon Glass */ 342f255d31fSSimon Glass int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size, 343f255d31fSSimon Glass uint8_t *recvbuf, size_t *recv_size); 344f255d31fSSimon Glass 345f255d31fSSimon Glass #endif /* CONFIG_DM_TPM */ 346f255d31fSSimon Glass 347be6c1529SReinhard Pfau /** 3488732b070SChe-liang Chiou * Initialize TPM device. It must be called before any TPM commands. 3495e124724SVadim Bendebury * 3508732b070SChe-liang Chiou * @return 0 on success, non-0 on error. 3515e124724SVadim Bendebury */ 352*c8a8c510SSimon Glass int tpm_init(void); 3535e124724SVadim Bendebury 3548732b070SChe-liang Chiou /** 3558732b070SChe-liang Chiou * Issue a TPM_Startup command. 3565e124724SVadim Bendebury * 3578732b070SChe-liang Chiou * @param mode TPM startup mode 3588732b070SChe-liang Chiou * @return return code of the operation 3595e124724SVadim Bendebury */ 3608732b070SChe-liang Chiou uint32_t tpm_startup(enum tpm_startup_type mode); 3615e124724SVadim Bendebury 3628732b070SChe-liang Chiou /** 3638732b070SChe-liang Chiou * Issue a TPM_SelfTestFull command. 3645e124724SVadim Bendebury * 3658732b070SChe-liang Chiou * @return return code of the operation 3665e124724SVadim Bendebury */ 3678732b070SChe-liang Chiou uint32_t tpm_self_test_full(void); 3685e124724SVadim Bendebury 3698732b070SChe-liang Chiou /** 3708732b070SChe-liang Chiou * Issue a TPM_ContinueSelfTest command. 3718732b070SChe-liang Chiou * 3728732b070SChe-liang Chiou * @return return code of the operation 3738732b070SChe-liang Chiou */ 3748732b070SChe-liang Chiou uint32_t tpm_continue_self_test(void); 3758732b070SChe-liang Chiou 3768732b070SChe-liang Chiou /** 3778732b070SChe-liang Chiou * Issue a TPM_NV_DefineSpace command. The implementation is limited 3788732b070SChe-liang Chiou * to specify TPM_NV_ATTRIBUTES and size of the area. The area index 3798732b070SChe-liang Chiou * could be one of the special value listed in enum tpm_nv_index. 3808732b070SChe-liang Chiou * 3818732b070SChe-liang Chiou * @param index index of the area 3828732b070SChe-liang Chiou * @param perm TPM_NV_ATTRIBUTES of the area 3838732b070SChe-liang Chiou * @param size size of the area 3848732b070SChe-liang Chiou * @return return code of the operation 3858732b070SChe-liang Chiou */ 3868732b070SChe-liang Chiou uint32_t tpm_nv_define_space(uint32_t index, uint32_t perm, uint32_t size); 3878732b070SChe-liang Chiou 3888732b070SChe-liang Chiou /** 3898732b070SChe-liang Chiou * Issue a TPM_NV_ReadValue command. This implementation is limited 3908732b070SChe-liang Chiou * to read the area from offset 0. The area index could be one of 3918732b070SChe-liang Chiou * the special value listed in enum tpm_nv_index. 3928732b070SChe-liang Chiou * 3938732b070SChe-liang Chiou * @param index index of the area 3948732b070SChe-liang Chiou * @param data output buffer of the area contents 3958732b070SChe-liang Chiou * @param count size of output buffer 3968732b070SChe-liang Chiou * @return return code of the operation 3978732b070SChe-liang Chiou */ 3988732b070SChe-liang Chiou uint32_t tpm_nv_read_value(uint32_t index, void *data, uint32_t count); 3998732b070SChe-liang Chiou 4008732b070SChe-liang Chiou /** 4018732b070SChe-liang Chiou * Issue a TPM_NV_WriteValue command. This implementation is limited 4028732b070SChe-liang Chiou * to write the area from offset 0. The area index could be one of 4038732b070SChe-liang Chiou * the special value listed in enum tpm_nv_index. 4048732b070SChe-liang Chiou * 4058732b070SChe-liang Chiou * @param index index of the area 4068732b070SChe-liang Chiou * @param data input buffer to be wrote to the area 4078732b070SChe-liang Chiou * @param length length of data bytes of input buffer 4088732b070SChe-liang Chiou * @return return code of the operation 4098732b070SChe-liang Chiou */ 4108732b070SChe-liang Chiou uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length); 4118732b070SChe-liang Chiou 4128732b070SChe-liang Chiou /** 4138732b070SChe-liang Chiou * Issue a TPM_Extend command. 4148732b070SChe-liang Chiou * 4158732b070SChe-liang Chiou * @param index index of the PCR 4168732b070SChe-liang Chiou * @param in_digest 160-bit value representing the event to be 4178732b070SChe-liang Chiou * recorded 4188732b070SChe-liang Chiou * @param out_digest 160-bit PCR value after execution of the 4198732b070SChe-liang Chiou * command 4208732b070SChe-liang Chiou * @return return code of the operation 4218732b070SChe-liang Chiou */ 4228732b070SChe-liang Chiou uint32_t tpm_extend(uint32_t index, const void *in_digest, void *out_digest); 4238732b070SChe-liang Chiou 4248732b070SChe-liang Chiou /** 4258732b070SChe-liang Chiou * Issue a TPM_PCRRead command. 4268732b070SChe-liang Chiou * 4278732b070SChe-liang Chiou * @param index index of the PCR 4288732b070SChe-liang Chiou * @param data output buffer for contents of the named PCR 4298732b070SChe-liang Chiou * @param count size of output buffer 4308732b070SChe-liang Chiou * @return return code of the operation 4318732b070SChe-liang Chiou */ 4328732b070SChe-liang Chiou uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count); 4338732b070SChe-liang Chiou 4348732b070SChe-liang Chiou /** 4358732b070SChe-liang Chiou * Issue a TSC_PhysicalPresence command. TPM physical presence flag 4368732b070SChe-liang Chiou * is bit-wise OR'ed of flags listed in enum tpm_physical_presence. 4378732b070SChe-liang Chiou * 4388732b070SChe-liang Chiou * @param presence TPM physical presence flag 4398732b070SChe-liang Chiou * @return return code of the operation 4408732b070SChe-liang Chiou */ 4418732b070SChe-liang Chiou uint32_t tpm_tsc_physical_presence(uint16_t presence); 4428732b070SChe-liang Chiou 4438732b070SChe-liang Chiou /** 4448732b070SChe-liang Chiou * Issue a TPM_ReadPubek command. 4458732b070SChe-liang Chiou * 4468732b070SChe-liang Chiou * @param data output buffer for the public endorsement key 4478732b070SChe-liang Chiou * @param count size of ouput buffer 4488732b070SChe-liang Chiou * @return return code of the operation 4498732b070SChe-liang Chiou */ 4508732b070SChe-liang Chiou uint32_t tpm_read_pubek(void *data, size_t count); 4518732b070SChe-liang Chiou 4528732b070SChe-liang Chiou /** 4538732b070SChe-liang Chiou * Issue a TPM_ForceClear command. 4548732b070SChe-liang Chiou * 4558732b070SChe-liang Chiou * @return return code of the operation 4568732b070SChe-liang Chiou */ 4578732b070SChe-liang Chiou uint32_t tpm_force_clear(void); 4588732b070SChe-liang Chiou 4598732b070SChe-liang Chiou /** 4608732b070SChe-liang Chiou * Issue a TPM_PhysicalEnable command. 4618732b070SChe-liang Chiou * 4628732b070SChe-liang Chiou * @return return code of the operation 4638732b070SChe-liang Chiou */ 4648732b070SChe-liang Chiou uint32_t tpm_physical_enable(void); 4658732b070SChe-liang Chiou 4668732b070SChe-liang Chiou /** 4678732b070SChe-liang Chiou * Issue a TPM_PhysicalDisable command. 4688732b070SChe-liang Chiou * 4698732b070SChe-liang Chiou * @return return code of the operation 4708732b070SChe-liang Chiou */ 4718732b070SChe-liang Chiou uint32_t tpm_physical_disable(void); 4728732b070SChe-liang Chiou 4738732b070SChe-liang Chiou /** 4748732b070SChe-liang Chiou * Issue a TPM_PhysicalSetDeactivated command. 4758732b070SChe-liang Chiou * 4768732b070SChe-liang Chiou * @param state boolean state of the deactivated flag 4778732b070SChe-liang Chiou * @return return code of the operation 4788732b070SChe-liang Chiou */ 4798732b070SChe-liang Chiou uint32_t tpm_physical_set_deactivated(uint8_t state); 4808732b070SChe-liang Chiou 4818732b070SChe-liang Chiou /** 4828732b070SChe-liang Chiou * Issue a TPM_GetCapability command. This implementation is limited 4838732b070SChe-liang Chiou * to query sub_cap index that is 4-byte wide. 4848732b070SChe-liang Chiou * 4858732b070SChe-liang Chiou * @param cap_area partition of capabilities 4868732b070SChe-liang Chiou * @param sub_cap further definition of capability, which is 4878732b070SChe-liang Chiou * limited to be 4-byte wide 4888732b070SChe-liang Chiou * @param cap output buffer for capability information 4898732b070SChe-liang Chiou * @param count size of ouput buffer 4908732b070SChe-liang Chiou * @return return code of the operation 4918732b070SChe-liang Chiou */ 4928732b070SChe-liang Chiou uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap, 4938732b070SChe-liang Chiou void *cap, size_t count); 4948732b070SChe-liang Chiou 495be6c1529SReinhard Pfau /** 496be6c1529SReinhard Pfau * Issue a TPM_FlushSpecific command for a AUTH ressource. 497be6c1529SReinhard Pfau * 498be6c1529SReinhard Pfau * @param auth_handle handle of the auth session 499be6c1529SReinhard Pfau * @return return code of the operation 500be6c1529SReinhard Pfau */ 501be6c1529SReinhard Pfau uint32_t tpm_terminate_auth_session(uint32_t auth_handle); 502be6c1529SReinhard Pfau 503be6c1529SReinhard Pfau /** 504be6c1529SReinhard Pfau * Issue a TPM_OIAP command to setup an object independant authorization 505be6c1529SReinhard Pfau * session. 506be6c1529SReinhard Pfau * Information about the session is stored internally. 507be6c1529SReinhard Pfau * If there was already an OIAP session active it is terminated and a new 508be6c1529SReinhard Pfau * session is set up. 509be6c1529SReinhard Pfau * 510be6c1529SReinhard Pfau * @param auth_handle pointer to the (new) auth handle or NULL. 511be6c1529SReinhard Pfau * @return return code of the operation 512be6c1529SReinhard Pfau */ 513be6c1529SReinhard Pfau uint32_t tpm_oiap(uint32_t *auth_handle); 514be6c1529SReinhard Pfau 515be6c1529SReinhard Pfau /** 516be6c1529SReinhard Pfau * Ends an active OIAP session. 517be6c1529SReinhard Pfau * 518be6c1529SReinhard Pfau * @return return code of the operation 519be6c1529SReinhard Pfau */ 520be6c1529SReinhard Pfau uint32_t tpm_end_oiap(void); 521be6c1529SReinhard Pfau 522be6c1529SReinhard Pfau /** 523be6c1529SReinhard Pfau * Issue a TPM_LoadKey2 (Auth1) command using an OIAP session for authenticating 524be6c1529SReinhard Pfau * the usage of the parent key. 525be6c1529SReinhard Pfau * 526be6c1529SReinhard Pfau * @param parent_handle handle of the parent key. 527be6c1529SReinhard Pfau * @param key pointer to the key structure (TPM_KEY or TPM_KEY12). 528be6c1529SReinhard Pfau * @param key_length size of the key structure 529be6c1529SReinhard Pfau * @param parent_key_usage_auth usage auth for the parent key 530be6c1529SReinhard Pfau * @param key_handle pointer to the key handle 531be6c1529SReinhard Pfau * @return return code of the operation 532be6c1529SReinhard Pfau */ 533be6c1529SReinhard Pfau uint32_t tpm_load_key2_oiap(uint32_t parent_handle, 534be6c1529SReinhard Pfau const void *key, size_t key_length, 535be6c1529SReinhard Pfau const void *parent_key_usage_auth, 536be6c1529SReinhard Pfau uint32_t *key_handle); 537be6c1529SReinhard Pfau 538be6c1529SReinhard Pfau /** 539be6c1529SReinhard Pfau * Issue a TPM_GetPubKey (Auth1) command using an OIAP session for 540be6c1529SReinhard Pfau * authenticating the usage of the key. 541be6c1529SReinhard Pfau * 542be6c1529SReinhard Pfau * @param key_handle handle of the key 543be6c1529SReinhard Pfau * @param usage_auth usage auth for the key 544be6c1529SReinhard Pfau * @param pubkey pointer to the pub key buffer; may be NULL if the pubkey 545be6c1529SReinhard Pfau * should not be stored. 546be6c1529SReinhard Pfau * @param pubkey_len pointer to the pub key buffer len. On entry: the size of 547be6c1529SReinhard Pfau * the provided pubkey buffer. On successful exit: the size 548be6c1529SReinhard Pfau * of the stored TPM_PUBKEY structure (iff pubkey != NULL). 549be6c1529SReinhard Pfau * @return return code of the operation 550be6c1529SReinhard Pfau */ 551be6c1529SReinhard Pfau uint32_t tpm_get_pub_key_oiap(uint32_t key_handle, const void *usage_auth, 552be6c1529SReinhard Pfau void *pubkey, size_t *pubkey_len); 553be6c1529SReinhard Pfau 5548732b070SChe-liang Chiou #endif /* __TPM_H */ 555