Skip to content
Merged
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
152 changes: 152 additions & 0 deletions examples/u-boot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# wolfTPM Support For Das U-boot

wolfTPM provides experimental support for U-Boot with the following key features:

- Utilizes SOFT SPI driver in U-Boot for TPM communication
- Implements TPM 2.0 driver functionality through its internal TIS layer
- Provides native API access to all TPM 2.0 commands
- Includes wrapper API for common TPM 2.0 operations
- Supports two integration paths:
- `__linux__`: Uses existing tpm interface via tpm2_linux.c
- `__UBOOT__`: Direct SPI communication through tpm_io_uboot.c

## wolfTPM U-Boot Commands

The following commands are available through the `wolftpm` interface:

### Basic Commands

- `help` - Show help text
- `device [num device]` - Show all devices or set the specified device
- `info` - Show information about the TPM
- `state` - Show internal state from the TPM (if available)
- `autostart` - Initialize the TPM, perform a Startup(clear) and run a full selftest sequence
- `init` - Initialize the software stack (must be first command)
- `startup <mode> [<op>]` - Issue a TPM2_Startup command
- `<mode>`: TPM2_SU_CLEAR (reset state) or TPM2_SU_STATE (preserved state)
- `[<op>]`: optional shutdown with "off"
- `self_test <type>` - Test TPM capabilities
- `<type>`: "full" (all tests) or "continue" (untested tests only)

### PCR Operations

- `pcr_extend <pcr> <digest_addr> [<digest_algo>]` - Extend PCR with digest
- `pcr_read <pcr> <digest_addr> [<digest_algo>]` - Read PCR to memory
- `pcr_allocate <algorithm> <on/off> [<password>]` - Reconfig PCR bank algorithm
- `pcr_setauthpolicy | pcr_setauthvalue <pcr> <key> [<password>]` - Change PCR access key
- `pcr_print` - Print current PCR state

### Security Management

- `clear <hierarchy>` - Issue TPM2_Clear command
- `<hierarchy>`: TPM2_RH_LOCKOUT or TPM2_RH_PLATFORM
- `change_auth <hierarchy> <new_pw> [<old_pw>]` - Change hierarchy password
- `<hierarchy>`: TPM2_RH_LOCKOUT, TPM2_RH_ENDORSEMENT, TPM2_RH_OWNER, or TPM2_RH_PLATFORM
- `dam_reset [<password>]` - Reset internal error counter
- `dam_parameters <max_tries> <recovery_time> <lockout_recovery> [<password>]` - Set DAM parameters
- `caps` - Show TPM capabilities and info

### Firmware Management

- `firmware_update <manifest_addr> <manifest_sz> <firmware_addr> <firmware_sz>` - Update TPM firmware
- `firmware_cancel` - Cancel TPM firmware update

## Enabling wolfTPM in U-Boot

Enable wolfTPM support in U-Boot by adding these options to your board's defconfig:

```
CONFIG_TPM=y
CONFIG_TPM_V2=y
CONFIG_TPM_WOLF=y
CONFIG_CMD_WOLFTPM=y
```

Or use `make menuconfig` and enable:
- Device Drivers → TPM → TPM 2.0 Support
- Device Drivers → TPM → wolfTPM Support
- Command line interface → Security commands → Enable wolfTPM commands

## Building and Running wolfTPM with U-Boot using QEMU

To build and run wolfTPM with U-Boot using QEMU and a tpm simulator, follow these steps:

1. Install swtpm:
```
git clone [email protected]:stefanberger/swtpm.git
cd swtpm
./autogen.sh
make
```

2. Build U-Boot:
```
make distclean
export CROSS_COMPILE=aarch64-linux-gnu-
export ARCH=aarch64
make qemu_arm64_defconfig
make -j4
```

3. Create TPM directory:
```
mkdir -p /tmp/mytpm1
```

4. Start swtpm (in first terminal):
```
swtpm socket --tpm2 --tpmstate dir=/tmp/mytpm1 --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock --log level=20
```

5. Start QEMU (in second terminal):
```
qemu-system-aarch64 -machine virt -nographic -cpu cortex-a57 -bios u-boot.bin -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis-device,tpmdev=tpm0
```

6. Example output:

```
U-Boot 2025.07-rc1-ge15cbf232ddf-dirty (May 06 2025 - 16:25:56 -0700)

DRAM: 128 MiB
using memory 0x46658000-0x47698000 for malloc()
Core: 52 devices, 15 uclasses, devicetree: board
Flash: 64 MiB
Loading Environment from Flash... *** Warning - bad CRC, using default environment

In: serial,usbkbd
Out: serial,vidconsole
Err: serial,vidconsole
No USB controllers found
Net: eth0: virtio-net#32

Hit any key to stop autoboot: 0
=> tpm2 help
tpm2 - Issue a TPMv2.x command

Usage:
tpm2 <command> [<arguments>]

device [num device]
Show all devices or set the specified device
info
Show information about the TPM.
```

7. Example commands:

