Skip to content

Add official wolfTPM Rust wrapper crate - #602

Open
aidangarske wants to merge 3 commits into
wolfSSL:masterfrom
aidangarske:wolftpm-rust-wrapper
Open

Add official wolfTPM Rust wrapper crate#602
aidangarske wants to merge 3 commits into
wolfSSL:masterfrom
aidangarske:wolftpm-rust-wrapper

Conversation

@aidangarske

@aidangarske aidangarske commented Sep 9, 2026

Copy link
Copy Markdown
Member

wolfTPM Rust Support

Current public types

Type Purpose
Device Open TPM context (RAII; closes on drop). One live Device at a time.
Key<'d> A loaded TPM key; unloads its handle on drop. Borrows the Device.
KeyBlob<'d> A created-but-not-loaded key (wrapped pub/priv blob); serialize and reload.
Template A TPM public-area key template (SRK, AIK, EK, signing, decrypt, HMAC, symmetric, ECDH).
Session<'d> A parameter-encryption (salted) session. One at a time; RAII drops it.
Secret Owned secret buffer that zeroizes on drop; Deref to &[u8].
TpmError A failed operation carrying the raw TPM/wolfCrypt return code. Implements Error/Display/Debug.
Result<T> Alias for core::result::Result<T, TpmError>.
Hierarchy Hierarchy selector: Owner, Endorsement, Platform.
KeyAlg Key algorithm: Rsa, EccP256.
HashAlg Hash algorithm (with digest_size()).
NvSlot<'d> A defined NV index handle.
Attestation Result of certify/quote: attest bytes, signature, signature algorithm.
Caps TPM capabilities / vendor info.
EcdhResult Ephemeral ECDH public point plus the derived shared Secret.
Credential MakeCredential output (encrypted secret + blob) for activation.

Public API's

Device — connection, RNG, self-test/caps

  • open() (cfg: any transport) — open the default TPM (autodetect transport)
  • open_swtpm() (cfg: swtpm) — open against a swtpm/fwTPM socket
  • get_random(buf) (cfg: rng) — fill a buffer from the TPM RNG
  • self_test() (cfg: caps) — run the TPM self-test
  • capabilities() (cfg: caps) — query Caps

Device — key creation and import

  • create_primary(hierarchy, alg, auth) — create a primary/storage-root key under a hierarchy
  • create_ek(alg) — create the Endorsement Key
  • create_key(parent, template, auth) — create a child key blob (not loaded)
  • create_and_load(parent, template, auth) — create and load a child key in one step
  • import_rsa_key(...) (cfg: import) — import an external RSA private key
  • import_ecc_key(...) (cfg: import) — import an external ECC private key

Device — seal / unseal

  • seal(parent, data, auth) (cfg: seal) — seal data to the TPM
  • unseal(...) (cfg: seal) — unseal (returns Secret)
  • seal_pcr(parent, data, pcr_indices) (cfg: seal) — PCR-policy-bound seal
  • unseal_pcr(...) (cfg: seal) — unseal a PCR-bound blob (returns Secret)

Device — NV storage

  • nv_create(index, size, auth) (cfg: nv) — define an NV index
  • nv_write(slot, data, offset) (cfg: nv)
  • nv_read(slot, buf, offset) (cfg: nv)
  • nv_delete(index) (cfg: nv)
  • read_cert(nv_handle) (cfg: nvcert) — read an EK certificate from NV

Device — PCRs

  • pcr_read(index, hash) (cfg: pcr)
  • pcr_extend(index, hash, digest) (cfg: pcr)

Device — attestation

  • certify(...) — an AIK certifies another object (returns Attestation)
  • quote(...) — signed PCR quote (returns Attestation)
  • make_credential(...)TPM2_MakeCredential (returns Credential)
  • activate_credential(...) (cfg: ek_policy)TPM2_ActivateCredential (returns Secret)

Device — persistent handles

  • persist_key(...) (cfg: persist) — persist a key to an NV persistent handle
  • read_persistent(persistent_handle, auth) (cfg: persist)
  • evict_key(key, hierarchy) (cfg: persist)

