Add config struct for AttestPlatform(), to configure event log source (#118)

This commit is contained in:
Tom D 2019-10-03 11:09:32 -07:00 committed by GitHub
parent 56dc743f14
commit de6a3af7e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 56 deletions

View File

@ -119,6 +119,9 @@ func (k *AIK) ActivateCredential(tpm *TPM, in EncryptedCredential) (secret []byt
}
// Quote returns a quote over the platform state, signed by the AIK.
//
// This is a low-level API. Consumers seeking to attest the state of the
// platform should use tpm.AttestPlatform() instead.
func (k *AIK) Quote(tpm *TPM, nonce []byte, alg HashAlg) (*Quote, error) {
return k.aik.quote(tpm.tpm, nonce, alg)
}

View File

@ -91,46 +91,22 @@ func ExampleAIK_credentialActivation() {
}
}
func ExampleAIK_quote() {
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)
}
func TestExampleAIK(t *testing.T) {
if !*testExamples {
t.SkipNow()
}
ExampleAIK()
ExampleAIK_credentialActivation()
ExampleAIK_quote()
}
func ExampleAIKPublic_Verify() {
func TestExampleTPM(t *testing.T) {
if !*testExamples {
t.SkipNow()
}
ExampleTPM_AttestPlatform()
}
func ExampleTPM_AttestPlatform() {
tpm, err := attest.OpenTPM(nil)
if err != nil {
log.Fatalf("Failed to open TPM: %v", err)
@ -147,30 +123,27 @@ func ExampleAIKPublic_Verify() {
// 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)
// Perform an attestation against the state of the plaform. Usually, you
// would pass a nil config, and the event log would be read from the
// platform. To ensure this example runs on platforms without event logs,
// we pass a fake EventLog value.
att, err := tpm.AttestPlatform(aik, nonce, &attest.PlatformAttestConfig{
EventLog: []byte{0},
})
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)
log.Fatalf("Failed to attest the platform state: %v", err)
}
// Construct an AIKPublic struct from the parameters of the key.
// Construct an AIKPublic struct from the parameters of the key. This
// will be used to verify the quote signatures.
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)
for i, q := range att.Quotes {
if err := pub.Verify(q, att.PCRs, nonce); err != nil {
log.Fatalf("quote[%d] verification failed: %v", i, err)
}
}
}
func TestExampleAIKPublic(t *testing.T) {
if !*testExamples {
t.SkipNow()
}
ExampleAIKPublic_Verify()
}

View File

@ -298,6 +298,9 @@ func (t *TPM) LoadAIK(opaqueBlob []byte) (*AIK, error) {
}
// MeasurementLog returns the present value of the System Measurement Log.
//
// This is a low-level API. Consumers seeking to attest the state of the
// platform should use tpm.AttestPlatform() instead.
func (t *TPM) MeasurementLog() ([]byte, error) {
return t.tpm.measurementLog()
}
@ -310,9 +313,8 @@ func (t *TPM) NewAIK(opts *AIKConfig) (*AIK, error) {
// PCRs returns the present value of Platform Configuration Registers with
// the given digest algorithm.
//
// Use ParseEventLog to determine which algorithm to use to match the values
// present in the event log. It's not always guarenteed that a system with TPM
// 2.0 will extend PCRs with SHA256 digests.
// This is a low-level API. Consumers seeking to attest the state of the
// platform should use tpm.AttestPlatform() instead.
func (t *TPM) PCRs(alg HashAlg) ([]PCR, error) {
return t.tpm.pcrs(alg)
}
@ -358,16 +360,36 @@ func (t *TPM) attestPlatform(aik *AIK, nonce []byte, eventLog []byte) (*Platform
return &out, nil
}
// PlatformAttestConfig configures how attestations are generated through
// tpm.AttestPlatform().
type PlatformAttestConfig struct {
// If non-nil, the raw event log will be read from EventLog
// instead of being obtained from the running system.
EventLog []byte
}
// 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) {
el, err := t.MeasurementLog()
if err != nil {
return nil, fmt.Errorf("failed to read event log: %v", err)
// The provided config, if not nil, can be used to configure aspects of the
// platform attestation.
func (t *TPM) AttestPlatform(aik *AIK, nonce []byte, config *PlatformAttestConfig) (*PlatformParameters, error) {
if config == nil {
config = &PlatformAttestConfig{}
}
var el []byte
if config.EventLog != nil {
el = config.EventLog
} else {
var err error
if el, err = t.MeasurementLog(); err != nil {
return nil, fmt.Errorf("failed to read event log: %v", err)
}
}
return t.attestPlatform(aik, nonce, el)
}