Skip to content

tegmentum/tpm2-driver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tpm2-driver

Host-side TPM command drivers — the client side of a TPM. These crates build TPM command byte streams, hand them to a TPM, and parse the responses. They are not a TPM implementation (that's the guest, e.g. libtpms compiled to WASM) and contain no host or persistence knowledge — the same driver runs natively on Linux or inside UEFI firmware.

   citadel (Linux, std) ──EngineTransport (wasmtime JIT)──┐
                                                          ├─▶ tpm2-driver ──process(cmd)──▶ TPM (libtpms guest)
   uefi-wasmtime (UEFI, no_std) ─ComponentTransport (Pulley)─┘

The host seam is one trait:

pub trait TpmTransport {
    fn process(&mut self, command: &[u8]) -> Result<Vec<u8>>;
}

Implement it for your host (a wasmtime component call, a hardware TIS, a socket to swtpm, …) and every driver operation works over it.

Crates

crate what
tpm-driver-common the TpmTransport seam, TpmError, send_command (transparent TPM_RC_RETRY/TPM_RC_TESTING retry), response_rc, hash helpers (sha256/sha384/sha1), and shared value types (Algorithm, PcrValue)
tpm2-driver the full TPM 2.0 protocol — cmd (every command builder) + ops (high-level sequences: create-key, sign, sign-with-policy, verify, seal/unseal, PCR, NV counters, PolicyAuthorize) plus the direct-TPM2_Quote attestation builders
tpm12-driver a TPM 1.2 scaffold — real 1.2 wire structure (TPM_TAG_RQU_COMMAND + TPM_ORD_*) for the measured-boot subset (startup / self-test / random / extend / PCR-read); the key/quote/seal surface is stubbed Unimplemented

Why 2.0 and 1.2 are separate

TPM 1.2 and 2.0 are entirely different wire protocols (1.2 uses TPM_ORD_* ordinals and SHA-1 PCRs; 2.0 uses TPM_CC_* command codes). They share almost no bytes — so the shared abstraction lives at the TpmTransport seam and (in consumers) a TpmBackend-style trait, not in a merged byte protocol. The split mirrors the tpm-wit interface package.

no_std

All crates are no_std + alloc. Enable the std feature for impl std::error::Error for TpmError (so std hosts get ?-into-anyhow):

tpm2-driver = { path = "...", features = ["std"] }   # std host (citadel)
tpm2-driver = { path = "..." }                       # no_std host (UEFI)

Building & testing

cargo build                 # no_std libraries
cargo test                  # std test harness (builders, retry, parsers)
cargo build --target thumbv7em-none-eabi \
  -p tpm-driver-common -p tpm2-driver -p tpm12-driver   # prove genuine no_std

CI (.github/workflows/ci.yml) runs fmt + clippy + tests and the bare-target build.

Example: an attestation flow

use tpm2_driver::{cmd, ops, send_command, TpmTransport};

fn quote(t: &mut impl TpmTransport, pcr: u32, nonce: &[u8]) -> tpm2_driver::Result<Vec<u8>> {
    ops::startup(t, cmd::TPM_SU_CLEAR)?;
    ops::pcr_extend(t, "sha256", pcr, &[0x42; 32])?;
    let cp = send_command(t, &cmd::build_create_primary_signing())?; // restricted ECC P-256 AK
    let ak = u32::from_be_bytes([cp[10], cp[11], cp[12], cp[13]]);
    send_command(t, &cmd::build_quote(ak, pcr, nonce))
}

Provenance

The 2.0 protocol is the byte-for-byte extraction of Citadel's vtpm-backend, plus the direct-TPM2_Quote builders proven in the uefi-wasmtime firmware attestation work. cmd::quote_attestation_digest preserves Citadel's own sign-based-quote folding function verbatim so its quote/verify_quote pair stays self-consistent across the extraction.

About

Host-side TPM 2.0/1.2 command drivers (no_std), shared by Citadel and UEFI firmware

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages