惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
L
LINUX DO - 最新话题
N
News | PayPal Newsroom
S
Security Affairs
W
WeLiveSecurity
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Webroot Blog
Webroot Blog
Spread Privacy
Spread Privacy
A
Arctic Wolf
T
Troy Hunt's Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cybersecurity and Infrastructure Security Agency CISA
T
Threat Research - Cisco Blogs
V2EX - 技术
V2EX - 技术
Scott Helme
Scott Helme
Google Online Security Blog
Google Online Security Blog
Schneier on Security
Schneier on Security
F
Fortinet All Blogs
U
Unit 42
爱范儿
爱范儿
腾讯CDC
S
Security @ Cisco Blogs
PCI Perspectives
PCI Perspectives
Hacker News - Newest:
Hacker News - Newest: "LLM"
Apple Machine Learning Research
Apple Machine Learning Research
C
CERT Recently Published Vulnerability Notes
Security Latest
Security Latest
Y
Y Combinator Blog
S
Schneier on Security
Cisco Talos Blog
Cisco Talos Blog
T
The Blog of Author Tim Ferriss
Hugging Face - Blog
Hugging Face - Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
IT之家
IT之家
K
Kaspersky official blog
Security Archives - TechRepublic
Security Archives - TechRepublic
博客园 - 聂微东
Cloudbric
Cloudbric
V
V2EX
H
Help Net Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
小众软件
小众软件
TaoSecurity Blog
TaoSecurity Blog
T
Tor Project blog
G
Google Developers Blog
人人都是产品经理
人人都是产品经理
GbyAI
GbyAI
MyScale Blog
MyScale Blog

Morten Linderud

ACME device attestation, smallstep and pkcs11: attezt Personal infrastructure setup 2026 Self-hosting DNS for no fun, but a little profit! Easter hack: terraform-provider-openwrt SSH CA with device and identity attestation: ssh-tpm-ca-authority NixOS is not reproducible Stream to chromecast with resolved, vlc and bash Store ssh keys inside the TPM: ssh-tpm-agent Golang crypto/ecdh and the TPM My FOSS work update coredumpctl, delve and debug packages for Go Monitoring the kernel.org Transparency Log for a year Streaming the Steam Deck to OBS mkinitcpio v31 and UEFI stubs FOSS Activities in April 2021 FOSS Activities in March 2021 Simplifying and securing the boot process FOSS Activities in February 2021 FOSS Activities in January 2021 FOSS Activities in December 2020 Kubernetes in Arch Linux FOSS Activities in November 2020 PAM Bypass: when null(is not)ok FOSS Activities in October 2020 Improving the Secure Boot user experience Packaging LXD for Arch Linux Reproducible Arch Linux Packages Mailpile, sendmail and procmail The State of Hy Morten Linderud
Store age identities inside the TPM: age-plugin-tpm
Morten Linderud · 2023-07-18 · via Morten Linderud

The past year I have been trying to learn more about the Trusted Platform Module (TPM). This is a small device found on most modern laptops that has several cool security features like key creation, sealing and attestation, however I have been struggling to find a small project where I can learn more about it.

To my surprised I learned a couple of months ago that nobody has written a TPM plugin for age!

age is a file encryption tool written by Filippo Valsorda to replace the file encryption feature people utilize from GnuPG1. It has plugin system which allows you to encrypt to whatever key formate and storage you would need. Currently the most popular plugin seems to be age-plugin-yubikey which allows key storage on yubikeys.

Hardware tokens

So why do we want to store key material on hardware like Yubikey or a TPM?

I think the most obvious one is to prevent key extraction or the key leaking. We are all aware of the funny examples when people confuse a SSH private key with a public key and share the wrong file. If it’s stored as a resident key on the Yubikey, or stored inside the TPM, leaking this file would be harmless as it just contains some metadata.

It also prevents a compromised system from getting the key extracted. This means the active exploiter would need continuous presence on the system to abuse the key file. Disconnecting the machine from the internet would make the key material inaccessible to the attacker.

Another cool property of the TPM is that it supports defending against dictionary attacks. After 3 attempts to brute force the password of the key, the TPM will lock access to it until the TPM has been reset. Which makes brute forcing not possible.