```
=> tpm2 info
tpm_tis@0 v2.0: VendorID 0x1014, DeviceID 0x0001, RevisionID 0x01 [open]
=> tpm2 startup TPM2_SU_CLEAR
=> tpm2 get_capability 0x6 0x20e 0x200 1
Capabilities read from TPM:
Property 0x6a2e45a9: 0x6c3646a9
=> tpm2 pcr_read 10 0x100000
PCR #10 sha256 32 byte content (20 known updates):
20 25 73 0a 00 56 61 6c 75 65 3a 0a 00 23 23 20
4f 75 74 20 6f 66 20 6d 65 6d 6f 72 79 0a 00 23
```

8. Exiting the QEMU:
Press Ctrl-A followed by X
3 changes: 2 additions & 1 deletion examples/wrap/caps.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ int TPM2_Wrapper_CapsArgs(void* userCtx, int argc, char *argv[])
TPM2_PCRs_Print();

exit:
wolfTPM2_Shutdown(&dev, 0); /* 0=just shutdown, no startup */
/* Only doShutdown=1: Just shutdown the TPM */
wolfTPM2_Reset(&dev, 1, 0);

wolfTPM2_Cleanup(&dev);

Expand Down
3 changes: 2 additions & 1 deletion examples/wrap/wrap_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,8 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
wolfTPM2_UnloadHandle(&dev, &ekKey.handle);
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);

wolfTPM2_Shutdown(&dev, 0); /* 0=just shutdown, no startup */
/* Only doShutdown=1: Just shutdown the TPM */
wolfTPM2_Reset(&dev, 1, 0);

wolfTPM2_Cleanup(&dev);

Expand Down
1 change: 1 addition & 0 deletions hal/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ src_libwolftpm_la_SOURCES += \
hal/tpm_io_microchip.c \
hal/tpm_io_st.c \
hal/tpm_io_qnx.c \
hal/tpm_io_uboot.c \
hal/tpm_io_xilinx.c
endif

Expand Down
8 changes: 6 additions & 2 deletions hal/tpm_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@

#if defined(WOLFTPM_MMIO)
#include "tpm_io_mmio.c"
#elif defined(__UBOOT__)
#include "hal/tpm_io_uboot.c"
#elif defined(__linux__)
#include "hal/tpm_io_linux.c"
#elif defined(WOLFSSL_STM32_CUBEMX)
Expand All @@ -78,8 +80,10 @@ static int TPM2_IoCb_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
word16 xferSz, void* userCtx)
{
int ret = TPM_RC_FAILURE;

#if defined(__linux__)

#if defined(__UBOOT__)
ret = TPM2_IoCb_Uboot_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
#elif defined(__linux__)
ret = TPM2_IoCb_Linux_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
#elif defined(WOLFSSL_STM32_CUBEMX)
ret = TPM2_IoCb_STCubeMX_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
Expand Down
4 changes: 4 additions & 0 deletions hal/tpm_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
* - Xilinx Zynq
* - Barebox
* - QNX
* - uboot
* - Infineon Tri-Core
* - Microchip MPLAB X Harmony (WOLFTPM_MICROCHIP_HARMONY)
* Using custom IO Callback is always possible.
Expand Down Expand Up @@ -101,6 +102,9 @@ WOLFTPM_LOCAL int TPM2_IoCb_Atmel_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rx
#elif defined(__BAREBOX__)
WOLFTPM_LOCAL int TPM2_IoCb_Barebox_SPI(TPM2_CTX* ctx, const byte* txBuf,
byte* rxBuf, word16 xferSz, void* userCtx);
#elif defined(__UBOOT__)
WOLFTPM_LOCAL int TPM2_IoCb_Uboot_SPI(TPM2_CTX* ctx, const byte* txBuf,
byte* rxBuf, word16 xferSz, void* userCtx);
#elif defined(__linux__)
WOLFTPM_LOCAL int TPM2_IoCb_Linux_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
word16 xferSz, void* userCtx);
Expand Down
82 changes: 82 additions & 0 deletions hal/tpm_io_uboot.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/* tpm_io_uboot.c
*
* Copyright (C) 2006-2025 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 U-boot */

#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

#if defined(__UBOOT__)
#include <config.h>
int TPM2_IoCb_Uboot_SPI(TPM2_CTX* ctx, const byte* txBuf,
byte* rxBuf, word16 xferSz, void* userCtx)
{
int ret = 0;
struct udevice *dev;

/* Get the TPM device */
if (ret == 0) {
ret = tcg2_platform_get_tpm2(&dev);
if ( ret != 0 || dev == NULL) {
#ifdef DEBUG_WOLFTPM
printf("Failed to get TPM device with error: %d\n", ret);
#endif
return TPM_RC_FAILURE;
}
}

/* Transfer the device data using tpm_xfer */
if (ret == 0) {
ret = tpm_xfer(dev, txBuf, xferSz, rxBuf, &xferSz);
if (ret != 0) {
#ifdef DEBUG_WOLFTPM
printf("tpm_xfer failed with error: %d\n", ret);
#endif
return TPM_RC_FAILURE;
}
}

return TPM_RC_SUCCESS;
}
#endif /* __UBOOT__ */
#endif /* WOLFTPM_LINUX_DEV || WOLFTPM_SWTPM || WOLFTPM_WINAPI */
#endif /* WOLFTPM_INCLUDE_IO_FILE */

/******************************************************************************/
/* --- END IO Callback Logic -- */
/******************************************************************************/
Loading