Skip to content

Commit 33a5f47

Browse files
authored
Merge pull request #398 from aidangarske/uboot_support
wolfTPM Support For Das U-Boot Bootloader
2 parents 3bbed48 + 985abb5 commit 33a5f47

File tree

15 files changed

+595
-56
lines changed

15 files changed

+595
-56
lines changed

examples/u-boot/README.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# wolfTPM Support For Das U-boot
2+
3+
wolfTPM provides experimental support for U-Boot with the following key features:
4+
5+
- Utilizes SOFT SPI driver in U-Boot for TPM communication
6+
- Implements TPM 2.0 driver functionality through its internal TIS layer
7+
- Provides native API access to all TPM 2.0 commands
8+
- Includes wrapper API for common TPM 2.0 operations
9+
- Supports two integration paths:
10+
- `__linux__`: Uses existing tpm interface via tpm2_linux.c
11+
- `__UBOOT__`: Direct SPI communication through tpm_io_uboot.c
12+
13+
## wolfTPM U-Boot Commands
14+
15+
The following commands are available through the `wolftpm` interface:
16+
17+
### Basic Commands
18+
19+
- `help` - Show help text
20+
- `device [num device]` - Show all devices or set the specified device
21+
- `info` - Show information about the TPM
22+
- `state` - Show internal state from the TPM (if available)
23+
- `autostart` - Initialize the TPM, perform a Startup(clear) and run a full selftest sequence
24+
- `init` - Initialize the software stack (must be first command)
25+
- `startup <mode> [<op>]` - Issue a TPM2_Startup command
26+
- `<mode>`: TPM2_SU_CLEAR (reset state) or TPM2_SU_STATE (preserved state)
27+
- `[<op>]`: optional shutdown with "off"
28+
- `self_test <type>` - Test TPM capabilities
29+
- `<type>`: "full" (all tests) or "continue" (untested tests only)
30+
31+
### PCR Operations
32+
33+
- `pcr_extend <pcr> <digest_addr> [<digest_algo>]` - Extend PCR with digest
34+
- `pcr_read <pcr> <digest_addr> [<digest_algo>]` - Read PCR to memory
35+
- `pcr_allocate <algorithm> <on/off> [<password>]` - Reconfig PCR bank algorithm
36+
- `pcr_setauthpolicy | pcr_setauthvalue <pcr> <key> [<password>]` - Change PCR access key
37+
- `pcr_print` - Print current PCR state
38+
39+
### Security Management
40+
41+
- `clear <hierarchy>` - Issue TPM2_Clear command
42+
- `<hierarchy>`: TPM2_RH_LOCKOUT or TPM2_RH_PLATFORM
43+
- `change_auth <hierarchy> <new_pw> [<old_pw>]` - Change hierarchy password
44+
- `<hierarchy>`: TPM2_RH_LOCKOUT, TPM2_RH_ENDORSEMENT, TPM2_RH_OWNER, or TPM2_RH_PLATFORM
45+
- `dam_reset [<password>]` - Reset internal error counter
46+
- `dam_parameters <max_tries> <recovery_time> <lockout_recovery> [<password>]` - Set DAM parameters
47+
- `caps` - Show TPM capabilities and info
48+
49+
### Firmware Management
50+
51+
- `firmware_update <manifest_addr> <manifest_sz> <firmware_addr> <firmware_sz>` - Update TPM firmware
52+
- `firmware_cancel` - Cancel TPM firmware update
53+
54+
## Enabling wolfTPM in U-Boot
55+
56+
Enable wolfTPM support in U-Boot by adding these options to your board's defconfig:
57+
58+
```
59+
CONFIG_TPM=y
60+
CONFIG_TPM_V2=y
61+
CONFIG_TPM_WOLF=y
62+
CONFIG_CMD_WOLFTPM=y
63+
```
64+
65+
Or use `make menuconfig` and enable:
66+
- Device Drivers → TPM → TPM 2.0 Support
67+
- Device Drivers → TPM → wolfTPM Support
68+
- Command line interface → Security commands → Enable wolfTPM commands
69+
70+
## Building and Running wolfTPM with U-Boot using QEMU
71+
72+
To build and run wolfTPM with U-Boot using QEMU and a tpm simulator, follow these steps:
73+
74+
1. Install swtpm:
75+
```
76+
git clone [email protected]:stefanberger/swtpm.git
77+
cd swtpm
78+
./autogen.sh
79+
make
80+
```
81+
82+
2. Build U-Boot:
83+
```
84+
make distclean
85+
export CROSS_COMPILE=aarch64-linux-gnu-
86+
export ARCH=aarch64
87+
make qemu_arm64_defconfig
88+
make -j4
89+
```
90+
91+
3. Create TPM directory:
92+
```
93+
mkdir -p /tmp/mytpm1
94+
```
95+
96+
4. Start swtpm (in first terminal):
97+
```
98+
swtpm socket --tpm2 --tpmstate dir=/tmp/mytpm1 --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock --log level=20
99+
```
100+
101+
5. Start QEMU (in second terminal):
102+
```
103+
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
104+
```
105+
106+
6. Example output:
107+
108+
```
109+
U-Boot 2025.07-rc1-ge15cbf232ddf-dirty (May 06 2025 - 16:25:56 -0700)
110+
111+
DRAM: 128 MiB
112+
using memory 0x46658000-0x47698000 for malloc()
113+
Core: 52 devices, 15 uclasses, devicetree: board
114+
Flash: 64 MiB
115+
Loading Environment from Flash... *** Warning - bad CRC, using default environment
116+
117+
In: serial,usbkbd
118+
Out: serial,vidconsole
119+
Err: serial,vidconsole
120+
No USB controllers found
121+
Net: eth0: virtio-net#32
122+
123+
Hit any key to stop autoboot: 0
124+
=> tpm2 help
125+
tpm2 - Issue a TPMv2.x command
126+
127+
Usage:
128+
tpm2 <command> [<arguments>]
129+
130+
device [num device]
131+
Show all devices or set the specified device
132+
info
133+
Show information about the TPM.
134+
```
135+
136+
7. Example commands:
137+
138+
```
139+
=> tpm2 info
140+
tpm_tis@0 v2.0: VendorID 0x1014, DeviceID 0x0001, RevisionID 0x01 [open]
141+
=> tpm2 startup TPM2_SU_CLEAR
142+
=> tpm2 get_capability 0x6 0x20e 0x200 1
143+
Capabilities read from TPM:
144+
Property 0x6a2e45a9: 0x6c3646a9
145+
=> tpm2 pcr_read 10 0x100000
146+
PCR #10 sha256 32 byte content (20 known updates):
147+
20 25 73 0a 00 56 61 6c 75 65 3a 0a 00 23 23 20
148+
4f 75 74 20 6f 66 20 6d 65 6d 6f 72 79 0a 00 23
149+
```
150+
151+
8. Exiting the QEMU:
152+
Press Ctrl-A followed by X

