Skip to content

Building wolfTPM

To build the wolfTPM library, it's required to first build and install the wolfSSL library. This can be downloaded from the downloads page, or through a "git clone" command, shown below:

$ git clone https://github.com/wolfssl/wolfssl

Once the wolfSSL library has been downloaded, it needs to be built with the following option being passed to the configure script:

$ ./configure --enable-wolftpm

Or equivalently, with the following options:

$ ./configure --enable-certgen --enable-certreq --enable-certext
--enable-pkcs7 --enable-cryptocb --enable-aescfb

Then the wolfSSL library just needs to be built and installed however the user prefers.

The next step is to download and install the wolfTPM library. wolfTPM can similarly be downloaded from the downloads page or be cloned from GitHub. The following commands show how to clone and install wolfTPM:

$ git clone https://github.com/wolfssl/wolftpm
$ cd wolftpm
$ ./autogen.sh
$ ./configure
$ make

Build options and defines

--enable-debug          Add debug code/turns off optimizations (yes|no|verbose|io) 
                        - DEBUG_WOLFTPM, WOLFTPM_DEBUG_VERBOSE, WOLFTPM_DEBUG_IO
--enable-examples       Enable Examples (default: enabled)
--enable-wrapper        Enable wrapper code (default: enabled) - WOLFTPM2_NO_WRAPPER
--enable-wolfcrypt      Enable wolfCrypt hooks for RNG, Auth Sessions and Parameter encryption 
                        (default: enabled) - WOLFTPM2_NO_WOLFCRYPT
--enable-advio          Enable Advanced IO (default: disabled) - WOLFTPM_ADV_IO
--enable-i2c            Enable I2C TPM Support (default: disabled, requires advio) - WOLFTPM_I2C
--enable-checkwaitstate Enable TIS / SPI Check Wait State support (default: depends on chip) 
                        - WOLFTPM_CHECK_WAIT_STATE
--enable-smallstack     Enable options to reduce stack usage
--enable-tislock        Enable Linux Named Semaphore for locking access to SPI device for 
                        concurrent access between processes - WOLFTPM_TIS_LOCK

--enable-autodetect     Enable Runtime Module Detection (default: enable - when no module 
                        specified) - WOLFTPM_AUTODETECT
--enable-infineon       Enable Infineon SLB9670 TPM Support (default: disabled)
--enable-st             Enable ST ST33TPM Support (default: disabled) - WOLFTPM_ST33
--enable-microchip      Enable Microchip ATTPM20 Support (default: disabled) - WOLFTPM_MCHP
--enable-nuvoton        Enable Nuvoton NPCT65x/NPCT75x Support (default: disabled) 
                        - WOLFTPM_NUVOTON

--enable-devtpm         Enable using Linux kernel driver for /dev/tpmX (default: disabled) 
                        - WOLFTPM_LINUX_DEV
--enable-swtpm          Enable using SWTPM TCP protocol. For use with simulator. 
                        (default: disabled) - WOLFTPM_SWTPM
--enable-winapi         Use Windows TBS API. (default: disabled) - WOLFTPM_WINAPI

WOLFTPM_USE_SYMMETRIC   Enables symmetric AES/Hashing/HMAC support for TLS examples.
WOLFTPM2_USE_SW_ECDHE   Disables use of TPM for ECC ephemeral key generation and shared secret 
                        for TLS examples.
TLS_BENCH_MODE          Enables TLS benchmarking mode.
NO_TPM_BENCH            Disables the TPM benchmarking example.

Building Infineon SLB9670

Build wolfTPM:

git clone https://github.com/wolfSSL/wolfTPM.git
cd wolfTPM
./autogen.sh
./configure
make

Building ST ST33TP*

Build wolfTPM:

./autogen.sh
./configure --enable-st33 [--enable-i2c]
make

For the I2C support on Raspberry Pi you may need to enable I2C. Here are the steps: 1. Edit sudo vim /boot/config.txt 2. Uncomment dtparam=i2c_arm=on 3. Reboot sudo reboot

Building Microchip ATTPM20

Build wolfTPM:

