Use the legacy TPM API

This commit is contained in:
Ciprian Hacman 2023-06-30 11:43:23 +03:00
parent 961006c5f7
commit 89f7568deb
21 changed files with 1 additions and 9254 deletions

View File

@ -23,7 +23,7 @@ import (
"fmt"
"io"
"github.com/google/go-tpm/tpm2"
"github.com/google/go-tpm/legacy/tpm2"
)
var tpmPath = "/dev/tpm0"

View File

@ -1,87 +0,0 @@
package tpm2
import (
"bytes"
"fmt"
"reflect"
)
// CommandAudit represents an audit session for attesting the execution of a
// series of commands in the TPM. It is useful for both command and session
// auditing.
type CommandAudit struct {
hash TPMIAlgHash
digest []byte
}
// NewAudit initializes a new CommandAudit with the specified hash algorithm.
func NewAudit(hash TPMIAlgHash) (*CommandAudit, error) {
h, err := hash.Hash()
if err != nil {
return nil, err
}
return &CommandAudit{
hash: hash,
digest: make([]byte, h.Size()),
}, nil
}
// AuditCommand extends the audit digest with the given command and response.
// Go Generics do not allow type parameters on methods, otherwise this would be
// a method on CommandAudit.
// See https://github.com/golang/go/issues/49085 for more information.
func AuditCommand[C Command[R, *R], R any](a *CommandAudit, cmd C, rsp *R) error {
cc := cmd.Command()
cpHash, err := auditCPHash[R](cc, a.hash, cmd)
if err != nil {
return err
}
rpHash, err := auditRPHash(cc, a.hash, rsp)
if err != nil {
return err
}
ha, err := a.hash.Hash()
if err != nil {
return err
}
h := ha.New()
h.Write(a.digest)
h.Write(cpHash)
h.Write(rpHash)
a.digest = h.Sum(nil)
return nil
}
// Digest returns the current digest of the audit.
func (a *CommandAudit) Digest() []byte {
return a.digest
}
// auditCPHash calculates the command parameter hash for a given command with
// the given hash algorithm. The command is assumed to not have any decrypt
// sessions.
func auditCPHash[R any](cc TPMCC, h TPMIAlgHash, c Command[R, *R]) ([]byte, error) {
names, err := cmdNames(c)
if err != nil {
return nil, err
}
parms, err := cmdParameters(c, nil)
if err != nil {
return nil, err
}
return cpHash(h, cc, names, parms)
}
// auditRPHash calculates the response parameter hash for a given response with
// the given hash algorithm. The command is assumed to be successful and to not
// have any encrypt sessions.
func auditRPHash(cc TPMCC, h TPMIAlgHash, r any) ([]byte, error) {
var parms bytes.Buffer
parameters := taggedMembers(reflect.ValueOf(r).Elem(), "handle", true)
for i, parameter := range parameters {
if err := marshal(&parms, parameter); err != nil {
return nil, fmt.Errorf("marshalling parameter %v: %w", i+1, err)
}
}
return rpHash(h, TPMRCSuccess, cc, parms.Bytes())
}

View File

@ -1,82 +0,0 @@
package tpm2
import (
"fmt"
)
// Bitfield represents a TPM bitfield (i.e., TPMA_*) type.
type Bitfield interface {
// Length returns the length of the bitfield.
Length() int
}
// BitGetter represents a TPM bitfield (i.e., TPMA_*) type that can be read.
type BitGetter interface {
Bitfield
// GetReservedBit returns the value of the given reserved bit.
// If the bit is not reserved, returns false.
GetReservedBit(pos int) bool
}
// BitSetter represents a TPM bitfield (i.e., TPMA_*) type that can be written.
type BitSetter interface {
Bitfield
// GetReservedBit sets the value of the given reserved bit.
SetReservedBit(pos int, val bool)
}
func checkPos(pos int, len int) {
if pos >= len || pos < 0 {
panic(fmt.Errorf("bit %d out of range for %d-bit field", pos, len))
}
}
// bitfield8 represents an 8-bit bitfield which may have reserved bits.
// 8-bit TPMA_* types embed this one, and the reserved bits are stored in it.
type bitfield8 uint8
// Length implements the Bitfield interface.
func (bitfield8) Length() int {
return 8
}
// GetReservedBit implements the BitGetter interface.
func (r bitfield8) GetReservedBit(pos int) bool {
checkPos(pos, 8)
return r&(1<<pos) != 0
}
// SetReservedBit implements the BitSetter interface.
func (r *bitfield8) SetReservedBit(pos int, val bool) {
checkPos(pos, 8)
if val {
*r |= 1 << pos
} else {
*r &= ^(1 << pos)
}
}
// bitfield32 represents a 32-bit bitfield which may have reserved bits.
// 32-bit TPMA_* types embed this one, and the reserved bits are stored in it.
type bitfield32 uint32
// Length implements the Bitfield interface.
func (bitfield32) Length() int {
return 32
}
// GetReservedBit implements the BitGetter interface.
func (r bitfield32) GetReservedBit(pos int) bool {
checkPos(pos, 32)
return r&(1<<pos) != 0
}
// SetReservedBit implements the BitSetter interface.
func (r *bitfield32) SetReservedBit(pos int, val bool) {
checkPos(pos, 32)
if val {
*r |= 1 << pos
} else {
*r &= ^(1 << pos)
}
}

View File

