Merge pull request #398 from aidangarske/uboot_support

wolfTPM Support For Das U-Boot Bootloader
pull/395/head
Zackery 2025-05-06 18:17:56 -06:00 committed by GitHub
commit 33a5f47eaf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 595 additions and 56 deletions

View File

@ -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 git@github.com: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

View File

@ -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);

View File

@ -1010,7 +1010,8 @@ exit:
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);

View File

@ -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

View File

@ -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)
@ -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);

View File

@ -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.
@ -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);

82
hal/tpm_io_uboot.c 100644
View File

@ -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 -- */
/******************************************************************************/

View File

@ -6117,6 +6117,99 @@ 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;
}
#ifdef DEBUG_WOLFTPM
const char* TPM2_GetHierarchyDesc(TPMI_RH_HIERARCHY_AUTH authHandle)
{
switch (authHandle) {
case TPM_RH_LOCKOUT:
return "Lockout";
case TPM_RH_ENDORSEMENT:
return "Endorsement";
case TPM_RH_OWNER:
return "Owner";
case TPM_RH_PLATFORM:
return "Platform";
default:
return "Unknown";
}
}
#endif /* DEBUG_WOLFTPM */
int TPM2_GetCurveSize(TPM_ECC_CURVE curveID)
{
switch (curveID) {

View File

@ -28,6 +28,61 @@
#ifdef WOLFTPM_LINUX_DEV
#include <wolftpm/tpm2_linux.h>
#include <wolftpm/tpm2_packet.h>
#if defined(__UBOOT__)
#include <config.h>
#include <tpm-common.h>
/* import u-boot function helper to get device */
extern int tcg2_platform_get_tpm2(struct udevice **dev);
/* Use the U-Boot TPM device and TIS layer */
int TPM2_LINUX_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet)
{
int rc;
struct udevice *dev;
size_t rspSz = 0;
#ifdef WOLFTPM_DEBUG_VERBOSE
printf("Command size: %d\n", packet->pos);
TPM2_PrintBin(packet->buf, packet->pos);
#endif
/* Get the TPM2 U-boot device */
rc = tcg2_platform_get_tpm2(&dev);
if (rc != 0 || dev == NULL) {
#ifdef DEBUG_WOLFTPM
printf("Failed to find TPM2 U-boot device: %d\n", rc);
#endif
rc = TPM_RC_FAILURE;
}
if (rc == 0) {
/* Transfer the device data using tpm_xfer */
rspSz = packet->size;
rc = tpm_xfer(dev, packet->buf, packet->pos, packet->buf, &rspSz);
if (rc != 0) {
#ifdef DEBUG_WOLFTPM
printf("tpm_xfer failed with error: %d\n", rc);
#endif
rc = TPM_RC_FAILURE;
}
}
#ifdef WOLFTPM_DEBUG_VERBOSE
if (rspSz > 0) {
printf("Response size: %d\n", (int)rspSz);
TPM2_PrintBin(packet->buf, rspSz);
}
#endif
(void)ctx;
return rc;
}
#else /* __linux__ */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@ -125,4 +180,5 @@ int TPM2_LINUX_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet)
return rc;
}
#endif
#endif /* __UBOOT__ __linux__ */
#endif /* WOLFTPM_LINUX_DEV */

View File