Device — HMAC and sessions

  • hmac(...) (cfg: hmac) — one-shot raw-key HMAC
  • start_encrypted_session(salt) — start a parameter-encryption session

Key — identity, sign/verify

  • handle() — the TPM handle
  • name() — the object Name (hash of its public area)
  • export_public(pem) (cfg: pubexport) — export the public key as DER or PEM
  • sign_hash(digest) — sign a digest
  • verify_hash(digest, sig) — verify a signature

Key — RSA (OAEP), AES, ECDH, HMAC

  • rsa_encrypt(msg) (cfg: rsa) — RSA-OAEP encrypt
  • rsa_decrypt(ciphertext) (cfg: rsa) — RSA-OAEP decrypt (returns Secret)
  • rsa_encrypt_with_hash(msg, hash) (cfg: rsa) — OAEP with an explicit label hash (Microsoft enrollment)
  • rsa_decrypt_with_hash(ciphertext, hash) (cfg: rsa)
  • aes_encrypt(data, iv) (cfg: symmetric) — AES-CFB encrypt
  • aes_decrypt(data, iv) (cfg: symmetric) — AES-CFB decrypt (returns Secret)
  • ecdh_gen() (cfg: ecdh) — ephemeral ECDH (returns EcdhResult)
  • ecdh_z(point) (cfg: ecdh) — Z-agreement with a peer point (returns Secret)
  • hmac(data, hash) (cfg: keyedhash) — HMAC with a TPM-resident keyed-hash key

KeyBlob — serialize / load

  • to_bytes() — serialize the wrapped blob
  • from_bytes(dev, bytes) — deserialize a blob
  • load(parent, auth) — load into the TPM (yields a Key)

Template — key templates

  • srk(alg) — storage-root/primary (restricted decrypt parent)
  • attestation(alg) — restricted signing AIK
  • ek(alg) — endorsement key
  • signing(alg) — general signing key (ECDSA / RSASSA-SHA256)
  • rsa_decrypt() — RSA decryption key (OAEP)
  • hmac(hash) (cfg: keyedhash) — TPM-resident keyed-hash HMAC key
  • symmetric(bits) (cfg: symmetric) — AES-CFB key (128/256)
  • ecdh() (cfg: ecdh) — ECDH key-agreement key (P-256)

Secret: as_bytes(), len(), is_empty(), Deref<Target=[u8]>, zeroizes on drop.
TpmError: code() — the raw return code. HashAlg: digest_size().

Tests ran on fwtpm

File Tests
caps.rs self_test_and_capabilities
certify.rs certify_with_ecc_aik, certify_with_rsa_aik
credential.rs make_and_activate_credential
ecdh.rs ecdh_gen_then_z_agree
ek.rs create_ek_and_export_public
hmac.rs hmac_deterministic_and_keyed, loaded_hmac_key_compute
import.rs import_rsa_private_key, import_ecc_private_key
keys.rs create_and_load_child, key_blob_roundtrip_then_load, key_blob_roundtrip_preserves_short_auth, auth_protected_parent_loads_child
nv.rs nv_write_read_delete
pcr.rs pcr_extend_changes_digest
persist.rs persist_read_evict
quote.rs quote_ecc_aik, quote_rsa_aik, quote_rejects_invalid_pcr_selection
rsa.rs rsa_oaep_roundtrip, rsa_oaep_sha1_roundtrip
seal.rs seal_unseal_roundtrip, unseal_wrong_auth_fails
seal_pcr.rs pcr_bound_seal_roundtrip, pcr_change_breaks_unseal, seal_pcr_rejects_invalid_selection
session.rs secret_ops_under_encrypted_session, second_session_rejected, attestation_refused_during_session
sign.rs sign_then_verify, verify_rejects_tampered_signature
smoke.rs random_and_primary_keys
symmetric.rs aes_cfb_roundtrip
  • Shared helper tests/common/mod.rs::open() connects each test to the fwTPM.
  • Examples: examples/create_primary.rs, examples/full_flow.rs.
  • CI (.github/workflows/rust-test.yml): rust job builds wolfSSL (matrix: master and latest -stable) + wolfTPM with the in-tree fwTPM and runs the suite; rust-devtpm-compile job is a compile-only Linux kernel-device (--enable-devtpm) build.