@ -1,677 +0,0 @@
package tpm2
//go:generate stringer -trimprefix=TPM -type=TPMAlgID,TPMECCCurve,TPMCC,TPMRC,TPMEO,TPMST,TPMCap,TPMPT,TPMPTPCR,TPMHT,TPMHandle,TPMNT -output=constants_string.go constants.go
import (
// Register the relevant hash implementations.
_ "crypto/sha1"
_ "crypto/sha256"
_ "crypto/sha512"
)
// TPMAlgID represents a TPM_ALG_ID.
// See definition in Part 2: Structures, section 6.3.
type TPMAlgID uint16
// TPMAlgID values come from Part 2: Structures, section 6.3.
const (
TPMAlgRSA TPMAlgID = 0x0001
TPMAlgTDES TPMAlgID = 0x0003
TPMAlgSHA1 TPMAlgID = 0x0004
TPMAlgHMAC TPMAlgID = 0x0005
TPMAlgAES TPMAlgID = 0x0006
TPMAlgMGF1 TPMAlgID = 0x0007
TPMAlgKeyedHash TPMAlgID = 0x0008
TPMAlgXOR TPMAlgID = 0x000A
TPMAlgSHA256 TPMAlgID = 0x000B
TPMAlgSHA384 TPMAlgID = 0x000C
TPMAlgSHA512 TPMAlgID = 0x000D
TPMAlgNull TPMAlgID = 0x0010
TPMAlgSM3256 TPMAlgID = 0x0012
TPMAlgSM4 TPMAlgID = 0x0013
TPMAlgRSASSA TPMAlgID = 0x0014
TPMAlgRSAES TPMAlgID = 0x0015
TPMAlgRSAPSS TPMAlgID = 0x0016
TPMAlgOAEP TPMAlgID = 0x0017
TPMAlgECDSA TPMAlgID = 0x0018
TPMAlgECDH TPMAlgID = 0x0019
TPMAlgECDAA TPMAlgID = 0x001A
TPMAlgSM2 TPMAlgID = 0x001B
TPMAlgECSchnorr TPMAlgID = 0x001C
TPMAlgECMQV TPMAlgID = 0x001D
TPMAlgKDF1SP80056A TPMAlgID = 0x0020
TPMAlgKDF2 TPMAlgID = 0x0021
TPMAlgKDF1SP800108 TPMAlgID = 0x0022
TPMAlgECC TPMAlgID = 0x0023
TPMAlgSymCipher TPMAlgID = 0x0025
TPMAlgCamellia TPMAlgID = 0x0026
TPMAlgSHA3256 TPMAlgID = 0x0027
TPMAlgSHA3384 TPMAlgID = 0x0028
TPMAlgSHA3512 TPMAlgID = 0x0029
TPMAlgCMAC TPMAlgID = 0x003F
TPMAlgCTR TPMAlgID = 0x0040
TPMAlgOFB TPMAlgID = 0x0041
TPMAlgCBC TPMAlgID = 0x0042
TPMAlgCFB TPMAlgID = 0x0043
TPMAlgECB TPMAlgID = 0x0044
)
// TPMECCCurve represents a TPM_ECC_Curve.
// See definition in Part 2: Structures, section 6.4.
type TPMECCCurve uint16
// TPMECCCurve values come from Part 2: Structures, section 6.4.
const (
TPMECCNone TPMECCCurve = 0x0000
TPMECCNistP192 TPMECCCurve = 0x0001
TPMECCNistP224 TPMECCCurve = 0x0002
TPMECCNistP256 TPMECCCurve = 0x0003
TPMECCNistP384 TPMECCCurve = 0x0004
TPMECCNistP521 TPMECCCurve = 0x0005
TPMECCBNP256 TPMECCCurve = 0x0010
TPMECCBNP638 TPMECCCurve = 0x0011
TPMECCSM2P256 TPMECCCurve = 0x0020
)
// TPMCC represents a TPM_CC.
// See definition in Part 2: Structures, section 6.5.2.
type TPMCC uint32
// TPMCC values come from Part 2: Structures, section 6.5.2.
const (
TPMCCNVUndefineSpaceSpecial TPMCC = 0x0000011F
TPMCCEvictControl TPMCC = 0x00000120
TPMCCHierarchyControl TPMCC = 0x00000121
TPMCCNVUndefineSpace TPMCC = 0x00000122
TPMCCChangeEPS TPMCC = 0x00000124
TPMCCChangePPS TPMCC = 0x00000125
TPMCCClear TPMCC = 0x00000126
TPMCCClearControl TPMCC = 0x00000127
TPMCCClockSet TPMCC = 0x00000128
TPMCCHierarchyChanegAuth TPMCC = 0x00000129
TPMCCNVDefineSpace TPMCC = 0x0000012A
TPMCCPCRAllocate TPMCC = 0x0000012B
TPMCCPCRSetAuthPolicy TPMCC = 0x0000012C
TPMCCPPCommands TPMCC = 0x0000012D
TPMCCSetPrimaryPolicy TPMCC = 0x0000012E
TPMCCFieldUpgradeStart TPMCC = 0x0000012F
TPMCCClockRateAdjust TPMCC = 0x00000130
TPMCCCreatePrimary TPMCC = 0x00000131
TPMCCNVGlobalWriteLock TPMCC = 0x00000132
TPMCCGetCommandAuditDigest TPMCC = 0x00000133
TPMCCNVIncrement TPMCC = 0x00000134
TPMCCNVSetBits TPMCC = 0x00000135
TPMCCNVExtend TPMCC = 0x00000136
TPMCCNVWrite TPMCC = 0x00000137
TPMCCNVWriteLock TPMCC = 0x00000138
TPMCCDictionaryAttackLockReset TPMCC = 0x00000139
TPMCCDictionaryAttackParameters TPMCC = 0x0000013A
TPMCCNVChangeAuth TPMCC = 0x0000013B
TPMCCPCREvent TPMCC = 0x0000013C
TPMCCPCRReset TPMCC = 0x0000013D
TPMCCSequenceComplete TPMCC = 0x0000013E
TPMCCSetAlgorithmSet TPMCC = 0x0000013F
TPMCCSetCommandCodeAuditStatus TPMCC = 0x00000140
TPMCCFieldUpgradeData TPMCC = 0x00000141
TPMCCIncrementalSelfTest TPMCC = 0x00000142
TPMCCSelfTest TPMCC = 0x00000143
TPMCCStartup TPMCC = 0x00000144
TPMCCShutdown TPMCC = 0x00000145
TPMCCStirRandom TPMCC = 0x00000146
TPMCCActivateCredential TPMCC = 0x00000147
TPMCCCertify TPMCC = 0x00000148
TPMCCPolicyNV TPMCC = 0x00000149
TPMCCCertifyCreation TPMCC = 0x0000014A
TPMCCDuplicate TPMCC = 0x0000014B
TPMCCGetTime TPMCC = 0x0000014C
TPMCCGetSessionAuditDigest TPMCC = 0x0000014D
TPMCCNVRead TPMCC = 0x0000014E
TPMCCNVReadLock TPMCC = 0x0000014F
TPMCCObjectChangeAuth TPMCC = 0x00000150
TPMCCPolicySecret TPMCC = 0x00000151
TPMCCRewrap TPMCC = 0x00000152
TPMCCCreate TPMCC = 0x00000153
TPMCCECDHZGen TPMCC = 0x00000154
TPMCCMAC TPMCC = 0x00000155
TPMCCImport TPMCC = 0x00000156
TPMCCLoad TPMCC = 0x00000157
TPMCCQuote TPMCC = 0x00000158
TPMCCRSADecrypt TPMCC = 0x00000159
TPMCCMACStart TPMCC = 0x0000015B
TPMCCSequenceUpdate TPMCC = 0x0000015C
TPMCCSign TPMCC = 0x0000015D
TPMCCUnseal TPMCC = 0x0000015E
TPMCCPolicySigned TPMCC = 0x00000160
TPMCCContextLoad TPMCC = 0x00000161
TPMCCContextSave TPMCC = 0x00000162
TPMCCECDHKeyGen TPMCC = 0x00000163
TPMCCEncryptDecrypt TPMCC = 0x00000164
TPMCCFlushContext TPMCC = 0x00000165
TPMCCLoadExternal TPMCC = 0x00000167
TPMCCMakeCredential TPMCC = 0x00000168
TPMCCNVReadPublic TPMCC = 0x00000169
TPMCCPolicyAuthorize TPMCC = 0x0000016A
TPMCCPolicyAuthValue TPMCC = 0x0000016B
TPMCCPolicyCommandCode TPMCC = 0x0000016C
TPMCCPolicyCounterTimer TPMCC = 0x0000016D
TPMCCPolicyCpHash TPMCC = 0x0000016E
TPMCCPolicyLocality TPMCC = 0x0000016F
TPMCCPolicyNameHash TPMCC = 0x00000170
TPMCCPolicyOR TPMCC = 0x00000171
TPMCCPolicyTicket TPMCC = 0x00000172
TPMCCReadPublic TPMCC = 0x00000173
TPMCCRSAEncrypt TPMCC = 0x00000174
TPMCCStartAuthSession TPMCC = 0x00000176
TPMCCVerifySignature TPMCC = 0x00000177
TPMCCECCParameters TPMCC = 0x00000178
TPMCCFirmwareRead TPMCC = 0x00000179
TPMCCGetCapability TPMCC = 0x0000017A
TPMCCGetRandom TPMCC = 0x0000017B
TPMCCGetTestResult TPMCC = 0x0000017C
TPMCCHash TPMCC = 0x0000017D
TPMCCPCRRead TPMCC = 0x0000017E
TPMCCPolicyPCR TPMCC = 0x0000017F
TPMCCPolicyRestart TPMCC = 0x00000180
TPMCCReadClock TPMCC = 0x00000181
TPMCCPCRExtend TPMCC = 0x00000182
TPMCCPCRSetAuthValue TPMCC = 0x00000183
TPMCCNVCertify TPMCC = 0x00000184
TPMCCEventSequenceComplete TPMCC = 0x00000185
TPMCCHashSequenceStart TPMCC = 0x00000186
TPMCCPolicyPhysicalPresence TPMCC = 0x00000187
TPMCCPolicyDuplicationSelect TPMCC = 0x00000188
TPMCCPolicyGetDigest TPMCC = 0x00000189
TPMCCTestParams TPMCC = 0x0000018A
TPMCCCommit TPMCC = 0x0000018B
TPMCCPolicyPassword TPMCC = 0x0000018C
TPMCCZGen2Phase TPMCC = 0x0000018D
TPMCCECEphemeral TPMCC = 0x0000018E
TPMCCPolicyNvWritten TPMCC = 0x0000018F
TPMCCPolicyTemplate TPMCC = 0x00000190
TPMCCCreateLoaded TPMCC = 0x00000191
TPMCCPolicyAuthorizeNV TPMCC = 0x00000192
TPMCCEncryptDecrypt2 TPMCC = 0x00000193
TPMCCACGetCapability TPMCC = 0x00000194
TPMCCACSend TPMCC = 0x00000195
TPMCCPolicyACSendSelect TPMCC = 0x00000196
TPMCCCertifyX509 TPMCC = 0x00000197
TPMCCACTSetTimeout TPMCC = 0x00000198
)
// TPMRC represents a TPM_RC.
// See definition in Part 2: Structures, section 6.6.
type TPMRC uint32
// TPMRC values come from Part 2: Structures, section 6.6.3.
const (
rcVer1 = 0x00000100
rcFmt1 = 0x00000080
rcWarn = 0x00000900
rcP = 0x00000040
rcS = 0x00000800
TPMRCSuccess TPMRC = 0x00000000
// FMT0 error codes
TPMRCInitialize TPMRC = rcVer1 + 0x000
TPMRCFailure TPMRC = rcVer1 + 0x001
TPMRCSequence TPMRC = rcVer1 + 0x003
TPMRCPrivate TPMRC = rcVer1 + 0x00B
TPMRCHMAC TPMRC = rcVer1 + 0x019
TPMRCDisabled TPMRC = rcVer1 + 0x020
TPMRCExclusive TPMRC = rcVer1 + 0x021
TPMRCAuthType TPMRC = rcVer1 + 0x024
TPMRCAuthMissing TPMRC = rcVer1 + 0x025
TPMRCPolicy TPMRC = rcVer1 + 0x026
TPMRCPCR TPMRC = rcVer1 + 0x027
TPMRCPCRChanged TPMRC = rcVer1 + 0x028
TPMRCUpgrade TPMRC = rcVer1 + 0x02D
TPMRCTooManyContexts TPMRC = rcVer1 + 0x02E
TPMRCAuthUnavailable TPMRC = rcVer1 + 0x02F
TPMRCReboot TPMRC = rcVer1 + 0x030
TPMRCUnbalanced TPMRC = rcVer1 + 0x031
TPMRCCommandSize TPMRC = rcVer1 + 0x042
TPMRCCommandCode TPMRC = rcVer1 + 0x043
TPMRCAuthSize TPMRC = rcVer1 + 0x044
TPMRCAuthContext TPMRC = rcVer1 + 0x045
TPMRCNVRange TPMRC = rcVer1 + 0x046
TPMRCNVSize TPMRC = rcVer1 + 0x047
TPMRCNVLocked TPMRC = rcVer1 + 0x048
TPMRCNVAuthorization TPMRC = rcVer1 + 0x049
TPMRCNVUninitialized TPMRC = rcVer1 + 0x04A
TPMRCNVSpace TPMRC = rcVer1 + 0x04B
TPMRCNVDefined TPMRC = rcVer1 + 0x04C
TPMRCBadContext TPMRC = rcVer1 + 0x050
TPMRCCPHash TPMRC = rcVer1 + 0x051
TPMRCParent TPMRC = rcVer1 + 0x052
TPMRCNeedsTest TPMRC = rcVer1 + 0x053
TPMRCNoResult TPMRC = rcVer1 + 0x054
TPMRCSensitive TPMRC = rcVer1 + 0x055
// FMT1 error codes
TPMRCAsymmetric TPMRC = rcFmt1 + 0x001
TPMRCAttributes TPMRC = rcFmt1 + 0x002
TPMRCHash TPMRC = rcFmt1 + 0x003
TPMRCValue TPMRC = rcFmt1 + 0x004
TPMRCHierarchy TPMRC = rcFmt1 + 0x005
TPMRCKeySize TPMRC = rcFmt1 + 0x007
TPMRCMGF TPMRC = rcFmt1 + 0x008
TPMRCMode TPMRC = rcFmt1 + 0x009
TPMRCType TPMRC = rcFmt1 + 0x00A
TPMRCHandle TPMRC = rcFmt1 + 0x00B
TPMRCKDF TPMRC = rcFmt1 + 0x00C
TPMRCRange TPMRC = rcFmt1 + 0x00D
TPMRCAuthFail TPMRC = rcFmt1 + 0x00E
TPMRCNonce TPMRC = rcFmt1 + 0x00F
TPMRCPP TPMRC = rcFmt1 + 0x010
TPMRCScheme TPMRC = rcFmt1 + 0x012
TPMRCSize TPMRC = rcFmt1 + 0x015
TPMRCSymmetric TPMRC = rcFmt1 + 0x016
TPMRCTag TPMRC = rcFmt1 + 0x017
TPMRCSelector TPMRC = rcFmt1 + 0x018
TPMRCInsufficient TPMRC = rcFmt1 + 0x01A
TPMRCSignature TPMRC = rcFmt1 + 0x01B
TPMRCKey TPMRC = rcFmt1 + 0x01C
TPMRCPolicyFail TPMRC = rcFmt1 + 0x01D
TPMRCIntegrity TPMRC = rcFmt1 + 0x01F
TPMRCTicket TPMRC = rcFmt1 + 0x020
TPMRCReservedBits TPMRC = rcFmt1 + 0x021
TPMRCBadAuth TPMRC = rcFmt1 + 0x022
TPMRCExpired TPMRC = rcFmt1 + 0x023
TPMRCPolicyCC TPMRC = rcFmt1 + 0x024
TPMRCBinding TPMRC = rcFmt1 + 0x025
TPMRCCurve TPMRC = rcFmt1 + 0x026
TPMRCECCPoint TPMRC = rcFmt1 + 0x027
// Warnings
TPMRCContextGap TPMRC = rcWarn + 0x001
TPMRCObjectMemory TPMRC = rcWarn + 0x002
TPMRCSessionMemory TPMRC = rcWarn + 0x003
TPMRCMemory TPMRC = rcWarn + 0x004
TPMRCSessionHandles TPMRC = rcWarn + 0x005
TPMRCObjectHandles TPMRC = rcWarn + 0x006
TPMRCLocality TPMRC = rcWarn + 0x007
TPMRCYielded TPMRC = rcWarn + 0x008
TPMRCCanceled TPMRC = rcWarn + 0x009
TPMRCTesting TPMRC = rcWarn + 0x00A
TPMRCReferenceH0 TPMRC = rcWarn + 0x010
TPMRCReferenceH1 TPMRC = rcWarn + 0x011
TPMRCReferenceH2 TPMRC = rcWarn + 0x012
TPMRCReferenceH3 TPMRC = rcWarn + 0x013
TPMRCReferenceH4 TPMRC = rcWarn + 0x014
TPMRCReferenceH5 TPMRC = rcWarn + 0x015
TPMRCReferenceH6 TPMRC = rcWarn + 0x016
TPMRCReferenceS0 TPMRC = rcWarn + 0x018
TPMRCReferenceS1 TPMRC = rcWarn + 0x019
TPMRCReferenceS2 TPMRC = rcWarn + 0x01A
TPMRCReferenceS3 TPMRC = rcWarn + 0x01B
TPMRCReferenceS4 TPMRC = rcWarn + 0x01C
TPMRCReferenceS5 TPMRC = rcWarn + 0x01D
TPMRCReferenceS6 TPMRC = rcWarn + 0x01E
TPMRCNVRate TPMRC = rcWarn + 0x020
TPMRCLockout TPMRC = rcWarn + 0x021
TPMRCRetry TPMRC = rcWarn + 0x022
TPMRCNVUnavailable TPMRC = rcWarn + 0x023
)
// TPMEO represents a TPM_EO.
// See definition in Part 2: Structures, section 6.8.
type TPMEO uint16
// TPMEO values come from Part 2: Structures, section 6.8.
const (
TPMEOEq TPMEO = 0x0000
TPMEONeq TPMEO = 0x0001
TPMEOSignedGT TPMEO = 0x0002
TPMEOUnsignedGT TPMEO = 0x0003
TPMEOSignedLT TPMEO = 0x0004
TPMEOUnsignedLT TPMEO = 0x0005
TPMEOSignedGE TPMEO = 0x0006
TPMEOUnsignedGE TPMEO = 0x0007
TPMEOSignedLE TPMEO = 0x0008
TPMEOUnsignedLE TPMEO = 0x0009
TPMEOBitSet TPMEO = 0x000A
TPMEOBitClear TPMEO = 0x000B
)
// TPMST represents a TPM_ST.
// See definition in Part 2: Structures, section 6.9.
type TPMST uint16
// TPMST values come from Part 2: Structures, section 6.9.
const (
TPMSTRspCommand TPMST = 0x00C4
TPMSTNull TPMST = 0x8000
TPMSTNoSessions TPMST = 0x8001
TPMSTSessions TPMST = 0x8002
TPMSTAttestNV TPMST = 0x8014
TPMSTAttestCommandAudit TPMST = 0x8015
TPMSTAttestSessionAudit TPMST = 0x8016
TPMSTAttestCertify TPMST = 0x8017
TPMSTAttestQuote TPMST = 0x8018
TPMSTAttestTime TPMST = 0x8019
TPMSTAttestCreation TPMST = 0x801A
TPMSTAttestNVDigest TPMST = 0x801C
TPMSTCreation TPMST = 0x8021
TPMSTVerified TPMST = 0x8022
TPMSTAuthSecret TPMST = 0x8023
TPMSTHashCheck TPMST = 0x8024
TPMSTAuthSigned TPMST = 0x8025
TPMSTFuManifest TPMST = 0x8029
)
// TPMSU represents a TPM_SU.
// See definition in Part 2: Structures, section 6.10.
type TPMSU uint16
// TPMSU values come from Part 2: Structures, section 6.10.
const (
TPMSUClear TPMSU = 0x0000
TPMSUState TPMSU = 0x0001
)
// TPMSE represents a TPM_SE.
// See definition in Part 2: Structures, section 6.11.
type TPMSE uint8
// TPMSE values come from Part 2: Structures, section 6.11.
const (
TPMSEHMAC TPMSE = 0x00
TPMSEPolicy TPMSE = 0x01
TPMSETrial TPMSE = 0x03
)
// TPMCap represents a TPM_CAP.
// See definition in Part 2: Structures, section 6.12.
type TPMCap uint32
// TPMCap values come from Part 2: Structures, section 6.12.
const (
TPMCapAlgs TPMCap = 0x00000000
TPMCapHandles TPMCap = 0x00000001
TPMCapCommands TPMCap = 0x00000002
TPMCapPPCommands TPMCap = 0x00000003
TPMCapAuditCommands TPMCap = 0x00000004
TPMCapPCRs TPMCap = 0x00000005
TPMCapTPMProperties TPMCap = 0x00000006
TPMCapPCRProperties TPMCap = 0x00000007
TPMCapECCCurves TPMCap = 0x00000008
TPMCapAuthPolicies TPMCap = 0x00000009
TPMCapACT TPMCap = 0x0000000A
)
// TPMPT represents a TPM_PT.
// See definition in Part 2: Structures, section 6.13.
type TPMPT uint32
// TPMPT values come from Part 2: Structures, section 6.13.
const (
// a 4-octet character string containing the TPM Family value
// (TPM_SPEC_FAMILY)
TPMPTFamilyIndicator TPMPT = 0x00000100
// the level of the specification
TPMPTLevel TPMPT = 0x00000101
// the specification Revision times 100
TPMPTRevision TPMPT = 0x00000102
// the specification day of year using TCG calendar
TPMPTDayofYear TPMPT = 0x00000103
// the specification year using the CE
TPMPTYear TPMPT = 0x00000104
// the vendor ID unique to each TPM manufacturer
TPMPTManufacturer TPMPT = 0x00000105
// the first four characters of the vendor ID string
TPMPTVendorString1 TPMPT = 0x00000106
// the second four characters of the vendor ID string
TPMPTVendorString2 TPMPT = 0x00000107
// the third four characters of the vendor ID string
TPMPTVendorString3 TPMPT = 0x00000108
// the fourth four characters of the vendor ID sting
TPMPTVendorString4 TPMPT = 0x00000109
// vendor-defined value indicating the TPM model
TPMPTVendorTPMType TPMPT = 0x0000010A
// the most-significant 32 bits of a TPM vendor-specific value
// indicating the version number of the firmware.
TPMPTFirmwareVersion1 TPMPT = 0x0000010B
// the least-significant 32 bits of a TPM vendor-specific value
// indicating the version number of the firmware.
TPMPTFirmwareVersion2 TPMPT = 0x0000010C
// the maximum size of a parameter TPM2B_MAX_BUFFER)
TPMPTInputBuffer TPMPT = 0x0000010D
// the minimum number of transient objects that can be held in TPM RAM
TPMPTHRTransientMin TPMPT = 0x0000010E
// the minimum number of persistent objects that can be held in TPM NV
// memory
TPMPTHRPersistentMin TPMPT = 0x0000010F
// the minimum number of authorization sessions that can be held in TPM
// RAM
TPMPTHRLoadedMin TPMPT = 0x00000110
// the number of authorization sessions that may be active at a time
TPMPTActiveSessionsMax TPMPT = 0x00000111
// the number of PCR implemented
TPMPTPCRCount TPMPT = 0x00000112
// the minimum number of octets in a TPMS_PCR_SELECT.sizeOfSelect
TPMPTPCRSelectMin TPMPT = 0x00000113
// the maximum allowed difference (unsigned) between the contextID
// values of two saved session contexts
TPMPTContextGapMax TPMPT = 0x00000114
// the maximum number of NV Indexes that are allowed to have the
// TPM_NT_COUNTER attribute
TPMPTNVCountersMax TPMPT = 0x00000116
// the maximum size of an NV Index data area
TPMPTNVIndexMax TPMPT = 0x00000117
// a TPMA_MEMORY indicating the memory management method for the TPM
TPMPTMemory TPMPT = 0x00000118
// interval, in milliseconds, between updates to the copy of
// TPMS_CLOCK_INFO.clock in NV
TPMPTClockUpdate TPMPT = 0x00000119
// the algorithm used for the integrity HMAC on saved contexts and for
// hashing the fuData of TPM2_FirmwareRead()
TPMPTContextHash TPMPT = 0x0000011A
// TPM_ALG_ID, the algorithm used for encryption of saved contexts
TPMPTContextSym TPMPT = 0x0000011B
// TPM_KEY_BITS, the size of the key used for encryption of saved
// contexts
TPMPTContextSymSize TPMPT = 0x0000011C
// the modulus - 1 of the count for NV update of an orderly counter
TPMPTOrderlyCount TPMPT = 0x0000011D
// the maximum value for commandSize in a command
TPMPTMaxCommandSize TPMPT = 0x0000011E
// the maximum value for responseSize in a response
TPMPTMaxResponseSize TPMPT = 0x0000011F
// the maximum size of a digest that can be produced by the TPM
TPMPTMaxDigest TPMPT = 0x00000120
// the maximum size of an object context that will be returned by
// TPM2_ContextSave
TPMPTMaxObjectContext TPMPT = 0x00000121
// the maximum size of a session context that will be returned by
// TPM2_ContextSave
TPMPTMaxSessionContext TPMPT = 0x00000122
// platform-specific family (a TPM_PS value)(see Table 25)
TPMPTPSFamilyIndicator TPMPT = 0x00000123
// the level of the platform-specific specification
TPMPTPSLevel TPMPT = 0x00000124
// a platform specific value
TPMPTPSRevision TPMPT = 0x00000125
// the platform-specific TPM specification day of year using TCG
// calendar
TPMPTPSDayOfYear TPMPT = 0x00000126
// the platform-specific TPM specification year using the CE
TPMPTPSYear TPMPT = 0x00000127
// the number of split signing operations supported by the TPM
TPMPTSplitMax TPMPT = 0x00000128
// total number of commands implemented in the TPM
TPMPTTotalCommands TPMPT = 0x00000129
// number of commands from the TPM library that are implemented
TPMPTLibraryCommands TPMPT = 0x0000012A
// number of vendor commands that are implemented
TPMPTVendorCommands TPMPT = 0x0000012B
// the maximum data size in one NV write, NV read, NV extend, or NV
// certify command
TPMPTNVBufferMax TPMPT = 0x0000012C
// a TPMA_MODES value, indicating that the TPM is designed for these
// modes.
TPMPTModes TPMPT = 0x0000012D
// the maximum size of a TPMS_CAPABILITY_DATA structure returned in
// TPM2_GetCapability().
TPMPTMaxCapBuffer TPMPT = 0x0000012E
// TPMA_PERMANENT
TPMPTPermanent TPMPT = 0x00000200
// TPMA_STARTUP_CLEAR
TPMPTStartupClear TPMPT = 0x00000201
// the number of NV Indexes currently defined
TPMPTHRNVIndex TPMPT = 0x00000202
// the number of authorization sessions currently loaded into TPM RAM
TPMPTHRLoaded TPMPT = 0x00000203
// the number of additional authorization sessions, of any type, that
// could be loaded into TPM RAM
TPMPTHRLoadedAvail TPMPT = 0x00000204
// the number of active authorization sessions currently being tracked
// by the TPM
TPMPTHRActive TPMPT = 0x00000205
// the number of additional authorization sessions, of any type, that
// could be created
TPMPTHRActiveAvail TPMPT = 0x00000206
// estimate of the number of additional transient objects that could be
// loaded into TPM RAM
TPMPTHRTransientAvail TPMPT = 0x00000207
// the number of persistent objects currently loaded into TPM NV memory
TPMPTHRPersistent TPMPT = 0x00000208
// the number of additional persistent objects that could be loaded into
// NV memory
TPMPTHRPersistentAvail TPMPT = 0x00000209
// the number of defined NV Indexes that have NV the TPM_NT_COUNTER
// attribute
TPMPTNVCounters TPMPT = 0x0000020A
// the number of additional NV Indexes that can be defined with their
// TPM_NT of TPM_NV_COUNTER and the TPMA_NV_ORDERLY attribute SET
TPMPTNVCountersAvail TPMPT = 0x0000020B
// code that limits the algorithms that may be used with the TPM
TPMPTAlgorithmSet TPMPT = 0x0000020C
// the number of loaded ECC curves
TPMPTLoadedCurves TPMPT = 0x0000020D
// the current value of the lockout counter (failedTries)
TPMPTLockoutCounter TPMPT = 0x0000020E
// the number of authorization failures before DA lockout is invoked
TPMPTMaxAuthFail TPMPT = 0x0000020F
// the number of seconds before the value reported by
// TPM_PT_LOCKOUT_COUNTER is decremented
TPMPTLockoutInterval TPMPT = 0x00000210
// the number of seconds after a lockoutAuth failure before use of
// lockoutAuth may be attempted again
TPMPTLockoutRecovery TPMPT = 0x00000211
// number of milliseconds before the TPM will accept another command
// that will modify NV
TPMPTNVWriteRecovery TPMPT = 0x00000212
// the high-order 32 bits of the command audit counter
TPMPTAuditCounter0 TPMPT = 0x00000213
// the low-order 32 bits of the command audit counter
TPMPTAuditCounter1 TPMPT = 0x00000214
)
// TPMPTPCR represents a TPM_PT_PCR.
// See definition in Part 2: Structures, section 6.14.
type TPMPTPCR uint32
// TPMPTPCR values come from Part 2: Structures, section 6.14.
const (
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR is saved and
// restored by TPM_SU_STATE
TPMPTPCRSave TPMPTPCR = 0x00000000
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be
// extended from locality 0
TPMPTPCRExtendL0 TPMPTPCR = 0x00000001
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be reset
// by TPM2_PCR_Reset() from locality 0
TPMPTPCRResetL0 TPMPTPCR = 0x00000002
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be
// extended from locality 1
TPMPTPCRExtendL1 TPMPTPCR = 0x00000003
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be reset
// by TPM2_PCR_Reset() from locality 1
TPMPTPCRResetL1 TPMPTPCR = 0x00000004
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be
// extended from locality 2
TPMPTPCRExtendL2 TPMPTPCR = 0x00000005
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be reset
// by TPM2_PCR_Reset() from locality 2
TPMPTPCRResetL2 TPMPTPCR = 0x00000006
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be
// extended from locality 3
TPMPTPCRExtendL3 TPMPTPCR = 0x00000007
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be reset
// by TPM2_PCR_Reset() from locality 3
TPMPTPCRResetL3 TPMPTPCR = 0x00000008
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be
// extended from locality 4
TPMPTPCRExtendL4 TPMPTPCR = 0x00000009
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR may be reset
// by TPM2_PCR_Reset() from locality 4
TPMPTPCRResetL4 TPMPTPCR = 0x0000000A
// a SET bit in the TPMS_PCR_SELECT indicates that modifications to this
// PCR (reset or Extend) will not increment the pcrUpdateCounter
TPMPTPCRNoIncrement TPMPTPCR = 0x00000011
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR is reset by a
// D-RTM event
TPMPTPCRDRTMRest TPMPTPCR = 0x00000012
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR is controlled
// by policy
TPMPTPCRPolicy TPMPTPCR = 0x00000013
// a SET bit in the TPMS_PCR_SELECT indicates that the PCR is controlled
// by an authorization value
TPMPTPCRAuth TPMPTPCR = 0x00000014
)
// TPMHT represents a TPM_HT.
// See definition in Part 2: Structures, section 7.2.
type TPMHT uint8
// TPMHT values come from Part 2: Structures, section 7.2.
const (
TPMHTPCR TPMHT = 0x00
TPMHTNVIndex TPMHT = 0x01
TPMHTHMACSession TPMHT = 0x02
TPMHTPolicySession TPMHT = 0x03
TPMHTPermanent TPMHT = 0x40
TPMHTTransient TPMHT = 0x80
TPMHTPersistent TPMHT = 0x81
TPMHTAC TPMHT = 0x90
)
// TPMHandle represents a TPM_HANDLE.
// See definition in Part 2: Structures, section 7.1.
type TPMHandle uint32
// TPMHandle values come from Part 2: Structures, section 7.4.
const (
TPMRHOwner TPMHandle = 0x40000001
TPMRHNull TPMHandle = 0x40000007
TPMRSPW TPMHandle = 0x40000009
TPMRHLockout TPMHandle = 0x4000000A
TPMRHEndorsement TPMHandle = 0x4000000B
TPMRHPlatform TPMHandle = 0x4000000C
TPMRHPlatformNV TPMHandle = 0x4000000D
)
// TPMNT represents a TPM_NT.
// See definition in Part 2: Structures, section 13.4.
type TPMNT uint8
// TPMNT values come from Part 2: Structures, section 13.2.
const (
// contains data that is opaque to the TPM that can only be modified
// using TPM2_NV_Write().
TPMNTOrdinary TPMNT = 0x0
// contains an 8-octet value that is to be used as a counter and can
// only be modified with TPM2_NV_Increment()
TPMNTCounter TPMNT = 0x1
// contains an 8-octet value to be used as a bit field and can only be
// modified with TPM2_NV_SetBits().
TPMNTBits TPMNT = 0x2
// contains a digest-sized value used like a PCR. The Index can only be
// modified using TPM2_NV_Extend(). The extend will use the nameAlg of
// the Index.
TPMNTExtend TPMNT = 0x4
// contains pinCount that increments on a PIN authorization failure and
// a pinLimit
TPMNTPinFail TPMNT = 0x8
// contains pinCount that increments on a PIN authorization success and
// a pinLimit
TPMNTPinPass TPMNT = 0x9
)