./autogen.sh
./configure --enable-microchip
make

Building Nuvoton

Build wolfTPM:

./autogen.sh
./configure --enable-nuvoton
make

Building for "/dev/tpmX"

This build option allows you to talk to any TPM vendor supported by the Linux TIS kernel driver

Build wolfTPM:

./autogen.sh
./configure --enable-devtpm
make

Note: When using a TPM device through the Linux kernel driver make sure sufficient permissions are given to the application that uses wolfTPM, because the "/dev/tpmX" typically has read-write permissions only for the "tss" user group. Either run wolfTPM examples and your application using sudo or add your user to the "tss" group like this:

sudo adduser yourusername tss

With QEMU and swtpm

This demonstrates using wolfTPM in QEMU to communicate using the linux kernel device "/dev/tpmX". You will need to install or build swtpm. Below are a short method to build. You may need to consult the instructions for libtpms and swtpm

PREFIX=$PWD/inst
git clone git@github.com:stefanberger/libtpms.git
cd libtpms/
./autogen.sh --with-openssl --with-tpm2 --prefix=$PREFIX && make install
cd ..
git clone git@github.com:stefanberger/swtpm.git
cd swtpm
PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig/ ./autogen.sh --with-openssl --with-tpm2 \
    --prefix=$PREFIX && \
  make install
cd ..

You can setup a basic linux installation. Other installation bases can be used. This step will take some time to install the base linux system.

# download mini install image
curl -O http://archive.ubuntu.com/ubuntu/dists/bionic-updates/main/installer-amd64/current/images/netboot/mini.iso
# create qemu image file
qemu-img create -f qcow2 lubuntu.qcow2 5G
# create directory for tpm state and socket
mkdir $PREFIX/mytpm
# start swtpm
$PREFIX/bin/swtpm socket --tpm2 --tpmstate dir=$PREFIX/mytpm \
  --ctrl type=unixio,path=$PREFIX/mytpm/swtpm-sock --log level=20 &
# start qemu for installation
qemu-system-x86_64 -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
  -chardev socket,id=chrtpm,path=$PREFIX/mytpm/swtpm-sock \
  -tpmdev emulator,id=tpm0,chardev=chrtpm \
  -device tpm-tis,tpmdev=tpm0 -hda lubuntu.qcow2 -cdrom mini.iso

Once a base system is installed it's ready to start the qemu and build wolfSSL and wolfTPM in the qemu instance.

# start swtpm again
$PREFIX/bin/swtpm socket --tpm2 --tpmstate dir=$PREFIX/mytpm \
  --ctrl type=unixio,path=$PREFIX/mytpm/swtpm-sock --log level=20 &
# start qemu system to install and run wolfTPM
qemu-system-x86_64 -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
  -chardev socket,id=chrtpm,path=$PREFIX/mytpm/swtpm-sock \
  -tpmdev emulator,id=tpm0,chardev=chrtpm \
  -device tpm-tis,tpmdev=tpm0 -hda lubuntu.qcow2

To build checkout and build wolfTPM, in the QEMU terminal

sudo apt install automake libtool gcc git make

# get and build wolfSSL
git clone https://github.com/wolfssl/wolfssl.git
pushd wolfssl
./autogen.sh && \
  ./configure --enable-wolftpm --disable-examples --prefix=$PWD/../inst && \
  make install
popd

# get and build wolfTPM
git clone https://github.com/wolfssl/wolftpm.git
pushd wolftpm
./autogen.sh && \
  ./configure --enable-devtpm --prefix=$PWD/../inst --enable-debug && \
  make install
sudo make check
popd

You can now run the examples such as sudo ./examples/wrap/wrap within QEMU. Using sudo maybe required for access to /dev/tpm0.

Building for SWTPM

wolfTPM is to be able to interface with SW TPM interfaces defined by section D.3 of TPM-Rev-2.0-Part-4-Supporting-Routines-01.38-code

Using the socket connection for SWTPM is exclusive and not compatible with TIS or devtpm.

Only a subset of functionality is implemented to support testing of wolfTPM. The platform requests are not used by wolfTPM.

