75: Make PCRs() take the digest algorithm (#77)

This commit is contained in:
Tom D 2019-08-20 11:52:12 -07:00 committed by GitHub
parent 6b09d5331a
commit 6e2e8693ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 62 additions and 70 deletions

View File

@ -113,11 +113,14 @@ func runCommand(tpm *attest.TPM) error {
} }
case "list-pcrs": case "list-pcrs":
pcrs, alg, err := tpm.PCRs() alg := attest.HashSHA1
if *useSHA256 {
alg = attest.HashSHA256
}
pcrs, err := tpm.PCRs(alg)
if err != nil { if err != nil {
return fmt.Errorf("failed to read PCRs: %v", err) return fmt.Errorf("failed to read PCRs: %v", err)
} }
fmt.Printf("PCR digest: %v\n", alg)
for _, pcr := range pcrs { for _, pcr := range pcrs {
fmt.Printf("PCR[%d]: %x\n", pcr.Index, pcr.Digest) fmt.Printf("PCR[%d]: %x\n", pcr.Index, pcr.Digest)
} }
@ -180,13 +183,9 @@ func runDump(tpm *attest.TPM) (*internal.Dump, error) {
return nil, fmt.Errorf("failed to read measurement log: %v", err) return nil, fmt.Errorf("failed to read measurement log: %v", err)
} }
// Get PCR values. // Get PCR values.
pcrs, _, err := tpm.PCRs() if out.Log.PCRs, err = tpm.PCRs(out.Quote.Alg); err != nil {
if err != nil {
return nil, fmt.Errorf("failed to read PCRs: %v", err) return nil, fmt.Errorf("failed to read PCRs: %v", err)
} }
for _, pcr := range pcrs {
out.Log.PCRs = append(out.Log.PCRs, pcr)
}
return &out, nil return &out, nil
} }

View File

@ -254,6 +254,26 @@ var (
HashSHA256 = HashAlg(tpm2.AlgSHA256) HashSHA256 = HashAlg(tpm2.AlgSHA256)
) )
func (a HashAlg) cryptoHash() crypto.Hash {
switch a {
case HashSHA1:
return crypto.SHA1
case HashSHA256:
return crypto.SHA256
}
return 0
}
func (a HashAlg) goTPMAlg() tpm2.Algorithm {
switch a {
case HashSHA1:
return tpm2.AlgSHA1
case HashSHA256:
return tpm2.AlgSHA256
}
return 0
}
var ( var (
defaultOpenConfig = &OpenConfig{} defaultOpenConfig = &OpenConfig{}

View File

@ -25,7 +25,6 @@ import (
"github.com/google/certificate-transparency-go/x509" "github.com/google/certificate-transparency-go/x509"
"github.com/google/go-tpm-tools/simulator" "github.com/google/go-tpm-tools/simulator"
"github.com/google/go-tpm/tpm2"
) )
func setupSimulatedTPM(t *testing.T) (*simulator.Simulator, *TPM) { func setupSimulatedTPM(t *testing.T) (*simulator.Simulator, *TPM) {
@ -193,16 +192,14 @@ func TestSimTPM20PCRs(t *testing.T) {
sim, tpm := setupSimulatedTPM(t) sim, tpm := setupSimulatedTPM(t)
defer sim.Close() defer sim.Close()
PCRs, alg, err := tpm.PCRs() PCRs, err := tpm.PCRs(HashSHA256)
if err != nil { if err != nil {
t.Fatalf("PCRs() failed: %v", err) t.Fatalf("PCRs() failed: %v", err)
} }
if len(PCRs) != 24 { if len(PCRs) != 24 {
t.Errorf("len(PCRs) = %d, want %d", len(PCRs), 24) t.Errorf("len(PCRs) = %d, want %d", len(PCRs), 24)
} }
if got, want := tpm2.AlgSHA256, alg; got != want {
t.Errorf("alg = %v, want %v", got, want)
}
for i, pcr := range PCRs { for i, pcr := range PCRs {
if len(pcr.Digest) != pcr.DigestAlg.Size() { if len(pcr.Digest) != pcr.DigestAlg.Size() {
t.Errorf("PCR %d len(digest) = %d, expected match with digest algorithm size (%d)", pcr.Index, len(pcr.Digest), pcr.DigestAlg.Size()) t.Errorf("PCR %d len(digest) = %d, expected match with digest algorithm size (%d)", pcr.Index, len(pcr.Digest), pcr.DigestAlg.Size())

View File

@ -146,7 +146,7 @@ func TestPCRs(t *testing.T) {
} }
defer tpm.Close() defer tpm.Close()
PCRs, _, err := tpm.PCRs() PCRs, err := tpm.PCRs(HashSHA1)
if err != nil { if err != nil {
t.Fatalf("PCRs() failed: %v", err) t.Fatalf("PCRs() failed: %v", err)
} }

View File

@ -54,7 +54,7 @@ func TestTPM12PCRs(t *testing.T) {
tpm := openTPM12(t) tpm := openTPM12(t)
defer tpm.Close() defer tpm.Close()
PCRs, _, err := tpm.PCRs() PCRs, err := tpm.PCRs(HashSHA1)
if err != nil { if err != nil {
t.Fatalf("Failed to get PCR values: %v", err) t.Fatalf("Failed to get PCR values: %v", err)
} }

View File

@ -16,7 +16,6 @@ package attest
import ( import (
"bytes" "bytes"
"crypto"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"io" "io"
@ -251,16 +250,6 @@ func readAllPCRs20(tpm io.ReadWriter, alg tpm2.Algorithm) (map[uint32][]byte, er
return out, nil return out, nil
} }
func allPCRs20(tpm io.ReadWriter) (map[uint32][]byte, crypto.Hash, error) {
out256, err256 := readAllPCRs20(tpm, tpm2.AlgSHA256)
if err256 != nil {
// TPM may not implement active banks with SHA256 - try SHA1.
out1, err1 := readAllPCRs20(tpm, tpm2.AlgSHA1)
return out1, crypto.SHA1, err1
}
return out256, crypto.SHA256, nil
}
// LoadAIK loads a previously-created aik into the TPM for use. // LoadAIK loads a previously-created aik into the TPM for use.
// A key loaded via this function needs to be closed with .Close(). // A key loaded via this function needs to be closed with .Close().
// Only blobs generated by calling AIK.Serialize() are valid parameters // Only blobs generated by calling AIK.Serialize() are valid parameters

View File

@ -17,7 +17,6 @@
package attest package attest
import ( import (
"crypto"
"crypto/rsa" "crypto/rsa"
"encoding/binary" "encoding/binary"
"errors" "errors"
@ -358,49 +357,45 @@ func allPCRs12(ctx *tspi.Context) (map[uint32][]byte, error) {
return PCRs, nil return PCRs, nil
} }
// PCRs returns the present value of all Platform Configuration Registers. // TODO: Refactor PCRs() into a file not subject to build tags, and implement
func (t *TPM) PCRs() (map[int]PCR, tpm2.Algorithm, error) { // platform-specific logic in private methods.
// PCRs returns the present value of Platform Configuration Registers with the
// given digest algorithm.
func (t *TPM) PCRs(alg HashAlg) ([]PCR, error) {
var PCRs map[uint32][]byte var PCRs map[uint32][]byte
var alg crypto.Hash
var err error var err error
switch t.version { switch t.version {
case TPMVersion12: case TPMVersion12:
if alg != HashSHA1 {
return nil, fmt.Errorf("non-SHA1 algorithm %v is not supported on TPM 1.2", alg)
}
PCRs, err = allPCRs12(t.ctx) PCRs, err = allPCRs12(t.ctx)
if err != nil { if err != nil {
return nil, 0, fmt.Errorf("failed to read PCRs: %v", err) return nil, fmt.Errorf("failed to read PCRs: %v", err)
} }
alg = crypto.SHA1
case TPMVersion20: case TPMVersion20:
PCRs, alg, err = allPCRs20(t.rwc) PCRs, err = readAllPCRs20(t.rwc, alg.goTPMAlg())
if err != nil { if err != nil {
return nil, 0, fmt.Errorf("failed to read PCRs: %v", err) return nil, fmt.Errorf("failed to read PCRs: %v", err)
} }
default: default:
return nil, 0, fmt.Errorf("unsupported TPM version: %x", t.version) return nil, fmt.Errorf("unsupported TPM version: %x", t.version)
} }
out := map[int]PCR{} out := make([]PCR, len(PCRs))
var lastAlg crypto.Hash
for index, digest := range PCRs { for index, digest := range PCRs {
out[int(index)] = PCR{ out[int(index)] = PCR{
Index: int(index), Index: int(index),
Digest: digest, Digest: digest,
DigestAlg: alg, DigestAlg: alg.cryptoHash(),
} }
lastAlg = alg
} }
switch lastAlg { return out, nil
case crypto.SHA1:
return out, tpm2.AlgSHA1, nil
case crypto.SHA256:
return out, tpm2.AlgSHA256, nil
default:
return nil, 0, fmt.Errorf("unexpected algorithm: %v", lastAlg)
}
} }
// MeasurementLog returns the present value of the System Measurement Log. // MeasurementLog returns the present value of the System Measurement Log.

View File

@ -18,7 +18,6 @@ package attest
import ( import (
"bytes" "bytes"
"crypto"
"crypto/aes" "crypto/aes"
"crypto/cipher" "crypto/cipher"
"crypto/rand" "crypto/rand"
@ -34,7 +33,6 @@ import (
"net/http" "net/http"
tpm1 "github.com/google/go-tpm/tpm" tpm1 "github.com/google/go-tpm/tpm"
"github.com/google/go-tpm/tpm2"
tpmtbs "github.com/google/go-tpm/tpmutil/tbs" tpmtbs "github.com/google/go-tpm/tpmutil/tbs"
) )
@ -364,55 +362,49 @@ func allPCRs12(tpm io.ReadWriter) (map[uint32][]byte, error) {
return out, nil return out, nil
} }
// PCRs returns the present value of all Platform Configuration Registers. // PCRs returns the present value of Platform Configuration Registers with the
func (t *TPM) PCRs() (map[int]PCR, tpm2.Algorithm, error) { // given digest algorithm.
func (t *TPM) PCRs(alg HashAlg) ([]PCR, error) {
var PCRs map[uint32][]byte var PCRs map[uint32][]byte
var alg crypto.Hash
switch t.version { switch t.version {
case TPMVersion12: case TPMVersion12:
alg = crypto.SHA1 if alg != HashSHA1 {
return nil, fmt.Errorf("non-SHA1 algorithm %v is not supported on TPM 1.2", alg)
}
tpm, err := t.pcp.TPMCommandInterface() tpm, err := t.pcp.TPMCommandInterface()
if err != nil { if err != nil {
return nil, 0, fmt.Errorf("TPMCommandInterface() failed: %v", err) return nil, fmt.Errorf("TPMCommandInterface() failed: %v", err)
} }
PCRs, err = allPCRs12(tpm) PCRs, err = allPCRs12(tpm)
if err != nil { if err != nil {
return nil, 0, fmt.Errorf("failed to read PCRs: %v", err) return nil, fmt.Errorf("failed to read PCRs: %v", err)
} }
case TPMVersion20: case TPMVersion20:
tpm, err := t.pcp.TPMCommandInterface() tpm, err := t.pcp.TPMCommandInterface()
if err != nil { if err != nil {
return nil, 0, fmt.Errorf("TPMCommandInterface() failed: %v", err) return nil, fmt.Errorf("TPMCommandInterface() failed: %v", err)
} }
PCRs, alg, err = allPCRs20(tpm) PCRs, err = readAllPCRs20(tpm, alg.goTPMAlg())
if err != nil { if err != nil {
return nil, 0, fmt.Errorf("failed to read PCRs: %v", err) return nil, fmt.Errorf("failed to read PCRs: %v", err)
} }
default: default:
return nil, 0, fmt.Errorf("unsupported TPM version: %x", t.version) return nil, fmt.Errorf("unsupported TPM version: %x", t.version)
} }
out := map[int]PCR{} out := make([]PCR, len(PCRs))
var lastAlg crypto.Hash
for index, digest := range PCRs { for index, digest := range PCRs {
out[int(index)] = PCR{ out[int(index)] = PCR{
Index: int(index), Index: int(index),
Digest: digest, Digest: digest,
DigestAlg: alg, DigestAlg: alg.cryptoHash(),
} }
lastAlg = alg
} }
switch lastAlg { return out, nil
case crypto.SHA1:
return out, tpm2.AlgSHA1, nil
case crypto.SHA256:
return out, tpm2.AlgSHA256, nil
default:
return nil, 0, fmt.Errorf("unexpected algorithm: %v", lastAlg)
}
} }
// MeasurementLog returns the present value of the System Measurement Log. // MeasurementLog returns the present value of the System Measurement Log.