View File

@ -1,14 +0,0 @@
package tpm2
// This file contains constant definitions we don't want to use stringer with
// (because they are duplicates of other values, and we would prefer those values
// to influence the string representations).
// Hash algorithm IDs and command codes that got re-used.
const (
TPMAlgSHA = TPMAlgSHA1
TPMCCHMAC = TPMCCMAC
TPMCCHMACStart = TPMCCMACStart
TPMHTLoadedSession = TPMHTHMACSession
TPMHTSavedSession = TPMHTPolicySession
)

View File

@ -1,43 +0,0 @@
package tpm2
import (
"crypto/elliptic"
"crypto/rsa"
"math/big"
)
// RSAPub converts a TPM RSA public key into one recognized by the rsa package.
func RSAPub(parms *TPMSRSAParms, pub *TPM2BPublicKeyRSA) (*rsa.PublicKey, error) {
result := rsa.PublicKey{
N: big.NewInt(0).SetBytes(pub.Buffer),
E: int(parms.Exponent),
}
// TPM considers 65537 to be the default RSA public exponent, and 0 in
// the parms
// indicates so.
if result.E == 0 {
result.E = 65537
}
return &result, nil
}
// ECDHPub is a convenience wrapper around the necessary info to perform point
// multiplication with the elliptic package.
type ECDHPub struct {
Curve elliptic.Curve
X, Y *big.Int
}
// ECCPub converts a TPM ECC public key into one recognized by the elliptic
// package's point-multiplication functions, for use in ECDH.
func ECCPub(parms *TPMSECCParms, pub *TPMSECCPoint) (*ECDHPub, error) {
curve, err := parms.CurveID.Curve()
if err != nil {
return nil, err
}
return &ECDHPub{
Curve: curve,
X: big.NewInt(0).SetBytes(pub.X.Buffer),
Y: big.NewInt(0).SetBytes(pub.Y.Buffer),
}, nil
}