Two implementations were used in testing:

  • https://sourceforge.net/projects/ibmswtpm2/files/
  • https://github.com/stefanberger/swtpm

To enable this functionality, build wolfTPM as shown below:

./configure --enable-swtpm
make

SWTPM simulator setup

ibmswtpm2

Checkout and Build

git clone https://github.com/kgoldman/ibmswtpm2.git
cd ibmswtpm2/src/
make

Running:

./tpm_server --rm

The rm switch is optional and remove the cache file NVChip. Alternately you can rm NVChip

swtpm

Build libtpms

git clone git@github.com:stefanberger/libtpms.git
(cd libtpms && ./autogen.sh --with-tpm2 --with-openssl --prefix=/usr && make install)

Build swtpm

git clone git@github.com:stefanberger/swtpm.git
(cd swtpm && ./autogen.sh && make install)

Note: On Mac OS X had to do the following first:

brew install openssl socat
pip3 install cryptography

export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"

# libtpms had to use --prefix=/usr/local

Running swtpm

mkdir -p /tmp/myvtpm
swtpm socket --tpmstate dir=/tmp/myvtpm --tpm2 --ctrl type=tcp,port=2322 --server type=tcp,port=2321 --flags not-need-init

Running examples

./examples/pcr/extend
./examples/wrap/wrap_test

Building for Windows TBS API

wolfTPM can be built to use Windows native TBS (TPM Base Services)

When using the Windows TBS interface the NV access is blocked by default. TPM NV storage space is very limited and when filled can cause undefined behaviors, such as failures loading key handles. These are not managed by TBS.

The TPM is designed to return an encrypted private key blob on key creation using TPM2_Create, which you can safely store on the disk and load when needed. The symmetric encryption key used to protect the private key blob is only known by the TPM. When you load a key using TPM2_Load you get a transient handle, which can be used for signing and even encryption/decryption.

For primary keys created with TPM2_CreatePrimary you get back a handle. There is no encrypted private data returned. That handle will remain loaded until TPM2_FlushContext is called.

For normal key creation using TPM2_Create you get back a TPM2B_PRIVATE outPrivate, which is the encrypted blob that you can store and load anytime using TPM2_Load.

Limitations

wolfTPM has been tested on Windows 10 with TPM 2.0 devices. While Windows does support TPM 1.2, functionality is limited and not supported by wolfTPM.

Presence of TPM 2.0 can be checked by opening PowerShell and running Get-PnpDevice -Class SecurityDevices

Status     Class           FriendlyName
------     -----           ------------
OK         SecurityDevices Trusted Platform Module 2.0
Unknown    SecurityDevices Trusted Platform Module 2.0

Building in MSYS2

Tested using MSYS2

export PREFIX=$PWD/tmp_install

cd wolfssl
./autogen.sh
./configure --prefix="$PREFIX" --enable-wolftpm
make
make install

cd ../wolftpm/
./autogen.sh
./configure --prefix="$PREFIX" --enable-winapi
make

Building on linux

Tested using mingw-w32-bin_x86_64-linux_20131221.tar.bz2 source

Extract the tools and add them to the PATH

mkdir mingw_tools
cd mingw_tools
tar xjvf ../mingw-w32-bin_x86_64-linux_20131221.tar.bz2
export PATH=$PWD/bin/:$PWD/i686-w64-mingw32/bin:$PATH
cd ..

Build

export PREFIX=$PWD/tmp_install
export CFLAGS="-DWIN32 -DMINGW -D_WIN32_WINNT=0x0600 -DUSE_WOLF_STRTOK"
export LIBS="-lws2_32"

cd wolfssl
./autogen.sh
./configure --host=i686 CC=i686-w64-mingw32-gcc --prefix="$PREFIX" --enable-wolftpm
make
make install

cd ../wolftpm/
./autogen.sh
./configure --host=i686 CC=i686-w64-mingw32-gcc --prefix="$PREFIX" --enable-winapi
make
cd ..

Running on Windows

To confirm presence and status of TPM on the machine run tpm.msc