This feature allows us to effectively move away from a password, or a passphrase, to a smaller PIN as we don’t need to rely on the entropy any more.

A TPM plugin for age would make the above security aspects more easily accessible for people. Instead of buying an expensive security key, we can just utilize the TPM we already have.

age-plugin-tpm is my first attempt at writing something useable that interfaces with the TPM. It is written in Golang and uses the google/go-tpm library which is a native API for interacting with the TPM. This is neat as it allows us to not rely on external C libraries.

https://github.com/Foxboron/age-plugin-tpm

The crypto primitives is a very close reimplementation of what age itself is doing with it’s native keys.

It uses NIST P256 keys with a Elliptic-curve Diffie–Hellman (ECDH) shared secret which is used inside a HMAC based key derivative function (hkdf) to protect the key used for file encryption and decryption. The ECDH shared secret is done inside the TPM, while rest is done in Go itself.

To use the plugin one can either install it with go install, or download the pre-compiled binaries and throw them into $PATH.

λ » age-plugin-tpm --generate -o - | tee age-identity.txt
# Created: 2023-07-17 17:51:01.821730119 +0200 CEST m=+0.473471400
# Recipient: age1tpm1q045hl84w9hhy2kjvs9tyugfqal083qw9nc60m5pk824u8q3manuuy96qpf

AGE-PLUGIN-TPM-1QYQQQKQQYVQQKQQZQPEQQQQQZQQPJQQTQQPSQYQQYR45HL84W9HHY2KJVS9TYUGFQAL083QW9NC60M5PK824U8Q3MANUUQPQ2NEEA5Q3DST4WUWFQLXH67F50DFQZD4WVA704NMM23HXE7Z2JMASQLSQYZ904GFUL3XLSX8HZ0RM6E852JDUAKZAP63ZAPWC9MSR6MP6NTDD5QQSWMLCU8UKWF4ZEP9GH77R6JHQA6H68WSJ3VCJSHALCCWT7NDNMUJNKTYTQ93KQWJ53J03J2W9Z4GXRK0ZERPR3NDAY5GL7NWCAM7YXA3UH7856J780P9R2ER6G57PU9HJRVQC7VAPDKN5N4YM7D5M6F

All identities we create with age-plugin-tpm are stored outside of the TPM as the TPM are small devices with limited memory. The private parts of the TPM object is wrapped by a parent key which never leaves the TPM and can’t be decrypted outside of the TPM.

We can also optionally include a PIN to the key by passing the --pin flag or setting the AGE_TPM_PIN environment variable.

To get the recipient from the identity, we can just pass the identity with the -y flag.

λ » age-plugin-tpm -y age-identity.txt
age1tpm1qfnxa6c5q007tt6pn9h4yz6krf04qusdf76ppxnax0na8h9ygwx7zp4dq3l

You can also pipe stuff to encrypt and decrypt things.

λ » echo "Hack the planet" | \
    age -r $(age-plugin-tpm -y age-identity.txt) -a | \
    age -d -i age-identity.txt
Hack the planet

If you don’t feel like trying to use your TPM when trying out the tool, I’ve implemented a --swtpm and a AGE_PLUGIN_TPM_SWTPM environment variable which is going to start a new instance of the software TPM swtpm and allow you to try out the plugin. This requires swtpm installed to work.

This project uses the new tpmdirect API which intends to replace the old tpm2 library inside go-tpm. This allows us to make use of session encryption when communicating with the TPM. This prevents a common attack vector where people with physical access to the machine is capable of sniffing secrets part of the TPM interaction.

In age-plugin-tpm the PIN passed to the TPM through an encrypted session, as well as the output when we generated the shared secret during the ECDH handshake.

Chris Fenner, who is the author of this library, was also very kind to look over the API usage :)

Generally I think this project should in a useable state for people. The key format and the crypto should not see any large revisions. However I would like to try and implement some PCR sealing, but this is a larger thing I need to learn more about.

The codebase needs some work in some places, and while go-tpm supports Windows I have only been writing this for Linux. Patches and feature requests are always welcome!

Back to posts