View File

@ -1,561 +0,0 @@
package tpm2
import (
"fmt"
)
type errorDesc struct {
name string
description string
}
var fmt0Descs = map[TPMRC]errorDesc{
TPMRCInitialize: {
name: "TPM_RC_INITIALIZE",
description: "TPM not initialized by TPM2_Startup or already initialized",
},
TPMRCFailure: {
name: "TPM_RC_FAILURE",
description: "commands not being accepted because of a TPM failure",
},
TPMRCSequence: {
name: "TPM_RC_SEQUENCE",
description: "improper use of a sequence handle",
},
TPMRCPrivate: {
name: "TPM_RC_PRIVATE",
description: "not currently used",
},
TPMRCHMAC: {
name: "TPM_RC_HMAC",
description: "not currently used",
},
TPMRCDisabled: {
name: "TPM_RC_DISABLED",
description: "the command is disabled",
},
TPMRCExclusive: {
name: "TPM_RC_EXCLUSIVE",
description: "command failed because audit sequence required exclusivity",
},
TPMRCAuthType: {
name: "TPM_RC_AUTH_TYPE",
description: "authorization handle is not correct for command",
},
TPMRCAuthMissing: {
name: "TPM_RC_AUTH_MISSING",
description: "command requires an authorization session for handle and it is not present.",
},
TPMRCPolicy: {
name: "TPM_RC_POLICY",
description: "policy failure in math operation or an invalid authPolicy value",
},
TPMRCPCR: {
name: "TPM_RC_PCR",
description: "PCR check fail",
},
TPMRCPCRChanged: {
name: "TPM_RC_PCR_CHANGED",
description: "PCR have changed since checked.",
},
TPMRCUpgrade: {
name: "TPM_RC_UPGRADE",
description: "for all commands other than TPM2_FieldUpgradeData(), this code indicates that the TPM is in field upgrade mode; for TPM2_FieldUpgradeData(), this code indicates that the TPM is not in field upgrade mode",
},
TPMRCTooManyContexts: {
name: "TPM_RC_TOO_MANY_CONTEXTS",
description: "context ID counter is at maximum.",
},
TPMRCAuthUnavailable: {
name: "TPM_RC_AUTH_UNAVAILABLE",
description: "authValue or authPolicy is not available for selected entity.",
},
TPMRCReboot: {
name: "TPM_RC_REBOOT",
description: "a _TPM_Init and Startup(CLEAR) is required before the TPM can resume operation.",
},
TPMRCUnbalanced: {
name: "TPM_RC_UNBALANCED",
description: "the protection algorithms (hash and symmetric) are not reasonably balanced. The digest size of the hash must be larger than the key size of the symmetric algorithm.",
},
TPMRCCommandSize: {
name: "TPM_RC_COMMAND_SIZE",
description: "command commandSize value is inconsistent with contents of the command buffer; either the size is not the same as the octets loaded by the hardware interface layer or the value is not large enough to hold a command header",
},
TPMRCCommandCode: {
name: "TPM_RC_COMMAND_CODE",
description: "command code not supported",
},
TPMRCAuthSize: {
name: "TPM_RC_AUTHSIZE",
description: "the value of authorizationSize is out of range or the number of octets in the Authorization Area is greater than required",
},
TPMRCAuthContext: {
name: "TPM_RC_AUTH_CONTEXT",
description: "use of an authorization session with a context command or another command that cannot have an authorization session.",
},
TPMRCNVRange: {
name: "TPM_RC_NV_RANGE",
description: "NV offset+size is out of range.",
},
TPMRCNVSize: {
name: "TPM_RC_NV_SIZE",
description: "Requested allocation size is larger than allowed.",
},
TPMRCNVLocked: {
name: "TPM_RC_NV_LOCKED",
description: "NV access locked.",
},
TPMRCNVAuthorization: {
name: "TPM_RC_NV_AUTHORIZATION",
description: "NV access authorization fails in command actions (this failure does not affect lockout.action)",
},
TPMRCNVUninitialized: {
name: "TPM_RC_NV_UNINITIALIZED",
description: "an NV Index is used before being initialized or the state saved by TPM2_Shutdown(STATE) could not be restored",
},
TPMRCNVSpace: {
name: "TPM_RC_NV_SPACE",
description: "insufficient space for NV allocation",
},
TPMRCNVDefined: {
name: "TPM_RC_NV_DEFINED",
description: "NV Index or persistent object already defined",
},
TPMRCBadContext: {
name: "TPM_RC_BAD_CONTEXT",
description: "context in TPM2_ContextLoad() is not valid",
},
TPMRCCPHash: {
name: "TPM_RC_CPHASH",
description: "cpHash value already set or not correct for use",
},
TPMRCParent: {
name: "TPM_RC_PARENT",
description: "handle for parent is not a valid parent",
},
TPMRCNeedsTest: {
name: "TPM_RC_NEEDS_TEST",
description: "some function needs testing.",
},
TPMRCNoResult: {
name: "TPM_RC_NO_RESULT",
description: "an internal function cannot process a request due to an unspecified problem. This code is usually related to invalid parameters that are not properly filtered by the input unmarshaling code.",
},
TPMRCSensitive: {
name: "TPM_RC_SENSITIVE",
description: "the sensitive area did not unmarshal correctly after decryption this code is used in lieu of the other unmarshaling errors so that an attacker cannot determine where the unmarshaling error occurred",
},
}
var fmt1Descs = map[TPMRC]errorDesc{
TPMRCAsymmetric: {
name: "TPM_RC_ASYMMETRIC RC_FMT1",
description: "asymmetric algorithm not supported or not correct",
},
TPMRCAttributes: {
name: "TPM_RC_ATTRIBUTES",
description: "inconsistent attributes",
},
TPMRCHash: {
name: "TPM_RC_HASH",
description: "hash algorithm not supported or not appropriate",
},
TPMRCValue: {
name: "TPM_RC_VALUE",
description: "value is out of range or is not correct for the context",
},
TPMRCHierarchy: {
name: "TPM_RC_HIERATPMRCHY",
description: "hierarchy is not enabled or is not correct for the use",
},
TPMRCKeySize: {
name: "TPM_RC_KEY_SIZE",
description: "key size is not supported",
},
TPMRCMGF: {
name: "TPM_RC_MGF",
description: "mask generation function not supported",
},
TPMRCMode: {
name: "TPM_RC_MODE",
description: "mode of operation not supported",
},
TPMRCType: {
name: "TPM_RC_TYPE",
description: "the type of the value is not appropriate for the use",
},
TPMRCHandle: {
name: "TPM_RC_HANDLE",
description: "the handle is not correct for the use",
},
TPMRCKDF: {
name: "TPM_RC_KDF",
description: "unsupported key derivation function or function not appropriate for use",
},
TPMRCRange: {
name: "TPM_RC_RANGE",
description: "value was out of allowed range.",
},
TPMRCAuthFail: {
name: "TPM_RC_AUTH_FAIL",
description: "the authorization HMAC check failed and DA counter incremented",
},
TPMRCNonce: {
name: "TPM_RC_NONCE",
description: "invalid nonce size or nonce value mismatch",
},
TPMRCPP: {
name: "TPM_RC_PP",
description: "authorization requires assertion of PP",
},
TPMRCScheme: {
name: "TPM_RC_SCHEME",
description: "unsupported or incompatible scheme",
},
TPMRCSize: {
name: "TPM_RC_SIZE",
description: "structure is the wrong size",
},
TPMRCSymmetric: {
name: "TPM_RC_SYMMETRIC",
description: "unsupported symmetric algorithm or key size, or not appropriate for instance",
},
TPMRCTag: {
name: "TPM_RC_TAG",
description: "incorrect structure tag",
},
TPMRCSelector: {
name: "TPM_RC_SELECTOR",
description: "union selector is incorrect",
},
TPMRCInsufficient: {
name: "TPM_RC_INSUFFICIENT",
description: "the TPM was unable to unmarshal a value because there were not enough octets in the input buffer",
},
TPMRCSignature: {
name: "TPM_RC_SIGNATURE",
description: "the signature is not valid",
},
TPMRCKey: {
name: "TPM_RC_KEY",
description: "key fields are not compatible with the selected use",
},
TPMRCPolicyFail: {
name: "TPM_RC_POLICY_FAIL",
description: "a policy check failed",
},
TPMRCIntegrity: {
name: "TPM_RC_INTEGRITY",
description: "integrity check failed",
},
TPMRCTicket: {
name: "TPM_RC_TICKET",
description: "invalid ticket",
},
TPMRCReservedBits: {
name: "TPM_RC_RESERVED_BITS",
description: "reserved bits not set to zero as required",
},
TPMRCBadAuth: {
name: "TPM_RC_BAD_AUTH",
description: "authorization failure without DA implications",
},
TPMRCExpired: {
name: "TPM_RC_EXPIRED",
description: "the policy has expired",
},
TPMRCPolicyCC: {
name: "TPM_RC_POLICY_CC",
description: "the commandCode in the policy is not the commandCode of the command or the command code in a policy command references a command that is not implemented",
},
TPMRCBinding: {
name: "TPM_RC_BINDING",
description: "public and sensitive portions of an object are not cryptographically bound",
},
TPMRCCurve: {
name: "TPM_RC_CURVE",
description: "curve not supported",
},
TPMRCECCPoint: {
name: "TPM_RC_ECC_POINT",
description: "point is not on the required curve.",
},
}
var warnDescs = map[TPMRC]errorDesc{
TPMRCContextGap: {
name: "TPM_RC_CONTEXT_GAP",
description: "gap for context ID is too large",
},
TPMRCObjectMemory: {
name: "TPM_RC_OBJECT_MEMORY",
description: "out of memory for object contexts",
},
TPMRCSessionMemory: {
name: "TPM_RC_SESSION_MEMORY",
description: "out of memory for session contexts",
},
TPMRCMemory: {
name: "TPM_RC_MEMORY",
description: "out of shared object/session memory or need space for internal operations",
},
TPMRCSessionHandles: {
name: "TPM_RC_SESSION_HANDLES",
description: "out of session handles a session must be flushed before a new session may be created",
},
TPMRCObjectHandles: {
name: "TPM_RC_OBJECT_HANDLES",
description: "out of object handles the handle space for objects is depleted and a reboot is required",
},
TPMRCLocality: {
name: "TPM_RC_LOCALITY",
description: "bad locality",
},
TPMRCYielded: {
name: "TPM_RC_YIELDED",
description: "the TPM has suspended operation on the command; forward progress was made and the command may be retried",
},
TPMRCCanceled: {
name: "TPM_RC_CANCELED",
description: "the command was canceled",
},
TPMRCTesting: {
name: "TPM_RC_TESTING",
description: "TPM is performing self-tests",
},
TPMRCReferenceH0: {
name: "TPM_RC_REFERENCE_H0",
description: "the 1st handle in the handle area references a transient object or session that is not loaded",
},
TPMRCReferenceH1: {
name: "TPM_RC_REFERENCE_H1",
description: "the 2nd handle in the handle area references a transient object or session that is not loaded",
},
TPMRCReferenceH2: {
name: "TPM_RC_REFERENCE_H2",
description: "the 3rd handle in the handle area references a transient object or session that is not loaded",
},
TPMRCReferenceH3: {
name: "TPM_RC_REFERENCE_H3",
description: "the 4th handle in the handle area references a transient object or session that is not loaded",
},
TPMRCReferenceH4: {
name: "TPM_RC_REFERENCE_H4",
description: "the 5th handle in the handle area references a transient object or session that is not loaded",
},
TPMRCReferenceH5: {
name: "TPM_RC_REFERENCE_H5",
description: "the 6th handle in the handle area references a transient object or session that is not loaded",
},
TPMRCReferenceH6: {
name: "TPM_RC_REFERENCE_H6",
description: "the 7th handle in the handle area references a transient object or session that is not loaded",
},
TPMRCReferenceS0: {
name: "TPM_RC_REFERENCE_S0",
description: "the 1st authorization session handle references a session that is not loaded",
},
TPMRCReferenceS1: {
name: "TPM_RC_REFERENCE_S1",
description: "the 2nd authorization session handle references a session that is not loaded",
},
TPMRCReferenceS2: {
name: "TPM_RC_REFERENCE_S2",
description: "the 3rd authorization session handle references a session that is not loaded",
},
TPMRCReferenceS3: {
name: "TPM_RC_REFERENCE_S3",
description: "the 4th authorization session handle references a session that is not loaded",
},
TPMRCReferenceS4: {
name: "TPM_RC_REFERENCE_S4",
description: "the 5th session handle references a session that is not loaded",
},
TPMRCReferenceS5: {
name: "TPM_RC_REFERENCE_S5",
description: "the 6th session handle references a session that is not loaded",
},
TPMRCReferenceS6: {
name: "TPM_RC_REFERENCE_S6",
description: "the 7th authorization session handle references a session that is not loaded",
},
TPMRCNVRate: {
name: "TPM_RC_NV_RATE",
description: "the TPM is rate-limiting accesses to prevent wearout of NV",
},
TPMRCLockout: {
name: "TPM_RC_LOCKOUT",
description: "authorizations for objects subject to DA protection are not allowed at this time because the TPM is in DA lockout mode",
},
TPMRCRetry: {
name: "TPM_RC_RETRY",
description: "the TPM was not able to start the command",
},
TPMRCNVUnavailable: {
name: "TPM_RC_NV_UNAVAILABLE",
description: "the command may require writing of NV and NV is not current accessible",
},
}
// subject represents a subject of a TPM error code with additional details
// (i.e., FMT1 codes)
type subject int
const (
handleRelated subject = iota + 1
parameterRelated
sessionRelated
)
// String returns the string representation of the ErrorSubject.
func (s subject) String() string {
switch s {
case handleRelated:
return "handle"
case parameterRelated:
return "parameter"
case sessionRelated:
return "session"
default:
return "unknown subject"
}
}
// TPMFmt1Error represents a TPM 2.0 format-1 error, with additional information.
type TPMFmt1Error struct {
// The canonical TPM error code, with handle/parameter/session info
// stripped out.
canonical TPMRC
// Whether this was a handle, parameter, or session error.
subject subject
// Which handle, parameter, or session was in error
index int
}
// Error returns the string representation of the error.
func (e TPMFmt1Error) Error() string {
desc, ok := fmt1Descs[e.canonical]
if !ok {
return fmt.Sprintf("unknown format-1 error: %s %d (%x)", e.subject, e.index, uint32(e.canonical))
}
return fmt.Sprintf("%s (%v %d): %s", desc.name, e.subject, e.index, desc.description)
}
// Handle returns whether the error is handle-related and if so, which handle is
// in error.
func (e TPMFmt1Error) Handle() (bool, int) {
if e.subject != handleRelated {
return false, 0
}
return true, e.index
}
// Parameter returns whether the error is handle-related and if so, which handle
// is in error.
func (e TPMFmt1Error) Parameter() (bool, int) {
if e.subject != parameterRelated {
return false, 0
}
return true, e.index
}
// Session returns whether the error is handle-related and if so, which handle
// is in error.
func (e TPMFmt1Error) Session() (bool, int) {
if e.subject != sessionRelated {
return false, 0
}
return true, e.index
}
// isFmt0Error returns true if the result is a format-0 error.
func (r TPMRC) isFmt0Error() bool {
return (r&rcVer1) == rcVer1 && (r&rcWarn) != rcWarn
}
// isFmt1Error returns true and a format-1 error structure if the error is a
// format-1 error.
func (r TPMRC) isFmt1Error() (bool, TPMFmt1Error) {
if (r & rcFmt1) != rcFmt1 {
return false, TPMFmt1Error{}
}
subj := handleRelated
if (r & rcP) == rcP {
subj = parameterRelated
r ^= rcP
} else if (r & rcS) == rcS {
subj = sessionRelated
r ^= rcS
}
idx := int((r & 0xF00) >> 8)
r &= 0xFFFFF0FF
return true, TPMFmt1Error{
canonical: r,
subject: subj,
index: idx,
}
}
// IsWarning returns true if the error is a warning code.
// This usually indicates a problem with the TPM state, and not the command.
// Retrying the command later may succeed.
func (r TPMRC) IsWarning() bool {
if isFmt1, _ := r.isFmt1Error(); isFmt1 {
// There aren't any format-1 warnings.
return false
}
return (r&rcVer1) == rcVer1 && (r&rcWarn) == rcWarn
}
// Error produces a nice human-readable representation of the error, parsing TPM
// FMT1 errors as needed.
func (r TPMRC) Error() string {
if isFmt1, fmt1 := r.isFmt1Error(); isFmt1 {
return fmt1.Error()
}
if r.isFmt0Error() {
desc, ok := fmt0Descs[r]
if !ok {
return fmt.Sprintf("unknown format-0 error code (0x%x)", uint32(r))
}
return fmt.Sprintf("%s: %s", desc.name, desc.description)
}
if r.IsWarning() {
desc, ok := warnDescs[r]
if !ok {
return fmt.Sprintf("unknown warning (0x%x)", uint32(r))
}
return fmt.Sprintf("%s: %s", desc.name, desc.description)
}
return fmt.Sprintf("unrecognized error code (0x%x)", uint32(r))
}
// Is returns whether the TPMRC (which may be a FMT1 error) is equal to the
// given canonical error.
func (r TPMRC) Is(target error) bool {
targetTPMRC, ok := target.(TPMRC)
if !ok {
return false
}
if isFmt1, fmt1 := r.isFmt1Error(); isFmt1 {
return fmt1.canonical == targetTPMRC
}
return r == targetTPMRC
}
// As returns whether the error can be assigned to the given interface type.
// If supported, it updates the value pointed at by target.
// Supports the Fmt1Error type.
func (r TPMRC) As(target interface{}) bool {
pFmt1, ok := target.(*TPMFmt1Error)
if !ok {
return false
}
isFmt1, fmt1 := r.isFmt1Error()
if !isFmt1 {
return false
}
*pFmt1 = fmt1
return true
}

