Skip to content
Open
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
140 changes: 140 additions & 0 deletions .github/workflows/rust-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
name: WolfTPM Rust Wrapper Tests

on:
push:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '**' ]
types: [opened, synchronize, reopened, ready_for_review]
repository_dispatch:
types: [nightly-trigger]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
# Resolve the latest wolfSSL -stable tag so we also test the shipped release.
discover:
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
uses: ./.github/workflows/_resolve-wolfssl.yml

rust:
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
needs: discover
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: master
wolfssl_ref: master
- name: latest-stable
wolfssl_ref: ${{ needs.discover.outputs.latest_stable }}
steps:
- name: Checkout wolfTPM
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

# Build + install wolfSSL with the crypto-callback support the wrapper
# (and the TPM-backed TLS bridge) needs; installs to /usr/local so
# pkg-config finds it for both wolfTPM configure and the Rust build.rs.
- name: Setup wolfSSL
uses: ./.github/actions/setup-wolfssl
with:
ref: ${{ matrix.wolfssl_ref || 'master' }}
# fwTPM RSA object creation needs WOLFSSL_KEY_GEN and the raw-RSA
# padding path, or TPM2_Create returns TPM_RC_COMMAND_CODE for RSA
# keys (see src/fwtpm/README.md).
configure-flags: --enable-wolftpm --enable-pkcallbacks --enable-keygen
cflags: -DWC_RSA_NO_PADDING

# Use the runner's preinstalled rustup rather than a mutable third-party
# action, so no external action code runs with the job token.
- name: Install Rust
run: |
rustup toolchain install stable --profile minimal --component clippy --component rustfmt
rustup default stable

- name: Generate TPM port
run: |
MATRIX_HASH=$(echo -n "rust-${{ matrix.name }}" | cksum | cut -d' ' -f1)
TPM_PORT=$((40000 + (MATRIX_HASH % 1000) * 2))
echo "TPM_PORT=$TPM_PORT" >> $GITHUB_ENV
echo "TPM2_SWTPM_PORT=$TPM_PORT" >> $GITHUB_ENV
echo "TPM2_SWTPM_HOST=localhost" >> $GITHUB_ENV

# Build wolfTPM with our in-tree firmware TPM (fwtpm_server) as the
# software TPM the Rust tests run against — no external simulator.
- name: Build wolfTPM (swtpm + fwtpm)
run: |
./autogen.sh
./configure --enable-swtpm --enable-fwtpm --with-swtpm-port=$TPM_PORT
make -j"$(nproc)"

- name: Start fwTPM server
run: |
./src/fwtpm/fwtpm_server --clear --port "$TPM_PORT" \
--platform-port "$((TPM_PORT + 1))" &
sleep 1

- name: Build Rust wrapper
working-directory: ./wrapper/rust/wolftpm
run: cargo build --locked --all-targets --features swtpm-tests

# Style gates are advisory on the first runs (annotate, don't fail the
# pipeline); flip continue-on-error off once a `cargo fmt` pass is landed.
- name: Clippy
working-directory: ./wrapper/rust/wolftpm
continue-on-error: true
run: cargo clippy --locked --all-targets --features swtpm-tests -- -D warnings

- name: Rustfmt check
working-directory: ./wrapper/rust/wolftpm
continue-on-error: true
run: cargo fmt --check

- name: Test against fwTPM
working-directory: ./wrapper/rust/wolftpm
run: cargo test --locked --features swtpm-tests -- --test-threads=1

- name: Docs
working-directory: ./wrapper/rust/wolftpm
run: cargo doc --locked --no-deps

# Compile-only against the Linux kernel-device transport, so the non-swtpm
# cfg paths and the callback-free open() build are exercised too.
rust-devtpm-compile:
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- name: Checkout wolfTPM
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup wolfSSL
uses: ./.github/actions/setup-wolfssl
with:
ref: master
configure-flags: --enable-wolftpm --enable-pkcallbacks
- name: Install Rust
run: |
rustup toolchain install stable --profile minimal
rustup default stable
- name: Build wolfTPM (devtpm)
run: |
./autogen.sh
./configure --enable-devtpm
make -j"$(nproc)"
- name: Compile Rust wrapper (no swtpm)
working-directory: ./wrapper/rust/wolftpm
run: cargo build --locked --all-targets

