Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
107 changes: 107 additions & 0 deletions examples/u-boot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# 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. Exiting the QEMU:
Press Ctrl-A followed by X
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 */

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 shut down 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 shut down 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 -- */
/******************************************************************************/
75 changes: 75 additions & 0 deletions src/tpm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -6122,6 +6122,81 @@ const char* TPM2_GetAlgName(TPM_ALG_ID alg)
return "Unknown";
}

TPM_ALG_ID TPM2_GetAlgId(const char* name)
{
if (!name)
return TPM_ALG_ERROR;

if (!XSTRCMP(name, "RSA"))
return TPM_ALG_RSA;
if (!XSTRCMP(name, "SHA1"))
return TPM_ALG_SHA1;
if (!XSTRCMP(name, "HMAC"))
return TPM_ALG_HMAC;
if (!XSTRCMP(name, "AES"))
return TPM_ALG_AES;
if (!XSTRCMP(name, "MGF1"))
return TPM_ALG_MGF1;
if (!XSTRCMP(name, "KEYEDHASH"))
return TPM_ALG_KEYEDHASH;
if (!XSTRCMP(name, "XOR"))
return TPM_ALG_XOR;
if (!XSTRCMP(name, "SHA256"))
return TPM_ALG_SHA256;
if (!XSTRCMP(name, "SHA384"))
return TPM_ALG_SHA384;
if (!XSTRCMP(name, "SHA512"))
return TPM_ALG_SHA512;
if (!XSTRCMP(name, "NULL"))
return TPM_ALG_NULL;
if (!XSTRCMP(name, "SM3_256"))
return TPM_ALG_SM3_256;
if (!XSTRCMP(name, "SM4"))
return TPM_ALG_SM4;
if (!XSTRCMP(name, "RSASSA"))
return TPM_ALG_RSASSA;
if (!XSTRCMP(name, "RSAES"))
return TPM_ALG_RSAES;
if (!XSTRCMP(name, "RSAPSS"))
return TPM_ALG_RSAPSS;
if (!XSTRCMP(name, "OAEP"))
return TPM_ALG_OAEP;
if (!XSTRCMP(name, "ECDSA"))
return TPM_ALG_ECDSA;
if (!XSTRCMP(name, "ECDH"))
return TPM_ALG_ECDH;
if (!XSTRCMP(name, "ECDAA"))
return TPM_ALG_ECDAA;
if (!XSTRCMP(name, "SM2"))
return TPM_ALG_SM2;
if (!XSTRCMP(name, "ECSCHNORR"))
return TPM_ALG_ECSCHNORR;
if (!XSTRCMP(name, "ECMQV"))
return TPM_ALG_ECMQV;
if (!XSTRCMP(name, "KDF1_SP800_56A"))
return TPM_ALG_KDF1_SP800_56A;
if (!XSTRCMP(name, "KDF2"))
return TPM_ALG_KDF2;
if (!XSTRCMP(name, "KDF1_SP800_108"))
return TPM_ALG_KDF1_SP800_108;
if (!XSTRCMP(name, "ECC"))
return TPM_ALG_ECC;
if (!XSTRCMP(name, "SYMCIPHER"))
return TPM_ALG_SYMCIPHER;
if (!XSTRCMP(name, "AES-CTR"))
return TPM_ALG_CTR;
if (!XSTRCMP(name, "AES-OFB"))
return TPM_ALG_OFB;
if (!XSTRCMP(name, "AES-CBC"))
return TPM_ALG_CBC;
if (!XSTRCMP(name, "AES-CFB"))
return TPM_ALG_CFB;
if (!XSTRCMP(name, "AES-ECB"))
return TPM_ALG_ECB;

return TPM_ALG_ERROR;
}

int TPM2_GetCurveSize(TPM_ECC_CURVE curveID)
{
switch (curveID) {
Expand Down
Loading