View File

@ -1,29 +0,0 @@
package tpm2
import (
"crypto"
legacy "github.com/google/go-tpm/legacy/tpm2"
)
// KDFa implements TPM 2.0's default key derivation function, as defined in
// section 11.4.9.2 of the TPM revision 2 specification part 1.
// See: https://trustedcomputinggroup.org/resource/tpm-library-specification/
// The key & label parameters must not be zero length.
// The label parameter is a non-null-terminated string.
// The contextU & contextV parameters are optional.
func KDFa(h crypto.Hash, key []byte, label string, contextU, contextV []byte, bits int) []byte {
return legacy.KDFaHash(h, key, label, contextU, contextV, bits)
}
// KDFe implements TPM 2.0's ECDH key derivation function, as defined in
// section 11.4.9.3 of the TPM revision 2 specification part 1.
// See: https://trustedcomputinggroup.org/resource/tpm-library-specification/
// The z parameter is the x coordinate of one party's private ECC key multiplied
// by the other party's public ECC point.
// The use parameter is a non-null-terminated string.
// The partyUInfo and partyVInfo are the x coordinates of the initiator's and
// the responder's ECC points, respectively.
func KDFe(h crypto.Hash, z []byte, use string, partyUInfo, partyVInfo []byte, bits int) []byte {
return legacy.KDFeHash(h, z, use, partyUInfo, partyVInfo, bits)
}

