Show HN: MTLS with keys never leaving the TPM

alexpadula2 pts0 comments

GitHub - bschaatsbergen/go-tpm-tls: A, Go, crypto.Signer backed by a TPM key, so crypto/tls can authenticate with a key that never leaves the hardware. · GitHub

/" data-turbo-transient="true" />

Skip to content

Search or jump to...

Search code, repositories, users, issues, pull requests...

-->

Search

Clear

Search syntax tips

Provide feedback

--><br>We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

-->

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

bschaatsbergen

go-tpm-tls

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star

main

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>8 Commits<br>8 Commits

.github/workflows

.github/workflows

.gitignore

.gitignore

.golangci.yml

.golangci.yml

LICENSE

LICENSE

README.md

README.md

example_test.go

example_test.go

find.go

find.go

find_test.go

find_test.go

go.mod

go.mod

go.sum

go.sum

helpers_test.go

helpers_test.go

key.go

key.go

key_test.go

key_test.go

tls.go

tls.go

tls_test.go

tls_test.go

View all files

Repository files navigation

go-tpm-tls

Provides a crypto.Signer<br>backed by a key in a TPM, so crypto/tls can<br>authenticate a client or server with a key that never leaves the TPM. It is a<br>small layer over<br>go-tpm and<br>go-tpm-tools.

It does not create keys. It attaches to one that already exists, usually<br>provisioned by an attestation agent that generated it inside the TPM and had it<br>certified.

crypto/tls asks a private key to sign the handshake transcript. The TPM signs<br>internally and hands back the signature. The key is never read out, so there is<br>nothing in process memory to leak.

cert, err := x509.ParseCertificate(certDER)<br>if err != nil {<br>return err

key, err := tpmtls.OpenForCertificate(tpmtls.DefaultDevice, cert)<br>if err != nil {<br>return err<br>defer key.Close()

conn, err := tls.Dial("tcp", "store.example.com:443", &tls.Config{<br>MinVersion: tls.VersionTLS13,<br>Certificates: []tls.Certificate{key.TLSCertificate(certDER)},<br>})

Install

go get github.com/bschaatsbergen/go-tpm-tls

The import path is hyphenated, the package is not:

import "github.com/bschaatsbergen/go-tpm-tls" // package tpmtls

Attaching to a key

Use OpenForCertificate and pass the certificate you plan to present. It opens<br>the TPM and picks the key whose public half matches, so you do not have to<br>configure a handle that differs from machine to machine. Use Open when you do<br>know the handle. Both close the device when you close the key.

New and NewForCertificate are the same two over a TPM connection you already<br>have, and they leave it open. Use them when the TPM is shared with other code in<br>the same process, or in tests against a simulator.

The full API — signing, CSRs, finding handles — is documented at<br>pkg.go.dev.

Notes

Use an ECDSA key. RSA keys attach and sign, but not the way crypto/tls asks:<br>TLS wants RSA-PSS at a salt length the TPM will not use, so the handshake fails<br>at signing time with an error that does not mention any of this.

A TPM signature costs milliseconds where a software key costs microseconds, and<br>it lands once per full handshake rather than once per request. Session resumption<br>and connection reuse keep it off later connections, which is usually enough to<br>make it irrelevant.

Signing is serialized, since a TPM runs one command at a time, so what a machine<br>is limited to is new handshakes per second, not requests per second. That limit<br>is per machine, since each machine has its own TPM.

Where the key sits matters as much as any of this. A transient object is swapped<br>in and out by the kernel resource manager around each command, so every signature<br>pays to load the key back in, roughly ten times the cost of a persistent one.<br>Measurements are in<br>go-tpm-tls-bench.

Tests

go test ./...<br>golangci-lint run

Tests run against the TPM 2.0 reference simulator, so they need no TPM and no<br>root.

License

go-tpm-tls is released under a BSD-style license. See LICENSE.

Links

TCG TPM 2.0 Library specification

go-tpm and go-tpm-tools

RFC 8446, TLS 1.3, for what CertificateVerify signs

About<br>A, Go, crypto.Signer backed by a TPM key, so crypto/tls can authenticate with a key that never leaves the hardware.<br>Topics<br>gomtlstpm2<br>Resources<br>Readme<br>BSD-3-Clause license<br>Activity<br>Stars<br>2 stars<br>Watchers<br>0 watching<br>Forks<br>0 forks<br>Report repository

Used...

crypto github license never search sign

Related Articles