- name: Upload failure logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: wolftpm-rust-devtpm-logs
path: |
wrapper/rust/wolftpm/target/debug/build/*/output
retention-days: 5
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ config.log
config.status
libtool
Makefile
!/wrapper/rust/Makefile
!/wrapper/rust/wolftpm/Makefile
wolftpm-config
.dirstamp
*.la
Expand Down Expand Up @@ -154,6 +156,7 @@ docs/xml
# Wrapper
wrapper/CSharp/obj
wrapper/CSharp/bin
/wrapper/rust/wolftpm/target/

# Visual Studio
IDE/VisualStudio/Debug
Expand Down
1 change: 1 addition & 0 deletions wrapper/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# All paths should be given relative to the root

include wrapper/CSharp/include.am
include wrapper/rust/include.am

wrapperdir = $(docdir)/wrapper
dist_wrapper_DATA= wrapper/wolfTPM-csharp.sln
11 changes: 11 additions & 0 deletions wrapper/rust/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.PHONY: all
all:
+$(MAKE) -C wolftpm

.PHONY: test
test:
+$(MAKE) -C wolftpm test

.PHONY: clean
clean:
+$(MAKE) -C wolftpm clean
16 changes: 16 additions & 0 deletions wrapper/rust/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# wolfTPM Rust wrapper

Official Rust bindings for wolfTPM. The crate lives in [`wolftpm/`](wolftpm/);
see its [README](wolftpm/README.md) for the full API, build, and test details.

```sh
# 1. build the C library first (with a software TPM for testing)
cd ../.. # wolfTPM repo root
./autogen.sh && ./configure --enable-swtpm --enable-fwtpm && make

# 2. build, lint, and document the Rust crate against it
make -C wrapper/rust

# 3. test (needs a running software TPM on localhost:2321)
make -C wrapper/rust test
```
52 changes: 52 additions & 0 deletions wrapper/rust/include.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# vim:ft=automake
# included from wrapper/include.am
# All paths should be given relative to the root

EXTRA_DIST += wrapper/rust/README.md
EXTRA_DIST += wrapper/rust/Makefile
EXTRA_DIST += wrapper/rust/wolftpm/CHANGELOG.md
EXTRA_DIST += wrapper/rust/wolftpm/Cargo.toml
EXTRA_DIST += wrapper/rust/wolftpm/Cargo.lock
EXTRA_DIST += wrapper/rust/wolftpm/README.md
EXTRA_DIST += wrapper/rust/wolftpm/Makefile
EXTRA_DIST += wrapper/rust/wolftpm/build.rs
EXTRA_DIST += wrapper/rust/wolftpm/headers.h
EXTRA_DIST += wrapper/rust/wolftpm/src/lib.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/sys.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/device.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/key.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/sign.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/seal.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/nv.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/pcr.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/certify.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/rsa.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/persist.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/hmac.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/session.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/caps.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/symmetric.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/ecdh.rs
EXTRA_DIST += wrapper/rust/wolftpm/src/credential.rs
EXTRA_DIST += wrapper/rust/wolftpm/examples/create_primary.rs
EXTRA_DIST += wrapper/rust/wolftpm/examples/full_flow.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/smoke.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/common/mod.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/keys.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/sign.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/seal.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/nv.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/pcr.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/certify.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/ek.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/persist.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/rsa.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/hmac.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/seal_pcr.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/session.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/caps.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/quote.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/credential.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/ecdh.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/symmetric.rs
EXTRA_DIST += wrapper/rust/wolftpm/tests/import.rs
61 changes: 61 additions & 0 deletions wrapper/rust/wolftpm/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# wolftpm Change Log

## v1.0.0

**Summary**

Initial stable release of the official `wolftpm` Rust crate. The crate provides
a safe `no_std` API over the wolfTPM C library, with RAII-managed TPM resources,
zeroization of secret material, parameter-encrypted sessions, and support for
software, operating-system, and embedded TPM transports.

**Detail**

* Safe API and resource management
- `Device` owns the TPM connection and cleans it up on drop
- `Key` unloads transient handles on drop, while `KeyBlob` supports wrapped
key serialization and reloading
- `Session` manages a salted AES-CFB parameter-encryption session and clears
its authorization slot on drop
- `Secret` owns sensitive output and zeroizes its buffer on drop
- `TpmError` preserves wolfTPM and TPM return codes with `Display`, `Debug`,
and `core::error::Error` support
* Key creation and lifecycle
- Create RSA or ECC primary, endorsement, attestation, signing, decryption,
HMAC, symmetric, and ECDH keys
- Create, load, serialize, restore, persist, read, and evict TPM keys
- Import external RSA and ECC private keys
- Export public keys in DER or PEM form
* Cryptographic operations
- Sign and verify message digests with TPM-resident RSA and ECC keys
- RSA-OAEP encryption and decryption with SHA-256 or SHA-1 label hashing
- AES-CFB encryption and decryption with TPM-resident symmetric keys
- HMAC with raw key material or TPM-resident keyed-hash keys
- ECDH ephemeral-key generation and shared-secret derivation
* Protected data and TPM state
- Seal and unseal data with optional object authorization
- Seal and unseal data against PCR policies
- Define, write, read, and delete authorization-protected NV indices
- Read EK certificates from NV storage
- Read and extend PCRs, query TPM capabilities, run self-tests, and obtain
TPM-generated random data
* Attestation and provisioning
- Certify TPM objects and produce signed PCR quotes
- Create and activate credentials using endorsement-key policy sessions
- Start salted parameter-encryption sessions for protected command and
response data
* Portability and build integration
- Support `no_std` targets with an application-provided allocator
- Generate `core`-based FFI bindings for the linked wolfTPM configuration
- Discover in-tree or installed wolfTPM and wolfSSL headers and libraries
- Translate Rust target triples for clang and discover bare-metal sysroots
when cross-compiling, including RISC-V targets
- Support configured swtpm/fwTPM sockets, Linux TPM devices, MMIO, Windows
TBS, and caller-provided hardware I/O callbacks
* Examples and validation
- Add primary-key and full API walkthrough examples
- Add serialized fwTPM integration coverage for keys, sealing, sessions,
attestation, credentials, PCRs, NV storage, persistence, RSA, AES, HMAC,
ECDH, capabilities, and error paths
- Add compile coverage for the Linux kernel-device transport
- Add build, Clippy, formatting, documentation, and integration-test CI
Loading
Loading