From 3806ac7cf9eac307bf080a1f3339e1835b011fad Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 22 Oct 2026 07:46:06 -0700 Subject: [PATCH] pikeos: add PikeOS TPM driver transport (--enable-pikeos) --- .github/workflows/pikeos-build.yml | 76 +++++++++++++++++++++ CMakeLists.txt | 6 +- configure.ac | 28 +++++++- docs/build-options.md | 3 +- docs/getting-started.md | 2 +- docs/hal-io-callback.md | 1 + examples/tpm_test.h | 6 ++ hal/tpm_io.c | 3 +- hal/tpm_io.h | 2 +- src/include.am | 3 +- src/tpm2.c | 8 ++- src/tpm2_pikeos.c | 106 +++++++++++++++++++++++++++++ src/tpm2_spdm.c | 2 +- src/tpm2_wrap.c | 16 +++-- wolftpm/include.am | 1 + wolftpm/tpm2.h | 13 ++++ wolftpm/tpm2_pikeos.h | 46 +++++++++++++ wolftpm/tpm2_types.h | 11 ++- 18 files changed, 314 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/pikeos-build.yml create mode 100644 src/tpm2_pikeos.c create mode 100644 wolftpm/tpm2_pikeos.h diff --git a/.github/workflows/pikeos-build.yml b/.github/workflows/pikeos-build.yml new file mode 100644 index 000000000..d5826115e --- /dev/null +++ b/.github/workflows/pikeos-build.yml @@ -0,0 +1,76 @@ +name: PikeOS Build (WOLFTPM_PIKEOS) + +# Compile-only check of the PikeOS TPM driver transport (--enable-pikeos). +# The PikeOS SDK is not available in CI, so minimal p4.h/vm.h stubs supply the +# types and prototypes used by src/tpm2_pikeos.c with the SDK's signatures. + +on: + push: + branches: [ 'master', 'main', 'release/**' ] + pull_request: + branches: [ '*' ] + types: [opened, synchronize, reopened, ready_for_review] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + pikeos: + if: github.event_name != 'pull_request' || github.event.pull_request.draft == false + runs-on: ubuntu-latest + container: + image: ghcr.io/wolfssl/wolftpm-ci:v1.1 + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Write PikeOS p4.h/vm.h stubs + run: | + mkdir -p pikeos_stub + cat > pikeos_stub/p4.h <<'EOF' + #ifndef PIKEOS_STUB_P4_H + #define PIKEOS_STUB_P4_H + typedef int P4_e_t; + typedef unsigned long P4_size_t; + typedef unsigned long long P4_time_t; + #define P4_E_OK 0 + #define P4_MSEC(to) ((to) * 1000000ULL) + P4_e_t p4_sleep(P4_time_t timeout); + P4_time_t p4_get_time(void); + #endif + EOF + cat > pikeos_stub/vm.h <<'EOF' + #ifndef PIKEOS_STUB_VM_H + #define PIKEOS_STUB_VM_H + #include + typedef struct { unsigned int gdh; } vm_file_desc_t; + #define VM_O_RD_WR 3 + P4_e_t vm_open(const char *name, unsigned int oflags, + vm_file_desc_t *fd); + P4_e_t vm_read(vm_file_desc_t *fd, void *buff, P4_size_t buff_size, + P4_size_t *read_size); + P4_e_t vm_write(vm_file_desc_t *fd, const void *buff, + P4_size_t buff_size, P4_size_t *written_size); + P4_e_t vm_close(vm_file_desc_t *fd); + #endif + EOF + + - name: Configure (PikeOS transport, no wolfCrypt) + run: | + ./autogen.sh + ./configure --enable-pikeos --disable-wolfcrypt --disable-examples + + - name: Build library + run: | + make src/libwolftpm.la CFLAGS="-Ipikeos_stub -Werror" + + - name: Build library (debug) + run: | + make clean + make src/libwolftpm.la \ + CFLAGS="-Ipikeos_stub -Werror -DDEBUG_WOLFTPM -DWOLFTPM_DEBUG_VERBOSE" diff --git a/CMakeLists.txt b/CMakeLists.txt index 987184c19..6b7d427b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,7 @@ set(TPM_SOURCES src/tpm2.c src/tpm2_linux.c src/tpm2_packet.c + src/tpm2_pikeos.c src/tpm2_param_enc.c src/tpm2_swtpm.c src/tpm2_tis.c @@ -196,7 +197,7 @@ endif() set(WOLFTPM_INTERFACE "auto" CACHE STRING "Select interface to TPM") set_property(CACHE WOLFTPM_INTERFACE - PROPERTY STRINGS "auto;SWTPM;WINAPI;DEVTPM;SPI;I2C;MMIO") + PROPERTY STRINGS "auto;SWTPM;WINAPI;DEVTPM;PIKEOS;SPI;I2C;MMIO") # automatically set message("INTERFACE ${WOLFTPM_INTERFACE}") @@ -236,6 +237,9 @@ if("${WOLFTPM_INTERFACE}" STREQUAL "SWTPM") elseif("${WOLFTPM_INTERFACE}" STREQUAL "DEVTPM") list(APPEND WOLFTPM_DEFINITIONS "-DWOLFTPM_LINUX_DEV") +elseif("${WOLFTPM_INTERFACE}" STREQUAL "PIKEOS") + list(APPEND WOLFTPM_DEFINITIONS "-DWOLFTPM_PIKEOS") + elseif("${WOLFTPM_INTERFACE}" STREQUAL "WINAPI") list(APPEND WOLFTPM_DEFINITIONS "-DWOLFTPM_WINAPI") if(BUILD_WOLFTPM_LIB) diff --git a/configure.ac b/configure.ac index c90bdc20b..e8cb5f725 100644 --- a/configure.ac +++ b/configure.ac @@ -247,6 +247,22 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_LINUX_DEV" fi +# PikeOS TPM driver through the vm_open/vm_read/vm_write file provider +AC_ARG_ENABLE([pikeos], + [AS_HELP_STRING([--enable-pikeos],[Enable use of TPM through the PikeOS driver file provider (default: disabled)])], + [ ENABLED_PIKEOS=$enableval ], + [ ENABLED_PIKEOS=no ] + ) + +if test "x$ENABLED_PIKEOS" = "xyes" +then + if test "x$ENABLED_DEVTPM" = "xyes" + then + AC_MSG_ERROR([Cannot enable both pikeos and devtpm]) + fi + AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_PIKEOS" +fi + # If the user explicitly picked any hardware path (vendor, bus, kernel # driver, autodetect), don't default-enable the software TPMs — the SPI HAL # in hal/tpm_io_linux.c is excluded when WOLFTPM_SWTPM is defined. @@ -255,7 +271,7 @@ for _wt_v in "$enable_infineon" "$enable_st" "$enable_st33" \ "$enable_microchip" "$enable_mchp" \ "$enable_nuvoton" "$enable_nations" "$enable_sealsq" \ "$enable_spi" "$enable_i2c" "$enable_mmio" \ - "$enable_devtpm" "$enable_autodetect" \ + "$enable_devtpm" "$enable_pikeos" "$enable_autodetect" \ "$enable_winapi" "$enable_wintbs"; do if test -n "$_wt_v" && test "x$_wt_v" != "xno"; then WOLFTPM_HW_SELECTED=yes @@ -284,7 +300,7 @@ fi # SW TPM device Support AC_ARG_ENABLE([swtpm], - [AS_HELP_STRING([--enable-swtpm],[Enable use of TPM through the SW socket driver (default: enabled on Linux x86_64/aarch64, disabled elsewhere or when any --enable-/--enable-spi/--enable-i2c/--enable-mmio/--enable-devtpm/--enable-autodetect is explicitly set)])], + [AS_HELP_STRING([--enable-swtpm],[Enable use of TPM through the SW socket driver (default: enabled on Linux x86_64/aarch64, disabled elsewhere or when any --enable-/--enable-spi/--enable-i2c/--enable-mmio/--enable-devtpm/--enable-pikeos/--enable-autodetect is explicitly set)])], [ ENABLED_SWTPM=$enableval ], [ ENABLED_SWTPM=$WOLFTPM_DEFAULT_SWTPM ] ) @@ -306,6 +322,10 @@ then then AC_MSG_ERROR([Cannot enable both swtpm and devtpm]) fi + if test "x$ENABLED_PIKEOS" = "xyes" + then + AC_MSG_ERROR([Cannot enable both swtpm and pikeos]) + fi AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_SWTPM" @@ -345,7 +365,7 @@ AC_SUBST([DISTCHECK_SWTPM_PORT_FLAG]) # Firmware TPM (fwTPM) - software TPM 2.0 simulator AC_ARG_ENABLE([fwtpm], - [AS_HELP_STRING([--enable-fwtpm],[Enable firmware TPM (fwTPM) server (default: enabled on Linux x86_64/aarch64, disabled elsewhere or when any --enable-/--enable-spi/--enable-i2c/--enable-mmio/--enable-devtpm/--enable-autodetect is explicitly set)])], + [AS_HELP_STRING([--enable-fwtpm],[Enable firmware TPM (fwTPM) server (default: enabled on Linux x86_64/aarch64, disabled elsewhere or when any --enable-/--enable-spi/--enable-i2c/--enable-mmio/--enable-devtpm/--enable-pikeos/--enable-autodetect is explicitly set)])], [ ENABLED_FWTPM=$enableval ], [ ENABLED_FWTPM=$WOLFTPM_DEFAULT_FWTPM ] ) @@ -1253,6 +1273,7 @@ SPI_ACTUAL=yes if test "x$ENABLED_I2C" = "xyes" || \ test "x$ENABLED_SWTPM" = "xyes" || test "x$ENABLED_SWTPM" = "xuart" || \ test "x$ENABLED_DEVTPM" = "xyes" || \ + test "x$ENABLED_PIKEOS" = "xyes" || \ test "x$ENABLED_WINAPI" = "xyes" then SPI_ACTUAL=no @@ -1260,6 +1281,7 @@ fi echo " * SPI: $SPI_ACTUAL" echo " * I2C: $ENABLED_I2C" echo " * Linux kernel TPM device: $ENABLED_DEVTPM" +echo " * PikeOS TPM driver: $ENABLED_PIKEOS" echo " * SWTPM: $ENABLED_SWTPM" if test "x$ENABLED_SWTPM" = "xyes"; then echo " * SWTPM Port: $SWTPM_PORT" diff --git a/docs/build-options.md b/docs/build-options.md index 4145ff986..7a78e2bdd 100644 --- a/docs/build-options.md +++ b/docs/build-options.md @@ -75,6 +75,7 @@ Selecting an Infineon device with its argument looks like this: | Option | Default | Effect and macros | | --- | --- | --- | | `--enable-devtpm` | disabled | Use the Linux kernel driver (`/dev/tpmrm0` or `/dev/tpm0`). Defines `WOLFTPM_LINUX_DEV`. Cannot be combined with swTPM. | +| `--enable-pikeos` | disabled | Use the PikeOS TPM driver through its file provider (`vm_open`/`vm_write`/`vm_read`). Defines `WOLFTPM_PIKEOS`. The device defaults to `/dev/tpm0`; override with `-DTPM2_PIKEOS_DEV="..."`. The application must call `vm_init()` first. PikeOS native has no `ssize_t`, so build the examples with `-DNO_FILESYSTEM`. Cannot be combined with swTPM or devtpm. | | `--enable-swtpm` | see below | Talk to a simulator over the swtpm TCP protocol. Defines `WOLFTPM_SWTPM` and `TPM2_SWTPM_PORT`. | | `--enable-swtpm=uart` | disabled | swtpm protocol over a UART serial port, for fwTPM on embedded targets such as STM32H5. Defines `WOLFTPM_SWTPM`, `WOLFTPM_SWTPM_UART` and `TPM2_SWTPM_PORT`, where the port value is the baud rate (default 115200). | | `--with-swtpm-port=PORT` | 2321 | Sets `TPM2_SWTPM_PORT`. For `--enable-swtpm=uart` it sets the baud rate instead. | @@ -88,7 +89,7 @@ Selecting an Infineon device with its argument looks like this: - the host CPU is x86_64, amd64 or aarch64; - the host OS is not Windows (mingw, cygwin, msys, win32); - wolfCrypt is enabled; -- no hardware path was selected with any of `--enable-spi`, `--enable-i2c`, `--enable-mmio`, `--enable-devtpm`, `--enable-autodetect`, `--enable-winapi`, `--enable-infineon`, `--enable-st`, `--enable-st33`, `--enable-microchip`, `--enable-nuvoton`, `--enable-nations` or `--enable-sealsq`. +- no hardware path was selected with any of `--enable-spi`, `--enable-i2c`, `--enable-mmio`, `--enable-devtpm`, `--enable-pikeos`, `--enable-autodetect`, `--enable-winapi`, `--enable-infineon`, `--enable-st`, `--enable-st33`, `--enable-microchip`, `--enable-nuvoton`, `--enable-nations` or `--enable-sealsq`. This applies to macOS and BSD as well as Linux. Everywhere else the default is off. diff --git a/docs/getting-started.md b/docs/getting-started.md index 814ce6398..0771eb2e6 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -31,7 +31,7 @@ make ``` !!! note - On any non-Windows x86_64/aarch64 host (Linux, macOS, or BSD), a bare `./configure` automatically enables the software TPM backends (swTPM and fwTPM). This lets `make check` run without any TPM hardware attached. Selecting a hardware path turns this default off: any `--enable-`, or `--enable-spi`, `--enable-i2c`, `--enable-mmio`, `--enable-devtpm`, `--enable-autodetect`, `--enable-winapi`, or `--enable-wintbs`. See [System Interfaces](system-interfaces.md). + On any non-Windows x86_64/aarch64 host (Linux, macOS, or BSD), a bare `./configure` automatically enables the software TPM backends (swTPM and fwTPM). This lets `make check` run without any TPM hardware attached. Selecting a hardware path turns this default off: any `--enable-`, or `--enable-spi`, `--enable-i2c`, `--enable-mmio`, `--enable-devtpm`, `--enable-pikeos`, `--enable-autodetect`, `--enable-winapi`, or `--enable-wintbs`. See [System Interfaces](system-interfaces.md). For hardware specific build steps, see [Supported Hardware](supported-hardware.md). diff --git a/docs/hal-io-callback.md b/docs/hal-io-callback.md index 0e0bafeb0..383b7aa54 100644 --- a/docs/hal-io-callback.md +++ b/docs/hal-io-callback.md @@ -8,6 +8,7 @@ The available system TPM interfaces are: * Linux `/dev/tpm0`: enabled with `WOLFTPM_LINUX_DEV` or `--enable-devtpm`. * Windows TBS: enabled with `WOLFTPM_WINAPI` or `--enable-winapi`. +* PikeOS TPM driver: enabled with `WOLFTPM_PIKEOS` or `--enable-pikeos`. * Software TPM simulator: enabled with `WOLFTPM_SWTPM` or `--enable-swtpm`. If you use a HAL IO callback, it is registered on library initialization with: diff --git a/examples/tpm_test.h b/examples/tpm_test.h index 765dfaac6..cfbc8f33d 100644 --- a/examples/tpm_test.h +++ b/examples/tpm_test.h @@ -117,6 +117,8 @@ static const char pemFileKey[] = PEM_FILE_KEY; #include "system/time/sys_time.h" #elif defined(WOLFTPM_ZEPHYR) #include +#elif defined(WOLFTPM_PIKEOS) + #include #else #include #endif @@ -139,6 +141,10 @@ static const char pemFileKey[] = PEM_FILE_KEY; #elif defined(WOLFTPM_ZEPHYR) (void)reset; return (double)k_uptime_get() / 1000.0; + #elif defined(WOLFTPM_PIKEOS) + P4_time_t now = p4_get_time(); /* nanoseconds since boot */ + (void)reset; + return (double)now / 1000000000.0; #else struct timeval tv; gettimeofday(&tv, 0); diff --git a/hal/tpm_io.c b/hal/tpm_io.c index ade038c9a..245748e6d 100644 --- a/hal/tpm_io.c +++ b/hal/tpm_io.c @@ -46,7 +46,8 @@ /* Native Windows, native Linux and TPM Simulator do not need an IO callback */ #if ! (defined(WOLFTPM_LINUX_DEV) || \ defined(WOLFTPM_SWTPM) || \ - defined(WOLFTPM_WINAPI) ) && \ + defined(WOLFTPM_WINAPI) || \ + defined(WOLFTPM_PIKEOS) ) && \ (defined(WOLFTPM_EXAMPLE_HAL) || defined(WOLFTPM_MMIO) || \ defined(WOLFTPM_FWTPM_HAL)) diff --git a/hal/tpm_io.h b/hal/tpm_io.h index 1d4da11be..65a7096a7 100644 --- a/hal/tpm_io.h +++ b/hal/tpm_io.h @@ -57,7 +57,7 @@ */ #if defined(WOLFTPM_LINUX_DEV) || defined(WOLFTPM_SWTPM) || \ - defined(WOLFTPM_WINAPI) + defined(WOLFTPM_WINAPI) || defined(WOLFTPM_PIKEOS) /* HAL not required, so use NULL */ #define TPM2_IoCb NULL diff --git a/src/include.am b/src/include.am index c07f4a75e..c774b05d3 100644 --- a/src/include.am +++ b/src/include.am @@ -15,7 +15,8 @@ src_libwolftpm_la_SOURCES = \ src/tpm2_crypto.c \ src/tpm2_param_enc.c \ src/tpm2_cryptocb.c \ - src/tpm2_linux.c + src/tpm2_linux.c \ + src/tpm2_pikeos.c if BUILD_SWTPM src_libwolftpm_la_SOURCES += src/tpm2_swtpm.c endif diff --git a/src/tpm2.c b/src/tpm2.c index 8f74566a8..65f786c69 100644 --- a/src/tpm2.c +++ b/src/tpm2.c @@ -38,6 +38,9 @@ #ifdef WOLFTPM_WINAPI #include #endif +#ifdef WOLFTPM_PIKEOS + #include +#endif #include #ifdef WOLFTPM_SPDM #include @@ -81,6 +84,9 @@ static THREAD_LS_T TPM2_CTX* gActiveTPM; #elif defined(WOLFTPM_WINAPI) #define INTERNAL_SEND_COMMAND TPM2_WinApi_SendCommand #define TPM2_INTERNAL_CLEANUP(ctx) TPM2_WinApi_Cleanup(ctx) +#elif defined(WOLFTPM_PIKEOS) +#define INTERNAL_SEND_COMMAND TPM2_PIKEOS_SendCommand +#define TPM2_INTERNAL_CLEANUP(ctx) TPM2_PIKEOS_Cleanup(ctx) #else #define INTERNAL_SEND_COMMAND TPM2_TIS_SendCommand #define TPM2_INTERNAL_CLEANUP(ctx) @@ -1072,7 +1078,7 @@ TPM_RC TPM2_Init_ex(TPM2_CTX* ctx, TPM2HalIoCb ioCb, void* userCtx, #endif #if defined(WOLFTPM_LINUX_DEV) || defined(WOLFTPM_SWTPM) || \ - defined(WOLFTPM_WINAPI) + defined(WOLFTPM_WINAPI) || defined(WOLFTPM_PIKEOS) if (ioCb != NULL || userCtx != NULL) { rc = BAD_FUNC_ARG; goto exit; diff --git a/src/tpm2_pikeos.c b/src/tpm2_pikeos.c new file mode 100644 index 000000000..75e74091f --- /dev/null +++ b/src/tpm2_pikeos.c @@ -0,0 +1,106 @@ +/* tpm2_pikeos.c + * + * Copyright (C) 2006-2026 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 3 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 + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifdef WOLFTPM_PIKEOS +#include + +/* The PikeOS TPM driver is reached through a file provider that takes a + * complete TPM command per vm_write and returns the complete response per + * vm_read. The task must have called vm_init() before the first command. */ +#ifndef TPM2_PIKEOS_DEV + #define TPM2_PIKEOS_DEV "/dev/tpm0" +#endif + +int TPM2_PIKEOS_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet) +{ + P4_e_t e; + P4_size_t written = 0; + P4_size_t readSz = 0; + + if (ctx == NULL || packet == NULL) { + return BAD_FUNC_ARG; + } + + if (!ctx->pikeosCtx.isOpen) { + e = vm_open(TPM2_PIKEOS_DEV, VM_O_RD_WR, &ctx->pikeosCtx.fd); + if (e != P4_E_OK) { + #ifdef DEBUG_WOLFTPM + printf("Failed to open %s: %d\n", TPM2_PIKEOS_DEV, (int)e); + #endif + return TPM_RC_FAILURE; + } + ctx->pikeosCtx.isOpen = 1; + } + +#ifdef WOLFTPM_DEBUG_VERBOSE + printf("Command size: %d\n", packet->pos); + TPM2_PrintBin(packet->buf, packet->pos); +#endif + + e = vm_write(&ctx->pikeosCtx.fd, packet->buf, (P4_size_t)packet->pos, + &written); + if (e != P4_E_OK || written != (P4_size_t)packet->pos) { + #ifdef DEBUG_WOLFTPM + printf("Failed write to %s: %d\n", TPM2_PIKEOS_DEV, (int)e); + #endif + return TPM_RC_FAILURE; + } + + e = vm_read(&ctx->pikeosCtx.fd, packet->buf, (P4_size_t)packet->size, + &readSz); + /* The caller parses the TPM_Packet for correctness */ + if (e != P4_E_OK || readSz < TPM2_HEADER_SIZE) { + #ifdef DEBUG_WOLFTPM + printf("Failed read from %s: %d (size %d)\n", TPM2_PIKEOS_DEV, + (int)e, (int)readSz); + #endif + return TPM_RC_FAILURE; + } + +#ifdef WOLFTPM_DEBUG_VERBOSE + printf("Response size: %d\n", (int)readSz); + TPM2_PrintBin(packet->buf, (int)readSz); +#endif + + return TPM_RC_SUCCESS; +} + +int TPM2_PIKEOS_Cleanup(TPM2_CTX* ctx) +{ + int rc = TPM_RC_SUCCESS; + + if (ctx != NULL && ctx->pikeosCtx.isOpen) { + if (vm_close(&ctx->pikeosCtx.fd) != P4_E_OK) { + rc = TPM_RC_FAILURE; + } + ctx->pikeosCtx.isOpen = 0; + } + + return rc; +} + +#endif /* WOLFTPM_PIKEOS */ diff --git a/src/tpm2_spdm.c b/src/tpm2_spdm.c index b9c5e5322..616b19f08 100644 --- a/src/tpm2_spdm.c +++ b/src/tpm2_spdm.c @@ -44,7 +44,7 @@ /* TIS functions for SPI/I2C TPM transport */ #if defined(WOLFTPM_SPDM_TCG) && \ !defined(WOLFTPM_LINUX_DEV) && !defined(WOLFTPM_SWTPM) && \ - !defined(WOLFTPM_WINAPI) + !defined(WOLFTPM_WINAPI) && !defined(WOLFTPM_PIKEOS) #include #include #define WOLFTPM_SPDM_TIS_IO diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index 13d027868..9346dcaa3 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -129,7 +129,7 @@ static int wolfTPM2_Init_ex(TPM2_CTX* ctx, TPM2HalIoCb ioCb, void* userCtx, /* Fall through to Startup/SelfTest below */ #elif defined(WOLFTPM_LINUX_DEV) || defined(WOLFTPM_SWTPM) || \ - defined(WOLFTPM_WINAPI) + defined(WOLFTPM_WINAPI) || defined(WOLFTPM_PIKEOS) rc = TPM2_Init_minimal(ctx); /* Using standard file I/O for the Linux TPM device */ (void)ioCb; @@ -7298,8 +7298,10 @@ int wolfTPM2_ResetPCR(WOLFTPM2_DEV* dev, int pcrIndex) int wolfTPM2_SetLocality(WOLFTPM2_DEV* dev, int locality) { -#if defined(WOLFTPM_LINUX_DEV) || defined(WOLFTPM_WINAPI) - /* The Linux kernel driver and Windows TBS own the TPM locality */ +#if defined(WOLFTPM_LINUX_DEV) || defined(WOLFTPM_WINAPI) || \ + defined(WOLFTPM_PIKEOS) + /* The Linux kernel driver, Windows TBS and PikeOS driver own the TPM + * locality */ (void)dev; (void)locality; return NOT_COMPILED_IN; @@ -12337,7 +12339,7 @@ static int tpm2_ifx_firmware_start(WOLFTPM2_DEV* dev, TPM_ALG_ID hashAlg, * since TPM reset into firmware upgrade mode */ #if !defined(WOLFTPM_LINUX_DEV) && !defined(WOLFTPM_SWTPM) && \ - !defined(WOLFTPM_WINAPI) + !defined(WOLFTPM_WINAPI) && !defined(WOLFTPM_PIKEOS) /* Do chip startup and request locality again */ #ifdef WOLFTPM_LINUX_DEV_AUTODETECT if (dev->ctx.fd < 0) /* Only needed for SPI path */ @@ -12453,7 +12455,7 @@ static int tpm2_ifx_firmware_data(WOLFTPM2_DEV* dev, XSLEEP_MS(300); #if !defined(WOLFTPM_LINUX_DEV) && !defined(WOLFTPM_SWTPM) && \ - !defined(WOLFTPM_WINAPI) + !defined(WOLFTPM_WINAPI) && !defined(WOLFTPM_PIKEOS) /* Do chip startup and request locality again */ #ifdef WOLFTPM_LINUX_DEV_AUTODETECT if (dev->ctx.fd < 0) /* Only needed for SPI path */ @@ -12983,7 +12985,7 @@ static int tpm2_st33_firmware_start_common(WOLFTPM2_DEV* dev, XSLEEP_MS(300); #if !defined(WOLFTPM_LINUX_DEV) && !defined(WOLFTPM_SWTPM) && \ - !defined(WOLFTPM_WINAPI) + !defined(WOLFTPM_WINAPI) && !defined(WOLFTPM_PIKEOS) /* Do chip startup and request locality again */ #ifdef WOLFTPM_LINUX_DEV_AUTODETECT if (dev->ctx.fd < 0) /* Only needed for SPI path */ @@ -13108,7 +13110,7 @@ static int tpm2_st33_firmware_data(WOLFTPM2_DEV* dev, TPM_CC ccData, XSLEEP_MS(300); #if !defined(WOLFTPM_LINUX_DEV) && !defined(WOLFTPM_SWTPM) && \ - !defined(WOLFTPM_WINAPI) + !defined(WOLFTPM_WINAPI) && !defined(WOLFTPM_PIKEOS) /* Do chip startup and request locality again */ #ifdef WOLFTPM_LINUX_DEV_AUTODETECT if (dev->ctx.fd < 0) /* Only needed for SPI path */ diff --git a/wolftpm/include.am b/wolftpm/include.am index 713eea2ca..47a9b0fe3 100644 --- a/wolftpm/include.am +++ b/wolftpm/include.am @@ -9,6 +9,7 @@ nobase_include_HEADERS+= \ wolftpm/tpm2_types.h \ wolftpm/tpm2_wrap.h \ wolftpm/tpm2_linux.h \ + wolftpm/tpm2_pikeos.h \ wolftpm/tpm2_swtpm.h \ wolftpm/tpm2_winapi.h \ wolftpm/tpm2_param_enc.h \ diff --git a/wolftpm/tpm2.h b/wolftpm/tpm2.h index 3863f88ce..2b36486dc 100644 --- a/wolftpm/tpm2.h +++ b/wolftpm/tpm2.h @@ -2243,6 +2243,16 @@ struct wolfTPM_tcpContext { }; #endif /* WOLFTPM_SWTPM */ +#ifdef WOLFTPM_PIKEOS +#include +#include + +struct wolfTPM_pikeosContext { + vm_file_desc_t fd; + int isOpen; +}; +#endif /* WOLFTPM_PIKEOS */ + #ifdef WOLFTPM_WINAPI #include #include @@ -2327,6 +2337,9 @@ typedef struct TPM2_CTX { #ifdef WOLFTPM_WINAPI struct wolfTPM_winContext winCtx; #endif +#ifdef WOLFTPM_PIKEOS + struct wolfTPM_pikeosContext pikeosCtx; +#endif #ifndef WOLFTPM2_NO_WOLFCRYPT #ifdef WOLFTPM2_USE_WOLF_RNG WC_RNG rng; diff --git a/wolftpm/tpm2_pikeos.h b/wolftpm/tpm2_pikeos.h new file mode 100644 index 000000000..a215d9b83 --- /dev/null +++ b/wolftpm/tpm2_pikeos.h @@ -0,0 +1,46 @@ +/* tpm2_pikeos.h + * + * Copyright (C) 2006-2026 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 3 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 + */ + +#ifndef _TPM2_PIKEOS_H_ +#define _TPM2_PIKEOS_H_ + +#ifdef WOLFTPM_PIKEOS + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* TPM2 IO for using TPM through a PikeOS file provider (vm_open/vm_read) */ +WOLFTPM_LOCAL int TPM2_PIKEOS_SendCommand(TPM2_CTX* ctx, TPM2_Packet* packet); + +/* Close the PikeOS TPM device */ +WOLFTPM_LOCAL int TPM2_PIKEOS_Cleanup(TPM2_CTX* ctx); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFTPM_PIKEOS */ + +#endif /* _TPM2_PIKEOS_H_ */ diff --git a/wolftpm/tpm2_types.h b/wolftpm/tpm2_types.h index d5d97557c..1a4097cad 100644 --- a/wolftpm/tpm2_types.h +++ b/wolftpm/tpm2_types.h @@ -622,7 +622,8 @@ typedef int64_t INT64; #endif #ifndef TPM_TIMEOUT_TRIES - #if defined(WOLFTPM_LINUX_DEV) || defined(WOLFTPM_SWTPM) || defined(WOLFTPM_WINAPI) + #if defined(WOLFTPM_LINUX_DEV) || defined(WOLFTPM_SWTPM) || \ + defined(WOLFTPM_WINAPI) || defined(WOLFTPM_PIKEOS) #define TPM_TIMEOUT_TRIES 0 #else #define TPM_TIMEOUT_TRIES 1000000 @@ -715,6 +716,9 @@ typedef int64_t INT64; #elif defined(WOLFSSL_ESPIDF) #include #define XSLEEP_MS(ms) esp_rom_delay_us((word32)(ms) * 1000U) + #elif defined(WOLFTPM_PIKEOS) + #include + #define XSLEEP_MS(ms) p4_sleep(P4_MSEC(ms)) #elif defined(__linux__) || defined(__ARM_EABI__) #include #define XSLEEP_MS(ms) do { \ @@ -769,6 +773,11 @@ typedef int64_t INT64; #include #define XTPM_GET_TIMEMS() ((word32)GetTickCount64()) #define WOLFTPM_HAVE_MONOTONIC_MS + #elif defined(WOLFTPM_PIKEOS) + #include + /* p4_get_time() is nanoseconds since boot */ + #define XTPM_GET_TIMEMS() ((word32)(p4_get_time() / 1000000ULL)) + #define WOLFTPM_HAVE_MONOTONIC_MS #else /* Include first, then feature-test: strict C99 may not expose * CLOCK_MONOTONIC, and __linux__ alone would fail to compile. */