mirror of
https://github.com/google/go-attestation.git
synced 2025-06-17 22:48:20 +00:00
Support AIKPublic.validate20Quote() consuming PCRs not part of the quote (#115)
This commit is contained in:
@ -33,7 +33,7 @@ func setupSimulatedTPM(t *testing.T) (*simulator.Simulator, *TPM) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
return tpm, &TPM{&platformTPM{
|
return tpm, &TPM{tpm: &platformTPM{
|
||||||
version: TPMVersion20,
|
version: TPMVersion20,
|
||||||
interf: TPMInterfaceKernelManaged,
|
interf: TPMInterfaceKernelManaged,
|
||||||
sysPath: "/dev/tpmrm0",
|
sysPath: "/dev/tpmrm0",
|
||||||
@ -148,7 +148,7 @@ func TestParseAIKPublic20(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSimTPM20Quote(t *testing.T) {
|
func TestSimTPM20QuoteAndVerify(t *testing.T) {
|
||||||
sim, tpm := setupSimulatedTPM(t)
|
sim, tpm := setupSimulatedTPM(t)
|
||||||
defer sim.Close()
|
defer sim.Close()
|
||||||
|
|
||||||
@ -163,9 +163,51 @@ func TestSimTPM20Quote(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("aik.Quote() failed: %v", err)
|
t.Fatalf("aik.Quote() failed: %v", err)
|
||||||
}
|
}
|
||||||
// TODO(jsonp): Parse quote structure once gotpm/tpm2 supports it.
|
|
||||||
if quote == nil {
|
// Providing both PCR banks to AIKPublic.Verify() ensures we can handle
|
||||||
t.Error("quote was nil, want *Quote")
|
// the case where extra PCRs of a different digest algorithm are provided.
|
||||||
|
var pcrs []PCR
|
||||||
|
for _, alg := range []HashAlg{HashSHA256, HashSHA1} {
|
||||||
|
p, err := tpm.PCRs(alg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("tpm.PCRs(%v) failed: %v", alg, err)
|
||||||
|
}
|
||||||
|
pcrs = append(pcrs, p...)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub, err := ParseAIKPublic(tpm.Version(), aik.AttestationParameters().Public)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ParseAIKPublic() failed: %v", err)
|
||||||
|
}
|
||||||
|
if err := pub.Verify(*quote, pcrs, nonce); err != nil {
|
||||||
|
t.Errorf("quote verification failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSimTPM20AttestPlatform(t *testing.T) {
|
||||||
|
sim, tpm := setupSimulatedTPM(t)
|
||||||
|
defer sim.Close()
|
||||||
|
|
||||||
|
aik, err := tpm.NewAIK(nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewAIK() failed: %v", err)
|
||||||
|
}
|
||||||
|
defer aik.Close(tpm)
|
||||||
|
|
||||||
|
nonce := []byte{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
|
attestation, err := tpm.attestPlatform(aik, nonce, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("AttestPlatform() failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub, err := ParseAIKPublic(attestation.TPMVersion, attestation.Public)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ParseAIKPublic() failed: %v", err)
|
||||||
|
}
|
||||||
|
for i, q := range attestation.Quotes {
|
||||||
|
if err := pub.Verify(q, attestation.PCRs, nonce); err != nil {
|
||||||
|
t.Errorf("quote[%d] verification failed: %v", i, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,8 +198,12 @@ func (a *AIKPublic) validate20Quote(quote Quote, pcrs []PCR, nonce []byte) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
pcrByIndex := map[int][]byte{}
|
pcrByIndex := map[int][]byte{}
|
||||||
|
pcrDigestLength := HashAlg(att.AttestedQuoteInfo.PCRSelection.Hash).cryptoHash().Size()
|
||||||
for _, pcr := range pcrs {
|
for _, pcr := range pcrs {
|
||||||
pcrByIndex[pcr.Index] = pcr.Digest
|
// TODO(jsonp): Use pcr.DigestAlg once #116 is fixed.
|
||||||
|
if len(pcr.Digest) == pcrDigestLength {
|
||||||
|
pcrByIndex[pcr.Index] = pcr.Digest
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n := len(att.AttestedQuoteInfo.PCRDigest)
|
n := len(att.AttestedQuoteInfo.PCRDigest)
|
||||||
|
@ -329,20 +329,11 @@ func (t *TPM) attestPCRs(aik *AIK, nonce []byte, alg HashAlg) (*Quote, []PCR, er
|
|||||||
return quote, pcrs, nil
|
return quote, pcrs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AttestPlatform computes the set of information necessary to attest the
|
func (t *TPM) attestPlatform(aik *AIK, nonce []byte, eventLog []byte) (*PlatformParameters, error) {
|
||||||
// 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{
|
out := PlatformParameters{
|
||||||
TPMVersion: t.Version(),
|
TPMVersion: t.Version(),
|
||||||
Public: aik.AttestationParameters().Public,
|
Public: aik.AttestationParameters().Public,
|
||||||
}
|
EventLog: eventLog,
|
||||||
|
|
||||||
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}
|
algs := []HashAlg{HashSHA1}
|
||||||
@ -367,6 +358,19 @@ func (t *TPM) AttestPlatform(aik *AIK, nonce []byte) (*PlatformParameters, error
|
|||||||
return &out, nil
|
return &out, 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) {
|
||||||
|
el, err := t.MeasurementLog()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to read event log: %v", err)
|
||||||
|
}
|
||||||
|
return t.attestPlatform(aik, nonce, el)
|
||||||
|
}
|
||||||
|
|
||||||
// Version returns the version of the TPM.
|
// Version returns the version of the TPM.
|
||||||
func (t *TPM) Version() TPMVersion {
|
func (t *TPM) Version() TPMVersion {
|
||||||
return t.tpm.tpmVersion()
|
return t.tpm.tpmVersion()
|
||||||
|
@ -122,7 +122,7 @@ func openTPM(tpm probedTPM) (*TPM, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &TPM{&platformTPM{
|
return &TPM{tpm: &platformTPM{
|
||||||
version: tpm.Version,
|
version: tpm.Version,
|
||||||
interf: interf,
|
interf: interf,
|
||||||
sysPath: tpm.Path,
|
sysPath: tpm.Path,
|
||||||
|
@ -89,7 +89,7 @@ func openTPM(tpm probedTPM) (*TPM, error) {
|
|||||||
return nil, fmt.Errorf("tbsConvertVersion(%v) failed: %v", info.TBSInfo.TPMVersion, err)
|
return nil, fmt.Errorf("tbsConvertVersion(%v) failed: %v", info.TBSInfo.TPMVersion, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &TPM{&platformTPM{
|
return &TPM{tpm: &platformTPM{
|
||||||
pcp: pcp,
|
pcp: pcp,
|
||||||
version: vers,
|
version: vers,
|
||||||
}}, nil
|
}}, nil
|
||||||
|
Reference in New Issue
Block a user