examples/wrap/caps.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ int TPM2_Wrapper_CapsArgs(void* userCtx, int argc, char *argv[])
130130
TPM2_PCRs_Print();
131131

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

135136
wolfTPM2_Cleanup(&dev);
136137

examples/wrap/wrap_test.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,8 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
10101010
wolfTPM2_UnloadHandle(&dev, &ekKey.handle);
10111011
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
10121012

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

10151016
wolfTPM2_Cleanup(&dev);
10161017

hal/include.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ src_libwolftpm_la_SOURCES += \
1313
hal/tpm_io_microchip.c \
1414
hal/tpm_io_st.c \
1515
hal/tpm_io_qnx.c \
16+
hal/tpm_io_uboot.c \
1617
hal/tpm_io_xilinx.c
1718
endif
1819

hal/tpm_io.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353

5454
#if defined(WOLFTPM_MMIO)
5555
#include "tpm_io_mmio.c"
56+
#elif defined(__UBOOT__)
57+
#include "hal/tpm_io_uboot.c"
5658
#elif defined(__linux__)
5759
#include "hal/tpm_io_linux.c"
5860
#elif defined(WOLFSSL_STM32_CUBEMX)
@@ -78,8 +80,10 @@ static int TPM2_IoCb_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
7880
word16 xferSz, void* userCtx)
7981
{
8082
int ret = TPM_RC_FAILURE;
81-
82-
#if defined(__linux__)
83+
84+
#if defined(__UBOOT__)
85+
ret = TPM2_IoCb_Uboot_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
86+
#elif defined(__linux__)
8387
ret = TPM2_IoCb_Linux_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);
8488
#elif defined(WOLFSSL_STM32_CUBEMX)
8589
ret = TPM2_IoCb_STCubeMX_SPI(ctx, txBuf, rxBuf, xferSz, userCtx);

