Go to file
Matthew Garrett fe22f29ec8 Handle StartupLocality events
Systems with TXT enabled may issue the TPM2_Startup() command from a
locality other than 0. In this case, the initial value of PCR0 will
represent the locality that the call was made from. This is exposed to
higher layers by an EV_NO_ACTION event that has data containing the
NULL-terminated string "StartupLocality" followed by a single byte
representing the state of the locality. As this event is EV_NO_ACTION,
it does not represent an extension in itself.

So:

1) Ignore events that are EV_NO_ACTION when replaying the log, except:
2) For PCR0, if an event is EV_NO_ACTION and contains the string
"StartupLocality", use the final byte of the event data as the initial
value of PCR0 for the replay.
2020-06-11 13:18:05 -07:00
attest Handle StartupLocality events 2020-06-11 13:18:05 -07:00
attributecert Handle platform certificates that only provide a single property (#168) 2020-05-29 17:24:06 -07:00
ci Implement full coverage for TPM 1.2 tests. (#7) 2019-04-04 15:33:00 -07:00
docs docs: small changes to wording in the event log disclosure 2019-12-12 09:33:10 -08:00
CONTRIBUTING.md Initial commit. 2019-03-28 13:21:16 -07:00
go.mod Fix oss-fuzz, update to latest go-tpm (#165) 2020-05-07 15:25:53 -07:00
go.sum Fix oss-fuzz, update to latest go-tpm (#165) 2020-05-07 15:25:53 -07:00
LICENSE Initial commit. 2019-03-28 13:21:16 -07:00
README.md Fixed typo 2020-06-10 10:57:09 -04:00

Go-Attestation

GoDoc

Go-Attestation abstracts remote attestation operations across a variety of platforms and TPMs, enabling remote validation of machine identity and state. This project attempts to provide high level primitives for both client and server logic.

Talks on this project:

  • "Making Device Identity Trustworthy" - Open Source Summit Europe - October 2019 - (Slides)
  • "Using TPMs to Cryptographically Verify Devices at Scale" - Open Source Summit North America - September 2019 - (Video 39min)
  • "Making Remote Attestation Useful on Linux" - Linux Security Summit - September 2019 - (Video 26min)

Status

Go-Attestation is under active development and is not ready for production use. Expect API changes at any time.

Please note that this is not an official Google product.

Installation

The go-attestation package is installable using go get: go get github.com/google/go-attestation/attest

Linux users must install libtspi and its headers. This can be installed on debian-based systems using: sudo apt-get install libtspi-dev.

Example: device identity

TPMs can be used to identify a device remotely and provision unique per-device hardware-bound keys.

TPMs are provisioned with a set of Endorsement Keys (EKs) by the manufacturer. These optionally include a certificate signed by the manufacturer and act as a TPM's identity. For privacy reasons the EK can't be used to sign or encrypt data directly, and is instead used to attest to the presence of a signing key, an Attestation Key (AK), on the same TPM. (Newer versions of the spec may allow the EK to sign directly.)

During attestation, a TPM generates an AK and proves to a certificate authority that the AK is on the same TPM as a EK. If the certificate authority trusts the EK, it can transitively trust the AK, for example by issuing a certificate for the AK.

To perform attestation, the client generates an AK and sends the EK and AK parameters to the server:

// Client generates an AK and sends it to the server

config := &attest.OpenConfig{}
tpm, err := attest.OpenTPM(config)
if err != nil {
    // handle error
}

eks, err := tpm.EKs()
if err != nil {
    // handle error
}
ek := eks[0]

akConfig := &attest.AKConfig{}
ak, err := tpm.NewAK(akConfig)
if err != nil {
    // handle error
}
attestParams := ak.AttestationParameters()

akBytes, err := ak.Marshal()
if err != nil {
    // handle error
}

if err := ioutil.WriteFile("encrypted_aik.json", akBytes, 0600); err != nil {
    // handle error
}

// send TPM version, EK, and attestParams to the server

The server uses the EK and AK parameters to generate a challenge encrypted to the EK, returning the challenge to the client. During this phase, the server determines if it trusts the EK, either by chaining its certificate to a known manufacturer and/or querying an inventory system.

// Server validates EK and/or EK certificate

params := attest.ActivationParameters{
    TPMVersion: tpmVersion,
    EK:         ek.Public,
    AK:         attestParams,
}
secret, encryptedCredentials, err := params.Generate()
if err != nil {
    // handle error
}

// return encrypted credentials to client

The client proves possession of the AK by decrypting the challenge and returning the same secret to the server.

// Client decrypts the credential

akBytes, err := ioutil.ReadFile("encrypted_aik.json")
if err != nil {
    // handle error
}
ak, err := tpm.LoadAK(akBytes)
if err != nil {
    // handle error
}
secret, err := ak.ActivateCredential(tpm, encryptedCredentials)
if err != nil {
    // handle error
}

// return secret to server

At this point, the server records the AK and EK association and allows the client to use its AK as a credential (e.g. by issuing it a client certificate).