Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ dist_example_DATA+= examples/README.md \
examples/tpm_io_linux.c \
examples/tpm_io_st.c \
examples/tpm_io_qnx.c \
examples/tpm_io_uboot.c \
examples/tpm_io_xilinx.c \
examples/tpm_io.h \
examples/tpm_test_keys.c \
Expand Down
4 changes: 4 additions & 0 deletions examples/tpm_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
#include "examples/tpm_io_barebox.c"
#elif defined(__QNX__) || defined(__QNXNTO__)
#include "examples/tpm_io_qnx.c"
#elif defined(__UBOOT__)
#include "examples/tpm_io_uboot.c"
#elif defined(__XILINX__)
#include "examples/tpm_io_xilinx.c"
#endif
Expand All @@ -76,6 +78,8 @@ static int TPM2_IoCb_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
ret = TPM2_IoCb_Barebox_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
#elif defined(__QNX__) || defined(__QNXNTO__)
ret = TPM2_IoCb_QNX_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
#elif defined(__UBOOT__)
ret = TPM2_IoCb_Uboot_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
#elif defined(__XILINX__)
ret = TPM2_IoCb_Xilinx_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
#else
Expand Down
4 changes: 4 additions & 0 deletions examples/tpm_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
* * Xilinx Zynq
* * Barebox
* * QNX
* * Uboot
*
* Using custom IO Callback is always possible.
*
Expand Down Expand Up @@ -91,6 +92,9 @@ int TPM2_IoCb_STCubeMX_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
#elif defined(__QNX__) || defined(__QNXTO__)
int TPM2_IoCb_QNX_SPI(TPM2_CTX* ctx, const byte* txBuf,
byte* rxBuf, word16 xferSz, void* userCtx);
#elif defined(__UBOOT__)
int TPM2_IoCb_Uboot_SPI(TPM2_CTX* ctx, const byte* txBuf,
byte* rxBuf, word16 xferSz, void* userCtx);
#elif defined(__XILINX__)
int TPM2_IoCb_Xilinx_SPI(TPM2_CTX* ctx, const byte* txBuf,
byte* rxBuf, word16 xferSz, void* userCtx);
Expand Down
127 changes: 127 additions & 0 deletions examples/tpm_io_uboot.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/* tpm_io_uboot.c
*
* Copyright (C) 2006-2021 wolfSSL Inc.
*
* This file is part of wolfTPM.
*
* wolfTPM 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; either version 2 of the License, or
* (at your option) any later version.
*
* wolfTPM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/

/* This example shows IO interfaces for Uboot */


#include <wolftpm/tpm2.h>
#include <wolftpm/tpm2_tis.h>
#include "tpm_io.h"

/******************************************************************************/
/* --- BEGIN IO Callback Logic -- */
/******************************************************************************/

/* Included via tpm_io.c if WOLFTPM_INCLUDE_IO_FILE is defined */
#ifdef WOLFTPM_INCLUDE_IO_FILE

#if ! (defined(WOLFTPM_LINUX_DEV) || \
defined(WOLFTPM_SWTPM) || \
defined(WOLFTPM_WINAPI) )

/* Use the max speed by default - see tpm2_types.h for chip specific max values */
#ifndef TPM2_SPI_HZ
#define TPM2_SPI_HZ TPM2_SPI_MAX_HZ
#endif

#ifndef CONFIG_DEFAULT_SPI_BUS
#define CONFIG_DEFAULT_SPI_BUS 1
#define CONFIG_DEFAULT_SPI_CS 0
#define CONFIG_DEFAULT_SPI_FREQ 1000000
#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_3
#define CONFIG_DEFAULT_SPI_NAME "generic_1:0\0"
#endif

#if defined(__UBOOT__)
#include <common.h>
#include <dm.h>
#include <spi.h>

int TPM2_IoCb_Uboot_SPI(TPM2_CTX* ctx, const byte* txBuf,
byte* rxBuf, word16 xferSz, void* userCtx)
{
int ret = TPM_RC_FAILURE;
struct udevice *udev = NULL; /* u-boot device */
struct spi_slave *slave = NULL;

#ifdef WOLFTPM_CHECK_WAIT_STATE
#error SPI check wait state logic not supported for U-boot
#endif

if (userCtx == NULL) {
#ifdef DEBUG_WOLFTPM
printf("userCtx is NULL, can not acccess udev\n");
#endif
return TPM_RC_FAILURE;
}

#if CONFIG_IS_ENABLED(DM_SPI)
/* If Driver-model is enabled, we can acquire SPI udevice using bus number */
ret = spi_get_bus_and_cs(CONFIG_DEFAULT_SPI_BUS, CONFIG_DEFAULT_SPI_CS,
CONFIG_DEFAULT_SPI_FREQ, CONFIG_DEFAULT_SPI_MODE,
"spi_generic_drv", CONFIG_DEFAULT_SPI_NAME,
&dev, &slave);
if (ret) {
return ret;
}

#else
/* Acquire the SPI bus from manually passed udevice through wolfTPM2_Init */
udev = (struct udevice*)userCtx;
slave = dev_get_parent_priv(dev);
#endif

ret = spi_claim_bus(slave);
if (ret < 0) {
#ifdef DEBUG_WOLFTPM
printf("Failed to acquire access to u-boot spi bus\n");
return ret;
#endif
}

ret = spi_xfer(slave, xferSz * 8, tx_buf, rx_buf,
SPI_XFER_BEGIN | /* Assert CS before transfer */
SPI_XFER_END); /* Deassert CS after transfer */
#ifdef DEBUG_WOLFTPM
if (ret < 0) {
printf("Failed to transmit data over the SPI bus\n");
}
#endif

/* Regardless of the SPI operation outcome, release the SPI bus */
spi_release_bus(slave);

if (ret == 0) {
ret = TPM_RC_SUCCESS;
}

(void)ctx;

return ret;
}

#endif
#endif /* !(WOLFTPM_LINUX_DEV || WOLFTPM_SWTPM || WOLFTPM_WINAPI) */
#endif /* WOLFTPM_INCLUDE_IO_FILE */

/******************************************************************************/
/* --- END IO Callback Logic -- */
/******************************************************************************/
92 changes: 92 additions & 0 deletions examples/u-boot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Experimental support for Das U-boot

wolfTPM could be used with all platforms that have hardware SPI support or can use the U-boot software bit-bang implementation(SPI_SOFT).

The example wolfTPM IO Callback was tested on RPI3 model B with ST33 TPM 2.0 module, using `make rpi_3_32b_defconfig` and changes to the DeviceTree as described below in `U-boot preparations`.

https://source.denx.de/u-boot/u-boot

## Current state of TPM support in U-boot

The internal U-boot support for TPM is limited to only several commands:

* TPM2_PCR_Read
* TPM2_PCR_Extend
* TPM2_GetCapability

and few others for maintenance purposes, like TPM2_Clear.

## Using wolfTPM with U-boot

Thanks to wolfTPM, U-boot can perform all TPM 2.0 operations, including TPM2_Seal/Unseal, TPM2_Quote, TPM2_EncryptDecrypt2 and TPM2_NV_Write/TPM2_NV_Read.

### U-boot preparation

wolfTPM has a internal TPM Interface Command(TIS) layer and allows wolfTPM to be used as TPM 2.0 driver for baremetal and embedded systems.

Our example IO callback in examples/tpm_io_uboot.c uses the existing SPI driver in U-boot. It is up to the developer to choose between hardware SPI driver or U-boot's software SPI driver. Best compatibility is offered through the software SPI driver that uses bit-bang GPIO to implement SPI interface. For example, U-boot does not offer hardware SPI for Raspberry Pi boards and other Broadcom SoC systems.

To enable U-boot's software SPI driver make sure to enable SPI_SOFT in your U-boot's configuration manually or using `make menuconfig` under Device Drivers, SPI Support.

Once enabled, it is also needed to add Device Tree entry for SPI Slave device

```

tpm2-spi {

compatible = "spi-gpio"; /* Selection the SPI_SOFT driver */
cs-gpios = <&gpio 24 0>; /* Pinout from ST33 RPI Eval Board */
gpio-sck = <&gpio 23 0>;
gpio-miso = <&gpio 21 0>;
gpio-mosi = <&gpio 19 0>;
spi-delay-us = <10>;
cs@0 {
};
};

```

Note:

U-boot should use the new Driver Model or when initializing wolfTPM in U-boot it is required to pass handle to the SPI device registered as the user context. Example below:

```

struct udevice *uDev = &spiDev; /* replace with correct udevice instance */
WOLFTPM2_DEV tpmDev;
wolfTPM2_Init(&tpmDev, TPM2_IoCb_SPI, uDev);

```

In case U-boot's driver model is used, then the Io Callback will try to automatically acquire the spi device at the default SPI bus.

### wolfTPM compilation

To build static version of wolfTPM for U-boot, use the configure script or use the example options.h file in examples/u-boot.

To use configure:

./configure --disable-shared --enable-autodetect --disable-wolfcrypt

This way u-boot can be later linked together with wolfTPM.

## Benefits of using wolfTPM with U-boot

### Native API

wolfTPM provides native API with full access to all TPM 2.0 commands. For example:

* TPM2_Seal/TPM2_Unseal
* TPM2_DefineSpace/TPM2_UndefineSpace
* TPM2_CreatePrimary/TPM2_Create
* TPM2_EncryptDecrypt2

Internal U-boot TPM support for these commands is missing. By adding wolfTPM the system can perform symmetric and asymmetric key generation, PCR operations, TPM 2.0 Quote, TPM 2.0 Certify Creation, Key import, extra GPIO for safety-critical systems, Signature verification, Hash generation and all other TPM 2.0 capabilities.

### Wrappers

wolfTPM's rich API provides wrappers for performing complete TPM 2.0 operations. There are wolfTPM wrappers for the most common and complex TPM 2.0 operations. The wrappers also protect from wrong TPM 2.0 settings and execute all necessary TPM 2.0 commands to achieve the end goal.

wolfTPM wrappers also provide templates for the most commonly used types of TPM 2.0 keys.

Please contact us at [email protected] if you are interested in using wolfTPM with U-boot.
48 changes: 48 additions & 0 deletions examples/u-boot/options.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* examples/u-boot/options.h
*
* Copyright (C) 2006-2021 wolfSSL Inc.
*
* This file is part of wolfTPM.
*
* wolfTPM 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; either version 2 of the License, or
* (at your option) any later version.
*
* wolfTPM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/

/* Example wolfTPM options.h for U-boot compilation */

#ifndef WOLFTPM_OPTIONS_H
#define WOLFTPM_OPTIONS_H

#ifdef __cplusplus
extern "C" {
#endif

#undef __UBOOT__
#define __UBOOT__

#undef SIZEOF_LONG
#define SIZEOF_LONG 8

#undef WOLFTPM2_NO_WOLFCRYPT
#define WOLFTPM2_NO_WOLFCRYPT

#undef WOLFTPM_AUTODETECT
#define WOLFTPM_AUTODETECT

#ifdef __cplusplus
}
#endif

#endif /* WOLFTPM_OPTIONS_H */