uboot/include/tpm-common.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * Copyright (c) 2013 The Chromium OS Authors.
   4 * Coypright (c) 2013 Guntermann & Drunck GmbH
   5 */
   6
   7#ifndef __TPM_COMMON_H
   8#define __TPM_COMMON_H
   9
  10#include <command.h>
  11
  12struct udevice;
  13
  14enum tpm_duration {
  15        TPM_SHORT = 0,
  16        TPM_MEDIUM = 1,
  17        TPM_LONG = 2,
  18        TPM_UNDEFINED,
  19
  20        TPM_DURATION_COUNT,
  21};
  22
  23/*
  24 * Here is a partial implementation of TPM commands.  Please consult TCG Main
  25 * Specification for definitions of TPM commands.
  26 */
  27
  28#define TPM_HEADER_SIZE         10
  29
  30/* Max buffer size supported by our tpm */
  31#define TPM_DEV_BUFSIZE         1260
  32
  33#define TPM_PCR_MINIMUM_DIGEST_SIZE 20
  34
  35/**
  36 * enum tpm_version - The version of the TPM stack to be used
  37 * @TPM_V1:             Use TPM v1.x stack
  38 * @TPM_V2:             Use TPM v2.x stack
  39 */
  40enum tpm_version {
  41        TPM_V1 = 0,
  42        TPM_V2,
  43};
  44
  45/**
  46 * struct tpm_chip_priv - Information about a TPM, stored by the uclass
  47 *
  48 * These values must be set up by the device's probe() method before
  49 * communcation is attempted. If the device has an xfer() method, this is
  50 * not needed. There is no need to set up @buf.
  51 *
  52 * @version:            TPM stack to be used
  53 * @duration_ms:        Length of each duration type in milliseconds
  54 * @retry_time_ms:      Time to wait before retrying receive
  55 * @buf:                Buffer used during the exchanges with the chip
  56 * @pcr_count:          Number of PCR per bank
  57 * @pcr_select_min:     Minimum size in bytes of the pcrSelect array
  58 */
  59struct tpm_chip_priv {
  60        enum tpm_version version;
  61
  62        uint duration_ms[TPM_DURATION_COUNT];
  63        uint retry_time_ms;
  64        u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
  65
  66        /* TPM v2 specific data */
  67        uint pcr_count;
  68        uint pcr_select_min;
  69};
  70
  71/**
  72 * struct tpm_ops - low-level TPM operations
  73 *
  74 * These are designed to avoid loops and delays in the driver itself. These
  75 * should be handled in the uclass.
  76 *
  77 * In gneral you should implement everything except xfer(). Where you need
  78 * complete control of the transfer, then xfer() can be provided and will
  79 * override the other methods.
  80 *
  81 * This interface is for low-level TPM access. It does not understand the
  82 * concept of localities or the various TPM messages. That interface is
  83 * defined in the functions later on in this file, but they all translate
  84 * to bytes which are sent and received.
  85 */
  86struct tpm_ops {
  87        /**
  88         * open() - Request access to locality 0 for the caller
  89         *
  90         * After all commands have been completed the caller should call
  91         * close().
  92         *
  93         * @dev:        Device to open
  94         * @return 0 ok OK, -ve on error
  95         */
  96        int (*open)(struct udevice *dev);
  97
  98        /**
  99         * close() - Close the current session
 100         *
 101         * Releasing the locked locality. Returns 0 on success, -ve 1 on
 102         * failure (in case lock removal did not succeed).
 103         *
 104         * @dev:        Device to close
 105         * @return 0 ok OK, -ve on error
 106         */
 107        int (*close)(struct udevice *dev);
 108
 109        /**
 110         * get_desc() - Get a text description of the TPM
 111         *
 112         * @dev:        Device to check
 113         * @buf:        Buffer to put the string
 114         * @size:       Maximum size of buffer
 115         * @return length of string, or -ENOSPC it no space
 116         */
 117        int (*get_desc)(struct udevice *dev, char *buf, int size);
 118
 119        /**
 120         * send() - send data to the TPM
 121         *
 122         * @dev:        Device to talk to
 123         * @sendbuf:    Buffer of the data to send
 124         * @send_size:  Size of the data to send
 125         *
 126         * Returns 0 on success or -ve on failure.
 127         */
 128        int (*send)(struct udevice *dev, const u8 *sendbuf, size_t send_size);
 129
 130        /**
 131         * recv() - receive a response from the TPM
 132         *
 133         * @dev:        Device to talk to
 134         * @recvbuf:    Buffer to save the response to
 135         * @max_size:   Maximum number of bytes to receive
 136         *
 137         * Returns number of bytes received on success, -EAGAIN if the TPM
 138         * response is not ready, -EINTR if cancelled, or other -ve value on
 139         * failure.
 140         */
 141        int (*recv)(struct udevice *dev, u8 *recvbuf, size_t max_size);
 142
 143        /**
 144         * cleanup() - clean up after an operation in progress
 145         *
 146         * This is called if receiving times out. The TPM may need to abort
 147         * the current transaction if it did not complete, and make itself
 148         * ready for another.
 149         *
 150         * @dev:        Device to talk to
 151         */
 152        int (*cleanup)(struct udevice *dev);
 153
 154        /**
 155         * xfer() - send data to the TPM and get response
 156         *
 157         * This method is optional. If it exists it is used in preference
 158         * to send(), recv() and cleanup(). It should handle all aspects of
 159         * TPM communication for a single transfer.
 160         *
 161         * @dev:        Device to talk to
 162         * @sendbuf:    Buffer of the data to send
 163         * @send_size:  Size of the data to send
 164         * @recvbuf:    Buffer to save the response to
 165         * @recv_size:  Pointer to the size of the response buffer
 166         *
 167         * Returns 0 on success (and places the number of response bytes at
 168         * recv_size) or -ve on failure.
 169         */
 170        int (*xfer)(struct udevice *dev, const u8 *sendbuf, size_t send_size,
 171                    u8 *recvbuf, size_t *recv_size);
 172};
 173
 174#define tpm_get_ops(dev)        ((struct tpm_ops *)device_get_ops(dev))
 175
 176#define MAKE_TPM_CMD_ENTRY(cmd) \
 177        U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
 178
 179#define TPM_COMMAND_NO_ARG(cmd)                         \
 180int do_##cmd(struct cmd_tbl *cmdtp, int flag,           \
 181             int argc, char *const argv[])              \
 182{                                                       \
 183        struct udevice *dev;                            \
 184        int rc;                                         \
 185                                                        \
 186        rc = get_tpm(&dev);                             \
 187        if (rc)                                         \
 188                return rc;                              \
 189        if (argc != 1)                                  \
 190                return CMD_RET_USAGE;                   \
 191        return report_return_code(cmd(dev));            \
 192}
 193
 194/**
 195 * tpm_open() - Request access to locality 0 for the caller
 196 *
 197 * After all commands have been completed the caller is supposed to
 198 * call tpm_close().
 199 *
 200 * @dev - TPM device
 201 * Returns 0 on success, -ve on failure.
 202 */
 203int tpm_open(struct udevice *dev);
 204
 205/**
 206 * tpm_close() - Close the current session
 207 *
 208 * Releasing the locked locality. Returns 0 on success, -ve 1 on
 209 * failure (in case lock removal did not succeed).
 210 *
 211 * @dev - TPM device
 212 * Returns 0 on success, -ve on failure.
 213 */
 214int tpm_close(struct udevice *dev);
 215
 216/**
 217 * tpm_clear_and_reenable() - Force clear the TPM and reenable it
 218 *
 219 * @dev: TPM device
 220 * @return 0 on success, -ve on failure
 221 */
 222u32 tpm_clear_and_reenable(struct udevice *dev);
 223
 224/**
 225 * tpm_get_desc() - Get a text description of the TPM
 226 *
 227 * @dev:        Device to check
 228 * @buf:        Buffer to put the string
 229 * @size:       Maximum size of buffer
 230 * @return length of string, or -ENOSPC it no space
 231 */
 232int tpm_get_desc(struct udevice *dev, char *buf, int size);
 233
 234/**
 235 * tpm_xfer() - send data to the TPM and get response
 236 *
 237 * This first uses the device's send() method to send the bytes. Then it calls
 238 * recv() to get the reply. If recv() returns -EAGAIN then it will delay a
 239 * short time and then call recv() again.
 240 *
 241 * Regardless of whether recv() completes successfully, it will then call
 242 * cleanup() to finish the transaction.
 243 *
 244 * Note that the outgoing data is inspected to determine command type
 245 * (ordinal) and a timeout is used for that command type.
 246 *
 247 * @dev - TPM device
 248 * @sendbuf - buffer of the data to send
 249 * @send_size size of the data to send
 250 * @recvbuf - memory to save the response to
 251 * @recv_len - pointer to the size of the response buffer
 252 *
 253 * Returns 0 on success (and places the number of response bytes at
 254 * recv_len) or -ve on failure.
 255 */
 256int tpm_xfer(struct udevice *dev, const u8 *sendbuf, size_t send_size,
 257             u8 *recvbuf, size_t *recv_size);
 258
 259/**
 260 * Initialize TPM device.  It must be called before any TPM commands.
 261 *
 262 * @dev - TPM device
 263 * @return 0 on success, non-0 on error.
 264 */
 265int tpm_init(struct udevice *dev);
 266
 267/**
 268 * Retrieve the array containing all the v1 (resp. v2) commands.
 269 *
 270 * @return a struct cmd_tbl array.
 271 */
 272#if defined(CONFIG_TPM_V1)
 273struct cmd_tbl *get_tpm1_commands(unsigned int *size);
 274#else
 275static inline struct cmd_tbl *get_tpm1_commands(unsigned int *size)
 276{
 277        return NULL;
 278}
 279#endif
 280#if defined(CONFIG_TPM_V2)
 281struct cmd_tbl *get_tpm2_commands(unsigned int *size);
 282#else
 283static inline struct cmd_tbl *get_tpm2_commands(unsigned int *size)
 284{
 285        return NULL;
 286}
 287#endif
 288
 289/**
 290 * tpm_get_version() - Find the version of a TPM
 291 *
 292 * This checks the uclass data for a TPM device and returns the version number
 293 * it supports.
 294 *
 295 * @dev: TPM device
 296 * @return version number (TPM_V1 or TPMV2)
 297 */
 298enum tpm_version tpm_get_version(struct udevice *dev);
 299
 300/* Iterate on all TPM devices */
 301#define for_each_tpm_device(dev) uclass_foreach_dev_probe(UCLASS_TPM, (dev))
 302
 303#endif /* __TPM_COMMON_H */
 304