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
19 changes: 13 additions & 6 deletions .github/workflows/cmake-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,9 @@ jobs:
fi

# Verify that a static-library build can be installed and its exported
# CMake targets are self-consistent. The matrix builds above use
# WITH_WOLFSSL (shared library) and do not catch this because CMake only
# enforces export-set completeness for static libraries: any CMake target
# in a static library's PRIVATE link chain must be exported or wrapped in
# $<BUILD_INTERFACE:...>.
# CMake targets are self-consistent. The TIS build also verifies that an
# installed package resolves imported static-link dependencies before its
# exported target is loaded by a downstream project.
cmake-static-export:
name: CMake static export check
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
Expand Down Expand Up @@ -269,10 +267,19 @@ jobs:
cmake \
-DBUILD_SHARED_LIBS=OFF \
-DWOLFTPM_EXAMPLES=no \
-DWOLFTPM_FWTPM=no \
-DWOLFTPM_FWTPM=yes \
-DWOLFTPM_INTERFACE=SPI \
-DWOLFTPM_BUILD_OUT_OF_TREE=yes \
-DCMAKE_C_FLAGS="-DWOLFSSL_AES_CFB -DWOLFSSL_PUBLIC_MP" \
-DCMAKE_PREFIX_PATH="$GITHUB_WORKSPACE/install" \
-DCMAKE_INSTALL_PREFIX="$GITHUB_WORKSPACE/install" \
..
cmake --build . --parallel
cmake --install .

- name: Configure installed static consumer
run: |
cmake \
-S tests/cmake_static_consumer \
-B build-static-consumer \
-DCMAKE_PREFIX_PATH="$GITHUB_WORKSPACE/install"
11 changes: 10 additions & 1 deletion .github/workflows/fwtpm-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
# fwTPM with TIS/shared-memory transport
- name: fwtpm-tis
os: ubuntu-latest
wolftpm_config: --enable-fwtpm --enable-debug
wolftpm_config: --enable-fwtpm --disable-swtpm --enable-debug
wolfssl_config: --enable-wolftpm --enable-pkcallbacks --enable-keygen
build_only: false

Expand Down Expand Up @@ -254,6 +254,15 @@ jobs:
cc: clang
make_cflags: "-Wall -Wextra -Wpedantic -Werror -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wformat=2"

# Build-only: pedantic warnings on the POSIX TIS transport and its
# dedicated HAL/semaphore tests.
- name: fwtpm-pedantic-tis
os: ubuntu-latest
wolftpm_config: --enable-fwtpm --disable-swtpm
wolfssl_config: --enable-wolftpm --enable-pkcallbacks --enable-keygen
build_only: true
make_cflags: "-Wall -Wextra -Wpedantic -Werror -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wformat=2"

# Build-only: pedantic fwTPM-only (no client library)
- name: fwtpm-pedantic-only
os: ubuntu-latest
Expand Down
36 changes: 29 additions & 7 deletions .github/workflows/spdm-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ on:
permissions: read-all

jobs:
# Build-only matrix: every supported SPDM configure permutation compiles
# cleanly. Catches missing `#ifdef WOLFTPM_SPDM_*` guards in headers/sources
# and per-mode include.am gating regressions.
# Build matrix: every supported SPDM configure permutation compiles cleanly;
# the single-vendor entries also smoke-test unavailable-adapter rejection.
# Catches missing `#ifdef WOLFTPM_SPDM_*` guards and include.am gating.
build-only:
runs-on: ubuntu-latest
timeout-minutes: 15
Expand All @@ -36,6 +36,8 @@ jobs:
fail-fast: false
matrix:
include:
- name: spdm-base-only
wolftpm_config: "--enable-spdm --disable-fwtpm --disable-tcg --disable-psk"
- name: spdm-tcg-only
wolftpm_config: "--enable-fwtpm --enable-spdm --enable-tcg --disable-psk"
- name: spdm-both
Expand All @@ -50,6 +52,8 @@ jobs:
wolftpm_config: "--enable-spdm --enable-nuvoton --enable-nations"
- name: spdm-debug-on
wolftpm_config: "--enable-fwtpm --enable-spdm --enable-tcg --enable-psk --enable-debug"
- name: spdm-no-getenv
wolftpm_config: "--enable-fwtpm --enable-spdm --enable-tcg --enable-psk CFLAGS=-DNO_GETENV"

