mirror of
https://github.com/google/go-attestation.git
synced 2024-12-19 04:57:59 +00:00
75: Make PCRs() take the digest algorithm (#77)
This commit is contained in:
parent
6b09d5331a
commit
6e2e8693ad
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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{}
|
||||||
|
|
||||||
|
@ -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())
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user