From 20331edb0a91759d3194f155e299e576a292d1e6 Mon Sep 17 00:00:00 2001 From: DenisKarch <47127526+DenisKarch@users.noreply.github.com> Date: Mon, 8 Apr 2019 17:44:34 -0700 Subject: [PATCH] Add getCapability and GetManufacturer (#84) These methods can be used to query the TPM for various information. GetManufacturer specifically queries the Vendor ID. --- tpm/commands.go | 15 +++++++++++++++ tpm/constants.go | 8 +++++++- tpm/tpm.go | 13 ++++++------- tpm/tpm_test.go | 12 ++++++++++++ 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/tpm/commands.go b/tpm/commands.go index cb259462..f56bc89c 100644 --- a/tpm/commands.go +++ b/tpm/commands.go @@ -143,6 +143,21 @@ func getPubKey(rw io.ReadWriter, keyHandle tpmutil.Handle, ca *commandAuth) (*pu return &pk, &ra, ret, nil } +// getCapability reads the requested capability and sub-capability from NVRAM +func getCapability(rw io.ReadWriter, cap, subcap uint32) ([]byte, error) { + subCapBytes, err := tpmutil.Pack(subcap) + if err != nil { + return nil, err + } + var b []byte + in := []interface{}{cap, subCapBytes} + out := []interface{}{&b} + if _, err := submitTPMRequest(rw, tagRQUCommand, ordGetCapability, in, out); err != nil { + return nil, err + } + return b, nil +} + func nvReadValue(rw io.ReadWriter, index, offset, len uint32, ca *commandAuth) ([]byte, *responseAuth, uint32, error) { var b []byte var ra responseAuth diff --git a/tpm/constants.go b/tpm/constants.go index d2965d0b..60fce408 100644 --- a/tpm/constants.go +++ b/tpm/constants.go @@ -63,7 +63,13 @@ const ( // Capability types. const ( - capHandle uint32 = 0x00000014 + capProperty uint32 = 0x00000005 + capHandle uint32 = 0x00000014 +) + +// SubCapabilities +const ( + tpmCapPropManufacturer uint32 = 0x00000103 ) // Entity types. The LSB gives the entity type, and the MSB (currently fixed to diff --git a/tpm/tpm.go b/tpm/tpm.go index 8e713ddf..6a38821b 100644 --- a/tpm/tpm.go +++ b/tpm/tpm.go @@ -39,16 +39,10 @@ var OpenTPM = tpmutil.OpenTPM // GetKeys gets the list of handles for currently-loaded TPM keys. func GetKeys(rw io.ReadWriter) ([]tpmutil.Handle, error) { - var b []byte - subCap, err := tpmutil.Pack(rtKey) + b, err := getCapability(rw, capHandle, rtKey) if err != nil { return nil, err } - in := []interface{}{capHandle, subCap} - out := []interface{}{&b} - if _, err := submitTPMRequest(rw, tagRQUCommand, ordGetCapability, in, out); err != nil { - return nil, err - } var handles []tpmutil.Handle if _, err := tpmutil.Unpack(b, &handles); err != nil { return nil, err @@ -981,6 +975,11 @@ func ReadPubEK(rw io.ReadWriter) ([]byte, error) { return tpmutil.Pack(pk) } +// GetManufacturer returns the manufacturer ID +func GetManufacturer(rw io.ReadWriter) ([]byte, error) { + return getCapability(rw, capProperty, tpmCapPropManufacturer) +} + // OwnerClear uses owner auth to clear the TPM. After this operation, the TPM // can change ownership. func OwnerClear(rw io.ReadWriter, ownerAuth digest) error { diff --git a/tpm/tpm_test.go b/tpm/tpm_test.go index d278e3f9..12ceb546 100644 --- a/tpm/tpm_test.go +++ b/tpm/tpm_test.go @@ -58,6 +58,18 @@ func TestGetKeys(t *testing.T) { t.Logf("Got %d keys: % d\n", len(handles), handles) } +func TestGetManufacturer(t *testing.T) { + rwc := openTPMOrSkip(t) + defer rwc.Close() + + vendorID, err := GetManufacturer(rwc) + if err != nil { + t.Fatal("Couldn't read VendorID from TPM:", err) + } + + t.Logf("TPM VendorID: %v\n", vendorID) +} + func TestPcrExtend(t *testing.T) { rwc := openTPMOrSkip(t) defer rwc.Close()