steps:
- name: Harden Runner
Expand All @@ -76,10 +80,28 @@ jobs:
--with-wolfcrypt=$HOME/wolfssl-install
make -j"$(nproc)"

- name: Test unavailable vendor rejection (${{ matrix.name }})
if: matrix.name == 'spdm-nuvoton' || matrix.name == 'spdm-nations'
run: |
set -eo pipefail
if [ "${{ matrix.name }}" = "spdm-nuvoton" ]; then
vendor=nations
expected="Nations adapter is not available in this build"
else
vendor=nuvoton
expected="Nuvoton adapter is not available in this build"
fi
if output=$(./examples/spdm/spdm_ctrl \
"--vendor=$vendor" --status 2>&1); then
echo "Expected unavailable vendor rejection"
exit 1
fi
grep -F "$expected" <<< "$output"

# End-to-end matrix: same protocol coverage as the old hw-spdm-test, but
# against fwtpm_server instead of real silicon. fwtpm-tcg mirrors the
# Nuvoton 6-step sequence (status, connect, lock, unit.test, unlock,
# cleartext caps). fwtpm-psk mirrors the Nations-PSK 10-step sequence.
# against fwtpm_server instead of real silicon. fwtpm-tcg covers pinned and
# rejected initialization, the full unit suite over SPDM, lock/status/caps,
# unlock, and cleartext recovery. fwtpm-psk mirrors the Nations-PSK flow.
e2e:
runs-on: ubuntu-latest
timeout-minutes: 25
Expand Down Expand Up @@ -150,5 +172,5 @@ jobs:
config.log
test-suite.log
tests/*.log
/tmp/fwtpm_spdm_test.log
/tmp/fwtpm_spdm_test.*
retention-days: 14
75 changes: 70 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,27 @@ if(WOLFTPM_FWTPM_ONLY)
list(APPEND WOLFTPM_DEFINITIONS "-DWOLFTPM2_NO_WRAPPER")
endif()

set(WOLFTPM_FWTPM_THREAD_LIBS)
set(WOLFTPM_FWTPM_TIS_LIBS)
if(WOLFTPM_FWTPM AND UNIX)
find_package(Threads REQUIRED)
list(APPEND WOLFTPM_FWTPM_THREAD_LIBS Threads::Threads)
if(WOLFTPM_FWTPM_TIS)
set(WOLFTPM_FWTPM_TIS_LIBS ${WOLFTPM_FWTPM_THREAD_LIBS})
if(NOT APPLE)
include(CheckLibraryExists)
check_library_exists(rt sem_open "" WOLFTPM_FWTPM_HAVE_LIBRT)
if(WOLFTPM_FWTPM_HAVE_LIBRT)
list(APPEND WOLFTPM_FWTPM_TIS_LIBS rt)
endif()
endif()
endif()
endif()

if(WOLFTPM_FWTPM_TIS AND BUILD_WOLFTPM_LIB AND UNIX)
target_link_libraries(wolftpm PRIVATE ${WOLFTPM_FWTPM_TIS_LIBS})
endif()

# Examples
set(WOLFTPM_EXAMPLES "yes" CACHE BOOL
"Build examples")
Expand Down Expand Up @@ -541,9 +562,12 @@ if(WOLFTPM_FWTPM)
${CMAKE_CURRENT_BINARY_DIR}
)
if(UNIX)
target_link_libraries(fwtpm_server PRIVATE pthread)
if(NOT APPLE)
target_link_libraries(fwtpm_server PRIVATE rt)
if(WOLFTPM_FWTPM_TIS)
target_link_libraries(fwtpm_server PRIVATE
${WOLFTPM_FWTPM_TIS_LIBS})
else()
target_link_libraries(fwtpm_server PRIVATE
${WOLFTPM_FWTPM_THREAD_LIBS})
endif()
elseif(WIN32)
target_link_libraries(fwtpm_server PRIVATE ws2_32)
Expand All @@ -556,6 +580,7 @@ if(WOLFTPM_FWTPM)
)
target_compile_definitions(fwtpm_unit_test PRIVATE
"WOLFTPM_FWTPM"
"WOLFTPM_FWTPM_UNIT_TEST"
"FWTPM_NV_FILE=\"fwtpm_test_nv.bin\""
)
if(WOLFTPM_FWTPM_NV_APPEND_ONLY)
Expand All @@ -567,7 +592,28 @@ if(WOLFTPM_FWTPM)
${CMAKE_CURRENT_BINARY_DIR}
)
if(UNIX)
target_link_libraries(fwtpm_unit_test PRIVATE pthread)
target_link_libraries(fwtpm_unit_test PRIVATE
${WOLFTPM_FWTPM_THREAD_LIBS})
endif()

if(WOLFTPM_FWTPM_TIS)
add_executable(fwtpm_hal_unit_test
tests/fwtpm_hal_unit_tests.c
)
target_compile_definitions(fwtpm_hal_unit_test PRIVATE
"WOLFTPM_FWTPM_HAL"
"WOLFTPM_ADV_IO"
"WOLFTPM_EXAMPLE_HAL"
)
target_link_libraries(fwtpm_hal_unit_test PRIVATE wolftpm_wolfssl_dep)
target_include_directories(fwtpm_hal_unit_test PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
if(UNIX)
target_link_libraries(fwtpm_hal_unit_test PRIVATE
${WOLFTPM_FWTPM_TIS_LIBS})
endif()
endif()

# fwTPM fuzz target (libFuzzer)
Expand Down Expand Up @@ -595,6 +641,12 @@ if(WOLFTPM_FWTPM)
COMMAND fwtpm_unit_test
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
if(WOLFTPM_FWTPM_TIS)
add_test(NAME fwtpm_hal_unit_test
COMMAND fwtpm_hal_unit_test
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
endif()

message(STATUS "fwTPM server: enabled")
if(WOLFTPM_FWTPM_TIS)
Expand Down Expand Up @@ -764,6 +816,17 @@ endif()
include(GNUInstallDirs)

if(BUILD_WOLFTPM_LIB)
include(CMakePackageConfigHelpers)
set(WOLFTPM_CONFIG_NEEDS_THREADS OFF)
if(WOLFTPM_FWTPM_TIS AND UNIX)
set(WOLFTPM_CONFIG_NEEDS_THREADS ON)
endif()
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/wolftpm-config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/wolftpm-config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/wolftpm"
)

# Note: wolftpm_wolfssl_dep is an INTERFACE helper used only at build
# time to share wolfSSL include/link settings. It is intentionally NOT
# installed/exported — downstream `find_package(wolftpm)` should only
Expand All @@ -778,8 +841,10 @@ if(BUILD_WOLFTPM_LIB)
# Install the export set
install(EXPORT wolftpm-targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wolftpm
FILE wolftpm-config.cmake
FILE wolftpm-targets.cmake
NAMESPACE wolfssl::)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/wolftpm-config.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wolftpm)
endif()

# Install fwTPM server
Expand Down
8 changes: 8 additions & 0 deletions cmake/wolftpm-config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@PACKAGE_INIT@

include(CMakeFindDependencyMacro)
if(@WOLFTPM_CONFIG_NEEDS_THREADS@)
find_dependency(Threads)
endif()

include("${CMAKE_CURRENT_LIST_DIR}/wolftpm-targets.cmake")
19 changes: 19 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,25 @@ then
fi
fi

# POSIX TIS/shared-memory consumers need the platform's semaphore link flags.
# Keep these target-scoped instead of adding them to LIBS.
FWTPM_TIS_LIBS=""
if test "x$ENABLED_FWTPM_TIS" = "xyes"
then
fwtpm_tis_saved_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_SEARCH_LIBS([sem_open], [rt pthread], [
AS_IF([test "x$ac_cv_search_sem_open" != "xnone required"], [
FWTPM_TIS_LIBS="$FWTPM_TIS_LIBS $ac_cv_search_sem_open"
])
], [
AC_MSG_ERROR([fwTPM TIS transport requires POSIX sem_open])
])
LIBS="$fwtpm_tis_saved_LIBS"
FWTPM_TIS_LIBS="$PTHREAD_LIBS $FWTPM_TIS_LIBS"
fi
AC_SUBST([FWTPM_TIS_LIBS])

# Append-only NV journal for write-once flash fwTPM ports (opt-in)
AC_ARG_ENABLE([fwtpm-nv-appendonly],
[AS_HELP_STRING([--enable-fwtpm-nv-appendonly],[Enable the append-only NV journal mode for write-once flash fwTPM ports (default: disabled)])],
Expand Down
16 changes: 13 additions & 3 deletions docs/FWTPM.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ wolfTPM fwTPM Server v0.1.0
Model: fwTPM
```

In `--spdm-tcg` test mode the server also prints its generated responder
public key. This is a local test-harness convenience, not a provisioning or
trust-anchor channel for hardware responders.

### Connecting wolfTPM Clients

Any wolfTPM application built with `--enable-swtpm` connects to the fwTPM
Expand Down Expand Up @@ -643,7 +647,8 @@ disabled, the corresponding TPM commands are excluded from the build.
| `NO_RSA` | not defined | Excludes RSA keygen, sign, verify, `RSA_Encrypt`, `RSA_Decrypt` |
| `HAVE_ECC` | defined | Enables ECC keygen, sign, verify, `ECDH_KeyGen`, `ECDH_ZGen`, `ECC_Parameters` |
| `HAVE_ECC384` | defined | Enables P-384 curve support |
| `HAVE_ECC521` | defined | Enables P-521 curve support |
| `HAVE_ECC521` or `HAVE_ALL_CURVES` | build-dependent | Enables P-521 when `MAX_ECC_KEY_BITS >= 521` provides 66-byte TPM ECC fields |
| `ECC_MIN_KEY_SZ` | wolfCrypt-defined | Excludes smaller curves from `ECC_Parameters` and `TPM_CAP_ECC_CURVES` |
| `NO_AES` | not defined | Excludes `EncryptDecrypt`, `EncryptDecrypt2`, AES parameter encryption |
| `WOLFSSL_SHA384` | defined | Enables SHA-384 PCR bank |

Expand Down Expand Up @@ -749,7 +754,7 @@ register-level access. This mode simulates an SPI-attached TPM.

| Field | Description |
|-------|-------------|
| `magic` / `version` | Validation header (`0x57544953` / `"WTIS"`) |
| `magic` / `version` | Validation header (`0x57544953` / `"WTIS"`, protocol version 2) |
| `reg_addr`, `reg_len`, `reg_is_write`, `reg_data` | Register access request |
| TIS register shadow: `access`, `sts`, `int_enable`, `int_status`, `intf_caps`, `did_vid`, `rid` | Emulated TIS registers |
| `cmd_buf[4096]`, `cmd_len`, `fifo_write_pos` | Command FIFO |
Expand All @@ -759,10 +764,15 @@ register-level access. This mode simulates an SPI-attached TPM.

| Define | Default | Description |
|--------|---------|-------------|
| `FWTPM_TIS_SHM_PATH` | `/tmp/fwtpm.shm` | Shared memory file |
| `FWTPM_TIS_SHM_PATH` | `/tmp/fwtpm.shm` | Shared memory file; clients require a regular, single-link, same-UID, exact-size `0600` endpoint |
| `FWTPM_TIS_SEM_CMD` | `/fwtpm_cmd` | Command semaphore name |
| `FWTPM_TIS_SEM_RSP` | `/fwtpm_rsp` | Response semaphore name |

Clients require an exact protocol version and shared-region-size match, so
rebuild the client library and `fwtpm_server` together when changing options
that affect `FWTPM_TIS_FIFO_SIZE`. The default paths are global, so one server
per host.

**Server-side API:**

- `FWTPM_TIS_Init()` -- Create shared memory and semaphores
Expand Down
Loading
Loading