hal/tpm_io.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
* - Xilinx Zynq
5050
* - Barebox
5151
* - QNX
52+
* - uboot
5253
* - Infineon Tri-Core
5354
* - Microchip MPLAB X Harmony (WOLFTPM_MICROCHIP_HARMONY)
5455
* Using custom IO Callback is always possible.
@@ -101,6 +102,9 @@ WOLFTPM_LOCAL int TPM2_IoCb_Atmel_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rx
101102
#elif defined(__BAREBOX__)
102103
WOLFTPM_LOCAL int TPM2_IoCb_Barebox_SPI(TPM2_CTX* ctx, const byte* txBuf,
103104
byte* rxBuf, word16 xferSz, void* userCtx);
105+
#elif defined(__UBOOT__)
106+
WOLFTPM_LOCAL int TPM2_IoCb_Uboot_SPI(TPM2_CTX* ctx, const byte* txBuf,
107+
byte* rxBuf, word16 xferSz, void* userCtx);
104108
#elif defined(__linux__)
105109
WOLFTPM_LOCAL int TPM2_IoCb_Linux_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
106110
word16 xferSz, void* userCtx);

hal/tpm_io_uboot.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/* tpm_io_uboot.c
2+
*
3+
* Copyright (C) 2006-2025 wolfSSL Inc.
4+
*
5+
* This file is part of wolfTPM.
6+
*
7+
* wolfTPM is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfTPM is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20+
*/
21+
22+
/* This example shows IO interfaces for U-boot */
23+
24+
#include <wolftpm/tpm2.h>
25+
#include <wolftpm/tpm2_tis.h>
26+
#include "tpm_io.h"
27+
28+
/******************************************************************************/
29+
/* --- BEGIN IO Callback Logic -- */
30+
/******************************************************************************/
31+
32+
/* Included via tpm_io.c if WOLFTPM_INCLUDE_IO_FILE is defined */
33+
#ifdef WOLFTPM_INCLUDE_IO_FILE
34+
35+
#if ! (defined(WOLFTPM_LINUX_DEV) || \
36+
defined(WOLFTPM_SWTPM) || \
37+
defined(WOLFTPM_WINAPI) )
38+
39+
/* Use the max speed by default - see tpm2_types.h for chip specific max values */
40+
#ifndef TPM2_SPI_HZ
41+
#define TPM2_SPI_HZ TPM2_SPI_MAX_HZ
42+
#endif
43+
44+
#if defined(__UBOOT__)
45+
#include <config.h>
46+
int TPM2_IoCb_Uboot_SPI(TPM2_CTX* ctx, const byte* txBuf,
47+
byte* rxBuf, word16 xferSz, void* userCtx)
48+
{
49+
int ret = 0;
50+
struct udevice *dev;
51+
52+
/* Get the TPM device */
53+
if (ret == 0) {
54+
ret = tcg2_platform_get_tpm2(&dev);
55+
if ( ret != 0 || dev == NULL) {
56+
#ifdef DEBUG_WOLFTPM
57+
printf("Failed to get TPM device with error: %d\n", ret);
58+
#endif
59+
return TPM_RC_FAILURE;
60+
}
61+
}
62+
63+
/* Transfer the device data using tpm_xfer */
64+
if (ret == 0) {
65+
ret = tpm_xfer(dev, txBuf, xferSz, rxBuf, &xferSz);
66+
if (ret != 0) {
67+
#ifdef DEBUG_WOLFTPM
68+
printf("tpm_xfer failed with error: %d\n", ret);
69+
#endif
70+
return TPM_RC_FAILURE;
71+
}
72+
}
73+
74+
return TPM_RC_SUCCESS;
75+
}
76+
#endif /* __UBOOT__ */
77+
#endif /* WOLFTPM_LINUX_DEV || WOLFTPM_SWTPM || WOLFTPM_WINAPI */
78+
#endif /* WOLFTPM_INCLUDE_IO_FILE */
79+
80+
/******************************************************************************/
81+
/* --- END IO Callback Logic -- */
82+
/******************************************************************************/

0 commit comments

Comments
 (0)