attest

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 6, 2019 License: Apache-2.0 Imports: 29 Imported by: 44

Documentation

Overview

Package attest abstracts TPM attestation operations.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	HashSHA1   = HashAlg(tpm2.AlgSHA1)
	HashSHA256 = HashAlg(tpm2.AlgSHA256)
)

Valid hash algorithms.

View Source
var (

	// ErrTPMNotAvailable is returned in response to OpenTPM() when
	// either no TPM is available, or a TPM of the requested version
	// is not available (if TPMVersion was set in the provided config).
	ErrTPMNotAvailable = errors.New("TPM device not available")
	// ErrTPM12NotImplemented is returned in response to methods which
	// need to interact with the TPM1.2 device in ways that have not
	// yet been implemented.
	ErrTPM12NotImplemented = errors.New("TPM 1.2 support not yet implemented")
)

Functions

func ParseEKCertificate

func ParseEKCertificate(ekCert []byte) (*x509.Certificate, error)

ParseEKCertificate parses a raw DER encoded EK certificate blob.

Types

type AIK

type AIK struct {
	// contains filtered or unexported fields
}

AIK represents a key which can be used for attestation.

Example
package main

import (
	"log"

	"github.com/google/go-attestation/attest"
)

func main() {
	tpm, err := attest.OpenTPM(nil)
	if err != nil {
		log.Fatalf("Failed to open the TPM: %v", err)
	}
	defer tpm.Close()

	// Create a new AIK.
	aik, err := tpm.NewAIK(nil)
	if err != nil {
		log.Fatalf("Failed to create AIK: %v", err)
	}
	// Save a re-loadable representation to blob.
	blob, err := aik.Marshal()
	if err != nil {
		log.Fatalf("Failed to marshal AIK: %v", err)
	}
	// Close our handle to the AIK.
	if err := aik.Close(tpm); err != nil {
		log.Fatalf("Failed to close AIK: %v", err)
	}

	// Re-load the created AIK from the blob.
	aik, err = tpm.LoadAIK(blob)
	if err != nil {
		log.Fatalf("Failed to load AIK: %v", err)
	}
	if err := aik.Close(tpm); err != nil {
		log.Fatalf("Failed to close AIK: %v", err)
	}
}
Output:

Example (CredentialActivation)
package main

import (
	"crypto/subtle"
	"log"

	"github.com/google/go-attestation/attest"
)

func main() {
	tpm, err := attest.OpenTPM(nil)
	if err != nil {
		log.Fatalf("Failed to open TPM: %v", err)
	}
	defer tpm.Close()

	// Create a new AIK.
	aik, err := tpm.NewAIK(nil)
	if err != nil {
		log.Fatalf("Failed to create AIK: %v", err)
	}
	defer aik.Close(tpm)

	// Read the EK.
	ek, err := tpm.EKs()
	if err != nil {
		log.Fatalf("Failed to enumerate EKs: %v", err)
	}

	// Read parameters necessary to generate a challenge.
	ap := aik.AttestationParameters()

	// Generate a credential activation challenge (usually done on the server).
	activation := attest.ActivationParameters{
		TPMVersion: tpm.Version(),
		EK:         ek[0].Public,
		AIK:        ap,
	}
	secret, challenge, err := activation.Generate()
	if err != nil {
		log.Fatalf("Failed to generate activation challenge: %v", err)
	}

	// Challenge the AIK & EK properties to recieve the decrypted secret.
	decrypted, err := aik.ActivateCredential(tpm, *challenge)
	if err != nil {
		log.Fatalf("Failed to activate credential: %v", err)
	}

	// Check that the AIK completed the challenge (usually done on the server).
	if subtle.ConstantTimeCompare(secret, decrypted) == 0 {
		log.Fatal("Activation response did not match secret")
	}
}
Output:

Example (Quote)
package main

import (
	"log"

	"github.com/google/go-attestation/attest"
)