@ -5672,10 +5672,10 @@ int wolfTPM2_HmacFinish(WOLFTPM2_DEV* dev, WOLFTPM2_HMAC* hmac,
return rc;
}
/* performs a reset sequence */
int wolfTPM2_Shutdown(WOLFTPM2_DEV* dev, int doStartup)
/* performs a reset, shutdown, or startup sequence */
int wolfTPM2_Reset(WOLFTPM2_DEV* dev, int doShutdown, int doStartup)
{
int rc;
int rc = TPM_RC_SUCCESS;
Shutdown_In shutdownIn;
Startup_In startupIn;
@ -5684,17 +5684,20 @@ int wolfTPM2_Shutdown(WOLFTPM2_DEV* dev, int doStartup)
}
/* shutdown */
XMEMSET(&shutdownIn, 0, sizeof(shutdownIn));
shutdownIn.shutdownType = TPM_SU_CLEAR;
rc = TPM2_Shutdown(&shutdownIn);
if (rc != TPM_RC_SUCCESS) {
#ifdef DEBUG_WOLFTPM
printf("TPM2_Shutdown failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
#endif
if (doShutdown == 1) {
XMEMSET(&shutdownIn, 0, sizeof(shutdownIn));
shutdownIn.shutdownType = TPM_SU_CLEAR;
rc = TPM2_Shutdown(&shutdownIn);
if (rc != TPM_RC_SUCCESS) {
#ifdef DEBUG_WOLFTPM
printf("TPM2_Shutdown failed 0x%x: %s\n",
rc, TPM2_GetRCString(rc));
#endif
}
}
/* startup */
if (doStartup) {
if (doStartup == 1 && rc == TPM_RC_SUCCESS) {
XMEMSET(&startupIn, 0, sizeof(startupIn));
startupIn.startupType = TPM_SU_CLEAR;
rc = TPM2_Startup(&startupIn);
@ -5703,17 +5706,22 @@ int wolfTPM2_Shutdown(WOLFTPM2_DEV* dev, int doStartup)
printf("TPM2_Startup failed %d: %s\n",
rc, wolfTPM2_GetRCString(rc));
#endif
return rc;
}
}
#ifdef DEBUG_WOLFTPM
printf("wolfTPM2_Shutdown complete\n");
printf("wolfTPM2_Reset complete\n");
#endif
return rc;
}
/* performs a shutdown or reset sequence */
int wolfTPM2_Shutdown(WOLFTPM2_DEV* dev, int doStartup)
{
return wolfTPM2_Reset(dev, 1, doStartup);
}
int wolfTPM2_UnloadHandles(WOLFTPM2_DEV* dev, word32 handleStart,
word32 handleCount)
{
@ -5739,18 +5747,21 @@ int wolfTPM2_UnloadHandles_AllTransient(WOLFTPM2_DEV* dev)
return wolfTPM2_UnloadHandles(dev, TRANSIENT_FIRST, MAX_HANDLE_NUM);
}
int wolfTPM2_ChangePlatformAuth(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session)
int wolfTPM2_ChangeHierarchyAuth(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session,
TPMI_RH_HIERARCHY_AUTH authHandle)
{
int rc = 0;
HierarchyChangeAuth_In in;
#ifdef DEBUG_WOLFTPM
const char* desc = NULL;
#endif
if (dev == NULL) {
return BAD_FUNC_ARG;
}
XMEMSET(&in, 0, sizeof(in));
in.authHandle = TPM_RH_PLATFORM;
in.authHandle = authHandle;
/* use parameter encryption if session supplied */
if (session != NULL) {
@ -5771,16 +5782,17 @@ int wolfTPM2_ChangePlatformAuth(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session)
rc = TPM2_HierarchyChangeAuth(&in);
}
#ifdef DEBUG_WOLFTPM
desc = TPM2_GetHierarchyDesc(authHandle);
if (rc == 0) {
printf("Platform auth set to %d bytes of random\n", in.newAuth.size);
printf("%s auth set to %d bytes of random\n", desc, in.newAuth.size);
#ifdef WOLFTPM_DEBUG_VERBOSE
printf("\tAuth Sz %d\n", in.newAuth.size);
TPM2_PrintBin(in.newAuth.buffer, in.newAuth.size);
#endif
}
else {
printf("Error %d setting platform auth! %s\n",
rc, wolfTPM2_GetRCString(rc));
} else {
printf("Error %d setting %s auth! %s\n",
rc, desc, wolfTPM2_GetRCString(rc));
}
#endif
/* ensure the random secret is not left in stack */
@ -5788,6 +5800,11 @@ int wolfTPM2_ChangePlatformAuth(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session)
return rc;
}
int wolfTPM2_ChangePlatformAuth(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session)
{
return wolfTPM2_ChangeHierarchyAuth(dev, session, TPM_RH_PLATFORM);
}
/******************************************************************************/
/* --- END Wrapper Device Functions-- */
/******************************************************************************/
@ -8017,6 +8034,7 @@ int wolfTPM2_FirmwareUpgradeHash(WOLFTPM2_DEV* dev, TPM_ALG_ID hashAlg,
return rc;
}
#ifndef WOLFTPM2_NO_WOLFCRYPT
int wolfTPM2_FirmwareUpgrade(WOLFTPM2_DEV* dev,
uint8_t* manifest, uint32_t manifest_sz,
wolfTPM2FwDataCb cb, void* cb_ctx)
@ -8033,6 +8051,7 @@ int wolfTPM2_FirmwareUpgrade(WOLFTPM2_DEV* dev,
}
return rc;
}
#endif
int wolfTPM2_FirmwareUpgradeRecover(WOLFTPM2_DEV* dev,
uint8_t* manifest, uint32_t manifest_sz,

View File

@ -357,6 +357,12 @@ static void test_TPM2_KDFa(void)
rc >= 0 ? "Passed" : "Failed");
}
static void test_GetAlgId(void)
{
TPM_ALG_ID alg = TPM2_GetAlgId("SHA256");
AssertIntEQ(alg, TPM_ALG_SHA256);
}
static void test_wolfTPM2_CSR(void)
{
#if defined(WOLFTPM2_CERT_GEN) && !defined(WOLFTPM2_NO_HEAP) && \
@ -663,6 +669,7 @@ int unit_tests(int argc, char *argv[])
test_wolfTPM2_GetRandom();
test_TPM2_PCRSel();
test_TPM2_KDFa();
test_GetAlgId();
test_wolfTPM2_ReadPublicKey();
test_wolfTPM2_CSR();
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(WOLFTPM2_PEM_DECODE) && \

View File

@ -3550,6 +3550,46 @@ WOLFTPM_API const char* TPM2_GetRCString(int rc);
*/
WOLFTPM_API const char* TPM2_GetAlgName(TPM_ALG_ID alg);
/*!
\ingroup TPM2_Proprietary
\brief Translates a TPM algorithm name to its TPM algorithm ID
\return a TPM algorithm ID
\return TPM_ALG_ERROR if invalid algorithm name
\param name a pointer to a string constant specifying a valid TPM algorithm
name
_Example_
\code
TPM_ALG_ID alg = TPM2_GetAlgId("SHA256");
if (alg == TPM_ALG_ERROR) {
//TPM2_GetAlgId failed
}
\endcode
*/
WOLFTPM_API TPM_ALG_ID TPM2_GetAlgId(const char* name);
#ifdef DEBUG_WOLFTPM
/*!
\ingroup TPM2_Proprietary
\brief Get readable string for TPM 2.0 hierarchy
\return pointer to a string constant
\param authHandle value of type TPMI_RH_HIERARCHY_AUTH specifying a valid
TPM 2.0 hierarchy
_Example_
\code
TPMI_RH_HIERARCHY_AUTH authHandle = TPM_RH_OWNER;
printf("\tHierarchy: %s\n", TPM2_GetHierarchyDesc(authHandle));
\endcode
*/
WOLFTPM_API const char* TPM2_GetHierarchyDesc(TPMI_RH_HIERARCHY_AUTH authHandle);
#endif
/*!
\ingroup TPM2_Proprietary
\brief Determine the size in bytes of any TPM ECC Curve

View File

@ -30,21 +30,57 @@
#define TPM2_HEADER_SIZE 10 /* expected TPM2 header size */
/* Endianess Helpers */
#ifdef LITTLE_ENDIAN_ORDER
#define cpu_to_be16(d) ByteReverseWord16(d)
#define cpu_to_be32(d) ByteReverseWord32(d)
#define cpu_to_be64(d) ByteReverseWord64(d)
#define be16_to_cpu(d) ByteReverseWord16(d)
#define be32_to_cpu(d) ByteReverseWord32(d)
#define be64_to_cpu(d) ByteReverseWord64(d)
#else
#define cpu_to_be16(d) (d)
#define cpu_to_be32(d) (d)
#define cpu_to_be64(d) (d)
#define be16_to_cpu(d) (d)
#define be32_to_cpu(d) (d)
#define be64_to_cpu(d) (d)
/* Endianess Helpers
* Check if byte-order functions are already defined by the system:
* U-boot defines these functions, so we need to check if they are
* already defined.
*/
#ifndef cpu_to_be16
#ifdef LITTLE_ENDIAN_ORDER
#define cpu_to_be16(d) ByteReverseWord16(d)
#else
#define cpu_to_be16(d) (d)
#endif
#endif
#ifndef cpu_to_be32
#ifdef LITTLE_ENDIAN_ORDER
#define cpu_to_be32(d) ByteReverseWord32(d)
#else
#define cpu_to_be32(d) (d)
#endif
#endif
#ifndef cpu_to_be64
#ifdef LITTLE_ENDIAN_ORDER
#define cpu_to_be64(d) ByteReverseWord64(d)
#else
#define cpu_to_be64(d) (d)
#endif
#endif
#ifndef be16_to_cpu
#ifdef LITTLE_ENDIAN_ORDER
#define be16_to_cpu(d) ByteReverseWord16(d)
#else
#define be16_to_cpu(d) (d)
#endif
#endif
#ifndef be32_to_cpu
#ifdef LITTLE_ENDIAN_ORDER
#define be32_to_cpu(d) ByteReverseWord32(d)
#else
#define be32_to_cpu(d) (d)
#endif
#endif
#ifndef be64_to_cpu
#ifdef LITTLE_ENDIAN_ORDER
#define be64_to_cpu(d) ByteReverseWord64(d)
#else
#define be64_to_cpu(d) (d)
#endif
#endif
/* For reference here is the TPM2 header (not used) */

View File

@ -33,8 +33,14 @@
#include <wolftpm/options.h>
#endif
#ifdef __cplusplus
extern "C" {
#ifndef WOLFTPM2_NO_WOLFCRYPT
#ifndef WOLFSSL_USER_SETTINGS
#include <wolfssl/options.h>
#endif
#else
#ifdef WOLFTPM_USER_SETTINGS
#include "user_settings.h"
#endif
#endif
#ifdef WOLFTPM_WINAPI
@ -44,6 +50,10 @@
#include <windows.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* ---------------------------------------------------------------------------*/
/* TPM TYPES */
/* ---------------------------------------------------------------------------*/
@ -81,9 +91,6 @@ typedef int64_t INT64;
/* ---------------------------------------------------------------------------*/
#ifndef WOLFTPM2_NO_WOLFCRYPT
#ifndef WOLFSSL_USER_SETTINGS
#include <wolfssl/options.h>
#endif
/* enforce NO_THREAD_LS within wolfTPM */
#ifdef NO_THREAD_LS
#undef HAVE_THREAD_LS
@ -142,10 +149,6 @@ typedef int64_t INT64;
#include <stdlib.h>
#include <string.h>
#ifdef WOLFTPM_USER_SETTINGS
#include "user_settings.h"
#endif
typedef uint8_t byte;
typedef uint16_t word16;
typedef uint32_t word32;
@ -704,11 +707,9 @@ typedef int64_t INT64;
#define WOLFTPM2_PEM_DECODE
#endif
/* Firmware upgrade requires wolfCrypt for hashing.
* Supported only for Infineon SLB9672/SLB9673 */
#if defined(WOLFTPM_FIRMWARE_UPGRADE) && \
(defined(WOLFTPM2_NO_WOLFCRYPT) || \
(!defined(WOLFTPM_SLB9672) && !defined(WOLFTPM_SLB9673)))
/* Firmware upgrade supported only for Infineon SLB9672/SLB9673 */
#if defined(WOLFTPM_FIRMWARE_UPGRADE) && (!defined(WOLFTPM_AUTODETECT) && \
(!defined(WOLFTPM_SLB9672) && !defined(WOLFTPM_SLB9673)))
#undef WOLFTPM_FIRMWARE_UPGRADE
#endif

View File

@ -2590,6 +2590,27 @@ WOLFTPM_API int wolfTPM2_EncryptDecrypt(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
WOLFTPM_API int wolfTPM2_SetCommand(WOLFTPM2_DEV* dev, TPM_CC commandCode,
int enableFlag);
/*!
\ingroup wolfTPM2_Wrappers
\brief Helper function to shutdown, startup or reset the TPM
\note The behavior depends on the doStartup and doShutdown flags:
\note - Both flags set to 1: Performs a full TPM restart (shutdown then startup)
\note - Only doStartup=1: Just starts up the TPM
\note - Only doShutdown=1: Just shuts down the TPM
\return TPM_RC_SUCCESS: successful
\return TPM_RC_FAILURE: generic failure (check TPM IO and TPM return code)
\return BAD_FUNC_ARG: check the provided arguments
\param dev pointer to a TPM2_DEV struct
\param doStartup integer value, non-zero values represent "perform Startup after Shutdown"
\param doShutdown integer value, non-zero values represent "perform Shutdown"
\sa wolfTPM2_Init
\sa wolfTPM2_Reset
*/
WOLFTPM_API int wolfTPM2_Reset(WOLFTPM2_DEV* dev, int doShutdown, int doStartup);
/*!
\ingroup wolfTPM2_Wrappers
\brief Helper function to shutdown or reset the TPM
@ -2603,6 +2624,7 @@ WOLFTPM_API int wolfTPM2_SetCommand(WOLFTPM2_DEV* dev, TPM_CC commandCode,
\param doStartup integer value, non-zero values represent "perform Startup after Shutdown"
\sa wolfTPM2_Init
\sa wolfTPM2_Shutdown
*/
WOLFTPM_API int wolfTPM2_Shutdown(WOLFTPM2_DEV* dev, int doStartup);
@ -3262,7 +3284,7 @@ WOLFTPM_API int wolfTPM2_CSR_Generate(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
/*!
\ingroup wolfTPM2_Wrappers
\brief Helper to set the platform heirarchy authentication value to random.
\brief Helper to set the platform hierarchy authentication value to random.
Setting the platform auth to random value is used to prevent application
from being able to use platform hierarchy. This is defined in section 10
of the TCG PC Client Platform specification.
@ -3275,10 +3297,30 @@ WOLFTPM_API int wolfTPM2_CSR_Generate(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
\param session the current session, a session is required to protect the new platform auth
\sa TPM2_HierarchyChangeAuth
\sa wolfTPM2_ChangeHierarchyAuth
*/
WOLFTPM_API int wolfTPM2_ChangePlatformAuth(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session);
/*!
\ingroup wolfTPM2_Wrappers
\brief Helper to set the hierarchy authentication value to random.
Setting the platform auth to random value is used to prevent application
from being able to use platform hierarchy. This is defined in section 10
of the TCG PC Client Platform specification.
\return Success: Positive integer (size of the output)
\return TPM_RC_FAILURE: generic failure (check TPM IO and TPM return code)
\return BAD_FUNC_ARG: check the provided arguments
\param dev pointer to a TPM2_DEV struct
\param session the current session, a session is required to protect the new platform auth
\param authHandle the auth hierarchy (example: TPM_RH_PLATFORM or TPM_RH_LOCKOUT)
\sa TPM2_HierarchyChangeAuth
\sa wolfTPM2_ChangePlatformAuth
*/
WOLFTPM_API int wolfTPM2_ChangeHierarchyAuth(WOLFTPM2_DEV* dev, WOLFTPM2_SESSION* session,
TPMI_RH_HIERARCHY_AUTH authHandle);
/* moved to tpm.h native code. macros here for backwards compatibility */
#define wolfTPM2_SetupPCRSel TPM2_SetupPCRSel