Just some sample common flows for use with TPM modules and libraries.
The primary focus is how use tpm2_tools to perform common tasks that i've come across.
Also shown equivalent use of go-tpm library set.
- tpmcopy: Transfer RSA|ECC|AES|HMAC key to a remote Trusted Platform Module (TPM)
- Go-TPM-Wrapping - Go library for encrypting data using Trusted Platform Module (TPM)
- Transferring RSA and Symmetric keys with GCP vTPMs
- TPM backed crypto/rand Reader
- golang-jwt for Trusted Platform Module (TPM)
- crypto.Signer, crypto.MessageSigner implementations for Trusted Platform Modules
- tpm2genkey go utility
- OCICrypt provider for Trusted Platform Modules (TPM)
For authentication using TPM based keys to cloud providers
-
AWS HMAC: AWS Credentials for Hardware Security Modules and TPM based AWS_SECRET_ACCESS_KEY -
AWS Roles Anywhere: AWS SDK CredentialProvider for RolesAnywhere -
AWS TPM process credentials: AWS Process Credentials for Trusted Platform Module (TPM) -
GCP Credential Source Binary: TPM Credential Source for Google Cloud SDK -
GCP TokenSource: GCP TPM AccessTokenSource
- Kubernetes Trusted Platform Module (TPM) DaemonSet
- Kubernetes Trusted Platform Module (TPM) using Device Plugin and Gatekeeper
- mTLS with TPM bound private key
- TPM based TLS using Attested Keys (experimental)
- TPM One Time Password using TLS SessionKey
Additional References:
-
Simple cli utility similar to tpm2tss-genkey which
- creates new TPM-based
RSA|ECCkeys and saves the keys inPEMformat. - converts basic the public/private keyfiles generated using
tpm2_toolsintoPEMfile format. - converts
PEMTPM keyfiles to public/private structures readable bytpm2_tools.
- creates new TPM-based
Update 8/28/21: Added a gRPC client/server that does full remote attestation, quote/verify and secret sharing:
-
encrypt_with_tpm_rsa: Encrypt with RSA Key generated on TPM (tpm2_create,tpm2_rsaencrypt, tpm2_decrypt) -
chained_keys: Encrypt/Decrypt using parent->child->child keys -
gcp_ek_ak: read gcp ek keys from NV using go-tpm-tools and gcloud API -
ek_cert_keyread generic the ek cert and key from NV -
ek_ak: generate ek and ak -
tpm2_tools_load_ctx: convert saved context files betweentpm2_tools<>go-tpm(experimental) -
go_ek_csr: issue CSR from EKRSA (signing) -
ek_import_blob: Seal data using a real tpm's ekcert signed by Optiga -
tpm_quote_verify: Generate TPM Quote blob with PCR23 value (tpm2_createak,tpm2_quote,tpm2_checkquote) -
event_log: Generate and Verify a TPM event log -
srk_seal_unseal: Seal arbitrary data directly to TPM; use PCR Policy (tpm2_create,tpm2_load,tpm2_seal,tpm2_unseal) -
sign_with_ak: Sign with Attestation Key (tpm2_createak,tpm2_hash,tpm2_sign,tpm2_verifysignature) -
sign_certify_ak: Generate Child key and Sign data with it. Create Attestation/Certify child key with AK. Verify Signature. -
sign_wth_rsa: Generate RSA key with TPM and sign (tpm2_create,tpm2_load,tpm2_sign,tpm2_verifysignature) -
sign_wth_ecc: Generate ECC key with TPM and sign, verify -
encrypte_decrypt_aes: encrypt and decrypt with aes key on tpm -
keyfile-go-tpm-tools: use go-tpm's direct api withgo-tpm-keyfilesandgo-tpm-tools.client.Key -
simulator_swtpm_tcpdump: run a software tpm locally use tcpdump to decode traffic with wireshark -
tpm2_tools_load_ctx: load a key context saved by tpm2_tools using go-tpm -
tpm_encrypted_session: demonstrate session encryption to protect cpu->tpm bus interface -
password: Encrypt/Decrypt with passwords on parent and key -
h2_primary_template: using the H2 primary key template -
rsa_import: Import external RSA key to TPM; decrypt data with TPM (tpm2_import, tpm2_load, tpm2_rsadecrypt) -
ecc_import: Import external ECC key to TPM; decrypt data with TPM (tpm2_import, tpm2_load, tpm2_rsadecrypt) -
tpm_make_activate: Attestation Protocol using Make-Activate credentials (tpm2_makecredential,tpm2_activatecredential) -
tpm2_get_ak_name: Gets the AK "name" given the PEM format of a public key. -
tpm2_duplicate: Use (tpm2_import,tpm2_duplicate) encrypt and transfer a key from one TPM to another. -
tpm2_duplicate_direct: duplicate an rsa key toTPM-Bmanually (i.,e withoutTPM-A) -
tpm2_duplicate_go: Duplicate HMAC key from one tpm to another using go-tpm's direct API. Also calculate HMAC in go using the TPM -
hmac_import: Import an external hmac key and use it to do hmac-stuff -
hmac_import: Import an external aes key and use it to do hmac-stuff -
policy: Samples covering using session policy (pcr, policysigned, password, authvalue) -
policy_gen: Extract and use the raw low-level policy command parameters -
tpm_services: samples in go for standalone remote attestation, quote-verify and seal-unseal -
ek_import_blob: Transfer secret using ekPub only. Example only coversgo-tpmbased transfer (TODO: figure out thetpm2_toolsflow). * see to https://github.com/salrashid123/gcp_tpm_sealed_keys -
ek_import_rsa_blob: Transfer RSA key from your local system to a GCP vTPM using its ekPub only. Example only coversgo-tpmbased transfer. For example, use this mechanism to transfer a Service Account Private key securely such that the key on the vTPM cannot be exported but yet available to sign and authenticate. * see to https://github.com/salrashid123/gcp_tpm_sealed_keys -
mTLS: mTLS usinggo-tpmand nginx -
ima_policy: Sample 'helloworld' configuration of IMA. -
pcr_utils: Read and Extend PCR values -
PKCS11: Access TPM using PKCS-11 and openssl -
LUKS: Use TPM for LUKS encryption -
attest_verify: remote attestation usinggo-tpm-tools -
ak_sign_nv: read Attestation Key from NV index, sign and verify for Google Compute Engine VMs -
context_chain: create parent, child, grandchild keys -
resource_manager:tpm0`` vstpmrm0` -
kdf: Key Derivation Functions (KDF) based on the recommendations of NIST SP 800-108 using TPM baced HMAC -
tpm_remote: Connect to a remote TPM over inscure TCP socket
If you want to test locally with a software tpm (swtpm), install the swtpm and launch.
Just note that AFAIK, the swtpm does not have a resrouce manager so you'll have to run tpm2_flushcontext -t a lot...
swtpm socket
rm -rf /tmp/myvtpm && mkdir /tmp/myvtpm && \
swtpm_setup --tpmstate /tmp/myvtpm --tpm2 --create-ek-cert && \
swtpm socket --tpmstate dir=/tmp/myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear
export TPM2TOOLS_TCTI="swtpm:port=2321"swtpm socketwithsocat
rm -rf /tmp/myvtpm && mkdir /tmp/myvtpm && \
swtpm_setup --tpmstate /tmp/myvtpm --tpm2 --create-ek-cert && \
swtpm socket --tpmstate dir=/tmp/myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear
sudo socat pty,link=/tmp/vtpm,raw,echo=0 tcp:localhost:2321
sudo chmod go+rw /tmp/vtpm
export TPM2TOOLS_TCTI="device:/tmp/vtpm"swtpm chardev
TODO:,
Excercising any of the scenarios above requires access to a TPM(!). You can use vTPM included with a Google Cloud Shielded VM surfaced at /dev/tpmrm0 on the VM
gcloud compute instances create shielded-1 --zone=us-central1-a --machine-type=n1-standard-1 --no-service-account --no-scopes --image=ubuntu-1804-bionic-v20191002 --image-project=gce-uefi-images --no-shielded-secure-boot --shielded-vtpm --shielded-integrity-monitoring
note, you may need to update
--image=
-
Install golang
-
Install
tpm2_tools:
either from debian-testing
$ vi /etc/apt/sources.list
deb http://http.us.debian.org/debian/ testing non-free contrib main
$ export DEBIAN_FRONTEND=noninteractive
$ apt-get update && apt-get install libtpm2-pkcs11-1 tpm2-tools libengine-pkcs11-openssl opensc -y
or from source:
apt-get update
apt -y install autoconf-archive libcmocka0 libcmocka-dev procps iproute2 build-essential git pkg-config gcc libtool automake libssl-dev uthash-dev autoconf doxygen libcurl4-openssl-dev dbus-x11 libglib2.0-dev libjson-c-dev aclcd
git clone https://github.com/tpm2-software/tpm2-tss.git
cd tpm2-tss
./bootstrap
./configure --with-udevrulesdir=/etc/udev/rules.d
make -j$(nproc)
make install
udevadm control --reload-rules && sudo udevadm trigger
ldconfig
## to enable tss debug, set
### export TSS2_LOG=esys+debugcd
git clone https://github.com/tpm2-software/tpm2-tools.git
cd tpm2-tools
./bootstrap
./configure
make check
make installThis step is optional an only do this if you intend to use openssl w/ the TPM as the engine
cd
git clone https://github.com/tpm2-software/tpm2-tss-engine.git
cd tpm2-tss-engine
./bootstrap
./configure
make -j$(nproc)
sudo make installCheck if openssl works w/ tpm2 (optional)
$ openssl engine -t -c tpm2tss
(tpm2tss) TPM2-TSS engine for OpenSSL
[RSA, RAND]
[ available ]export OPENSSL_CONF=/path/to/openssl.cnf
$ openssl engine -t
(rdrand) Intel RDRAND engine
[ available ]
(dynamic) Dynamic engine loading support
[ unavailable ]
(tpm2tss) TPM2-TSS engine for OpenSSL
[ available ]openssl.cnf
[openssl_init]
engines = engine_section
[engine_section]
tpm2tss = tpm2tss_section
[tpm2tss_section]
engine_id = tpm2tss
dynamic_path = /usr/lib/x86_64-linux-gnu/engines-3/libtpm2tss.so
default_algorithms = RSA,ECDSA
init = 1
for openssl3 tpm2-openssl installed:
export OPENSSL_MODULES=/usr/lib/x86_64-linux-gnu/ossl-modules/ # or wherever tpm2.so sits, eg /usr/lib/x86_64-linux-gnu/ossl-modules/tpm2.so
$ openssl version
OpenSSL 3.0.9 30 May 2023 (Library: OpenSSL 3.0.9 30 May 2023)
$ openssl list --providers -provider tpm2
Providers:
tpm2
name: TPM 2.0 Provider
version: 1.2.0-25-g87082a3
status: activeFor non-root access using tss resource manager
# cat /etc/udev/rules.d/tpm-udev.rules
# tpm devices can only be accessed by the tss user but the tss
# group members can access tpmrm devices
KERNEL=="tpm[0-9]*", TAG+="systemd", MODE="0660", OWNER="tss"
KERNEL=="tpmrm[0-9]*", TAG+="systemd", MODE="0660", GROUP="tss"sudo usermod -a -G tss $USER
newgrp tss tpm2_flushcontext --loaded-session
tpm2_flushcontext --saved-session
tpm2_flushcontext --transient-objectGit repo demonstrating running mTLS using go-tpm and nginx webserver:
If you have openssl and want to issue a cert on the TPM,
using openssl3 tpm2-openssl installed:
git clone https://github.com/salrashid123/ca_scratchpad.git
cd ca_scratchpad/
mkdir -p ca/root-ca/private ca/root-ca/db crl certs
chmod 700 ca/root-ca/private
cp /dev/null ca/root-ca/db/root-ca.db
cp /dev/null ca/root-ca/db/root-ca.db.attr
echo 01 > ca/root-ca/db/root-ca.crt.srl
echo 01 > ca/root-ca/db/root-ca.crl.srl
export SAN=single-root-ca
openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 \
-pkeyopt rsa_keygen_pubexp:65537 -out ca/root-ca/private/root-ca.key
openssl req -new -config single-root-ca.conf -key ca/root-ca/private/root-ca.key \
-out ca/root-ca.csr
openssl ca -selfsign -config single-root-ca.conf \
-in ca/root-ca.csr -out ca/root-ca.crt \
-extensions root_ca_ext
export NAME=tpms
export SAN="DNS:server.domain.com"
openssl genpkey -provider tpm2 -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
-pkeyopt rsa_keygen_pubexp:65537 -out certs/$NAME.key
openssl req -new -provider tpm2 -provider default \
-config single-root-ca.conf -out certs/$NAME.csr \
-key certs/$NAME.key -subj "/C=US/O=Google/OU=Enterprise/CN=server.domain.com"
openssl ca \
-config single-root-ca.conf \
-in certs/$NAME.csr \
-out certs/$NAME.crt \
-extensions server_ext