func main() {
	tpm, err := attest.OpenTPM(nil)
	if err != nil {
		log.Fatalf("Failed to open TPM: %v", err)
	}
	defer tpm.Close()

	// Create a new AIK.
	aik, err := tpm.NewAIK(nil)
	if err != nil {
		log.Fatalf("Failed to create AIK: %v", err)
	}
	defer aik.Close(tpm)

	// The nonce would typically be provided by the server.
	nonce := []byte{1, 2, 3, 4, 5, 6, 7, 8}

	// Perform the quote & gather information necessary to verify it.
	quote, err := aik.Quote(tpm, nonce, attest.HashSHA1)
	if err != nil {
		log.Fatalf("Failed to generate quote: %v", err)
	}
	pcrs, err := tpm.PCRs(attest.HashSHA1)
	if err != nil {
		log.Fatalf("Failed to collect PCR values: %v", err)
	}
	log.Printf("quote = %+v", quote)
	log.Printf("PCRs = %+v", pcrs)
}
Output:

func (*AIK) ActivateCredential

func (k *AIK) ActivateCredential(tpm *TPM, in EncryptedCredential) (secret []byte, err error)

ActivateCredential decrypts the secret using the key to prove that the AIK was generated on the same TPM as the EK.

This operation is synonymous with TPM2_ActivateCredential.

func (*AIK) AttestationParameters

func (k *AIK) AttestationParameters() AttestationParameters

Parameters returns information about the AIK, typically used to generate a credential activation challenge.

func (*AIK) Close

func (k *AIK) Close(t *TPM) error

Close unloads the AIK from the system.

func (*AIK) Marshal

func (k *AIK) Marshal() ([]byte, error)

Marshal encodes the AIK in a format that can be reloaded with tpm.LoadAIK(). This method exists to allow consumers to store the key persistently and load it as a later time. Users SHOULD NOT attempt to interpret or extract values from this blob.

func (*AIK) Quote

func (k *AIK) Quote(tpm *TPM, nonce []byte, alg HashAlg) (*Quote, error)

Quote returns a quote over the platform state, signed by the AIK.

type AIKConfig

type AIKConfig struct {
}

AIKConfig encapsulates parameters for minting keys. This type is defined now (despite being empty) for future interface compatibility.

type AIKPublic

type AIKPublic struct {
	// Public is the public part of the AIK. This can either be an *rsa.PublicKey or
	// and *ecdsa.PublicKey.
	Public crypto.PublicKey
	// Hash is the hashing algorithm the AIK will use when signing quotes.
	Hash crypto.Hash
}

AIKPublic holds structured information about an AIK's public key.

func ParseAIKPublic

func ParseAIKPublic(version TPMVersion, public []byte) (*AIKPublic, error)

ParseAIKPublic parses the Public blob from the AttestationParameters, returning the public key and signing parameters for the key.

func (*AIKPublic) Verify

func (a *AIKPublic) Verify(quote Quote, pcrs []PCR, nonce []byte) error

Verify is used to prove authenticity of the PCR measurements. It ensures that the quote was signed by the AIK, and that its contents matches the PCR and nonce combination.

The nonce is used to prevent replays of Quote and PCRs and is signed by the quote. Some TPMs don't support nonces longer than 20 bytes, and if the nonce is used to tie additional data to the quote, the additional data should be hashed to construct the nonce.

Example
package main

import (
	"log"

	"github.com/google/go-attestation/attest"
)

func main() {
	tpm, err := attest.OpenTPM(nil)
	if err != nil {
		log.Fatalf("Failed to open TPM: %v", err)
	}
	defer tpm.Close()

	// Create a new AIK.
	aik, err := tpm.NewAIK(nil)
	if err != nil {
		log.Fatalf("Failed to create AIK: %v", err)
	}
	defer aik.Close(tpm)

	// The nonce would typically be provided by the server.
	nonce := []byte{1, 2, 3, 4, 5, 6, 7, 8}

	// Perform the quote & gather information necessary to verify it.
	quote, err := aik.Quote(tpm, nonce, attest.HashSHA256)
	if err != nil {
		log.Fatalf("Failed to generate quote: %v", err)
	}
	pcrs, err := tpm.PCRs(attest.HashSHA256)
	if err != nil {
		log.Fatalf("Failed to collect PCR values: %v", err)
	}

	// Construct an AIKPublic struct from the parameters of the key.
	pub, err := attest.ParseAIKPublic(tpm.Version(), aik.AttestationParameters().Public)
	if err != nil {
		log.Fatalf("Failed to parse AIK public: %v", err)
	}

	if err := pub.Verify(*quote, pcrs, nonce); err != nil {
		log.Fatalf("Verification failed: %v", err)
	}
}
Output:

type ActivationParameters

type ActivationParameters struct {
	// TPMVersion holds the version of the TPM, either 1.2 or 2.0.
	TPMVersion TPMVersion

	// EK, the endorsement key, describes an asymmetric key who's
	// private key is permenantly bound to the TPM.
	//
	// Activation will verify that the provided EK is held on the same
	// TPM as the AIK. However, it is the callers responsibility to
	// ensure the EK they provide corresponds to the the device which
	// they are trying to associate the AIK with.
	EK crypto.PublicKey

	// AIK, the Attestation Identity Key, describes the properties of
	// an asymmetric key (managed by the TPM) which signs attestation
	// structures.
	// The values from this structure can be obtained by calling
	// Parameters() on an attest.AIK.
	AIK AttestationParameters

	// Rand is a source of randomness to generate a seed and secret for the
	// challenge.
	//
	// If nil, this defaults to crypto.Rand.
	Rand io.Reader
}

ActivationParameters encapsulates the inputs for activating an AIK.

func (*ActivationParameters) Generate

func (p *ActivationParameters) Generate() (secret []byte, ec *EncryptedCredential, err error)

Generate returns a credential activation challenge, which can be provided to the TPM to verify the AIK parameters given are authentic & the AIK is present on the same TPM as the EK.

The caller is expected to verify the secret returned from the TPM as as result of calling ActivateCredential() matches the secret returned here. The caller should use subtle.ConstantTimeCompare to avoid potential timing attack vectors.

type AttestationParameters

type AttestationParameters struct {
	// Public represents the AIK's canonical encoding. This blob includes the
	// public key, as well as signing parameters such as the hash algorithm
	// used to generate quotes.
	//
	// Use ParseAIKPublic to access the key's data.
	Public []byte

	// UseTCSDActivationFormat is set when tcsd (trousers daemon) is operating
	// as an intermediary between this library and the TPM. A value of true
	// indicates that activation challenges should use the TCSD-specific format.
	UseTCSDActivationFormat bool

	// CreateData represents the properties of a TPM 2.0 key. It is encoded
	// as a TPMS_CREATION_DATA structure.
	CreateData []byte
	// CreateAttestation represents an assertion as to the details of the key.
	// It is encoded as a TPMS_ATTEST structure.
	CreateAttestation []byte
	// CreateSignature represents a signature of the CreateAttestation structure.
	// It is encoded as a TPMT_SIGNATURE structure.
	CreateSignature []byte
}

AttestationParameters describes information about a key which is necessary for verifying its properties remotely.

type EK

type EK struct {
	// Public key of the EK.
	Public crypto.PublicKey

	// Certificate is the EK certificate for TPMs that provide it.
	Certificate *x509.Certificate

	// For Intel TPMs, Intel hosts certificates at a public URL derived from the
	// Public key. Clients or servers can perform an HTTP GET to this URL, and
	// use ParseEKCertificate on the response body.
	CertificateURL string
}

EK is a burned-in endorcement key bound to a TPM. This optionally contains a certificate that can chain to the TPM manufacturer.

type EncryptedCredential

type EncryptedCredential struct {
	Credential []byte
	Secret     []byte
}

EncryptedCredential represents encrypted parameters which must be activated against a key.

type Event

type Event struct {
	// PCR index of the event.
	Index int
	// Type of the event.
	Type EventType

	// Data of the event. For certain kinds of events, this must match the event
	// digest to be valid.
	Data []byte
	// Digest is the verified digest of the event data. While an event can have
	// multiple for different hash values, this is the one that was matched to the
	// PCR value.
	Digest []byte
}

Event is a single event from a TCG event log. This reports descrete items such as BIOs measurements or EFI states.

type EventLog

type EventLog struct {
	// contains filtered or unexported fields
}

EventLog is a parsed measurement log. This contains unverified data representing boot events that must be replayed against PCR values to determine authenticity.

func ParseEventLog

func ParseEventLog(measurementLog []byte) (*EventLog, error)

ParseEventLog parses an unverified measurement log.

func (*EventLog) Verify

func (e *EventLog) Verify(pcrs []PCR) ([]Event, error)

Verify replays the event log against a TPM's PCR values, returning events from the event log, or an error if the replayed PCR values did not match the provided PCR values.

type EventType

type EventType uint32

EventType indicates what kind of data an event is reporting.

type HashAlg

type HashAlg uint8

HashAlg identifies a hashing Algorithm.

type OpenConfig

type OpenConfig struct {
	// TPMVersion indicates which TPM version the library should
	// attempt to use. If the specified version is not available,
	// ErrTPMNotAvailable is returned. Defaults to TPMVersionAgnostic.
	TPMVersion TPMVersion
}

OpenConfig encapsulates settings passed to OpenTPM().

type PCR

type PCR struct {
	Index     int
	Digest    []byte
	DigestAlg crypto.Hash
}

PCR encapsulates the value of a PCR at a point in time.

type Quote

type Quote struct {
	Version   TPMVersion
	Quote     []byte
	Signature []byte
}

Quote encapsulates the results of a Quote operation against the TPM, using an attestation key.

type TCGVendorID

type TCGVendorID uint32

TCGVendorID represents a unique TCG manufacturer code. The canonical reference used is located at: https://trustedcomputinggroup.org/wp-content/uploads/TCG-TPM-Vendor-ID-Registry-Version-1.01-Revision-1.00.pdf

func (TCGVendorID) String

func (id TCGVendorID) String() string

type TPM

type TPM struct {
	// contains filtered or unexported fields
}

TPM interfaces with a TPM device on the system.

func OpenTPM

func OpenTPM(config *OpenConfig) (*TPM, error)

OpenTPM initializes access to the TPM based on the config provided.

func (*TPM) Close

func (t *TPM) Close() error

Close shuts down the connection to the TPM.

func (*TPM) EKs

func (t *TPM) EKs() ([]EK, error)

EKs returns the endorsement keys burned-in to the platform.

func (*TPM) Info

func (t *TPM) Info() (*TPMInfo, error)

Info returns information about the TPM.

func (*TPM) LoadAIK

func (t *TPM) LoadAIK(opaqueBlob []byte) (*AIK, error)

LoadAIK loads a previously-created aik into the TPM for use. A key loaded via this function needs to be closed with .Close(). Only blobs generated by calling AIK.Serialize() are valid parameters to this function.

func (*TPM) MeasurementLog

func (t *TPM) MeasurementLog() ([]byte, error)

MeasurementLog returns the present value of the System Measurement Log.

func (*TPM) NewAIK

func (t *TPM) NewAIK(opts *AIKConfig) (*AIK, error)

NewAIK creates an attestation key.

func (*TPM) PCRs

func (t *TPM) PCRs(alg HashAlg) ([]PCR, error)

PCRs returns the present value of Platform Configuration Registers with the given digest algorithm.

func (*TPM) Version

func (t *TPM) Version() TPMVersion

Version returns the version of the TPM.

type TPMInfo

type TPMInfo struct {
	Version      TPMVersion
	Interface    TPMInterface
	VendorInfo   string
	Manufacturer TCGVendorID

	// FirmwareVersionMajor and FirmwareVersionMinor describe
	// the firmware version of the TPM, but are only available
	// for TPM 2.0 devices.
	FirmwareVersionMajor int
	FirmwareVersionMinor int
}

TPMInfo contains information about the version & interface of an open TPM.

func AvailableTPMs

func AvailableTPMs(config *OpenConfig) ([]TPMInfo, error)

AvailableTPMs returns information about available TPMs matching the given config, without opening the devices.

type TPMInterface

type TPMInterface uint8

TPMInterface indicates how the client communicates with the TPM.

const (
	TPMInterfaceDirect TPMInterface = iota
	TPMInterfaceKernelManaged
	TPMInterfaceDaemonManaged
)

TPM interfaces

type TPMVersion

type TPMVersion uint8

TPMVersion is used to configure a preference in which TPM to use, if multiple are available.

const (
	TPMVersionAgnostic TPMVersion = iota
	TPMVersion12
	TPMVersion20
)

TPM versions

Directories

Path Synopsis
Binary attest-tool performs attestation operations on the local system.
Binary attest-tool performs attestation operations on the local system.
internal
Package internal contains marshalling structures for attest-tool and tests.
Package internal contains marshalling structures for attest-tool and tests.
internal/eventlog
Package eventlog implements experimental logic for parsing the TCG event log format.
Package eventlog implements experimental logic for parsing the TCG event log format.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL