mirror of
https://github.com/google/go-attestation.git
synced 2025-05-30 22:14:23 +00:00
Add config struct for AttestPlatform(), to configure event log source (#118)
This commit is contained in:
parent
56dc743f14
commit
de6a3af7e4
@ -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.
|
// 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) {
|
func (k *AIK) Quote(tpm *TPM, nonce []byte, alg HashAlg) (*Quote, error) {
|
||||||
return k.aik.quote(tpm.tpm, nonce, alg)
|
return k.aik.quote(tpm.tpm, nonce, alg)
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
func TestExampleAIK(t *testing.T) {
|
||||||
if !*testExamples {
|
if !*testExamples {
|
||||||
t.SkipNow()
|
t.SkipNow()
|
||||||
}
|
}
|
||||||
ExampleAIK()
|
ExampleAIK()
|
||||||
ExampleAIK_credentialActivation()
|
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)
|
tpm, err := attest.OpenTPM(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to open TPM: %v", err)
|
log.Fatalf("Failed to open TPM: %v", err)
|
||||||
@ -147,30 +123,27 @@ func ExampleAIKPublic_Verify() {
|
|||||||
// The nonce would typically be provided by the server.
|
// The nonce would typically be provided by the server.
|
||||||
nonce := []byte{1, 2, 3, 4, 5, 6, 7, 8}
|
nonce := []byte{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
|
|
||||||
// Perform the quote & gather information necessary to verify it.
|
// Perform an attestation against the state of the plaform. Usually, you
|
||||||
quote, err := aik.Quote(tpm, nonce, attest.HashSHA256)
|
// 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 {
|
if err != nil {
|
||||||
log.Fatalf("Failed to generate quote: %v", err)
|
log.Fatalf("Failed to attest the platform state: %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.
|
// 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)
|
pub, err := attest.ParseAIKPublic(tpm.Version(), aik.AttestationParameters().Public)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to parse AIK public: %v", err)
|
log.Fatalf("Failed to parse AIK public: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := pub.Verify(*quote, pcrs, nonce); err != nil {
|
for i, q := range att.Quotes {
|
||||||
log.Fatalf("Verification failed: %v", err)
|
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()
|
|
||||||
}
|
|
||||||
|
@ -298,6 +298,9 @@ func (t *TPM) LoadAIK(opaqueBlob []byte) (*AIK, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MeasurementLog returns the present value of the System Measurement Log.
|
// 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) {
|
func (t *TPM) MeasurementLog() ([]byte, error) {
|
||||||
return t.tpm.measurementLog()
|
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
|
// PCRs returns the present value of Platform Configuration Registers with
|
||||||
// the given digest algorithm.
|
// the given digest algorithm.
|
||||||
//
|
//
|
||||||
// Use ParseEventLog to determine which algorithm to use to match the values
|
// This is a low-level API. Consumers seeking to attest the state of the
|
||||||
// present in the event log. It's not always guarenteed that a system with TPM
|
// platform should use tpm.AttestPlatform() instead.
|
||||||
// 2.0 will extend PCRs with SHA256 digests.
|
|
||||||
func (t *TPM) PCRs(alg HashAlg) ([]PCR, error) {
|
func (t *TPM) PCRs(alg HashAlg) ([]PCR, error) {
|
||||||
return t.tpm.pcrs(alg)
|
return t.tpm.pcrs(alg)
|
||||||
}
|
}
|
||||||
@ -358,16 +360,36 @@ func (t *TPM) attestPlatform(aik *AIK, nonce []byte, eventLog []byte) (*Platform
|
|||||||
return &out, nil
|
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
|
// AttestPlatform computes the set of information necessary to attest the
|
||||||
// state of the platform. For TPM 2.0 devices, AttestPlatform will attempt
|
// 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
|
// 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
|
// platform firmware which break replay for one PCR bank can be mitigated
|
||||||
// using the other.
|
// using the other.
|
||||||
func (t *TPM) AttestPlatform(aik *AIK, nonce []byte) (*PlatformParameters, error) {
|
// The provided config, if not nil, can be used to configure aspects of the
|
||||||
el, err := t.MeasurementLog()
|
// platform attestation.
|
||||||
if err != nil {
|
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 nil, fmt.Errorf("failed to read event log: %v", err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return t.attestPlatform(aik, nonce, el)
|
return t.attestPlatform(aik, nonce, el)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user