View File

@ -1,128 +0,0 @@
package tpm2
import (
"bytes"
"fmt"
"reflect"
)
// Marshallable represents any TPM type that can be marshalled.
type Marshallable interface {
// marshal will serialize the given value, appending onto the given buffer.
// Returns an error if the value is not marshallable.
marshal(buf *bytes.Buffer)
}
// marshallableWithHint represents any TPM type that can be marshalled,
// but that requires a selector ("hint") value when marshalling. Most TPMU_ are
// an example of this.
type marshallableWithHint interface {
// get will return the corresponding union member by copy. If the union is
// uninitialized, it will initialize a new zero-valued one.
get(hint int64) (reflect.Value, error)
}
// Unmarshallable represents any TPM type that can be marshalled or unmarshalled.
type Unmarshallable interface {
Marshallable
// marshal will deserialize the given value from the given buffer.
// Returns an error if there was an unmarshalling error or if there was not
// enough data in the buffer.
unmarshal(buf *bytes.Buffer) error
}
// unmarshallableWithHint represents any TPM type that can be marshalled or unmarshalled,
// but that requires a selector ("hint") value when unmarshalling. Most TPMU_ are
// an example of this.
type unmarshallableWithHint interface {
marshallableWithHint
// create will instantiate and return the corresponding union member.
create(hint int64) (reflect.Value, error)
}
// Marshal will serialize the given values, returning them as a byte slice.
func Marshal(v Marshallable) []byte {
var buf bytes.Buffer
if err := marshal(&buf, reflect.ValueOf(v)); err != nil {
panic(fmt.Sprintf("unexpected error marshalling %v: %v", reflect.TypeOf(v).Name(), err))
}
return buf.Bytes()
}
// Unmarshal unmarshals the given type from the byte array.
// Returns an error if the buffer does not contain enough data to satisfy the
// types, or if the types are not unmarshallable.
func Unmarshal[T Marshallable, P interface {
*T
Unmarshallable
}](data []byte) (*T, error) {
buf := bytes.NewBuffer(data)
var t T
value := reflect.New(reflect.TypeOf(t))
if err := unmarshal(buf, value.Elem()); err != nil {
return nil, err
}
return value.Interface().(*T), nil
}
// marshallableByReflection is a placeholder interface, to hint to the unmarshalling
// library that it is supposed to use reflection.
type marshallableByReflection interface {
reflectionSafe()
}
// marshalByReflection is embedded into any type that can be marshalled by reflection,
// needing no custom logic.
type marshalByReflection struct{}
func (marshalByReflection) reflectionSafe() {}
// These placeholders are required because a type constraint cannot union another interface
// that contains methods.
// Otherwise, marshalByReflection would not implement Unmarshallable, and the Marshal/Unmarshal
// functions would accept interface{ Marshallable | marshallableByReflection } instead.
// Placeholder: because this type implements the defaultMarshallable interface,
// the reflection library knows not to call this.
func (marshalByReflection) marshal(_ *bytes.Buffer) {
panic("not implemented")
}
// Placeholder: because this type implements the defaultMarshallable interface,
// the reflection library knows not to call this.
func (*marshalByReflection) unmarshal(_ *bytes.Buffer) error {
panic("not implemented")
}
// boxed is a helper type for corner cases such as unions, where all members must be structs.
type boxed[T any] struct {
Contents *T
}
// box will put a value into a box.
func box[T any](contents *T) boxed[T] {
return boxed[T]{
Contents: contents,
}
}
// unbox will take a value out of a box.
func (b *boxed[T]) unbox() *T {
return b.Contents
}
// marshal implements the Marshallable interface.
func (b *boxed[T]) marshal(buf *bytes.Buffer) {
if b.Contents == nil {
var contents T
marshal(buf, reflect.ValueOf(&contents))
} else {
marshal(buf, reflect.ValueOf(b.Contents))
}
}
// unmarshal implements the Unmarshallable interface.
func (b *boxed[T]) unmarshal(buf *bytes.Buffer) error {
b.Contents = new(T)
return unmarshal(buf, reflect.ValueOf(b.Contents))
}

View File

@ -1,62 +0,0 @@
package tpm2
import (
"bytes"
"encoding/binary"
"reflect"
)
// HandleName returns the TPM Name of a PCR, session, or permanent value
// (e.g., hierarchy) handle.
func HandleName(h TPMHandle) TPM2BName {
result := make([]byte, 4)
binary.BigEndian.PutUint32(result, uint32(h))
return TPM2BName{
Buffer: result,
}
}
// objectOrNVName calculates the Name of an NV index or object.
// pub is a pointer to either a TPMTPublic or TPMSNVPublic.
func objectOrNVName(alg TPMAlgID, pub interface{}) (*TPM2BName, error) {
h, err := alg.Hash()
if err != nil {
return nil, err
}
// Create a byte slice with the correct reserved size and marshal the
// NameAlg to it.
result := make([]byte, 2, 2+h.Size())
binary.BigEndian.PutUint16(result, uint16(alg))
// Calculate the hash of the entire Public contents and append it to the
// result.
ha := h.New()
var buf bytes.Buffer
if err := marshal(&buf, reflect.ValueOf(pub)); err != nil {
return nil, err
}
ha.Write(buf.Bytes())
result = ha.Sum(result)
return &TPM2BName{
Buffer: result,
}, nil
}
// ObjectName returns the TPM Name of an object.
func ObjectName(p *TPMTPublic) (*TPM2BName, error) {
return objectOrNVName(p.NameAlg, p)
}
// NVName returns the TPM Name of an NV index.
func NVName(p *TPMSNVPublic) (*TPM2BName, error) {
return objectOrNVName(p.NameAlg, p)
}
// PrimaryHandleName returns the TPM Name of a primary handle.
func PrimaryHandleName(h TPMHandle) []byte {
result := make([]byte, 4)
binary.BigEndian.PutUint32(result, uint32(h))
return result
}

View File

@ -1,60 +0,0 @@
package tpm2
import (
"bytes"
"crypto"
"reflect"
)
// PolicyCalculator represents a TPM 2.0 policy that needs to be calculated
// synthetically (i.e., without a TPM).
type PolicyCalculator struct {
alg TPMIAlgHash
hash crypto.Hash
state []byte
}
// NewPolicyCalculator creates a fresh policy using the given hash algorithm.
func NewPolicyCalculator(alg TPMIAlgHash) (*PolicyCalculator, error) {
hash, err := alg.Hash()
if err != nil {
return nil, err
}
return &PolicyCalculator{
alg: alg,
hash: hash,
state: make([]byte, hash.Size()),
}, nil
}
// Reset resets the internal state of the policy hash to all 0x00.
func (p *PolicyCalculator) Reset() {
p.state = make([]byte, p.hash.Size())
}
// Update updates the internal state of the policy hash by appending the
// current state with the given contents, and updating the new state to the
// hash of that.
func (p *PolicyCalculator) Update(data ...interface{}) error {
hash := p.hash.New()
hash.Write(p.state)
var buf bytes.Buffer
for _, d := range data {
if err := marshal(&buf, reflect.ValueOf(d)); err != nil {
return err
}
}
hash.Write(buf.Bytes())
p.state = hash.Sum(nil)
return nil
}
// Hash returns the current state of the policy hash.
func (p *PolicyCalculator) Hash() *TPMTHA {
result := TPMTHA{
HashAlg: p.alg,
Digest: make([]byte, len(p.state)),
}
copy(result.Digest, p.state)
return &result
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,200 +0,0 @@
package tpm2
var (
// RSASRKTemplate contains the TCG reference RSA-2048 SRK template.
// https://trustedcomputinggroup.org/wp-content/uploads/TCG-TPM-v2.0-Provisioning-Guidance-Published-v1r1.pdf
RSASRKTemplate = TPMTPublic{
Type: TPMAlgRSA,
NameAlg: TPMAlgSHA256,
ObjectAttributes: TPMAObject{
FixedTPM: true,
STClear: false,
FixedParent: true,
SensitiveDataOrigin: true,
UserWithAuth: true,
AdminWithPolicy: false,
NoDA: true,
EncryptedDuplication: false,
Restricted: true,
Decrypt: true,
SignEncrypt: false,
},
Parameters: NewTPMUPublicParms(
TPMAlgRSA,
&TPMSRSAParms{
Symmetric: TPMTSymDefObject{
Algorithm: TPMAlgAES,
KeyBits: NewTPMUSymKeyBits(
TPMAlgAES,
TPMKeyBits(128),
),
Mode: NewTPMUSymMode(
TPMAlgAES,
TPMAlgCFB,
),
},
KeyBits: 2048,
},
),
Unique: NewTPMUPublicID(
TPMAlgRSA,
&TPM2BPublicKeyRSA{
Buffer: make([]byte, 256),
},
),
}
// RSAEKTemplate contains the TCG reference RSA-2048 EK template.
RSAEKTemplate = TPMTPublic{
Type: TPMAlgRSA,
NameAlg: TPMAlgSHA256,
ObjectAttributes: TPMAObject{
FixedTPM: true,
STClear: false,
FixedParent: true,
SensitiveDataOrigin: true,
UserWithAuth: false,
AdminWithPolicy: true,
NoDA: false,
EncryptedDuplication: false,
Restricted: true,
Decrypt: true,
SignEncrypt: false,
},
AuthPolicy: TPM2BDigest{
Buffer: []byte{
// TPM2_PolicySecret(RH_ENDORSEMENT)
0x83, 0x71, 0x97, 0x67, 0x44, 0x84, 0xB3, 0xF8,
0x1A, 0x90, 0xCC, 0x8D, 0x46, 0xA5, 0xD7, 0x24,
0xFD, 0x52, 0xD7, 0x6E, 0x06, 0x52, 0x0B, 0x64,
0xF2, 0xA1, 0xDA, 0x1B, 0x33, 0x14, 0x69, 0xAA,
},
},
Parameters: NewTPMUPublicParms(
TPMAlgRSA,
&TPMSRSAParms{
Symmetric: TPMTSymDefObject{
Algorithm: TPMAlgAES,
KeyBits: NewTPMUSymKeyBits(
TPMAlgAES,
TPMKeyBits(128),
),
Mode: NewTPMUSymMode(
TPMAlgAES,
TPMAlgCFB,
),
},
KeyBits: 2048,
},
),
Unique: NewTPMUPublicID(
TPMAlgRSA,
&TPM2BPublicKeyRSA{
Buffer: make([]byte, 256),
},
),
}
// ECCSRKTemplate contains the TCG reference ECC-P256 SRK template.
// https://trustedcomputinggroup.org/wp-content/uploads/TCG-TPM-v2.0-Provisioning-Guidance-Published-v1r1.pdf
ECCSRKTemplate = TPMTPublic{
Type: TPMAlgECC,
NameAlg: TPMAlgSHA256,
ObjectAttributes: TPMAObject{
FixedTPM: true,
STClear: false,
FixedParent: true,
SensitiveDataOrigin: true,
UserWithAuth: true,
AdminWithPolicy: false,
NoDA: true,
EncryptedDuplication: false,
Restricted: true,
Decrypt: true,
SignEncrypt: false,
},
Parameters: NewTPMUPublicParms(
TPMAlgECC,
&TPMSECCParms{
Symmetric: TPMTSymDefObject{
Algorithm: TPMAlgAES,
KeyBits: NewTPMUSymKeyBits(
TPMAlgAES,
TPMKeyBits(128),
),
Mode: NewTPMUSymMode(
TPMAlgAES,
TPMAlgCFB,
),
},
CurveID: TPMECCNistP256,
},
),
Unique: NewTPMUPublicID(
TPMAlgECC,
&TPMSECCPoint{
X: TPM2BECCParameter{
Buffer: make([]byte, 32),
},
Y: TPM2BECCParameter{
Buffer: make([]byte, 32),
},
},
),
}
// ECCEKTemplate contains the TCG reference ECC-P256 EK template.
ECCEKTemplate = TPMTPublic{
Type: TPMAlgECC,
NameAlg: TPMAlgSHA256,
ObjectAttributes: TPMAObject{
FixedTPM: true,
STClear: false,
FixedParent: true,
SensitiveDataOrigin: true,
UserWithAuth: false,
AdminWithPolicy: true,
NoDA: false,
EncryptedDuplication: false,
Restricted: true,
Decrypt: true,
SignEncrypt: false,
},
AuthPolicy: TPM2BDigest{
Buffer: []byte{
// TPM2_PolicySecret(RH_ENDORSEMENT)
0x83, 0x71, 0x97, 0x67, 0x44, 0x84, 0xB3, 0xF8,
0x1A, 0x90, 0xCC, 0x8D, 0x46, 0xA5, 0xD7, 0x24,
0xFD, 0x52, 0xD7, 0x6E, 0x06, 0x52, 0x0B, 0x64,
0xF2, 0xA1, 0xDA, 0x1B, 0x33, 0x14, 0x69, 0xAA,
},
},
Parameters: NewTPMUPublicParms(
TPMAlgECC,
&TPMSECCParms{
Symmetric: TPMTSymDefObject{
Algorithm: TPMAlgAES,
KeyBits: NewTPMUSymKeyBits(
TPMAlgAES,
TPMKeyBits(128),
),
Mode: NewTPMUSymMode(
TPMAlgAES,
TPMAlgCFB,
),
},
CurveID: TPMECCNistP256,
},
),
Unique: NewTPMUPublicID(
TPMAlgECC,
&TPMSECCPoint{
X: TPM2BECCParameter{
Buffer: make([]byte, 32),
},
Y: TPM2BECCParameter{
Buffer: make([]byte, 32),
},
},
),
}
)

File diff suppressed because it is too large Load Diff

View File

@ -1,83 +0,0 @@
package tpm2
import (
"bytes"
"encoding/binary"
"fmt"
"io"
)
// TPM2B is a helper type for all sized TPM structures. It can be instantiated with either a raw byte buffer or the actual struct.
type TPM2B[T Marshallable, P interface {
*T
Unmarshallable
}] struct {
contents *T
buffer []byte
}
// New2B creates a new TPM2B containing the given contents.
func New2B[T Marshallable, P interface {
*T
Unmarshallable
}](t T) TPM2B[T, P] {
return TPM2B[T, P]{contents: &t}
}
// BytesAs2B creates a new TPM2B containing the given byte array.
func BytesAs2B[T Marshallable, P interface {
*T
Unmarshallable
}](b []byte) TPM2B[T, P] {
return TPM2B[T, P]{buffer: b}
}
// Contents returns the structured contents of the TPM2B.
// It can fail if the TPM2B was instantiated with an invalid byte buffer.
func (value *TPM2B[T, P]) Contents() (*T, error) {
if value.contents != nil {
return value.contents, nil
}
if value.buffer == nil {
return nil, fmt.Errorf("TPMB had no contents or buffer")
}
contents, err := Unmarshal[T, P](value.buffer)
if err != nil {
return nil, err
}
// Cache the result
value.contents = (*T)(contents)
return value.contents, nil
}
// Bytes returns the inner contents of the TPM2B as a byte array, not including the length field.
func (value *TPM2B[T, P]) Bytes() []byte {
if value.buffer != nil {
return value.buffer
}
if value.contents == nil {
return []byte{}
}
// Cache the result
value.buffer = Marshal(*value.contents)
return value.buffer
}
// marshal implements the tpm2.Marshallable interface.
func (value TPM2B[T, P]) marshal(buf *bytes.Buffer) {
b := value.Bytes()
binary.Write(buf, binary.BigEndian, uint16(len(b)))
buf.Write(b)
}
// unmarshal implements the tpm2.Unmarshallable interface.
// Note: the structure contents are not validated during unmarshalling.
func (value *TPM2B[T, P]) unmarshal(buf *bytes.Buffer) error {
var size uint16
binary.Read(buf, binary.BigEndian, &size)
value.contents = nil
value.buffer = make([]byte, size)
_, err := io.ReadAtLeast(buf, value.buffer, int(size))
return err
}

View File

@ -1,28 +0,0 @@
//go:build !windows
package transport
import (
legacy "github.com/google/go-tpm/legacy/tpm2"
)
// Wrap the legacy OpenTPM function so callers don't have to import both the
// legacy and the new TPM 2.0 API.
// TODO: When we delete the legacy API, we can make this the only copy of
// OpenTPM.
// OpenTPM opens a channel to the TPM at the given path. If the file is a
// device, then it treats it like a normal TPM device, and if the file is a
// Unix domain socket, then it opens a connection to the socket.
//
// This function may also be invoked with no paths, as tpm2.OpenTPM(). In this
// case, the default paths on Linux (/dev/tpmrm0 then /dev/tpm0), will be used.
func OpenTPM(path ...string) (TPMCloser, error) {
rwc, err := legacy.OpenTPM(path...)
if err != nil {
return nil, err
}
return &wrappedRWC{
transport: rwc,
}, nil
}

View File

@ -1,28 +0,0 @@
//go:build windows
package transport
import (
legacy "github.com/google/go-tpm/legacy/tpm2"
)
// Wrap the legacy OpenTPM function so callers don't have to import both the
// legacy and the new TPM 2.0 API.
// TODO: When we delete the legacy API, we can make this the only copy of
// OpenTPM.
// OpenTPM opens a channel to the TPM at the given path. If the file is a
// device, then it treats it like a normal TPM device, and if the file is a
// Unix domain socket, then it opens a connection to the socket.
//
// This function may also be invoked with no paths, as tpm2.OpenTPM(). In this
// case, the default paths on Linux (/dev/tpmrm0 then /dev/tpm0), will be used.
func OpenTPM() (TPMCloser, error) {
rwc, err := legacy.OpenTPM()
if err != nil {
return nil, err
}
return &wrappedRWC{
transport: rwc,
}, nil
}

View File

@ -1,84 +0,0 @@
// Package transport implements types for physically talking to TPMs.
package transport
import (
"io"
"github.com/google/go-tpm/tpmutil"
)
// TPM represents a logical connection to a TPM.
type TPM interface {
Send(input []byte) ([]byte, error)
}
// TPMCloser represents a logical connection to a TPM and you can close it.
type TPMCloser interface {
TPM
io.Closer
}
// wrappedRW represents a struct that wraps an io.ReadWriter
// to a transport.TPM to be compatible with tpmdirect.
type wrappedRW struct {
transport io.ReadWriter
}
// wrappedRWC represents a struct that wraps an io.ReadWriteCloser
// to a transport.TPM to be compatible with tpmdirect.
type wrappedRWC struct {
transport io.ReadWriteCloser
}
// wrappedTPM represents a struct that wraps a transport.TPM's underlying
// transport to use with legacy code that expects an io.ReadWriter.
type wrappedTPM struct {
response []byte
tpm TPM
}
// FromReadWriter takes in a io.ReadWriter and returns a
// transport.TPM wrapping the io.ReadWriter.
func FromReadWriter(rw io.ReadWriter) TPM {
return &wrappedRW{transport: rw}
}
// ToReadWriter takes in a transport TPM and returns an
// io.ReadWriter wrapping the transport TPM.
func ToReadWriter(tpm TPM) io.ReadWriter {
return &wrappedTPM{tpm: tpm}
}
// Read copies t.response into the p buffer and return the appropriate length.
func (t *wrappedTPM) Read(p []byte) (int, error) {
n := copy(p, t.response)
t.response = t.response[n:]
if len(t.response) == 0 {
return n, io.EOF
}
return n, nil
}
// Write implements the io.ReadWriter interface.
func (t *wrappedTPM) Write(p []byte) (n int, err error) {
t.response, err = t.tpm.Send(p)
if err != nil {
return 0, err
}
return len(p), nil
}
// Send implements the TPM interface.
func (t *wrappedRW) Send(input []byte) ([]byte, error) {
return tpmutil.RunCommandRaw(t.transport, input)
}
// Send implements the TPM interface.
func (t *wrappedRWC) Send(input []byte) ([]byte, error) {
return tpmutil.RunCommandRaw(t.transport, input)
}
// Close implements the TPM interface.
func (t *wrappedRWC) Close() error {
return t.transport.Close()
}

2
vendor/modules.txt generated vendored
View File

@ -432,8 +432,6 @@ github.com/google/go-sev-guest/proto/sevsnp
# github.com/google/go-tpm v0.9.0
## explicit; go 1.20
github.com/google/go-tpm/legacy/tpm2
github.com/google/go-tpm/tpm2
github.com/google/go-tpm/tpm2/transport
github.com/google/go-tpm/tpmutil
github.com/google/go-tpm/tpmutil/tbs
# github.com/google/go-tpm-tools v0.4.0