Implement helper method + struct for getting a platform attestation (#113)

This commit is contained in:
Tom D 2019-09-26 13:00:20 -07:00 committed by GitHub
parent 82c790063a
commit 20ad7d44ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 0 deletions

View File

@ -312,6 +312,30 @@ func (a HashAlg) String() string {
return fmt.Sprintf("HashAlg<%d>", int(a))
}
// PlatformParameters encapsulates the set of information necessary to attest
// the booted state of the machine the TPM is attached to.
//
// The digests contained in the event log can be considered authentic if:
// - The AIK public corresponds to the known AIK for that platform.
// - All quotes are verified with AIKPublic.Verify(), and return no errors.
// - The event log parsed successfully using ParseEventLog(), and a call
// to EventLog.Verify() with the full set of PCRs returned no error.
type PlatformParameters struct {
// The version of the TPM which generated this attestation.
TPMVersion TPMVersion
// The public blob of the AIK which endorsed the platform state. This can
// be decoded to verify the adjacent quotes using ParseAIKPublic().
Public []byte
// The set of quotes which endorse the state of the PCRs.
Quotes []Quote
// The set of expected PCR values, which are used in replaying the event log
// to verify digests were not tampered with.
PCRs []PCR
// The raw event log provided by the platform. This can be processed with
// ParseEventLog().
EventLog []byte
}
var (
defaultOpenConfig = &OpenConfig{}

View File

@ -317,6 +317,56 @@ func (t *TPM) PCRs(alg HashAlg) ([]PCR, error) {
return t.tpm.pcrs(alg)
}
func (t *TPM) attestPCRs(aik *AIK, nonce []byte, alg HashAlg) (*Quote, []PCR, error) {
pcrs, err := t.PCRs(alg)
if err != nil {
return nil, nil, fmt.Errorf("failed to read %v PCRs: %v", alg, err)
}
quote, err := aik.Quote(t, nonce, alg)
if err != nil {
return nil, nil, fmt.Errorf("failed to quote using %v: %v", alg, err)
}
return quote, pcrs, nil
}
// AttestPlatform computes the set of information necessary to attest the
// state of the platform. For TPM 2.0 devices, AttestPlatform will attempt
// to read both SHA1 & SHA256 PCR banks and quote both of them, so bugs in
// platform firmware which break replay for one PCR bank can be mitigated
// using the other.
func (t *TPM) AttestPlatform(aik *AIK, nonce []byte) (*PlatformParameters, error) {
out := PlatformParameters{
TPMVersion: t.Version(),
Public: aik.AttestationParameters().Public,
}
var err error
if out.EventLog, err = t.MeasurementLog(); err != nil {
return nil, fmt.Errorf("failed to read event log: %v", err)
}
algs := []HashAlg{HashSHA1}
if t.Version() == TPMVersion20 {
algs = []HashAlg{HashSHA1, HashSHA256}
}
var lastErr error
for _, alg := range algs {
quote, pcrs, err := t.attestPCRs(aik, nonce, alg)
if err != nil {
lastErr = err
continue
}
out.Quotes = append(out.Quotes, *quote)
out.PCRs = append(out.PCRs, pcrs...)
}
if len(out.Quotes) == 0 {
return nil, lastErr
}
return &out, nil
}
// Version returns the version of the TPM.
func (t *TPM) Version() TPMVersion {
return t.tpm.tpmVersion()