Merge pull request #101 from ericchiang/api

attest: don't define exported API in files with build tags
This commit is contained in:
Eric Chiang 2019-09-19 13:58:37 -07:00 committed by GitHub
commit c251eb0fbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 107 additions and 116 deletions

View File

@ -85,11 +85,11 @@ const (
) )
type aik interface { type aik interface {
Close(*TPM) error close(*platformTPM) error
Marshal() ([]byte, error) marshal() ([]byte, error)
ActivateCredential(tpm *TPM, in EncryptedCredential) ([]byte, error) activateCredential(tpm *platformTPM, in EncryptedCredential) ([]byte, error)
Quote(t *TPM, nonce []byte, alg HashAlg) (*Quote, error) quote(t *platformTPM, nonce []byte, alg HashAlg) (*Quote, error)
AttestationParameters() AttestationParameters attestationParameters() AttestationParameters
} }
// AIK represents a key which can be used for attestation. // AIK represents a key which can be used for attestation.
@ -99,7 +99,7 @@ type AIK struct {
// Close unloads the AIK from the system. // Close unloads the AIK from the system.
func (k *AIK) Close(t *TPM) error { func (k *AIK) Close(t *TPM) error {
return k.aik.Close(t) return k.aik.close(t.tpm)
} }
// Marshal encodes the AIK in a format that can be reloaded with tpm.LoadAIK(). // Marshal encodes the AIK in a format that can be reloaded with tpm.LoadAIK().
@ -107,7 +107,7 @@ func (k *AIK) Close(t *TPM) error {
// it as a later time. Users SHOULD NOT attempt to interpret or extract values // it as a later time. Users SHOULD NOT attempt to interpret or extract values
// from this blob. // from this blob.
func (k *AIK) Marshal() ([]byte, error) { func (k *AIK) Marshal() ([]byte, error) {
return k.aik.Marshal() return k.aik.marshal()
} }
// ActivateCredential decrypts the secret using the key to prove that the AIK // ActivateCredential decrypts the secret using the key to prove that the AIK
@ -115,18 +115,18 @@ func (k *AIK) Marshal() ([]byte, error) {
// //
// This operation is synonymous with TPM2_ActivateCredential. // This operation is synonymous with TPM2_ActivateCredential.
func (k *AIK) ActivateCredential(tpm *TPM, in EncryptedCredential) (secret []byte, err error) { func (k *AIK) ActivateCredential(tpm *TPM, in EncryptedCredential) (secret []byte, err error) {
return k.aik.ActivateCredential(tpm, in) return k.aik.activateCredential(tpm.tpm, in)
} }
// Quote returns a quote over the platform state, signed by the AIK. // Quote returns a quote over the platform state, signed by the AIK.
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, nonce, alg) return k.aik.quote(tpm.tpm, nonce, alg)
} }
// Parameters returns information about the AIK, typically used to generate // Parameters returns information about the AIK, typically used to generate
// a credential activation challenge. // a credential activation challenge.
func (k *AIK) AttestationParameters() AttestationParameters { func (k *AIK) AttestationParameters() AttestationParameters {
return k.aik.AttestationParameters() return k.aik.attestationParameters()
} }
// AIKConfig encapsulates parameters for minting keys. This type is defined // AIKConfig encapsulates parameters for minting keys. This type is defined

View File

@ -13,6 +13,9 @@
// the License. // the License.
// +build !localtest !tpm12 // +build !localtest !tpm12
// +build cgo
// NOTE: simulator requires cgo, hence the build tag.
package attest package attest
@ -30,12 +33,12 @@ func setupSimulatedTPM(t *testing.T) (*simulator.Simulator, *TPM) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
return tpm, &TPM{ return tpm, &TPM{&platformTPM{
version: TPMVersion20, version: TPMVersion20,
interf: TPMInterfaceKernelManaged, interf: TPMInterfaceKernelManaged,
sysPath: "/dev/tpmrm0", sysPath: "/dev/tpmrm0",
rwc: tpm, rwc: tpm,
} }}
} }
func TestSimTPM20EK(t *testing.T) { func TestSimTPM20EK(t *testing.T) {
@ -195,7 +198,7 @@ func TestSimTPM20Persistence(t *testing.T) {
sim, tpm := setupSimulatedTPM(t) sim, tpm := setupSimulatedTPM(t)
defer sim.Close() defer sim.Close()
ekHnd, _, err := tpm.getPrimaryKeyHandle(commonEkEquivalentHandle) ekHnd, _, err := tpm.tpm.getPrimaryKeyHandle(commonEkEquivalentHandle)
if err != nil { if err != nil {
t.Fatalf("getPrimaryKeyHandle() failed: %v", err) t.Fatalf("getPrimaryKeyHandle() failed: %v", err)
} }
@ -203,7 +206,7 @@ func TestSimTPM20Persistence(t *testing.T) {
t.Fatalf("bad EK-equivalent handle: got 0x%x, wanted 0x%x", ekHnd, commonEkEquivalentHandle) t.Fatalf("bad EK-equivalent handle: got 0x%x, wanted 0x%x", ekHnd, commonEkEquivalentHandle)
} }
ekHnd, p, err := tpm.getPrimaryKeyHandle(commonEkEquivalentHandle) ekHnd, p, err := tpm.tpm.getPrimaryKeyHandle(commonEkEquivalentHandle)
if err != nil { if err != nil {
t.Fatalf("second getPrimaryKeyHandle() failed: %v", err) t.Fatalf("second getPrimaryKeyHandle() failed: %v", err)
} }

View File

@ -91,12 +91,9 @@ func TestNewAIK(t *testing.T) {
tpm := openTPM12(t) tpm := openTPM12(t)
defer tpm.Close() defer tpm.Close()
aik, err := tpm.NewAIK(nil) if _, err := tpm.NewAIK(nil); err != nil {
if err != nil {
t.Fatalf("NewAIK failed: %v", err) t.Fatalf("NewAIK failed: %v", err)
} }
k := aik.aik.(*key12)
t.Logf("aik blob: %x\naik pubkey: %x\n", k.blob, k.public)
} }
func TestTPMQuote(t *testing.T) { func TestTPMQuote(t *testing.T) {

View File

@ -39,7 +39,7 @@ func newKey12(blob, public []byte) aik {
// Marshal represents the key in a persistent format which may be // Marshal represents the key in a persistent format which may be
// loaded at a later time using tpm.LoadKey(). // loaded at a later time using tpm.LoadKey().
func (k *key12) Marshal() ([]byte, error) { func (k *key12) marshal() ([]byte, error) {
out := serializedKey{ out := serializedKey{
Encoding: keyEncodingEncrypted, Encoding: keyEncodingEncrypted,
TPMVersion: TPMVersion12, TPMVersion: TPMVersion12,
@ -49,13 +49,11 @@ func (k *key12) Marshal() ([]byte, error) {
return out.Serialize() return out.Serialize()
} }
func (k *key12) Close(tpm *TPM) error { func (k *key12) close(tpm *platformTPM) error {
return nil // No state for tpm 1.2. return nil // No state for tpm 1.2.
} }
// ActivateCredential decrypts the specified credential using key. func (k *key12) activateCredential(t *platformTPM, in EncryptedCredential) ([]byte, error) {
// This operation is synonymous with TPM2_ActivateCredential.
func (k *key12) ActivateCredential(t *TPM, in EncryptedCredential) ([]byte, error) {
cred, err := attestation.AIKChallengeResponse(t.ctx, k.blob, in.Credential, in.Secret) cred, err := attestation.AIKChallengeResponse(t.ctx, k.blob, in.Credential, in.Secret)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to activate aik: %v", err) return nil, fmt.Errorf("failed to activate aik: %v", err)
@ -63,8 +61,7 @@ func (k *key12) ActivateCredential(t *TPM, in EncryptedCredential) ([]byte, erro
return cred, nil return cred, nil
} }
// Quote returns a quote over the platform state, signed by the key. func (k *key12) quote(t *platformTPM, nonce []byte, alg HashAlg) (*Quote, error) {
func (k *key12) Quote(t *TPM, nonce []byte, alg HashAlg) (*Quote, error) {
if alg != HashSHA1 { if alg != HashSHA1 {
return nil, fmt.Errorf("only SHA1 algorithms supported on TPM 1.2, not HashAlg(%v)", alg) return nil, fmt.Errorf("only SHA1 algorithms supported on TPM 1.2, not HashAlg(%v)", alg)
} }
@ -81,8 +78,7 @@ func (k *key12) Quote(t *TPM, nonce []byte, alg HashAlg) (*Quote, error) {
}, nil }, nil
} }
// AttestationParameters returns information about the AIK. func (k *key12) attestationParameters() AttestationParameters {
func (k *key12) AttestationParameters() AttestationParameters {
return AttestationParameters{ return AttestationParameters{
Public: k.public, Public: k.public,
UseTCSDActivationFormat: true, UseTCSDActivationFormat: true,
@ -111,9 +107,7 @@ func newKey20(hnd tpmutil.Handle, blob, public, createData, createAttestation, c
} }
} }
// Marshal represents the key in a persistent format which may be func (k *key20) marshal() ([]byte, error) {
// loaded at a later time using tpm.LoadKey().
func (k *key20) Marshal() ([]byte, error) {
return (&serializedKey{ return (&serializedKey{
Encoding: keyEncodingEncrypted, Encoding: keyEncodingEncrypted,
TPMVersion: TPMVersion20, TPMVersion: TPMVersion20,
@ -126,14 +120,11 @@ func (k *key20) Marshal() ([]byte, error) {
}).Serialize() }).Serialize()
} }
// Close frees any resources associated with the key. func (k *key20) close(tpm *platformTPM) error {
func (k *key20) Close(tpm *TPM) error {
return tpm2.FlushContext(tpm.rwc, k.hnd) return tpm2.FlushContext(tpm.rwc, k.hnd)
} }
// ActivateCredential decrypts the specified credential using key. func (k *key20) activateCredential(t *platformTPM, in EncryptedCredential) ([]byte, error) {
// This operation is synonymous with TPM2_ActivateCredential.
func (k *key20) ActivateCredential(t *TPM, in EncryptedCredential) ([]byte, error) {
ekHnd, _, err := t.getPrimaryKeyHandle(commonEkEquivalentHandle) ekHnd, _, err := t.getPrimaryKeyHandle(commonEkEquivalentHandle)
if err != nil { if err != nil {
return nil, err return nil, err
@ -163,13 +154,11 @@ func (k *key20) ActivateCredential(t *TPM, in EncryptedCredential) ([]byte, erro
}, k.hnd, ekHnd, in.Credential[2:], in.Secret[2:]) }, k.hnd, ekHnd, in.Credential[2:], in.Secret[2:])
} }
// Quote returns a quote over the platform state, signed by the key. func (k *key20) quote(t *platformTPM, nonce []byte, alg HashAlg) (*Quote, error) {
func (k *key20) Quote(t *TPM, nonce []byte, alg HashAlg) (*Quote, error) {
return quote20(t.rwc, k.hnd, tpm2.Algorithm(alg), nonce) return quote20(t.rwc, k.hnd, tpm2.Algorithm(alg), nonce)
} }
// AttestationParameters returns information about the AIK. func (k *key20) attestationParameters() AttestationParameters {
func (k *key20) AttestationParameters() AttestationParameters {
return AttestationParameters{ return AttestationParameters{
Public: k.public, Public: k.public,
CreateData: k.createData, CreateData: k.createData,

View File

@ -37,9 +37,7 @@ func newKey12(hnd uintptr, pcpKeyName string, public []byte) aik {
} }
} }
// Marshal represents the key in a persistent format which may be func (k *key12) marshal() ([]byte, error) {
// loaded at a later time using tpm.LoadKey().
func (k *key12) Marshal() ([]byte, error) {
out := serializedKey{ out := serializedKey{
Encoding: keyEncodingOSManaged, Encoding: keyEncodingOSManaged,
TPMVersion: TPMVersion12, TPMVersion: TPMVersion12,
@ -49,9 +47,7 @@ func (k *key12) Marshal() ([]byte, error) {
return out.Serialize() return out.Serialize()
} }
// ActivateCredential decrypts the specified credential using key. func (k *key12) activateCredential(tpm *platformTPM, in EncryptedCredential) ([]byte, error) {
// This operation is synonymous with TPM_ActivateIdentity for TPM1.2.
func (k *key12) ActivateCredential(tpm *TPM, in EncryptedCredential) ([]byte, error) {
secretKey, err := tpm.pcp.ActivateCredential(k.hnd, in.Credential) secretKey, err := tpm.pcp.ActivateCredential(k.hnd, in.Credential)
if err != nil { if err != nil {
return nil, err return nil, err
@ -59,8 +55,7 @@ func (k *key12) ActivateCredential(tpm *TPM, in EncryptedCredential) ([]byte, er
return decryptCredential(secretKey, in.Secret) return decryptCredential(secretKey, in.Secret)
} }
// Quote returns a quote over the platform state, signed by the key. func (k *key12) quote(t *platformTPM, nonce []byte, alg HashAlg) (*Quote, error) {
func (k *key12) Quote(t *TPM, nonce []byte, alg HashAlg) (*Quote, error) {
if alg != HashSHA1 { if alg != HashSHA1 {
return nil, fmt.Errorf("only SHA1 algorithms supported on TPM 1.2, not HashAlg(%v)", alg) return nil, fmt.Errorf("only SHA1 algorithms supported on TPM 1.2, not HashAlg(%v)", alg)
} }
@ -98,13 +93,11 @@ func (k *key12) Quote(t *TPM, nonce []byte, alg HashAlg) (*Quote, error) {
}, nil }, nil
} }
// Close frees any resources associated with the key. func (k *key12) close(tpm *platformTPM) error {
func (k *key12) Close(tpm *TPM) error {
return closeNCryptObject(k.hnd) return closeNCryptObject(k.hnd)
} }
// AttestationParameters returns information about the AIK. func (k *key12) attestationParameters() AttestationParameters {
func (k *key12) AttestationParameters() AttestationParameters {
return AttestationParameters{ return AttestationParameters{
Public: k.public, Public: k.public,
} }
@ -132,9 +125,7 @@ func newKey20(hnd uintptr, pcpKeyName string, public, createData, createAttest,
} }
} }
// Marshal represents the key in a persistent format which may be func (k *key20) marshal() ([]byte, error) {
// loaded at a later time using tpm.LoadKey().
func (k *key20) Marshal() ([]byte, error) {
out := serializedKey{ out := serializedKey{
Encoding: keyEncodingOSManaged, Encoding: keyEncodingOSManaged,
TPMVersion: TPMVersion20, TPMVersion: TPMVersion20,
@ -148,14 +139,11 @@ func (k *key20) Marshal() ([]byte, error) {
return out.Serialize() return out.Serialize()
} }
// ActivateCredential decrypts the specified credential using the key. func (k *key20) activateCredential(tpm *platformTPM, in EncryptedCredential) ([]byte, error) {
// This operation is synonymous with TPM2_ActivateCredential.
func (k *key20) ActivateCredential(tpm *TPM, in EncryptedCredential) ([]byte, error) {
return tpm.pcp.ActivateCredential(k.hnd, append(in.Credential, in.Secret...)) return tpm.pcp.ActivateCredential(k.hnd, append(in.Credential, in.Secret...))
} }
// Quote returns a quote over the platform state, signed by the key. func (k *key20) quote(t *platformTPM, nonce []byte, alg HashAlg) (*Quote, error) {
func (k *key20) Quote(t *TPM, nonce []byte, alg HashAlg) (*Quote, error) {
tpmKeyHnd, err := t.pcp.TPMKeyHandle(k.hnd) tpmKeyHnd, err := t.pcp.TPMKeyHandle(k.hnd)
if err != nil { if err != nil {
return nil, fmt.Errorf("TPMKeyHandle() failed: %v", err) return nil, fmt.Errorf("TPMKeyHandle() failed: %v", err)
@ -168,19 +156,11 @@ func (k *key20) Quote(t *TPM, nonce []byte, alg HashAlg) (*Quote, error) {
return quote20(tpm, tpmKeyHnd, alg.goTPMAlg(), nonce) return quote20(tpm, tpmKeyHnd, alg.goTPMAlg(), nonce)
} }
// Close frees any resources associated with the key. func (k *key20) close(tpm *platformTPM) error {
func (k *key20) Close(tpm *TPM) error {
return closeNCryptObject(k.hnd) return closeNCryptObject(k.hnd)
} }
// Delete permenantly removes the key from the system. This method func (k *key20) attestationParameters() AttestationParameters {
// invalidates Key and any further method invocations are invalid.
func (k *key20) Delete(tpm *TPM) error {
return tpm.pcp.DeleteKey(k.hnd)
}
// AttestationParameters returns information about the AIK.
func (k *key20) AttestationParameters() AttestationParameters {
return AttestationParameters{ return AttestationParameters{
Public: k.public, Public: k.public,
CreateData: k.createData, CreateData: k.createData,

View File

@ -267,10 +267,52 @@ func readAllPCRs20(tpm io.ReadWriter, alg tpm2.Algorithm) (map[uint32][]byte, er
return out, nil return out, nil
} }
//TPM interfaces with a TPM device on the system.
type TPM struct {
// tpm holds a platform specific implementation of TPM logic: Windows or Linux.
// see *_linux.go and *_windows.go files for definitions of these structs.
tpm *platformTPM
}
// Close shuts down the connection to the TPM.
func (t *TPM) Close() error {
return t.tpm.close()
}
// EKs returns the endorsement keys burned-in to the platform.
func (t *TPM) EKs() ([]EK, error) {
return t.tpm.eks()
}
// Info returns information about the TPM.
func (t *TPM) Info() (*TPMInfo, error) {
return t.tpm.info()
}
// 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
// to this function. // to this function.
func (t *TPM) LoadAIK(opaqueBlob []byte) (*AIK, error) { func (t *TPM) LoadAIK(opaqueBlob []byte) (*AIK, error) {
return t.loadAIK(opaqueBlob) return t.tpm.loadAIK(opaqueBlob)
}
// MeasurementLog returns the present value of the System Measurement Log.
func (t *TPM) MeasurementLog() ([]byte, error) {
return t.tpm.measurementLog()
}
// NewAIK creates an attestation key.
func (t *TPM) NewAIK(opts *AIKConfig) (*AIK, error) {
return t.tpm.newAIK(opts)
}
// PCRs returns the present value of Platform Configuration Registers with the given digest algorithm.
func (t *TPM) PCRs(alg HashAlg) ([]PCR, error) {
return t.tpm.pcrs(alg)
}
// Version returns the version of the TPM.
func (t *TPM) Version() TPMVersion {
return t.tpm.tpmVersion()
} }

View File

@ -42,8 +42,8 @@ const (
tpmRoot = "/sys/class/tpm" tpmRoot = "/sys/class/tpm"
) )
// TPM interfaces with a TPM device on the system. // platformTPM interfaces with a TPM device on the system.
type TPM struct { type platformTPM struct {
version TPMVersion version TPMVersion
interf TPMInterface interf TPMInterface
@ -122,22 +122,20 @@ func openTPM(tpm probedTPM) (*TPM, error) {
} }
} }
return &TPM{ return &TPM{&platformTPM{
version: tpm.Version, version: tpm.Version,
interf: interf, interf: interf,
sysPath: tpm.Path, sysPath: tpm.Path,
rwc: rwc, rwc: rwc,
ctx: ctx, ctx: ctx,
}, nil }}, nil
} }
// Version returns the version of the TPM. func (t *platformTPM) tpmVersion() TPMVersion {
func (t *TPM) Version() TPMVersion {
return t.version return t.version
} }
// Close shuts down the connection to the TPM. func (t *platformTPM) close() error {
func (t *TPM) Close() error {
switch t.version { switch t.version {
case TPMVersion12: case TPMVersion12:
return t.ctx.Close() return t.ctx.Close()
@ -162,7 +160,7 @@ func readTPM12VendorAttributes(context *tspi.Context) (TCGVendorID, string, erro
} }
// Info returns information about the TPM. // Info returns information about the TPM.
func (t *TPM) Info() (*TPMInfo, error) { func (t *platformTPM) info() (*TPMInfo, error) {
tInfo := TPMInfo{ tInfo := TPMInfo{
Version: t.version, Version: t.version,
Interface: t.interf, Interface: t.interf,
@ -190,7 +188,7 @@ func (t *TPM) Info() (*TPMInfo, error) {
} }
// Return value: handle, whether we generated a new one, error // Return value: handle, whether we generated a new one, error
func (t *TPM) getPrimaryKeyHandle(pHnd tpmutil.Handle) (tpmutil.Handle, bool, error) { func (t *platformTPM) getPrimaryKeyHandle(pHnd tpmutil.Handle) (tpmutil.Handle, bool, error) {
_, _, _, err := tpm2.ReadPublic(t.rwc, pHnd) _, _, _, err := tpm2.ReadPublic(t.rwc, pHnd)
if err == nil { if err == nil {
// Found the persistent handle, assume it's the key we want. // Found the persistent handle, assume it's the key we want.
@ -225,8 +223,7 @@ func readEKCertFromNVRAM12(ctx *tspi.Context) (*x509.Certificate, error) {
return ParseEKCertificate(ekCert) return ParseEKCertificate(ekCert)
} }
// EKs returns the endorsement keys burned-in to the platform. func (t *platformTPM) eks() ([]EK, error) {
func (t *TPM) EKs() ([]EK, error) {
switch t.version { switch t.version {
case TPMVersion12: case TPMVersion12:
cert, err := readEKCertFromNVRAM12(t.ctx) cert, err := readEKCertFromNVRAM12(t.ctx)
@ -270,8 +267,7 @@ func (t *TPM) EKs() ([]EK, error) {
} }
} }
// NewAIK creates an attestation key. func (t *platformTPM) newAIK(opts *AIKConfig) (*AIK, error) {
func (t *TPM) NewAIK(opts *AIKConfig) (*AIK, error) {
switch t.version { switch t.version {
case TPMVersion12: case TPMVersion12:
pub, blob, err := attestation.CreateAIK(t.ctx) pub, blob, err := attestation.CreateAIK(t.ctx)
@ -317,7 +313,7 @@ func (t *TPM) NewAIK(opts *AIKConfig) (*AIK, error) {
} }
} }
func (t *TPM) loadAIK(opaqueBlob []byte) (*AIK, error) { func (t *platformTPM) loadAIK(opaqueBlob []byte) (*AIK, error) {
sKey, err := deserializeKey(opaqueBlob, t.version) sKey, err := deserializeKey(opaqueBlob, t.version)
if err != nil { if err != nil {
return nil, fmt.Errorf("deserializeKey() failed: %v", err) return nil, fmt.Errorf("deserializeKey() failed: %v", err)
@ -359,12 +355,7 @@ func allPCRs12(ctx *tspi.Context) (map[uint32][]byte, error) {
return PCRs, nil return PCRs, nil
} }
// TODO: Refactor PCRs() into a file not subject to build tags, and implement func (t *platformTPM) pcrs(alg HashAlg) ([]PCR, 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 err error var err error
@ -400,7 +391,6 @@ func (t *TPM) PCRs(alg HashAlg) ([]PCR, error) {
return out, nil return out, nil
} }
// MeasurementLog returns the present value of the System Measurement Log. func (t *platformTPM) measurementLog() ([]byte, error) {
func (t *TPM) MeasurementLog() ([]byte, error) {
return ioutil.ReadFile("/sys/kernel/security/tpm0/binary_bios_measurements") return ioutil.ReadFile("/sys/kernel/security/tpm0/binary_bios_measurements")
} }

View File

@ -34,8 +34,7 @@ import (
var wellKnownAuth [20]byte var wellKnownAuth [20]byte
// TPM interfaces with a TPM device on the system. type platformTPM struct {
type TPM struct {
version TPMVersion version TPMVersion
pcp *winPCP pcp *winPCP
} }
@ -90,19 +89,17 @@ 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{ return &TPM{&platformTPM{
pcp: pcp, pcp: pcp,
version: vers, version: vers,
}, nil }}, nil
} }
// Version returns the version of the TPM. func (t *platformTPM) tpmVersion() TPMVersion {
func (t *TPM) Version() TPMVersion {
return t.version return t.version
} }
// Close shuts down the connection to the TPM. func (t *platformTPM) close() error {
func (t *TPM) Close() error {
return t.pcp.Close() return t.pcp.Close()
} }
@ -115,8 +112,7 @@ func readTPM12VendorAttributes(tpm io.ReadWriter) (TCGVendorID, string, error) {
return vendorID, vendorID.String(), nil return vendorID, vendorID.String(), nil
} }
// Info returns information about the TPM. func (t *platformTPM) info() (*TPMInfo, error) {
func (t *TPM) Info() (*TPMInfo, error) {
tInfo := TPMInfo{ tInfo := TPMInfo{
Version: t.version, Version: t.version,
Interface: TPMInterfaceKernelManaged, Interface: TPMInterfaceKernelManaged,
@ -146,8 +142,7 @@ func (t *TPM) Info() (*TPMInfo, error) {
return &tInfo, nil return &tInfo, nil
} }
// EKs returns the Endorsement Keys burned-in to the platform. func (t *platformTPM) eks() ([]EK, error) {
func (t *TPM) EKs() ([]EK, error) {
ekCerts, err := t.pcp.EKCerts() ekCerts, err := t.pcp.EKCerts()
if err != nil { if err != nil {
return nil, fmt.Errorf("could not read EKCerts: %v", err) return nil, fmt.Errorf("could not read EKCerts: %v", err)
@ -166,7 +161,7 @@ func (t *TPM) EKs() ([]EK, error) {
} }
ek := EK{Public: pub} ek := EK{Public: pub}
i, err := t.Info() i, err := t.info()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -176,7 +171,7 @@ func (t *TPM) EKs() ([]EK, error) {
return []EK{ek}, nil return []EK{ek}, nil
} }
func (t *TPM) ekPub() (*rsa.PublicKey, error) { func (t *platformTPM) ekPub() (*rsa.PublicKey, error) {
p, err := t.pcp.EKPub() p, err := t.pcp.EKPub()
if err != nil { if err != nil {
return nil, fmt.Errorf("could not read ekpub: %v", err) return nil, fmt.Errorf("could not read ekpub: %v", err)
@ -269,9 +264,7 @@ func decryptCredential(secretKey, blob []byte) ([]byte, error) {
return secret, nil return secret, nil
} }
// NewAIK creates a persistent attestation key. The returned key must be func (t *platformTPM) newAIK(opts *AIKConfig) (*AIK, error) {
// closed with a call to key.Close() when the caller has finished using it.
func (t *TPM) NewAIK(opts *AIKConfig) (*AIK, error) {
nameHex := make([]byte, 5) nameHex := make([]byte, 5)
if n, err := rand.Read(nameHex); err != nil || n != len(nameHex) { if n, err := rand.Read(nameHex); err != nil || n != len(nameHex) {
return nil, fmt.Errorf("rand.Read() failed with %d/%d bytes read and error: %v", n, len(nameHex), err) return nil, fmt.Errorf("rand.Read() failed with %d/%d bytes read and error: %v", n, len(nameHex), err)
@ -298,7 +291,7 @@ func (t *TPM) NewAIK(opts *AIKConfig) (*AIK, error) {
} }
} }
func (t *TPM) loadAIK(opaqueBlob []byte) (*AIK, error) { func (t *platformTPM) loadAIK(opaqueBlob []byte) (*AIK, error) {
sKey, err := deserializeKey(opaqueBlob, t.version) sKey, err := deserializeKey(opaqueBlob, t.version)
if err != nil { if err != nil {
return nil, fmt.Errorf("deserializeKey() failed: %v", err) return nil, fmt.Errorf("deserializeKey() failed: %v", err)
@ -341,9 +334,7 @@ func allPCRs12(tpm io.ReadWriter) (map[uint32][]byte, error) {
return out, nil return out, nil
} }
// PCRs returns the present value of Platform Configuration Registers with the func (t *platformTPM) pcrs(alg HashAlg) ([]PCR, error) {
// given digest algorithm.
func (t *TPM) PCRs(alg HashAlg) ([]PCR, error) {
var PCRs map[uint32][]byte var PCRs map[uint32][]byte
switch t.version { switch t.version {
@ -386,8 +377,7 @@ func (t *TPM) PCRs(alg HashAlg) ([]PCR, error) {
return out, nil return out, nil
} }
// MeasurementLog returns the present value of the System Measurement Log. func (t *platformTPM) measurementLog() ([]byte, error) {
func (t *TPM) MeasurementLog() ([]byte, error) {
context, err := tpmtbs.CreateContext(tpmtbs.TPMVersion20, tpmtbs.IncludeTPM20|tpmtbs.IncludeTPM12) context, err := tpmtbs.CreateContext(tpmtbs.TPMVersion20, tpmtbs.IncludeTPM20|tpmtbs.IncludeTPM12)
if err != nil { if err != nil {
return nil, err return nil, err