Post merge steps

  • Confirm Cargo.toml metadata: name wolftpm, version, license = GPL-3.0-or-later, description, repository, keywords, categories, readme
  • Verify the wolftpm name is owned by the wolfSSL org on crates.io (reserve it if not)
  • Make the docs.rs build succeed without the C libs: gate build.rs on DOCS_RS (generate bindings from vendored headers / skip the link step), since docs.rs has no prebuilt libwolftpm/libwolfssl
  • Set package.include/exclude so the published tarball ships only intended files (src, build.rs, headers.h, README, examples — not target/)
  • cargo publish --dry-run from wrapper/rust/wolftpm and review the packaged file list
  • cargo publish with a crates.io token that has wolfSSL-org publish rights
  • Verify the docs.rs build renders and the crate page is correct
  • Add crates.io + docs.rs badges and install/usage notes to wrapper/rust/README.md and the top-level wolfTPM README
  • Add a ChangeLog.md entry and tag the release
  • Announce (release notes / blog)

@aidangarske aidangarske self-assigned this Sep 9, 2026
Copilot AI lite review requested due to automatic review settings September 9, 2026 17:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Pull request overview

Adds an official wolftpm Rust crate that wraps wolfTPM’s C API via bindgen, provides a safe Rust interface for common TPM 2.0 workflows, and ships integration tests + CI to validate against an in-tree software TPM.

Changes:

  • Introduces the wolftpm crate with a safe API (Device/Key/KeyBlob/Session/Secret) layered over build-time-generated bindgen FFI.
  • Implements higher-level features (seal/unseal, PCR, NV, RSA-OAEP, AES-CFB, HMAC, ECDH, persistence, attestation, credential activation, encrypted sessions).
  • Adds integration tests, examples, packaging include lists, and a GitHub Actions workflow to build wolfSSL/wolfTPM and run the Rust suite.

Reviewed changes

Copilot reviewed 47 out of 47 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
wrapper/rust/wolftpm/Cargo.toml Defines the new wolftpm crate, features, and build dependencies
wrapper/rust/wolftpm/README.md Documents build/linking expectations, tests, examples, and API coverage
wrapper/rust/wolftpm/build.rs Generates bindgen FFI, links prebuilt libs, and emits cfgs reflecting C build options
wrapper/rust/wolftpm/headers.h Bindgen shim translation unit for wolfTPM public headers
wrapper/rust/wolftpm/src/lib.rs Crate root: exports safe API, error/Result types, and secret zeroization
wrapper/rust/wolftpm/src/sys.rs FFI module including bindgen output from $OUT_DIR
wrapper/rust/wolftpm/src/device.rs Implements Device open/init/cleanup + RNG + primary key creation
wrapper/rust/wolftpm/src/key.rs Implements templates, key/keyblob lifetimes, serialization, and imports
wrapper/rust/wolftpm/src/sign.rs Adds signing and verification methods on loaded keys
wrapper/rust/wolftpm/src/seal.rs Adds seal/unseal and PCR-policy-based sealing
wrapper/rust/wolftpm/src/nv.rs Adds NV define/write/read/delete and optional NV cert read API
wrapper/rust/wolftpm/src/pcr.rs Adds PCR read/extend helpers
wrapper/rust/wolftpm/src/certify.rs Adds certify + quote attestation APIs and signature marshalling
wrapper/rust/wolftpm/src/rsa.rs Adds RSA-OAEP encrypt/decrypt APIs including explicit OAEP hash
wrapper/rust/wolftpm/src/persist.rs Adds NV-backed key persistence, readback, and eviction
wrapper/rust/wolftpm/src/hmac.rs Adds raw-key HMAC and loaded keyed-hash HMAC APIs
wrapper/rust/wolftpm/src/session.rs Adds parameter-encryption session management with RAII
wrapper/rust/wolftpm/src/caps.rs Adds self-test and capability discovery
wrapper/rust/wolftpm/src/symmetric.rs Adds AES-CFB encrypt/decrypt with TPM-resident symmetric keys
wrapper/rust/wolftpm/src/ecdh.rs Adds ECDH generation + shared-secret derivation APIs
wrapper/rust/wolftpm/src/credential.rs Adds MakeCredential/ActivateCredential support
wrapper/rust/wolftpm/examples/create_primary.rs Minimal example exercising open/RNG/create-primary
wrapper/rust/wolftpm/examples/full_flow.rs End-to-end example walking through major APIs
wrapper/rust/wolftpm/tests/common/mod.rs Shared test harness for connecting to the software TPM
wrapper/rust/wolftpm/tests/smoke.rs Basic integration smoke test
wrapper/rust/wolftpm/tests/keys.rs Tests key creation/loading and blob serialization round-trips
wrapper/rust/wolftpm/tests/sign.rs Tests sign/verify and negative tamper case
wrapper/rust/wolftpm/tests/seal.rs Tests seal/unseal and wrong-auth negative case
wrapper/rust/wolftpm/tests/seal_pcr.rs Tests PCR-bound sealing and invalid selections
wrapper/rust/wolftpm/tests/nv.rs Tests NV create/write/read/delete
wrapper/rust/wolftpm/tests/pcr.rs Tests PCR read/extend behavior
wrapper/rust/wolftpm/tests/certify.rs Tests certify using ECC and RSA AIKs
wrapper/rust/wolftpm/tests/quote.rs Tests PCR quote and invalid PCR selection rejection
wrapper/rust/wolftpm/tests/credential.rs Tests MakeCredential/ActivateCredential round-trip
wrapper/rust/wolftpm/tests/ek.rs Tests EK creation + public export
wrapper/rust/wolftpm/tests/persist.rs Tests persist/readback/evict for persistent handles
wrapper/rust/wolftpm/tests/rsa.rs Tests RSA-OAEP round-trips including OAEP-SHA1 path
wrapper/rust/wolftpm/tests/hmac.rs Tests raw-key and TPM-resident HMAC
wrapper/rust/wolftpm/tests/caps.rs Tests self-test and capabilities
wrapper/rust/wolftpm/tests/ecdh.rs Tests ECDHGen/ECDHGenZ shared secret agreement
wrapper/rust/wolftpm/tests/symmetric.rs Tests AES-CFB encrypt/decrypt round-trip
wrapper/rust/wolftpm/tests/import.rs Tests external RSA/ECC private key import
wrapper/rust/include.am Adds Rust wrapper files to distribution packaging
wrapper/rust/README.md Top-level wrapper README pointing to the crate
wrapper/include.am Includes the Rust wrapper in the overall wrapper build/packaging
.github/workflows/rust-test.yml CI workflow building dependencies and running Rust tests/docs

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread wrapper/rust/wolftpm/src/rsa.rs Outdated
Comment thread wrapper/rust/wolftpm/src/rsa.rs Outdated
Comment thread wrapper/rust/wolftpm/build.rs
Comment thread wrapper/rust/wolftpm/build.rs
Comment thread wrapper/rust/wolftpm/build.rs
Comment thread wrapper/rust/wolftpm/src/credential.rs
Comment thread wrapper/rust/wolftpm/src/symmetric.rs
Comment thread wrapper/rust/wolftpm/src/symmetric.rs

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #602

No scan targets match the changed files in this PR. Review skipped.

@aidangarske
aidangarske marked this pull request as ready for review September 9, 2026 21:52
@aidangarske
aidangarske requested review from wolfSSL-Fenrir-bot and removed request for wolfSSL-Fenrir-bot September 10, 2026 16:56

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #602

No scan targets match the changed files in this PR. Review skipped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants