Skip to content

Commit 03fe730

Browse files
committed
Add fwTPM CMake support. Peer review fixes.
1 parent 578e0d4 commit 03fe730

9 files changed

Lines changed: 243 additions & 44 deletions

File tree

.github/workflows/cmake-build.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ jobs:
8484
# Test combination of options
8585
- name: "Combined Options"
8686
options: "-DWOLFTPM_INTERFACE=I2C -DWOLFTPM_MODULE=st33 -DWOLFTPM_ADVIO=yes -DWOLFTPM_CHECK_WAIT_STATE=yes"
87+
# fwTPM server with socket transport
88+
- name: "fwTPM Socket"
89+
options: "-DWOLFTPM_FWTPM=yes -DWOLFTPM_INTERFACE=SWTPM"
90+
# fwTPM server with TIS/shared-memory transport
91+
- name: "fwTPM TIS"
92+
options: "-DWOLFTPM_FWTPM=yes -DWOLFTPM_INTERFACE=SPI"
93+
# fwTPM server-only mode (no client library or examples)
94+
- name: "fwTPM Only"
95+
options: "-DWOLFTPM_FWTPM_ONLY=yes -DWOLFTPM_INTERFACE=SWTPM"
8796

8897
steps:
8998
#pull wolfTPM
@@ -107,7 +116,7 @@ jobs:
107116
mkdir build
108117
cd build
109118
# wolfSSL PR 7188 broke "make install" unless WOLFSSL_INSTALL is set
110-
cmake -DWOLFSSL_TPM=yes -DWOLFSSL_INSTALL=yes -DCMAKE_INSTALL_PREFIX="$GITHUB_WORKSPACE/install" ..
119+
cmake -DWOLFSSL_TPM=yes -DWOLFSSL_INSTALL=yes -DCMAKE_INSTALL_PREFIX="$GITHUB_WORKSPACE/install" -DCMAKE_C_FLAGS="-DWC_RSA_NO_PADDING" ..
111120
cmake --build .
112121
cmake --install .
113122
@@ -119,3 +128,9 @@ jobs:
119128
cmake ${{ matrix.config.options }} -DCMAKE_INSTALL_PREFIX="$GITHUB_WORKSPACE/install" -DWITH_WOLFSSL="$GITHUB_WORKSPACE/install" ..
120129
cmake --build .
121130
cmake --install .
131+
132+
- name: Test fwTPM
133+
if: contains(matrix.config.options, 'WOLFTPM_FWTPM')
134+
run: |
135+
cd build
136+
LD_LIBRARY_PATH="$GITHUB_WORKSPACE/install/lib" ctest --output-on-failure

CMakeLists.txt

Lines changed: 214 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,32 @@ project(wolfTPM VERSION 3.10.0 LANGUAGES C)
2626
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
2727
set(WOLFTPM_DEFINITIONS)
2828

29+
# Firmware TPM (fwTPM) server
30+
set(WOLFTPM_FWTPM "no" CACHE STRING
31+
"Enable firmware TPM (fwTPM) server (default: disabled)")
32+
set_property(CACHE WOLFTPM_FWTPM
33+
PROPERTY STRINGS "yes;no")
34+
set(WOLFTPM_FWTPM_ONLY "no" CACHE STRING
35+
"Build only the fwTPM server, skip client library and examples (default: disabled)")
36+
set_property(CACHE WOLFTPM_FWTPM_ONLY
37+
PROPERTY STRINGS "yes;no")
38+
set(WOLFTPM_FWTPM_FUZZ "no" CACHE STRING
39+
"Enable fwTPM fuzz target (requires libFuzzer, default: disabled)")
40+
set_property(CACHE WOLFTPM_FWTPM_FUZZ
41+
PROPERTY STRINGS "yes;no")
42+
43+
# fwtpm-only forces fwtpm on
44+
if(WOLFTPM_FWTPM_ONLY)
45+
set(WOLFTPM_FWTPM "yes" CACHE STRING "" FORCE)
46+
endif()
47+
48+
# Build wolftpm client library unless fwtpm-only mode
49+
if(WOLFTPM_FWTPM_ONLY)
50+
set(BUILD_WOLFTPM_LIB OFF)
51+
else()
52+
set(BUILD_WOLFTPM_LIB ON)
53+
endif()
54+
2955
set(TPM_SOURCES
3056
src/tpm2.c
3157
src/tpm2_linux.c
@@ -45,10 +71,12 @@ set(TPM_SOURCES
4571

4672
# default to build shared library
4773
option(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" ON)
48-
add_library(wolftpm ${TPM_SOURCES})
49-
target_compile_definitions(wolftpm PRIVATE
50-
"BUILDING_WOLFTPM"
51-
)
74+
if(BUILD_WOLFTPM_LIB)
75+
add_library(wolftpm ${TPM_SOURCES})
76+
target_compile_definitions(wolftpm PRIVATE
77+
"BUILDING_WOLFTPM"
78+
)
79+
endif()
5280

5381
include(CheckIncludeFile)
5482
check_include_file("fcntl.h" HAVE_FCNTL_H)
@@ -160,11 +188,11 @@ if("${WOLFTPM_INTERFACE}" STREQUAL "auto")
160188
endif("${WOLFTPM_INTERFACE}" STREQUAL "auto")
161189

162190

163-
if(WIN32)
191+
if(WIN32 AND BUILD_WOLFTPM_LIB)
164192
target_compile_definitions(wolftpm PRIVATE
165193
"WOLFTPM_DLL"
166194
)
167-
endif(WIN32)
195+
endif()
168196

169197
if("${WOLFTPM_INTERFACE}" STREQUAL "SWTPM")
170198
list(APPEND WOLFTPM_DEFINITIONS "-DWOLFTPM_SWTPM")
@@ -179,7 +207,9 @@ elseif("${WOLFTPM_INTERFACE}" STREQUAL "DEVTPM")
179207

180208
elseif("${WOLFTPM_INTERFACE}" STREQUAL "WINAPI")
181209
list(APPEND WOLFTPM_DEFINITIONS "-DWOLFTPM_WINAPI")
182-
target_link_libraries(wolftpm PRIVATE tbs)
210+
if(BUILD_WOLFTPM_LIB)
211+
target_link_libraries(wolftpm PRIVATE tbs)
212+
endif()
183213

184214
elseif("${WOLFTPM_INTERFACE}" STREQUAL "SPI")
185215
# SPI interface
@@ -344,49 +374,91 @@ if(WOLFTPM_FIRMWARE)
344374
list(APPEND WOLFTPM_DEFINITIONS "-DWOLFTPM_FIRMWARE_UPGRADE")
345375
endif()
346376

377+
# fwTPM definitions (after interface detection)
378+
if(WOLFTPM_FWTPM)
379+
# WOLFTPM_FWTPM_BUILD goes into options.h for build detection
380+
# Note: WOLFTPM_FWTPM itself is only set per-target on fwtpm_server/unit_test
381+
list(APPEND WOLFTPM_DEFINITIONS "-DWOLFTPM_FWTPM_BUILD")
382+
# Determine TIS vs socket transport
383+
if(NOT "${WOLFTPM_INTERFACE}" STREQUAL "SWTPM")
384+
list(APPEND WOLFTPM_DEFINITIONS "-DWOLFTPM_FWTPM_HAL")
385+
list(APPEND WOLFTPM_DEFINITIONS "-DWOLFTPM_ADV_IO")
386+
set(WOLFTPM_FWTPM_TIS ON)
387+
else()
388+
set(WOLFTPM_FWTPM_TIS OFF)
389+
endif()
390+
endif()
391+
392+
# If fwtpm-only, force examples off and disable wrapper
393+
if(WOLFTPM_FWTPM_ONLY)
394+
set(WOLFTPM_EXAMPLES OFF CACHE BOOL "" FORCE)
395+
list(APPEND WOLFTPM_DEFINITIONS "-DWOLFTPM2_NO_WRAPPER")
396+
endif()
397+
347398
# Examples
348399
set(WOLFTPM_EXAMPLES "yes" CACHE BOOL
349400
"Build examples")
350401

351-
target_include_directories(wolftpm
352-
PUBLIC
353-
$<INSTALL_INTERFACE:include>
354-
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
355-
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
356-
)
402+
if(BUILD_WOLFTPM_LIB)
403+
target_include_directories(wolftpm
404+
PUBLIC
405+
$<INSTALL_INTERFACE:include>
406+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
407+
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
408+
)
409+
endif()
357410

411+
# wolfSSL/wolfCrypt dependency (shared between wolftpm library and fwtpm targets)
412+
add_library(wolftpm_wolfssl_dep INTERFACE)
413+
set(WOLFCRYPT_AVAILABLE OFF)
358414

359415
if (WITH_WOLFSSL)
360-
target_link_libraries(wolftpm PUBLIC wolfssl)
361-
target_include_directories(wolftpm PUBLIC ${WITH_WOLFSSL}/include)
362-
target_link_directories(wolftpm PUBLIC ${WITH_WOLFSSL}/lib)
416+
target_link_libraries(wolftpm_wolfssl_dep INTERFACE wolfssl)
417+
target_include_directories(wolftpm_wolfssl_dep INTERFACE ${WITH_WOLFSSL}/include)
418+
target_link_directories(wolftpm_wolfssl_dep INTERFACE ${WITH_WOLFSSL}/lib)
419+
set(WOLFCRYPT_AVAILABLE ON)
363420
elseif (WITH_WOLFSSL_TREE)
364421
set(WOLFSSL_TPM "yes" CACHE STRING "")
365422
set(WOLFSSL_EXAMPLES "no" CACHE STRING "")
366423
set(WOLFSSL_CRYPT_TESTS "no" CACHE STRING "")
367424
add_subdirectory(${WITH_WOLFSSL_TREE} wolfssl)
368-
target_link_libraries(wolftpm PUBLIC wolfssl)
425+
target_link_libraries(wolftpm_wolfssl_dep INTERFACE wolfssl)
426+
set(WOLFCRYPT_AVAILABLE ON)
369427
else()
370428
find_package(PkgConfig)
371429
pkg_check_modules(WOLFSSL wolfssl)
372430

373431
if (WOLFSSL_FOUND)
374-
target_link_libraries(wolftpm PUBLIC ${WOLFSSL_LIBRARIES})
375-
target_include_directories(wolftpm PUBLIC ${WOLFSSL_INCLUDE_DIRS})
376-
target_link_directories(wolftpm PUBLIC ${WOLFSSL_LIBRARY_DIRS})
377-
target_compile_options(wolftpm PUBLIC ${WOLFSSL_CFLAGS_OTHER})
432+
target_link_libraries(wolftpm_wolfssl_dep INTERFACE ${WOLFSSL_LIBRARIES})
433+
target_include_directories(wolftpm_wolfssl_dep INTERFACE ${WOLFSSL_INCLUDE_DIRS})
434+
target_link_directories(wolftpm_wolfssl_dep INTERFACE ${WOLFSSL_LIBRARY_DIRS})
435+
target_compile_options(wolftpm_wolfssl_dep INTERFACE ${WOLFSSL_CFLAGS_OTHER})
436+
set(WOLFCRYPT_AVAILABLE ON)
378437
else()
379438
# For support with vcpkg
380439
find_package(wolfssl CONFIG REQUIRED)
381440
if (wolfssl_FOUND)
382-
target_link_libraries(wolftpm PUBLIC wolfssl::wolfssl)
441+
target_link_libraries(wolftpm_wolfssl_dep INTERFACE wolfssl::wolfssl)
442+
set(WOLFCRYPT_AVAILABLE ON)
383443
else()
384444
list(APPEND WOLFTPM_DEFINITIONS "-DWOLFTPM2_NO_WOLFCRYPT")
385445
endif()
386446
endif()
387447
endif()
388448

389-
if (WOLFTPM_EXAMPLES)
449+
# Link wolftpm library to wolfSSL
450+
if(BUILD_WOLFTPM_LIB)
451+
target_link_libraries(wolftpm PUBLIC wolftpm_wolfssl_dep)
452+
endif()
453+
454+
# fwTPM requires wolfCrypt
455+
if(WOLFTPM_FWTPM AND NOT WOLFCRYPT_AVAILABLE)
456+
message(FATAL_ERROR
457+
"fwTPM requires wolfCrypt. Provide wolfSSL via -DWITH_WOLFSSL=<path>, "
458+
"-DWITH_WOLFSSL_TREE=<path>, or install it system-wide.")
459+
endif()
460+
461+
if (WOLFTPM_EXAMPLES AND BUILD_WOLFTPM_LIB)
390462
add_library(tpm_test_lib STATIC
391463
examples/tpm_test_keys.c
392464
)
@@ -400,6 +472,104 @@ function(add_tpm_example name src)
400472
target_link_libraries(${name} wolftpm tpm_test_lib)
401473
endfunction()
402474

475+
####################################################
476+
# fwTPM targets
477+
####################################################
478+
479+
if(WOLFTPM_FWTPM)
480+
# Core fwTPM sources (shared between server, unit test, and fuzz)
481+
set(FWTPM_CORE_SOURCES
482+
src/fwtpm/fwtpm.c
483+
src/fwtpm/fwtpm_command.c
484+
src/fwtpm/fwtpm_crypto.c
485+
src/fwtpm/fwtpm_nv.c
486+
src/tpm2_util.c
487+
src/tpm2_packet.c
488+
src/tpm2_crypto.c
489+
src/tpm2_param_enc.c
490+
)
491+
492+
# Server-specific sources
493+
set(FWTPM_SERVER_SOURCES
494+
${FWTPM_CORE_SOURCES}
495+
src/fwtpm/fwtpm_io.c
496+
src/fwtpm/fwtpm_main.c
497+
)
498+
499+
# TIS sources (when not using SWTPM socket transport)
500+
if(WOLFTPM_FWTPM_TIS)
501+
list(APPEND FWTPM_SERVER_SOURCES
502+
src/fwtpm/fwtpm_tis.c
503+
src/fwtpm/fwtpm_tis_shm.c
504+
)
505+
endif()
506+
507+
# fwtpm_server executable
508+
add_executable(fwtpm_server ${FWTPM_SERVER_SOURCES})
509+
target_compile_definitions(fwtpm_server PRIVATE "WOLFTPM_FWTPM")
510+
if(WOLFTPM_FWTPM_TIS)
511+
target_compile_definitions(fwtpm_server PRIVATE "WOLFTPM_FWTPM_TIS")
512+
endif()
513+
target_link_libraries(fwtpm_server PRIVATE wolftpm_wolfssl_dep)
514+
target_include_directories(fwtpm_server PRIVATE
515+
${CMAKE_CURRENT_SOURCE_DIR}
516+
${CMAKE_CURRENT_BINARY_DIR}
517+
)
518+
if(UNIX AND NOT APPLE)
519+
target_link_libraries(fwtpm_server PRIVATE pthread rt)
520+
endif()
521+
522+
# fwtpm_unit_test executable
523+
add_executable(fwtpm_unit_test
524+
tests/fwtpm_unit_tests.c
525+
${FWTPM_CORE_SOURCES}
526+
)
527+
target_compile_definitions(fwtpm_unit_test PRIVATE
528+
"WOLFTPM_FWTPM"
529+
"FWTPM_NV_FILE=\"fwtpm_test_nv.bin\""
530+
)
531+
target_link_libraries(fwtpm_unit_test PRIVATE wolftpm_wolfssl_dep)
532+
target_include_directories(fwtpm_unit_test PRIVATE
533+
${CMAKE_CURRENT_SOURCE_DIR}
534+
${CMAKE_CURRENT_BINARY_DIR}
535+
)
536+
if(UNIX AND NOT APPLE)
537+
target_link_libraries(fwtpm_unit_test PRIVATE pthread)
538+
endif()
539+
540+
# fwTPM fuzz target (libFuzzer)
541+
if(WOLFTPM_FWTPM_FUZZ)
542+
add_executable(fwtpm_fuzz
543+
tests/fuzz/fwtpm_fuzz.c
544+
${FWTPM_CORE_SOURCES}
545+
)
546+
target_compile_definitions(fwtpm_fuzz PRIVATE "WOLFTPM_FWTPM")
547+
target_link_libraries(fwtpm_fuzz PRIVATE wolftpm_wolfssl_dep)
548+
target_include_directories(fwtpm_fuzz PRIVATE
549+
${CMAKE_CURRENT_SOURCE_DIR}
550+
${CMAKE_CURRENT_BINARY_DIR}
551+
)
552+
target_link_options(fwtpm_fuzz PRIVATE "-fsanitize=fuzzer")
553+
endif()
554+
555+
# CTest integration
556+
enable_testing()
557+
add_test(NAME fwtpm_unit_test
558+
COMMAND fwtpm_unit_test
559+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
560+
)
561+
562+
message(STATUS "fwTPM server: enabled")
563+
if(WOLFTPM_FWTPM_TIS)
564+
message(STATUS "fwTPM transport: TIS/shared-memory")
565+
else()
566+
message(STATUS "fwTPM transport: socket (SWTPM)")
567+
endif()
568+
if(WOLFTPM_FWTPM_ONLY)
569+
message(STATUS "fwTPM mode: server-only (no client library)")
570+
endif()
571+
endif()
572+
403573
function(add_to_options_file DEFINITIONS OPTION_FILE)
404574
list(REMOVE_DUPLICATES DEFINITIONS)
405575
foreach(DEF IN LISTS DEFINITIONS)
@@ -493,7 +663,7 @@ endif()
493663

494664

495665

496-
if (WOLFTPM_EXAMPLES)
666+
if (WOLFTPM_EXAMPLES AND BUILD_WOLFTPM_LIB)
497667
add_tpm_example(activate_credential attestation/activate_credential.c)
498668
add_tpm_example(certify attestation/certify.c)
499669
add_tpm_example(make_credential attestation/make_credential.c)
@@ -548,18 +718,27 @@ endif()
548718

549719
include(GNUInstallDirs)
550720

551-
install(TARGETS wolftpm
552-
EXPORT wolftpm-targets
553-
LIBRARY DESTINATION lib
554-
ARCHIVE DESTINATION lib
555-
RUNTIME DESTINATION bin
556-
)
721+
if(BUILD_WOLFTPM_LIB)
722+
install(TARGETS wolftpm wolftpm_wolfssl_dep
723+
EXPORT wolftpm-targets
724+
LIBRARY DESTINATION lib
725+
ARCHIVE DESTINATION lib
726+
RUNTIME DESTINATION bin
727+
)
728+
729+
# Install the export set
730+
install(EXPORT wolftpm-targets
731+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wolftpm
732+
FILE wolftpm-config.cmake
733+
NAMESPACE wolfssl::)
734+
endif()
557735

558-
# Install the export set
559-
install(EXPORT wolftpm-targets
560-
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wolftpm
561-
FILE wolftpm-config.cmake
562-
NAMESPACE wolfssl::)
736+
# Install fwTPM server
737+
if(WOLFTPM_FWTPM)
738+
install(TARGETS fwtpm_server
739+
RUNTIME DESTINATION bin
740+
)
741+
endif()
563742

564743
# Install the headers
565744
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/wolftpm/

examples/run_examples.sh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,6 @@ run_tpm_tls_client() { # Usage: run_tpm_tls_client [ecc/rsa] [tpmargs] [tlsversi
448448
pushd $WOLFSSL_PATH >> $TPMPWD/run.out 2>&1
449449
echo -e "./examples/server/server -v $3 -p $port -w -g -A ./certs/tpm-ca-$1-cert.pem -R $READY_FILE"
450450
./examples/server/server -v $3 -p $port -w -g -A ./certs/tpm-ca-$1-cert.pem -R "$READY_FILE" >> $TPMPWD/run.out 2>&1 &
451-
RESULT=$?
452-
[ $RESULT -ne 0 ] && echo -e "tls server $1 $2 failed! $RESULT" && exit 1
453451
popd >> $TPMPWD/run.out 2>&1
454452
wait_for_ready "$READY_FILE" 500
455453
rm -f "$READY_FILE"
@@ -466,8 +464,6 @@ run_tpm_tls_server() { # Usage: run_tpm_tls_server [ecc/rsa] [tpmargs] [tlsversi
466464

467465
echo -e "./examples/tls/tls_server -p=$port -$1 $2"
468466
./examples/tls/tls_server -p=$port -$1 $2 >> $TPMPWD/run.out 2>&1 &
469-
RESULT=$?
470-
[ $RESULT -ne 0 ] && echo -e "tpm tls server $1 $2 failed! $RESULT" && exit 1
471467
wait_for_port "$port" 500
472468
pushd $WOLFSSL_PATH >> $TPMPWD/run.out 2>&1
473469

0 commit comments

Comments
 (0)