From 89f7568deb26b429814ab2cbaddf05792391fc84 Mon Sep 17 00:00:00 2001 From: Ciprian Hacman Date: Fri, 30 Jun 2023 11:43:23 +0300 Subject: [PATCH] Use the legacy TPM API --- .../cloudup/gce/tpm/gcetpmsigner/tpm_other.go | 2 +- vendor/github.com/google/go-tpm/tpm2/audit.go | 87 - .../github.com/google/go-tpm/tpm2/bitfield.go | 82 - .../google/go-tpm/tpm2/constants.go | 677 ---- .../google/go-tpm/tpm2/constants_internal.go | 14 - .../github.com/google/go-tpm/tpm2/crypto.go | 43 - .../github.com/google/go-tpm/tpm2/errors.go | 561 --- vendor/github.com/google/go-tpm/tpm2/kdf.go | 29 - .../google/go-tpm/tpm2/marshalling.go | 128 - vendor/github.com/google/go-tpm/tpm2/names.go | 62 - .../github.com/google/go-tpm/tpm2/policy.go | 60 - .../github.com/google/go-tpm/tpm2/reflect.go | 1083 ------ .../github.com/google/go-tpm/tpm2/sessions.go | 1100 ------ .../google/go-tpm/tpm2/structures.go | 3150 ----------------- .../google/go-tpm/tpm2/templates.go | 200 -- vendor/github.com/google/go-tpm/tpm2/tpm2.go | 1752 --------- vendor/github.com/google/go-tpm/tpm2/tpm2b.go | 83 - .../go-tpm/tpm2/transport/open_other.go | 28 - .../go-tpm/tpm2/transport/open_windows.go | 28 - .../google/go-tpm/tpm2/transport/tpm.go | 84 - vendor/modules.txt | 2 - 21 files changed, 1 insertion(+), 9254 deletions(-) delete mode 100644 vendor/github.com/google/go-tpm/tpm2/audit.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/bitfield.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/constants.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/constants_internal.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/crypto.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/errors.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/kdf.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/marshalling.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/names.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/policy.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/reflect.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/sessions.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/structures.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/templates.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/tpm2.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/tpm2b.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/transport/open_other.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/transport/open_windows.go delete mode 100644 vendor/github.com/google/go-tpm/tpm2/transport/tpm.go diff --git a/upup/pkg/fi/cloudup/gce/tpm/gcetpmsigner/tpm_other.go b/upup/pkg/fi/cloudup/gce/tpm/gcetpmsigner/tpm_other.go index f2916eeab3..d8b1820cc6 100644 --- a/upup/pkg/fi/cloudup/gce/tpm/gcetpmsigner/tpm_other.go +++ b/upup/pkg/fi/cloudup/gce/tpm/gcetpmsigner/tpm_other.go @@ -23,7 +23,7 @@ import ( "fmt" "io" - "github.com/google/go-tpm/tpm2" + "github.com/google/go-tpm/legacy/tpm2" ) var tpmPath = "/dev/tpm0" diff --git a/vendor/github.com/google/go-tpm/tpm2/audit.go b/vendor/github.com/google/go-tpm/tpm2/audit.go deleted file mode 100644 index 95ad2cb028..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/audit.go +++ /dev/null @@ -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()) -} diff --git a/vendor/github.com/google/go-tpm/tpm2/bitfield.go b/vendor/github.com/google/go-tpm/tpm2/bitfield.go deleted file mode 100644 index c8f52b6f2e..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/bitfield.go +++ /dev/null @@ -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<> 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 -} diff --git a/vendor/github.com/google/go-tpm/tpm2/kdf.go b/vendor/github.com/google/go-tpm/tpm2/kdf.go deleted file mode 100644 index 569a4daf8a..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/kdf.go +++ /dev/null @@ -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) -} diff --git a/vendor/github.com/google/go-tpm/tpm2/marshalling.go b/vendor/github.com/google/go-tpm/tpm2/marshalling.go deleted file mode 100644 index 04d1607461..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/marshalling.go +++ /dev/null @@ -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)) -} diff --git a/vendor/github.com/google/go-tpm/tpm2/names.go b/vendor/github.com/google/go-tpm/tpm2/names.go deleted file mode 100644 index 4b5741d0df..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/names.go +++ /dev/null @@ -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 -} diff --git a/vendor/github.com/google/go-tpm/tpm2/policy.go b/vendor/github.com/google/go-tpm/tpm2/policy.go deleted file mode 100644 index c64f17e4e1..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/policy.go +++ /dev/null @@ -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 -} diff --git a/vendor/github.com/google/go-tpm/tpm2/reflect.go b/vendor/github.com/google/go-tpm/tpm2/reflect.go deleted file mode 100644 index ea9b172599..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/reflect.go +++ /dev/null @@ -1,1083 +0,0 @@ -// Package tpm2 provides 1:1 mapping to TPM 2.0 APIs. -package tpm2 - -import ( - "bytes" - "encoding/binary" - "fmt" - "math" - "reflect" - "strconv" - "strings" - - "github.com/google/go-tpm/tpm2/transport" -) - -const ( - // Chosen based on MAX_DIGEST_BUFFER, the length of the longest - // reasonable list returned by the reference implementation. - // The maxListLength must be greater than MAX_CONTEXT_SIZE = 1344, - // in order to allow for the unmarshalling of Context. - maxListLength uint32 = 4096 -) - -// execute sends the provided command and returns the TPM's response. -func execute[R any](t transport.TPM, cmd Command[R, *R], rsp *R, extraSess ...Session) error { - cc := cmd.Command() - sess, err := cmdAuths(cmd) - if err != nil { - return err - } - sess = append(sess, extraSess...) - if len(sess) > 3 { - return fmt.Errorf("too many sessions: %v", len(sess)) - } - hasSessions := len(sess) > 0 - // Initialize the sessions, if needed - for i, s := range sess { - if err := s.Init(t); err != nil { - return fmt.Errorf("initializing session %d: %w", i, err) - } - if err := s.NewNonceCaller(); err != nil { - return err - } - } - handles, err := cmdHandles(cmd) - if err != nil { - return err - } - parms, err := cmdParameters(cmd, sess) - if err != nil { - return err - } - var names []TPM2BName - var sessions []byte - if hasSessions { - var err error - names, err = cmdNames(cmd) - if err != nil { - return err - } - sessions, err = cmdSessions(sess, cc, names, parms) - if err != nil { - return err - } - } - hdr := cmdHeader(hasSessions, 10 /* size of command header */ +len(handles)+len(sessions)+len(parms), cc) - command := append(hdr, handles...) - command = append(command, sessions...) - command = append(command, parms...) - - // Send the command via the transport. - response, err := t.Send(command) - if err != nil { - return err - } - - // Parse the command tpm2ly into the response structure. - rspBuf := bytes.NewBuffer(response) - err = rspHeader(rspBuf) - if err != nil { - var bonusErrs []string - // Emergency cleanup, then return. - for _, s := range sess { - if err := s.CleanupFailure(t); err != nil { - bonusErrs = append(bonusErrs, err.Error()) - } - } - if len(bonusErrs) != 0 { - return fmt.Errorf("%w - additional errors encountered during cleanup: %v", err, strings.Join(bonusErrs, ", ")) - } - return err - } - err = rspHandles(rspBuf, rsp) - if err != nil { - return err - } - rspParms, err := rspParametersArea(hasSessions, rspBuf) - if err != nil { - return err - } - if hasSessions { - // We don't need the TPM RC here because we would have errored - // out from rspHeader - // TODO: Authenticate the error code with sessions, if desired. - err = rspSessions(rspBuf, TPMRCSuccess, cc, names, rspParms, sess) - if err != nil { - return err - } - } - err = rspParameters(rspParms, sess, rsp) - if err != nil { - return err - } - - return nil -} - -func isMarshalledByReflection(v reflect.Value) bool { - var mbr marshallableByReflection - if v.Type().AssignableTo(reflect.TypeOf(&mbr).Elem()) { - return true - } - // basic types are also marshalled by reflection, as are empty structs - switch v.Kind() { - case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Array, reflect.Slice, reflect.Ptr: - return true - case reflect.Struct: - if v.NumField() == 0 { - return true - } - } - return false -} - -// marshal will serialize the given value, appending onto the given buffer. -// Returns an error if the value is not marshallable. -func marshal(buf *bytes.Buffer, v reflect.Value) error { - // If the type is not marshalled by reflection, try to call the custom marshal method. - if !isMarshalledByReflection(v) { - u, ok := v.Interface().(Marshallable) - if ok { - u.marshal(buf) - return nil - } - if v.CanAddr() { - // Maybe we got an addressable value whose pointer implements Marshallable - pu, ok := v.Addr().Interface().(Marshallable) - if ok { - pu.marshal(buf) - return nil - } - } - return fmt.Errorf("can't marshal: type %v does not implement Marshallable or marshallableByReflection", v.Type().Name()) - } - - // Otherwise, use reflection. - switch v.Kind() { - case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return marshalNumeric(buf, v) - case reflect.Array, reflect.Slice: - return marshalArray(buf, v) - case reflect.Struct: - return marshalStruct(buf, v) - case reflect.Ptr: - return marshal(buf, v.Elem()) - case reflect.Interface: - // Special case: there are very few TPM types which, for TPM spec - // backwards-compatibility reasons, are implemented as Go interfaces - // so that callers can ergonomically satisfy cases where the TPM spec - // allows a parameter to literally be one of a couple of types. - // In a few of these cases, we want the caller to be able to sensibly - // omit the data, and fill in reasonable defaults. - // These cases are enumerated here. - if v.IsNil() { - switch v.Type().Name() { - case "TPMUSensitiveCreate": - return marshal(buf, reflect.ValueOf(TPM2BSensitiveData{})) - default: - return fmt.Errorf("missing required value for %v interface", v.Type().Name()) - } - } - return marshal(buf, v.Elem()) - default: - return fmt.Errorf("not marshallable: %#v", v) - } -} - -// marshalOptional will serialize the given value, appending onto the given -// buffer. -// Special case: Part 3 specifies some input/output -// parameters as "optional", which means that they are -// sized fields that can be zero-length, even if the -// enclosed type has no legal empty serialization. -// When nil, marshal the zero size. -// Returns an error if the value is not marshallable. -func marshalOptional(buf *bytes.Buffer, v reflect.Value) error { - if v.Kind() == reflect.Ptr && v.IsNil() { - return marshalArray(buf, reflect.ValueOf([2]byte{})) - } - return marshal(buf, v) -} - -func marshalNumeric(buf *bytes.Buffer, v reflect.Value) error { - return binary.Write(buf, binary.BigEndian, v.Interface()) -} - -func marshalArray(buf *bytes.Buffer, v reflect.Value) error { - for i := 0; i < v.Len(); i++ { - if err := marshal(buf, v.Index(i)); err != nil { - return fmt.Errorf("marshalling element %d of %v: %v", i, v.Type(), err) - } - } - return nil -} - -// Marshals the members of the struct, handling sized and bitwise fields. -func marshalStruct(buf *bytes.Buffer, v reflect.Value) error { - // Check if this is a bitwise-defined structure. This requires all the - // members to be bitwise-defined. - numBitwise := 0 - numChecked := 0 - for i := 0; i < v.NumField(); i++ { - // Ignore embedded Bitfield hints. - if !v.Type().Field(i).IsExported() { - //if _, isBitfield := v.Field(i).Interface().(TPMABitfield); isBitfield { - continue - } - thisBitwise := hasTag(v.Type().Field(i), "bit") - if thisBitwise { - numBitwise++ - if hasTag(v.Type().Field(i), "sized") || hasTag(v.Type().Field(i), "sized8") { - return fmt.Errorf("struct '%v' field '%v' is both bitwise and sized", - v.Type().Name(), v.Type().Field(i).Name) - } - if hasTag(v.Type().Field(i), "tag") { - return fmt.Errorf("struct '%v' field '%v' is both bitwise and a tagged union", - v.Type().Name(), v.Type().Field(i).Name) - } - } - numChecked++ - } - if numBitwise != numChecked && numBitwise != 0 { - return fmt.Errorf("struct '%v' has mixture of bitwise and non-bitwise members", v.Type().Name()) - } - if numBitwise > 0 { - return marshalBitwise(buf, v) - } - // Make a pass to create a map of tag values - // UInt64-valued fields with values greater than MaxInt64 cannot be - // selectors. - possibleSelectors := make(map[string]int64) - for i := 0; i < v.NumField(); i++ { - // Special case: Treat a zero-valued nullable field as - // TPMAlgNull for union selection. - // This allows callers to omit uninteresting scheme structures. - if v.Field(i).IsZero() && hasTag(v.Type().Field(i), "nullable") { - possibleSelectors[v.Type().Field(i).Name] = int64(TPMAlgNull) - continue - } - switch v.Field(i).Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - possibleSelectors[v.Type().Field(i).Name] = v.Field(i).Int() - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - val := v.Field(i).Uint() - if val <= math.MaxInt64 { - possibleSelectors[v.Type().Field(i).Name] = int64(val) - } - } - } - for i := 0; i < v.NumField(); i++ { - if hasTag(v.Type().Field(i), "skip") { - continue - } - list := hasTag(v.Type().Field(i), "list") - sized := hasTag(v.Type().Field(i), "sized") - sized8 := hasTag(v.Type().Field(i), "sized8") - tag, _ := tag(v.Type().Field(i), "tag") - // Serialize to a temporary buffer, in case we need to size it - // (Better to simplify this complex reflection-based marshalling - // code than to save some unnecessary copying before talking to - // a low-speed device like a TPM) - var res bytes.Buffer - if list { - binary.Write(&res, binary.BigEndian, uint32(v.Field(i).Len())) - } - if tag != "" { - // Check that the tagged value was present (and numeric - // and smaller than MaxInt64) - tagValue, ok := possibleSelectors[tag] - // Don't marshal anything if the tag value was TPM_ALG_NULL - if tagValue == int64(TPMAlgNull) { - continue - } - if !ok { - return fmt.Errorf("union tag '%v' for member '%v' of struct '%v' did not reference "+ - "a numeric field of int64-compatible value", - tag, v.Type().Field(i).Name, v.Type().Name()) - } - if u, ok := v.Field(i).Interface().(marshallableWithHint); ok { - v, err := u.get(tagValue) - if err != nil { - return err - } - if err := marshal(buf, v); err != nil { - return err - } - } - } else if v.Field(i).IsZero() && v.Field(i).Kind() == reflect.Uint32 && hasTag(v.Type().Field(i), "nullable") { - // Special case: Anything with the same underlying type - // as TPMHandle's zero value is TPM_RH_NULL. - // This allows callers to omit uninteresting handles - // instead of specifying them as TPM_RH_NULL. - if err := binary.Write(&res, binary.BigEndian, uint32(TPMRHNull)); err != nil { - return err - } - } else if v.Field(i).IsZero() && v.Field(i).Kind() == reflect.Uint16 && hasTag(v.Type().Field(i), "nullable") { - // Special case: Anything with the same underlying type - // as TPMAlg's zero value is TPM_ALG_NULL. - // This allows callers to omit uninteresting - // algorithms/schemes instead of specifying them as - // TPM_ALG_NULL. - if err := binary.Write(&res, binary.BigEndian, uint16(TPMAlgNull)); err != nil { - return err - } - } else if hasTag(v.Type().Field(i), "optional") { - if err := marshalOptional(&res, v.Field(i)); err != nil { - return err - } - } else { - if err := marshal(&res, v.Field(i)); err != nil { - return err - } - } - if sized { - if err := binary.Write(buf, binary.BigEndian, uint16(res.Len())); err != nil { - return err - } - } - if sized8 { - if err := binary.Write(buf, binary.BigEndian, uint8(res.Len())); err != nil { - return err - } - } - buf.Write(res.Bytes()) - } - return nil -} - -// Marshals a bitwise-defined struct. -func marshalBitwise(buf *bytes.Buffer, v reflect.Value) error { - bg, ok := v.Interface().(BitGetter) - if !ok { - return fmt.Errorf("'%v' was not a BitGetter", v.Type().Name()) - } - bitArray := make([]bool, bg.Length()) - // Marshal the defined fields - for i := 0; i < v.NumField(); i++ { - if !v.Type().Field(i).IsExported() { - continue - } - high, low, _ := rangeTag(v.Type().Field(i), "bit") - var buf bytes.Buffer - if err := marshal(&buf, v.Field(i)); err != nil { - return err - } - b := buf.Bytes() - for i := 0; i <= (high - low); i++ { - bitArray[low+i] = ((b[len(b)-i/8-1] >> (i % 8)) & 1) == 1 - } - } - // Also marshal the reserved values - for i := 0; i < len(bitArray); i++ { - if bg.GetReservedBit(i) { - bitArray[i] = true - } - } - result := make([]byte, len(bitArray)/8) - for i, bit := range bitArray { - if bit { - result[len(result)-(i/8)-1] |= (1 << (i % 8)) - } - } - buf.Write(result) - return nil -} - -// unmarshal will deserialize the given value from the given buffer. -// Returns an error if the buffer does not contain enough data to satisfy the -// type. -func unmarshal(buf *bytes.Buffer, v reflect.Value) error { - // If the type is not marshalled by reflection, try to call the custom unmarshal method. - if !isMarshalledByReflection(v) { - if u, ok := v.Addr().Interface().(Unmarshallable); ok { - return u.unmarshal(buf) - } - return fmt.Errorf("can't unmarshal: type %v does not implement Unmarshallable or marshallableByReflection", v.Type().Name()) - } - - switch v.Kind() { - case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - if err := unmarshalNumeric(buf, v); err != nil { - return err - } - case reflect.Slice: - var length uint32 - // special case for byte slices: just read the entire - // rest of the buffer - if v.Type().Elem().Kind() == reflect.Uint8 { - length = uint32(buf.Len()) - } else { - err := unmarshalNumeric(buf, reflect.ValueOf(&length).Elem()) - if err != nil { - return fmt.Errorf("deserializing size for field of type '%v': %w", v.Type(), err) - } - } - if length > uint32(math.MaxInt32) || length > maxListLength { - return fmt.Errorf("could not deserialize slice of length %v", length) - } - // Go's reflect library doesn't allow increasing the - // capacity of an existing slice. - // Since we can't be sure that the capacity of the - // passed-in value was enough, allocate - // a new temporary one of the correct length, unmarshal - // to it, and swap it in. - tmp := reflect.MakeSlice(v.Type(), int(length), int(length)) - if err := unmarshalArray(buf, tmp); err != nil { - return err - } - v.Set(tmp) - return nil - case reflect.Array: - return unmarshalArray(buf, v) - case reflect.Struct: - return unmarshalStruct(buf, v) - case reflect.Ptr: - return unmarshal(buf, v.Elem()) - default: - return fmt.Errorf("not unmarshallable: %v", v.Type()) - } - return nil -} - -func unmarshalNumeric(buf *bytes.Buffer, v reflect.Value) error { - return binary.Read(buf, binary.BigEndian, v.Addr().Interface()) -} - -// For slices, the slice's length must already be set to the expected amount of -// data. -func unmarshalArray(buf *bytes.Buffer, v reflect.Value) error { - for i := 0; i < v.Len(); i++ { - if err := unmarshal(buf, v.Index(i)); err != nil { - return fmt.Errorf("deserializing slice/array index %v: %w", i, err) - } - } - return nil -} - -func unmarshalStruct(buf *bytes.Buffer, v reflect.Value) error { - // Check if this is a bitwise-defined structure. This requires all the - // exported members to be bitwise-defined. - numBitwise := 0 - numChecked := 0 - for i := 0; i < v.NumField(); i++ { - // Ignore embedded Bitfield hints. - // Ignore embedded Bitfield hints. - if !v.Type().Field(i).IsExported() { - //if _, isBitfield := v.Field(i).Interface().(TPMABitfield); isBitfield { - continue - } - thisBitwise := hasTag(v.Type().Field(i), "bit") - if thisBitwise { - numBitwise++ - if hasTag(v.Type().Field(i), "sized") { - return fmt.Errorf("struct '%v' field '%v' is both bitwise and sized", - v.Type().Name(), v.Type().Field(i).Name) - } - if hasTag(v.Type().Field(i), "tag") { - return fmt.Errorf("struct '%v' field '%v' is both bitwise and a tagged union", - v.Type().Name(), v.Type().Field(i).Name) - } - } - numChecked++ - } - if numBitwise != numChecked && numBitwise != 0 { - return fmt.Errorf("struct '%v' has mixture of bitwise and non-bitwise members", v.Type().Name()) - } - if numBitwise > 0 { - return unmarshalBitwise(buf, v) - } - for i := 0; i < v.NumField(); i++ { - if hasTag(v.Type().Field(i), "skip") { - continue - } - list := hasTag(v.Type().Field(i), "list") - if list && (v.Field(i).Kind() != reflect.Slice) { - return fmt.Errorf("field '%v' of struct '%v' had the 'list' tag but was not a slice", - v.Type().Field(i).Name, v.Type().Name()) - } - // Slices of anything but byte/uint8 must have the 'list' tag. - if !list && (v.Field(i).Kind() == reflect.Slice) && (v.Type().Field(i).Type.Elem().Kind() != reflect.Uint8) { - return fmt.Errorf("field '%v' of struct '%v' was a slice of non-byte but did not have the 'list' tag", - v.Type().Field(i).Name, v.Type().Name()) - } - if hasTag(v.Type().Field(i), "optional") { - // Special case: Part 3 specifies some input/output - // parameters as "optional", which means that they are - // (2B-) sized fields that can be zero-length, even if the - // enclosed type has no legal empty serialization. - // When unmarshalling an optional field, test for zero size - // and skip if empty. - if buf.Len() < 2 { - if binary.BigEndian.Uint16(buf.Bytes()) == 0 { - // Advance the buffer past the zero size and skip to the - // next field of the struct. - buf.Next(2) - continue - } - // If non-zero size, proceed to unmarshal the contents below. - } - } - sized := hasTag(v.Type().Field(i), "sized") - sized8 := hasTag(v.Type().Field(i), "sized8") - // If sized, unmarshal a size field first, then restrict - // unmarshalling to the given size - bufToReadFrom := buf - if sized { - var expectedSize uint16 - binary.Read(buf, binary.BigEndian, &expectedSize) - sizedBufArray := make([]byte, int(expectedSize)) - n, err := buf.Read(sizedBufArray) - if n != int(expectedSize) { - return fmt.Errorf("ran out of data reading sized parameter '%v' inside struct of type '%v'", - v.Type().Field(i).Name, v.Type().Name()) - } - if err != nil { - return fmt.Errorf("error reading data for parameter '%v' inside struct of type '%v'", - v.Type().Field(i).Name, v.Type().Name()) - } - bufToReadFrom = bytes.NewBuffer(sizedBufArray) - } - if sized8 { - var expectedSize uint8 - binary.Read(buf, binary.BigEndian, &expectedSize) - sizedBufArray := make([]byte, int(expectedSize)) - n, err := buf.Read(sizedBufArray) - if n != int(expectedSize) { - return fmt.Errorf("ran out of data reading sized parameter '%v' inside struct of type '%v'", - v.Type().Field(i).Name, v.Type().Name()) - } - if err != nil { - return fmt.Errorf("error reading data for parameter '%v' inside struct of type '%v'", - v.Type().Field(i).Name, v.Type().Name()) - } - bufToReadFrom = bytes.NewBuffer(sizedBufArray) - } - tag, _ := tag(v.Type().Field(i), "tag") - if tag != "" { - // Make a pass to create a map of tag values - // UInt64-valued fields with values greater than - // MaxInt64 cannot be selectors. - possibleSelectors := make(map[string]int64) - for j := 0; j < v.NumField(); j++ { - switch v.Field(j).Kind() { - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - possibleSelectors[v.Type().Field(j).Name] = v.Field(j).Int() - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - val := v.Field(j).Uint() - if val <= math.MaxInt64 { - possibleSelectors[v.Type().Field(j).Name] = int64(val) - } - } - } - // Check that the tagged value was present (and numeric - // and smaller than MaxInt64) - tagValue, ok := possibleSelectors[tag] - // Don't marshal anything if the tag value was TPM_ALG_NULL - if tagValue == int64(TPMAlgNull) { - continue - } - if !ok { - return fmt.Errorf("union tag '%v' for member '%v' of struct '%v' did not reference "+ - "a numeric field of in64-compatible value", - tag, v.Type().Field(i).Name, v.Type().Name()) - } - var uwh unmarshallableWithHint - if v.Field(i).CanAddr() && v.Field(i).Addr().Type().AssignableTo(reflect.TypeOf(&uwh).Elem()) { - u := v.Field(i).Addr().Interface().(unmarshallableWithHint) - contents, err := u.create(tagValue) - if err != nil { - return fmt.Errorf("unmarshalling field %v of struct of type '%v', %w", i, v.Type(), err) - } - err = unmarshal(buf, contents) - if err != nil { - return fmt.Errorf("unmarshalling field %v of struct of type '%v', %w", i, v.Type(), err) - } - } else if v.Field(i).Type().AssignableTo(reflect.TypeOf(&uwh).Elem()) { - u := v.Field(i).Interface().(unmarshallableWithHint) - contents, err := u.create(tagValue) - if err != nil { - return fmt.Errorf("unmarshalling field %v of struct of type '%v', %w", i, v.Type(), err) - } - err = unmarshal(buf, contents) - if err != nil { - return fmt.Errorf("unmarshalling field %v of struct of type '%v', %w", i, v.Type(), err) - } - } - } else { - if err := unmarshal(bufToReadFrom, v.Field(i)); err != nil { - return fmt.Errorf("unmarshalling field %v of struct of type '%v', %w", i, v.Type(), err) - } - } - if sized || sized8 { - if bufToReadFrom.Len() != 0 { - return fmt.Errorf("extra data at the end of sized parameter '%v' inside struct of type '%v'", - v.Type().Field(i).Name, v.Type().Name()) - } - } - } - return nil -} - -// Unmarshals a bitwise-defined struct. -func unmarshalBitwise(buf *bytes.Buffer, v reflect.Value) error { - bs, ok := v.Addr().Interface().(BitSetter) - if !ok { - return fmt.Errorf("'%v' was not a BitSetter", v.Addr().Type()) - } - bitArray := make([]bool, bs.Length()) - // We will read big-endian, starting from the last byte and working our - // way down. - for i := len(bitArray)/8 - 1; i >= 0; i-- { - b, err := buf.ReadByte() - if err != nil { - return fmt.Errorf("error %d bits into field '%v' of struct '%v': %w", - i, v.Type().Field(i).Name, v.Type().Name(), err) - } - for j := 0; j < 8; j++ { - bitArray[8*i+j] = (((b >> j) & 1) == 1) - } - } - // Unmarshal the defined fields and clear the bits from the array as we - // read them. - for i := 0; i < v.NumField(); i++ { - if !v.Type().Field(i).IsExported() { - continue - } - high, low, _ := rangeTag(v.Type().Field(i), "bit") - var val uint64 - for j := 0; j <= high-low; j++ { - if bitArray[low+j] { - val |= (1 << j) - } - bitArray[low+j] = false - } - if v.Field(i).Kind() == reflect.Bool { - v.Field(i).SetBool((val & 1) == 1) - } else { - v.Field(i).SetUint(val) - } - } - // Unmarshal the remaining uncleared bits as reserved bits. - for i := 0; i < len(bitArray); i++ { - bs.SetReservedBit(i, bitArray[i]) - } - return nil -} - -// Looks up the given gotpm tag on a field. -// Some tags are settable (with "="). For these, the value is the RHS. -// For all others, the value is the empty string. -func tag(t reflect.StructField, query string) (string, bool) { - allTags, ok := t.Tag.Lookup("gotpm") - if !ok { - return "", false - } - tags := strings.Split(allTags, ",") - for _, tag := range tags { - // Split on the equals sign for settable tags. - // If the split returns a slice of length 1, this is an - // un-settable tag or an empty tag (which we'll ignore). - // If the split returns a slice of length 2, this is a settable - // tag. - if tag == query { - return "", true - } - if strings.HasPrefix(tag, query+"=") { - assignment := strings.SplitN(tag, "=", 2) - return assignment[1], true - } - } - return "", false -} - -// hasTag looks up to see if the type's gotpm-namespaced tag contains the -// given value. -// Returns false if there is no gotpm-namespaced tag on the type. -func hasTag(t reflect.StructField, query string) bool { - _, ok := tag(t, query) - return ok -} - -// Returns the range on a tag like 4:3 or 4. -// If there is no colon, the low and high part of the range are equal. -func rangeTag(t reflect.StructField, query string) (int, int, bool) { - val, ok := tag(t, query) - if !ok { - return 0, 0, false - } - vals := strings.Split(val, ":") - high, err := strconv.Atoi(vals[0]) - if err != nil { - return 0, 0, false - } - low := high - if len(vals) > 1 { - low, err = strconv.Atoi(vals[1]) - if err != nil { - return 0, 0, false - } - } - if low > high { - low, high = high, low - } - return high, low, true -} - -// taggedMembers will return a slice of all the members of the given -// structure that contain (or don't contain) the given tag in the "gotpm" -// namespace. -// Panics if v's Kind is not Struct. -func taggedMembers(v reflect.Value, tag string, invert bool) []reflect.Value { - var result []reflect.Value - t := v.Type() - - for i := 0; i < t.NumField(); i++ { - // Add this one to the list if it has the tag and we're not - // inverting, or if it doesn't have the tag and we are - // inverting. - if hasTag(t.Field(i), tag) != invert { - result = append(result, v.Field(i)) - } - } - - return result -} - -// cmdAuths returns the authorization sessions of the command. -func cmdAuths[R any](cmd Command[R, *R]) ([]Session, error) { - authHandles := taggedMembers(reflect.ValueOf(cmd), "auth", false) - var result []Session - for i, authHandle := range authHandles { - // TODO: A cleaner way to do this would be to have an interface method that - // returns a Session. - if h, ok := authHandle.Interface().(AuthHandle); ok { - if h.Auth == nil { - return nil, fmt.Errorf("missing auth for '%v' parameter", - reflect.ValueOf(cmd).Type().Field(i).Name) - } - result = append(result, h.Auth) - } else { - result = append(result, PasswordAuth(nil)) - } - } - - return result, nil -} - -// cmdHandles returns the handles area of the command. -func cmdHandles[R any](cmd Command[R, *R]) ([]byte, error) { - handles := taggedMembers(reflect.ValueOf(cmd), "handle", false) - - // Initial capacity is enough to hold 3 handles - result := bytes.NewBuffer(make([]byte, 0, 12)) - - for i, maybeHandle := range handles { - h, ok := maybeHandle.Interface().(handle) - if !ok { - return nil, fmt.Errorf("'handle'-tagged member of '%v' was of type '%v', which does not satisfy handle", - reflect.TypeOf(cmd), maybeHandle.Type()) - } - - // Special behavior: nullable handles have an effective zero-value of - // TPM_RH_NULL. - if h.HandleValue() == 0 && hasTag(reflect.TypeOf(cmd).Field(i), "nullable") { - h = TPMRHNull - } - - binary.Write(result, binary.BigEndian, h.HandleValue()) - } - - return result.Bytes(), nil -} - -// cmdNames returns the names of the entities referenced by the handles of the command. -func cmdNames[R any](cmd Command[R, *R]) ([]TPM2BName, error) { - handles := taggedMembers(reflect.ValueOf(cmd), "handle", false) - var result []TPM2BName - for i, maybeHandle := range handles { - h, ok := maybeHandle.Interface().(handle) - if !ok { - return nil, fmt.Errorf("'handle'-tagged member of '%v' was of type '%v', which does not satisfy handle", - reflect.TypeOf(cmd), maybeHandle.Type()) - } - - // Special behavior: nullable handles have an effective zero-value of - // TPM_RH_NULL. - if h.HandleValue() == 0 && hasTag(reflect.TypeOf(cmd).Field(i), "nullable") { - h = TPMRHNull - } - - name := h.KnownName() - if name == nil { - return nil, fmt.Errorf("missing Name for '%v' parameter", - reflect.ValueOf(cmd).Type().Field(i).Name) - } - result = append(result, *name) - } - - return result, nil -} - -// TODO: Extract the logic of "marshal the Nth field of some struct after the handles" -// For now, we duplicate some logic from marshalStruct here. -func marshalParameter[R any](buf *bytes.Buffer, cmd Command[R, *R], i int) error { - numHandles := len(taggedMembers(reflect.ValueOf(cmd), "handle", false)) - if numHandles+i >= reflect.TypeOf(cmd).NumField() { - return fmt.Errorf("invalid parameter index %v", i) - } - parm := reflect.ValueOf(cmd).Field(numHandles + i) - field := reflect.TypeOf(cmd).Field(numHandles + i) - if hasTag(field, "optional") { - return marshalOptional(buf, parm) - } else if parm.IsZero() && parm.Kind() == reflect.Uint32 && hasTag(field, "nullable") { - return marshal(buf, reflect.ValueOf(TPMRHNull)) - } else if parm.IsZero() && parm.Kind() == reflect.Uint16 && hasTag(field, "nullable") { - return marshal(buf, reflect.ValueOf(TPMAlgNull)) - } else { - return marshal(buf, parm) - } -} - -// cmdParameters returns the parameters area of the command. -// The first parameter may be encrypted by one of the sessions. -func cmdParameters[R any](cmd Command[R, *R], sess []Session) ([]byte, error) { - parms := taggedMembers(reflect.ValueOf(cmd), "handle", true) - if len(parms) == 0 { - return nil, nil - } - - var firstParm bytes.Buffer - if err := marshalParameter(&firstParm, cmd, 0); err != nil { - return nil, err - } - firstParmBytes := firstParm.Bytes() - - // Encrypt the first parameter if there are any decryption sessions. - encrypted := false - for i, s := range sess { - if s.IsDecryption() { - if encrypted { - // Only one session may be used for decryption. - return nil, fmt.Errorf("too many decrypt sessions") - } - if len(firstParmBytes) < 2 { - return nil, fmt.Errorf("this command's first parameter is not a tpm2b") - } - err := s.Encrypt(firstParmBytes[2:]) - if err != nil { - return nil, fmt.Errorf("encrypting with session %d: %w", i, err) - } - encrypted = true - } - } - - var result bytes.Buffer - result.Write(firstParmBytes) - // Write the rest of the parameters normally. - for i := 1; i < len(parms); i++ { - if err := marshalParameter(&result, cmd, i); err != nil { - return nil, err - } - } - return result.Bytes(), nil -} - -// cmdSessions returns the authorization area of the command. -func cmdSessions(sess []Session, cc TPMCC, names []TPM2BName, parms []byte) ([]byte, error) { - // There is no authorization area if there are no sessions. - if len(sess) == 0 { - return nil, nil - } - // Find the non-first-session encryption and decryption session - // nonceTPMs, if any. - var encNonceTPM, decNonceTPM []byte - if len(sess) > 0 { - for i := 1; i < len(sess); i++ { - s := sess[i] - if s.IsEncryption() { - if encNonceTPM != nil { - // Only one encrypt session is permitted. - return nil, fmt.Errorf("too many encrypt sessions") - } - encNonceTPM = s.NonceTPM().Buffer - // A session used for both encryption and - // decryption only needs its nonce counted once. - continue - } - if s.IsDecryption() { - if decNonceTPM != nil { - // Only one decrypt session is permitted. - return nil, fmt.Errorf("too many decrypt sessions") - } - decNonceTPM = s.NonceTPM().Buffer - } - } - } - - buf := bytes.NewBuffer(make([]byte, 0, 1024)) - // Skip space to write the size later - buf.Write(make([]byte, 4)) - // Calculate the authorization HMAC for each session - for i, s := range sess { - var addNonces []byte - // Special case: the HMAC on the first authorization session of - // a command also includes any decryption and encryption - // nonceTPMs, too. - if i == 0 { - addNonces = append(addNonces, decNonceTPM...) - addNonces = append(addNonces, encNonceTPM...) - } - auth, err := s.Authorize(cc, parms, addNonces, names, i) - if err != nil { - return nil, fmt.Errorf("session %d: %w", i, err) - } - marshal(buf, reflect.ValueOf(auth).Elem()) - } - - result := buf.Bytes() - // Write the size - binary.BigEndian.PutUint32(result[0:], uint32(buf.Len()-4)) - - return result, nil -} - -// cmdHeader returns the structured TPM command header. -func cmdHeader(hasSessions bool, length int, cc TPMCC) []byte { - tag := TPMSTNoSessions - if hasSessions { - tag = TPMSTSessions - } - hdr := TPMCmdHeader{ - Tag: tag, - Length: uint32(length), - CommandCode: cc, - } - buf := bytes.NewBuffer(make([]byte, 0, 8)) - marshal(buf, reflect.ValueOf(hdr)) - return buf.Bytes() -} - -// rspHeader parses the response header. If the TPM returned an error, -// returns an error here. -// rsp is updated to point to the rest of the response after the header. -func rspHeader(rsp *bytes.Buffer) error { - var hdr TPMRspHeader - if err := unmarshal(rsp, reflect.ValueOf(&hdr).Elem()); err != nil { - return fmt.Errorf("unmarshalling TPM response: %w", err) - } - if hdr.ResponseCode != TPMRCSuccess { - return hdr.ResponseCode - } - return nil -} - -// rspHandles parses the response handles area into the response structure. -// If there is a mismatch between the expected and actual amount of handles, -// returns an error here. -// rsp is updated to point to the rest of the response after the handles. -func rspHandles(rsp *bytes.Buffer, rspStruct any) error { - handles := taggedMembers(reflect.ValueOf(rspStruct).Elem(), "handle", false) - for i, handle := range handles { - if err := unmarshal(rsp, handle); err != nil { - return fmt.Errorf("unmarshalling handle %v: %w", i, err) - } - } - return nil -} - -// rspParametersArea fetches, but does not manipulate, the parameters area -// from the response. If there is a mismatch between the response's -// indicated parameters area size and the actual size, returns an error here. -// rsp is updated to point to the rest of the response after the handles. -func rspParametersArea(hasSessions bool, rsp *bytes.Buffer) ([]byte, error) { - var length uint32 - if hasSessions { - if err := binary.Read(rsp, binary.BigEndian, &length); err != nil { - return nil, fmt.Errorf("reading length of parameter area: %w", err) - } - } else { - // If there are no sessions, there is no length-of-parameters - // field, because the whole rest of the response is the - // parameters area. - length = uint32(rsp.Len()) - } - if length > uint32(rsp.Len()) { - return nil, fmt.Errorf("response indicated %d bytes of parameters but there "+ - "were only %d more bytes of response", length, rsp.Len()) - } - if length > math.MaxInt32 { - return nil, fmt.Errorf("invalid length of parameter area: %d", length) - } - parms := make([]byte, int(length)) - if n, err := rsp.Read(parms); err != nil { - return nil, fmt.Errorf("reading parameter area: %w", err) - } else if n != len(parms) { - return nil, fmt.Errorf("only read %d bytes of parameters, expected %d", n, len(parms)) - } - return parms, nil -} - -// rspSessions fetches the sessions area of the response and updates all -// the sessions with it. If there is a response validation error, returns -// an error here. -// rsp is updated to point to the rest of the response after the sessions. -func rspSessions(rsp *bytes.Buffer, rc TPMRC, cc TPMCC, names []TPM2BName, parms []byte, sess []Session) error { - for i, s := range sess { - var auth TPMSAuthResponse - if err := unmarshal(rsp, reflect.ValueOf(&auth).Elem()); err != nil { - return fmt.Errorf("reading auth session %d: %w", i, err) - } - if err := s.Validate(rc, cc, parms, names, i, &auth); err != nil { - return fmt.Errorf("validating auth session %d: %w", i, err) - } - } - if rsp.Len() != 0 { - return fmt.Errorf("%d unaccounted-for bytes at the end of the TPM response", rsp.Len()) - } - return nil -} - -// rspParameters decrypts (if needed) the parameters area of the response -// into the response structure. If there is a mismatch between the expected -// and actual response structure, returns an error here. -func rspParameters(parms []byte, sess []Session, rspStruct any) error { - numHandles := len(taggedMembers(reflect.ValueOf(rspStruct).Elem(), "handle", false)) - - // Use the heuristic of "does interpreting the first 2 bytes of response - // as a length make any sense" to attempt encrypted parameter - // decryption. - // If the command supports parameter encryption, the first parameter is - // a 2B. - if len(parms) < 2 { - return nil - } - length := binary.BigEndian.Uint16(parms[0:]) - // TODO: Make this nice using structure tagging. - if int(length)+2 <= len(parms) { - for i, s := range sess { - if !s.IsEncryption() { - continue - } - if err := s.Decrypt(parms[2 : 2+length]); err != nil { - return fmt.Errorf("decrypting first parameter with session %d: %w", i, err) - } - } - } - buf := bytes.NewBuffer(parms) - for i := numHandles; i < reflect.TypeOf(rspStruct).Elem().NumField(); i++ { - parmsField := reflect.ValueOf(rspStruct).Elem().Field(i) - if parmsField.Kind() == reflect.Ptr && hasTag(reflect.TypeOf(rspStruct).Elem().Field(i), "optional") { - if binary.BigEndian.Uint16(buf.Bytes()) == 0 { - // Advance the buffer past the zero size and skip to the - // next field of the struct. - buf.Next(2) - continue - } - } - if err := unmarshal(buf, parmsField); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/google/go-tpm/tpm2/sessions.go b/vendor/github.com/google/go-tpm/tpm2/sessions.go deleted file mode 100644 index 171adf8a38..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/sessions.go +++ /dev/null @@ -1,1100 +0,0 @@ -package tpm2 - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/elliptic" - "crypto/hmac" - "crypto/rand" - "crypto/rsa" - "encoding/binary" - "fmt" - - "github.com/google/go-tpm/tpm2/transport" -) - -// Session represents a session in the TPM. -type Session interface { - // Initializes the session, if needed. Has no effect if not needed or - // already done. Some types of sessions may need to be initialized - // just-in-time, e.g., to support calling patterns that help the user - // securely authorize their actions without writing a lot of code. - Init(tpm transport.TPM) error - // Cleans up the session, if needed. - // Some types of session need to be cleaned up if the command failed, - // again to support calling patterns that help the user securely - // authorize their actions without writing a lot of code. - CleanupFailure(tpm transport.TPM) error - // The last nonceTPM for this session. - NonceTPM() TPM2BNonce - // Updates nonceCaller to a new random value. - NewNonceCaller() error - // Computes the authorization HMAC for the session. - // If this is the first authorization session for a command, and - // there is another session (or sessions) for parameter - // decryption and/or encryption, then addNonces contains the - // nonceTPMs from each of them, respectively (see Part 1, 19.6.5) - Authorize(cc TPMCC, parms, addNonces []byte, names []TPM2BName, authIndex int) (*TPMSAuthCommand, error) - // Validates the response for the session. - // Updates NonceTPM for the session. - Validate(rc TPMRC, cc TPMCC, parms []byte, names []TPM2BName, authIndex int, auth *TPMSAuthResponse) error - // Returns true if this is an encryption session. - IsEncryption() bool - // Returns true if this is a decryption session. - IsDecryption() bool - // If this session is used for parameter decryption, encrypts the - // parameter. Otherwise, does not modify the parameter. - Encrypt(parameter []byte) error - // If this session is used for parameter encryption, encrypts the - // parameter. Otherwise, does not modify the parameter. - Decrypt(parameter []byte) error - // Returns the handle value of this session. - Handle() TPMHandle -} - -// CPHash calculates the TPM command parameter hash for a given Command. -// N.B. Authorization sessions on handles are ignored, but names aren't. -func CPHash[R any](alg TPMIAlgHash, cmd Command[R, *R]) (*TPM2BDigest, error) { - cc := cmd.Command() - names, err := cmdNames(cmd) - if err != nil { - return nil, err - } - parms, err := cmdParameters(cmd, nil) - if err != nil { - return nil, err - } - digest, err := cpHash(alg, cc, names, parms) - if err != nil { - return nil, err - } - return &TPM2BDigest{ - Buffer: digest, - }, nil -} - -// pwSession represents a password-pseudo-session. -type pwSession struct { - auth []byte -} - -// PasswordAuth assembles a password pseudo-session with the given auth value. -func PasswordAuth(auth []byte) Session { - return &pwSession{ - auth: auth, - } -} - -// Init is not required and has no effect for a password session. -func (s *pwSession) Init(_ transport.TPM) error { return nil } - -// Cleanup is not required and has no effect for a password session. -func (s *pwSession) CleanupFailure(_ transport.TPM) error { return nil } - -// NonceTPM normally returns the last nonceTPM value from the session. -// Since a password session is a pseudo-session with the auth value stuffed -// in where the HMAC should go, this is not used. -func (s *pwSession) NonceTPM() TPM2BNonce { return TPM2BNonce{} } - -// NewNonceCaller updates the nonceCaller for this session. -// Password sessions don't have nonces. -func (s *pwSession) NewNonceCaller() error { return nil } - -// Computes the authorization structure for the session. -func (s *pwSession) Authorize(_ TPMCC, _, _ []byte, _ []TPM2BName, _ int) (*TPMSAuthCommand, error) { - return &TPMSAuthCommand{ - Handle: TPMRSPW, - Nonce: TPM2BNonce{}, - Attributes: TPMASession{}, - Authorization: TPM2BData{ - Buffer: s.auth, - }, - }, nil -} - -// Validates the response session structure for the session. -func (s *pwSession) Validate(_ TPMRC, _ TPMCC, _ []byte, _ []TPM2BName, _ int, auth *TPMSAuthResponse) error { - if len(auth.Nonce.Buffer) != 0 { - return fmt.Errorf("expected empty nonce in response auth to PW session, got %x", auth.Nonce) - } - expectedAttrs := TPMASession{ - ContinueSession: true, - } - if auth.Attributes != expectedAttrs { - return fmt.Errorf("expected only ContinueSession in response auth to PW session, got %v", auth.Attributes) - } - if len(auth.Authorization.Buffer) != 0 { - return fmt.Errorf("expected empty HMAC in response auth to PW session, got %x", auth.Authorization) - } - return nil -} - -// IsEncryption returns true if this is an encryption session. -// Password sessions can't be used for encryption. -func (s *pwSession) IsEncryption() bool { return false } - -// IsDecryption returns true if this is a decryption session. -// Password sessions can't be used for decryption. -func (s *pwSession) IsDecryption() bool { return false } - -// If this session is used for parameter decryption, encrypts the -// parameter. Otherwise, does not modify the parameter. -// Password sessions can't be used for decryption. -func (s *pwSession) Encrypt(_ []byte) error { return nil } - -// If this session is used for parameter encryption, encrypts the -// parameter. Otherwise, does not modify the parameter. -// Password sessions can't be used for encryption. -func (s *pwSession) Decrypt(_ []byte) error { return nil } - -// Handle returns the handle value associated with this session. -// In the case of a password session, this is always TPM_RS_PW. -func (s *pwSession) Handle() TPMHandle { return TPMRSPW } - -// cpHash calculates the TPM command parameter hash. -// cpHash = hash(CC || names || parms) -func cpHash(alg TPMIAlgHash, cc TPMCC, names []TPM2BName, parms []byte) ([]byte, error) { - ha, err := alg.Hash() - if err != nil { - return nil, err - } - h := ha.New() - binary.Write(h, binary.BigEndian, cc) - for _, name := range names { - h.Write(name.Buffer) - } - h.Write(parms) - return h.Sum(nil), nil -} - -// rpHash calculates the TPM response parameter hash. -// rpHash = hash(RC || CC || parms) -func rpHash(alg TPMIAlgHash, rc TPMRC, cc TPMCC, parms []byte) ([]byte, error) { - ha, err := alg.Hash() - if err != nil { - return nil, err - } - h := ha.New() - binary.Write(h, binary.BigEndian, rc) - binary.Write(h, binary.BigEndian, cc) - h.Write(parms) - return h.Sum(nil), nil -} - -// sessionOptions represents extra options used when setting up an HMAC or policy session. -type sessionOptions struct { - auth []byte - password bool - bindHandle TPMIDHEntity - bindName TPM2BName - bindAuth []byte - saltHandle TPMIDHObject - saltPub TPMTPublic - attrs TPMASession - symmetric TPMTSymDef - trialPolicy bool -} - -// defaultOptions represents the default options used when none are provided. -func defaultOptions() sessionOptions { - return sessionOptions{ - symmetric: TPMTSymDef{ - Algorithm: TPMAlgNull, - }, - bindHandle: TPMRHNull, - saltHandle: TPMRHNull, - } -} - -// AuthOption is an option for setting up an auth session variadically. -type AuthOption func(*sessionOptions) - -// Auth uses the session to prove knowledge of the object's auth value. -func Auth(auth []byte) AuthOption { - return func(o *sessionOptions) { - o.auth = auth - } -} - -// Password is a policy-session-only option that specifies to provide the -// object's auth value in place of the authorization HMAC when authorizing. -// For HMAC sessions, has the same effect as using Auth. -// Deprecated: This is not recommended and is only provided for completeness; -// use Auth instead. -func Password(auth []byte) AuthOption { - return func(o *sessionOptions) { - o.auth = auth - o.password = true - } -} - -// Bound specifies that this session's session key should depend on the auth -// value of the given object. -func Bound(handle TPMIDHEntity, name TPM2BName, auth []byte) AuthOption { - return func(o *sessionOptions) { - o.bindHandle = handle - o.bindName = name - o.bindAuth = auth - } -} - -// Salted specifies that this session's session key should depend on an -// encrypted seed value using the given public key. -// 'handle' must refer to a loaded RSA or ECC key. -func Salted(handle TPMIDHObject, pub TPMTPublic) AuthOption { - return func(o *sessionOptions) { - o.saltHandle = handle - o.saltPub = pub - } -} - -// parameterEncryptiontpm2ion specifies whether the session-encrypted -// parameters are encrypted on the way into the TPM, out of the TPM, or both. -type parameterEncryptiontpm2ion int - -const ( - // EncryptIn specifies a decrypt session. - EncryptIn parameterEncryptiontpm2ion = 1 + iota - // EncryptOut specifies an encrypt session. - EncryptOut - // EncryptInOut specifies a decrypt+encrypt session. - EncryptInOut -) - -// AESEncryption uses the session to encrypt the first parameter sent to/from -// the TPM. -// Note that only commands whose first command/response parameter is a 2B can -// support session encryption. -func AESEncryption(keySize TPMKeyBits, dir parameterEncryptiontpm2ion) AuthOption { - return func(o *sessionOptions) { - o.attrs.Decrypt = (dir == EncryptIn || dir == EncryptInOut) - o.attrs.Encrypt = (dir == EncryptOut || dir == EncryptInOut) - o.symmetric = TPMTSymDef{ - Algorithm: TPMAlgAES, - KeyBits: NewTPMUSymKeyBits( - TPMAlgAES, - TPMKeyBits(keySize), - ), - Mode: NewTPMUSymMode( - TPMAlgAES, - TPMAlgCFB, - ), - } - } -} - -// Audit uses the session to compute extra HMACs. -// An Audit session can be used with GetSessionAuditDigest to obtain attestation -// over a sequence of commands. -func Audit() AuthOption { - return func(o *sessionOptions) { - o.attrs.Audit = true - } -} - -// AuditExclusive is like an audit session, but even more powerful. -// This allows an audit session to additionally indicate that no other auditable -// commands were executed other than the ones described by the audit hash. -func AuditExclusive() AuthOption { - return func(o *sessionOptions) { - o.attrs.Audit = true - o.attrs.AuditExclusive = true - } -} - -// Trial indicates that the policy session should be in trial-mode. -// This allows using the TPM to calculate policy hashes. -// This option has no effect on non-Policy sessions. -func Trial() AuthOption { - return func(o *sessionOptions) { - o.trialPolicy = true - } -} - -// hmacSession generally implements the HMAC session. -type hmacSession struct { - sessionOptions - hash TPMIAlgHash - nonceSize int - handle TPMHandle - sessionKey []byte - // last nonceCaller - nonceCaller TPM2BNonce - // last nonceTPM - nonceTPM TPM2BNonce -} - -// HMAC sets up a just-in-time HMAC session that is used only once. -// A real session is created, but just in time and it is flushed when used. -func HMAC(hash TPMIAlgHash, nonceSize int, opts ...AuthOption) Session { - // Set up a one-off session that knows the auth value. - sess := hmacSession{ - sessionOptions: defaultOptions(), - hash: hash, - nonceSize: nonceSize, - handle: TPMRHNull, - } - for _, opt := range opts { - opt(&sess.sessionOptions) - } - return &sess -} - -// HMACSession sets up a reusable HMAC session that needs to be closed. -func HMACSession(t transport.TPM, hash TPMIAlgHash, nonceSize int, opts ...AuthOption) (s Session, close func() error, err error) { - // Set up a not-one-off session that knows the auth value. - sess := hmacSession{ - sessionOptions: defaultOptions(), - hash: hash, - nonceSize: nonceSize, - handle: TPMRHNull, - } - for _, opt := range opts { - opt(&sess.sessionOptions) - } - // This session is reusable and is closed with the function we'll - // return. - sess.sessionOptions.attrs.ContinueSession = true - - // Initialize the session. - if err := sess.Init(t); err != nil { - return nil, nil, err - } - - closer := func() error { - _, err := (&FlushContext{FlushHandle: sess.handle}).Execute(t) - return err - } - - return &sess, closer, nil -} - -// Part 1, B.10.2 -func getEncryptedSaltRSA(nameAlg TPMIAlgHash, parms *TPMSRSAParms, pub *TPM2BPublicKeyRSA) (*TPM2BEncryptedSecret, []byte, error) { - rsaPub, err := RSAPub(parms, pub) - if err != nil { - return nil, nil, fmt.Errorf("could not encrypt salt to RSA key: %w", err) - } - // Odd special case: the size of the salt depends on the RSA scheme's - // hash alg. - var hAlg TPMIAlgHash - switch parms.Scheme.Scheme { - case TPMAlgRSASSA: - rsassa, err := parms.Scheme.Details.RSASSA() - if err != nil { - return nil, nil, err - } - hAlg = rsassa.HashAlg - case TPMAlgRSAES: - hAlg = nameAlg - case TPMAlgRSAPSS: - rsapss, err := parms.Scheme.Details.RSAPSS() - if err != nil { - return nil, nil, err - } - hAlg = rsapss.HashAlg - case TPMAlgOAEP: - oaep, err := parms.Scheme.Details.OAEP() - if err != nil { - return nil, nil, err - } - hAlg = oaep.HashAlg - case TPMAlgNull: - hAlg = nameAlg - default: - return nil, nil, fmt.Errorf("unsupported RSA salt key scheme: %v", parms.Scheme.Scheme) - } - ha, err := hAlg.Hash() - if err != nil { - return nil, nil, err - } - salt := make([]byte, ha.Size()) - if _, err := rand.Read(salt); err != nil { - return nil, nil, fmt.Errorf("generating random salt: %w", err) - } - // Part 1, section 4.6 specifies the trailing NULL byte for the label. - encSalt, err := rsa.EncryptOAEP(ha.New(), rand.Reader, rsaPub, salt, []byte("SECRET\x00")) - if err != nil { - return nil, nil, fmt.Errorf("encrypting salt: %w", err) - } - return &TPM2BEncryptedSecret{ - Buffer: encSalt, - }, salt, nil -} - -// Part 1, 19.6.13 -func getEncryptedSaltECC(nameAlg TPMIAlgHash, parms *TPMSECCParms, pub *TPMSECCPoint) (*TPM2BEncryptedSecret, []byte, error) { - curve, err := parms.CurveID.Curve() - if err != nil { - return nil, nil, fmt.Errorf("could not encrypt salt to ECC key: %w", err) - } - eccPub, err := ECCPub(parms, pub) - if err != nil { - return nil, nil, fmt.Errorf("could not encrypt salt to ECC key: %w", err) - } - ephPriv, ephPubX, ephPubY, err := elliptic.GenerateKey(curve, rand.Reader) - if err != nil { - return nil, nil, fmt.Errorf("could not encrypt salt to ECC key: %w", err) - } - zx, _ := curve.Params().ScalarMult(eccPub.X, eccPub.Y, ephPriv) - // ScalarMult returns a big.Int, whose Bytes() function may return the - // compacted form. In our case, we want to left-pad zx to the size of - // the curve. - z := make([]byte, (curve.Params().BitSize+7)/8) - zx.FillBytes(z) - ha, err := nameAlg.Hash() - if err != nil { - return nil, nil, err - } - salt := KDFe(ha, z, "SECRET", ephPubX.Bytes(), pub.X.Buffer, ha.Size()*8) - - var encSalt bytes.Buffer - binary.Write(&encSalt, binary.BigEndian, uint16(len(ephPubX.Bytes()))) - encSalt.Write(ephPubX.Bytes()) - binary.Write(&encSalt, binary.BigEndian, uint16(len(ephPubY.Bytes()))) - encSalt.Write(ephPubY.Bytes()) - return &TPM2BEncryptedSecret{ - Buffer: encSalt.Bytes(), - }, salt, nil -} - -// getEncryptedSalt creates a salt value for salted sessions. -// Returns the encrypted salt and plaintext salt, or an error value. -func getEncryptedSalt(pub TPMTPublic) (*TPM2BEncryptedSecret, []byte, error) { - switch pub.Type { - case TPMAlgRSA: - rsaParms, err := pub.Parameters.RSADetail() - if err != nil { - return nil, nil, err - } - rsaPub, err := pub.Unique.RSA() - if err != nil { - return nil, nil, err - } - return getEncryptedSaltRSA(pub.NameAlg, rsaParms, rsaPub) - case TPMAlgECC: - eccParms, err := pub.Parameters.ECCDetail() - if err != nil { - return nil, nil, err - } - eccPub, err := pub.Unique.ECC() - if err != nil { - return nil, nil, err - } - return getEncryptedSaltECC(pub.NameAlg, eccParms, eccPub) - default: - return nil, nil, fmt.Errorf("salt encryption alg '%v' not supported", pub.Type) - } -} - -// Init initializes the session, just in time, if needed. -func (s *hmacSession) Init(t transport.TPM) error { - if s.handle != TPMRHNull { - // Session is already initialized. - return nil - } - - // Get a high-quality nonceCaller for our use. - // Store it with the session object for later reference. - s.nonceCaller = TPM2BNonce{ - Buffer: make([]byte, s.nonceSize), - } - if _, err := rand.Read(s.nonceCaller.Buffer); err != nil { - return err - } - - // Start up the actual auth session. - sasCmd := StartAuthSession{ - TPMKey: s.saltHandle, - Bind: s.bindHandle, - NonceCaller: s.nonceCaller, - SessionType: TPMSEHMAC, - Symmetric: s.symmetric, - AuthHash: s.hash, - } - var salt []byte - if s.saltHandle != TPMRHNull { - var err error - var encSalt *TPM2BEncryptedSecret - encSalt, salt, err = getEncryptedSalt(s.saltPub) - if err != nil { - return err - } - sasCmd.EncryptedSalt = *encSalt - } - sasRsp, err := sasCmd.Execute(t) - if err != nil { - return err - } - s.handle = TPMHandle(sasRsp.SessionHandle.HandleValue()) - s.nonceTPM = sasRsp.NonceTPM - // Part 1, 19.6 - ha, err := s.hash.Hash() - if err != nil { - return err - } - if s.bindHandle != TPMRHNull || len(salt) != 0 { - var authSalt []byte - authSalt = append(authSalt, s.bindAuth...) - authSalt = append(authSalt, salt...) - s.sessionKey = KDFa(ha, authSalt, "ATH", s.nonceTPM.Buffer, s.nonceCaller.Buffer, ha.Size()*8) - } - return nil -} - -// Cleanup cleans up the session, if needed. -func (s *hmacSession) CleanupFailure(t transport.TPM) error { - // The user is already responsible to clean up this session. - if s.attrs.ContinueSession { - return nil - } - fc := FlushContext{FlushHandle: s.handle} - if _, err := fc.Execute(t); err != nil { - return err - } - s.handle = TPMRHNull - return nil -} - -// NonceTPM returns the last nonceTPM value from the session. -// May be nil, if the session hasn't been initialized yet. -func (s *hmacSession) NonceTPM() TPM2BNonce { return s.nonceTPM } - -// To avoid a circular dependency on gotpm by tpm2, implement a -// tiny serialization by hand for TPMASession here -func attrsToBytes(attrs TPMASession) []byte { - var res byte - if attrs.ContinueSession { - res |= (1 << 0) - } - if attrs.AuditExclusive { - res |= (1 << 1) - } - if attrs.AuditReset { - res |= (1 << 2) - } - if attrs.Decrypt { - res |= (1 << 5) - } - if attrs.Encrypt { - res |= (1 << 6) - } - if attrs.Audit { - res |= (1 << 7) - } - return []byte{res} -} - -// computeHMAC computes an authorization HMAC according to various equations in -// Part 1. -// This applies to both commands and responses. -// The value of key depends on whether the session is bound and/or salted. -// pHash cpHash for a command, or an rpHash for a response. -// nonceNewer in a command is the new nonceCaller sent in the command session packet. -// nonceNewer in a response is the new nonceTPM sent in the response session packet. -// nonceOlder in a command is the last nonceTPM sent by the TPM for this session. -// This may be when the session was created, or the last time it was used. -// nonceOlder in a response is the corresponding nonceCaller sent in the command. -func computeHMAC(alg TPMIAlgHash, key, pHash, nonceNewer, nonceOlder, addNonces []byte, attrs TPMASession) ([]byte, error) { - ha, err := alg.Hash() - if err != nil { - return nil, err - } - mac := hmac.New(ha.New, key) - mac.Write(pHash) - mac.Write(nonceNewer) - mac.Write(nonceOlder) - mac.Write(addNonces) - mac.Write(attrsToBytes(attrs)) - return mac.Sum(nil), nil -} - -// Trim trailing zeros from the auth value. Part 1, 19.6.5, Note 2 -// Does not allocate a new underlying byte array. -func hmacKeyFromAuthValue(auth []byte) []byte { - key := auth - for i := len(key) - 1; i >= 0; i-- { - if key[i] == 0 { - key = key[:i] - } - } - return key -} - -// NewNonceCaller updates the nonceCaller for this session. -func (s *hmacSession) NewNonceCaller() error { - _, err := rand.Read(s.nonceCaller.Buffer) - return err -} - -// Authorize computes the authorization structure for the session. -// Unlike the TPM spec, authIndex is zero-based. -func (s *hmacSession) Authorize(cc TPMCC, parms, addNonces []byte, names []TPM2BName, authIndex int) (*TPMSAuthCommand, error) { - if s.handle == TPMRHNull { - // Session is not initialized. - return nil, fmt.Errorf("session not initialized") - } - - // Part 1, 19.6 - // HMAC key is (sessionKey || auth) unless this session is authorizing - // its bind target - var hmacKey []byte - hmacKey = append(hmacKey, s.sessionKey...) - if len(s.bindName.Buffer) == 0 || authIndex >= len(names) || !bytes.Equal(names[authIndex].Buffer, s.bindName.Buffer) { - hmacKey = append(hmacKey, hmacKeyFromAuthValue(s.auth)...) - } - - // Compute the authorization HMAC. - cph, err := cpHash(s.hash, cc, names, parms) - if err != nil { - return nil, err - } - hmac, err := computeHMAC(s.hash, hmacKey, cph, s.nonceCaller.Buffer, s.nonceTPM.Buffer, addNonces, s.attrs) - if err != nil { - return nil, err - } - result := TPMSAuthCommand{ - Handle: s.handle, - Nonce: s.nonceCaller, - Attributes: s.attrs, - Authorization: TPM2BData{ - Buffer: hmac, - }, - } - return &result, nil -} - -// Validate validates the response session structure for the session. -// It updates nonceTPM from the TPM's response. -func (s *hmacSession) Validate(rc TPMRC, cc TPMCC, parms []byte, names []TPM2BName, authIndex int, auth *TPMSAuthResponse) error { - // Track the new nonceTPM for the session. - s.nonceTPM = auth.Nonce - // Track the session being automatically flushed. - if !auth.Attributes.ContinueSession { - s.handle = TPMRHNull - } - - // Part 1, 19.6 - // HMAC key is (sessionKey || auth) unless this session is authorizing - // its bind target - var hmacKey []byte - hmacKey = append(hmacKey, s.sessionKey...) - if len(s.bindName.Buffer) == 0 || authIndex >= len(names) || !bytes.Equal(names[authIndex].Buffer, s.bindName.Buffer) { - hmacKey = append(hmacKey, hmacKeyFromAuthValue(s.auth)...) - } - - // Compute the authorization HMAC. - rph, err := rpHash(s.hash, rc, cc, parms) - if err != nil { - return err - } - mac, err := computeHMAC(s.hash, hmacKey, rph, s.nonceTPM.Buffer, s.nonceCaller.Buffer, nil, auth.Attributes) - if err != nil { - return err - } - // Compare the HMAC (constant time) - if !hmac.Equal(mac, auth.Authorization.Buffer) { - return fmt.Errorf("incorrect authorization HMAC") - } - return nil -} - -// IsEncryption returns true if this is an encryption session. -func (s *hmacSession) IsEncryption() bool { - return s.attrs.Encrypt -} - -// IsDecryption returns true if this is a decryption session. -func (s *hmacSession) IsDecryption() bool { - return s.attrs.Decrypt -} - -// Encrypt decrypts the parameter in place, if this session is used for -// parameter decryption. Otherwise, it does not modify the parameter. -func (s *hmacSession) Encrypt(parameter []byte) error { - if !s.IsDecryption() { - return nil - } - // Only AES-CFB is supported. - bits, err := s.symmetric.KeyBits.AES() - if err != nil { - return err - } - keyBytes := *bits / 8 - keyIVBytes := int(keyBytes) + 16 - var sessionValue []byte - sessionValue = append(sessionValue, s.sessionKey...) - sessionValue = append(sessionValue, s.auth...) - ha, err := s.hash.Hash() - if err != nil { - return err - } - keyIV := KDFa(ha, sessionValue, "CFB", s.nonceCaller.Buffer, s.nonceTPM.Buffer, keyIVBytes*8) - key, err := aes.NewCipher(keyIV[:keyBytes]) - if err != nil { - return err - } - stream := cipher.NewCFBEncrypter(key, keyIV[keyBytes:]) - stream.XORKeyStream(parameter, parameter) - return nil -} - -// Decrypt encrypts the parameter in place, if this session is used for -// parameter encryption. Otherwise, it does not modify the parameter. -func (s *hmacSession) Decrypt(parameter []byte) error { - if !s.IsEncryption() { - return nil - } - // Only AES-CFB is supported. - bits, err := s.symmetric.KeyBits.AES() - if err != nil { - return err - } - keyBytes := *bits / 8 - keyIVBytes := int(keyBytes) + 16 - // Part 1, 21.1 - var sessionValue []byte - sessionValue = append(sessionValue, s.sessionKey...) - sessionValue = append(sessionValue, s.auth...) - ha, err := s.hash.Hash() - if err != nil { - return err - } - keyIV := KDFa(ha, sessionValue, "CFB", s.nonceTPM.Buffer, s.nonceCaller.Buffer, keyIVBytes*8) - key, err := aes.NewCipher(keyIV[:keyBytes]) - if err != nil { - return err - } - stream := cipher.NewCFBDecrypter(key, keyIV[keyBytes:]) - stream.XORKeyStream(parameter, parameter) - return nil -} - -// Handle returns the handle value of the session. -// If the session is created with HMAC (instead of HMACSession) this will be -// TPM_RH_NULL. -func (s *hmacSession) Handle() TPMHandle { - return s.handle -} - -// PolicyCallback represents an object's policy in the form of a function. -// This function makes zero or more TPM policy commands and returns error. -type PolicyCallback = func(tpm transport.TPM, handle TPMISHPolicy, nonceTPM TPM2BNonce) error - -// policySession generally implements the policy session. -type policySession struct { - sessionOptions - hash TPMIAlgHash - nonceSize int - handle TPMHandle - sessionKey []byte - // last nonceCaller - nonceCaller TPM2BNonce - // last nonceTPM - nonceTPM TPM2BNonce - callback *PolicyCallback -} - -// Policy sets up a just-in-time policy session that created each time it's -// needed. -// Each time the policy is created, the callback is invoked to authorize the -// session. -// A real session is created, but just in time, and it is flushed when used. -func Policy(hash TPMIAlgHash, nonceSize int, callback PolicyCallback, opts ...AuthOption) Session { - // Set up a one-off session that knows the auth value. - sess := policySession{ - sessionOptions: defaultOptions(), - hash: hash, - nonceSize: nonceSize, - handle: TPMRHNull, - callback: &callback, - } - for _, opt := range opts { - opt(&sess.sessionOptions) - } - return &sess -} - -// PolicySession opens a policy session that needs to be closed. -// The caller is responsible to call whichever policy commands they want in the -// session. -// Note that the TPM resets a policy session after it is successfully used. -func PolicySession(t transport.TPM, hash TPMIAlgHash, nonceSize int, opts ...AuthOption) (s Session, close func() error, err error) { - // Set up a not-one-off session that knows the auth value. - sess := policySession{ - sessionOptions: defaultOptions(), - hash: hash, - nonceSize: nonceSize, - handle: TPMRHNull, - } - for _, opt := range opts { - opt(&sess.sessionOptions) - } - - // This session is reusable and is closed with the function we'll - // return. - sess.sessionOptions.attrs.ContinueSession = true - - // Initialize the session. - if err := sess.Init(t); err != nil { - return nil, nil, err - } - - closer := func() error { - _, err := (&FlushContext{sess.handle}).Execute(t) - return err - } - - return &sess, closer, nil -} - -// Init initializes the session, just in time, if needed. -func (s *policySession) Init(t transport.TPM) error { - if s.handle != TPMRHNull { - // Session is already initialized. - return nil - } - - // Get a high-quality nonceCaller for our use. - // Store it with the session object for later reference. - s.nonceCaller = TPM2BNonce{ - Buffer: make([]byte, s.nonceSize), - } - if _, err := rand.Read(s.nonceCaller.Buffer); err != nil { - return err - } - - sessType := TPMSEPolicy - if s.sessionOptions.trialPolicy { - sessType = TPMSETrial - } - - // Start up the actual auth session. - sasCmd := StartAuthSession{ - TPMKey: s.saltHandle, - Bind: s.bindHandle, - NonceCaller: s.nonceCaller, - SessionType: sessType, - Symmetric: s.symmetric, - AuthHash: s.hash, - } - var salt []byte - if s.saltHandle != TPMRHNull { - var err error - var encSalt *TPM2BEncryptedSecret - encSalt, salt, err = getEncryptedSalt(s.saltPub) - if err != nil { - return err - } - sasCmd.EncryptedSalt = *encSalt - } - sasRsp, err := sasCmd.Execute(t) - if err != nil { - return err - } - s.handle = TPMHandle(sasRsp.SessionHandle.HandleValue()) - s.nonceTPM = sasRsp.NonceTPM - // Part 1, 19.6 - if s.bindHandle != TPMRHNull || len(salt) != 0 { - var authSalt []byte - authSalt = append(authSalt, s.bindAuth...) - authSalt = append(authSalt, salt...) - ha, err := s.hash.Hash() - if err != nil { - return err - } - s.sessionKey = KDFa(ha, authSalt, "ATH", s.nonceTPM.Buffer, s.nonceCaller.Buffer, ha.Size()*8) - } - - // Call the callback to execute the policy, if needed - if s.callback != nil { - if err := (*s.callback)(t, s.handle, s.nonceTPM); err != nil { - return fmt.Errorf("executing policy: %w", err) - } - } - - return nil -} - -// CleanupFailure cleans up the session, if needed. -func (s *policySession) CleanupFailure(t transport.TPM) error { - // The user is already responsible to clean up this session. - if s.attrs.ContinueSession { - return nil - } - fc := FlushContext{FlushHandle: s.handle} - if _, err := fc.Execute(t); err != nil { - return err - } - s.handle = TPMRHNull - return nil -} - -// NonceTPM returns the last nonceTPM value from the session. -// May be nil, if the session hasn't been initialized yet. -func (s *policySession) NonceTPM() TPM2BNonce { return s.nonceTPM } - -// NewNonceCaller updates the nonceCaller for this session. -func (s *policySession) NewNonceCaller() error { - _, err := rand.Read(s.nonceCaller.Buffer) - return err -} - -// Authorize computes the authorization structure for the session. -func (s *policySession) Authorize(cc TPMCC, parms, addNonces []byte, names []TPM2BName, _ int) (*TPMSAuthCommand, error) { - if s.handle == TPMRHNull { - // Session is not initialized. - return nil, fmt.Errorf("session not initialized") - } - - var hmac []byte - if s.password { - hmac = s.auth - } else { - // Part 1, 19.6 - // HMAC key is (sessionKey || auth). - var hmacKey []byte - hmacKey = append(hmacKey, s.sessionKey...) - hmacKey = append(hmacKey, hmacKeyFromAuthValue(s.auth)...) - - // Compute the authorization HMAC. - cph, err := cpHash(s.hash, cc, names, parms) - if err != nil { - return nil, err - } - hmac, err = computeHMAC(s.hash, hmacKey, cph, s.nonceCaller.Buffer, s.nonceTPM.Buffer, addNonces, s.attrs) - if err != nil { - return nil, err - } - } - - result := TPMSAuthCommand{ - Handle: s.handle, - Nonce: s.nonceCaller, - Attributes: s.attrs, - Authorization: TPM2BData{ - Buffer: hmac, - }, - } - return &result, nil -} - -// Validate valitades the response session structure for the session. -// Updates nonceTPM from the TPM's response. -func (s *policySession) Validate(rc TPMRC, cc TPMCC, parms []byte, _ []TPM2BName, _ int, auth *TPMSAuthResponse) error { - // Track the new nonceTPM for the session. - s.nonceTPM = auth.Nonce - // Track the session being automatically flushed. - if !auth.Attributes.ContinueSession { - s.handle = TPMRHNull - } - - if s.password { - // If we used a password, expect no nonce and no response HMAC. - if len(auth.Nonce.Buffer) != 0 { - return fmt.Errorf("expected empty nonce in response auth to PW policy, got %x", auth.Nonce) - } - if len(auth.Authorization.Buffer) != 0 { - return fmt.Errorf("expected empty HMAC in response auth to PW policy, got %x", auth.Authorization) - } - } else { - // Part 1, 19.6 - // HMAC key is (sessionKey || auth). - var hmacKey []byte - hmacKey = append(hmacKey, s.sessionKey...) - hmacKey = append(hmacKey, hmacKeyFromAuthValue(s.auth)...) - // Compute the authorization HMAC. - rph, err := rpHash(s.hash, rc, cc, parms) - if err != nil { - return err - } - mac, err := computeHMAC(s.hash, hmacKey, rph, s.nonceTPM.Buffer, s.nonceCaller.Buffer, nil, auth.Attributes) - if err != nil { - return err - } - // Compare the HMAC (constant time) - if !hmac.Equal(mac, auth.Authorization.Buffer) { - return fmt.Errorf("incorrect authorization HMAC") - } - } - return nil -} - -// IsEncryption returns true if this is an encryption session. -func (s *policySession) IsEncryption() bool { - return s.attrs.Encrypt -} - -// IsDecryption returns true if this is a decryption session. -func (s *policySession) IsDecryption() bool { - return s.attrs.Decrypt -} - -// Encrypt encrypts the parameter in place, if this session is used for -// parameter decryption. Otherwise, it does not modify the parameter. -func (s *policySession) Encrypt(parameter []byte) error { - if !s.IsDecryption() { - return nil - } - // Only AES-CFB is supported. - bits, err := s.symmetric.KeyBits.AES() - if err != nil { - return err - } - keyBytes := *bits / 8 - keyIVBytes := int(keyBytes) + 16 - var sessionValue []byte - sessionValue = append(sessionValue, s.sessionKey...) - sessionValue = append(sessionValue, s.auth...) - ha, err := s.hash.Hash() - if err != nil { - return err - } - keyIV := KDFa(ha, sessionValue, "CFB", s.nonceCaller.Buffer, s.nonceTPM.Buffer, keyIVBytes*8) - key, err := aes.NewCipher(keyIV[:keyBytes]) - if err != nil { - return err - } - stream := cipher.NewCFBEncrypter(key, keyIV[keyBytes:]) - stream.XORKeyStream(parameter, parameter) - return nil -} - -// Decrypt decrypts the parameter in place, if this session is used for -// parameter encryption. Otherwise, it does not modify the parameter. -func (s *policySession) Decrypt(parameter []byte) error { - if !s.IsEncryption() { - return nil - } - // Only AES-CFB is supported. - bits, err := s.symmetric.KeyBits.AES() - if err != nil { - return err - } - keyBytes := *bits / 8 - keyIVBytes := int(keyBytes) + 16 - // Part 1, 21.1 - var sessionValue []byte - sessionValue = append(sessionValue, s.sessionKey...) - sessionValue = append(sessionValue, s.auth...) - ha, err := s.hash.Hash() - if err != nil { - return err - } - keyIV := KDFa(ha, sessionValue, "CFB", s.nonceTPM.Buffer, s.nonceCaller.Buffer, keyIVBytes*8) - key, err := aes.NewCipher(keyIV[:keyBytes]) - if err != nil { - return err - } - stream := cipher.NewCFBDecrypter(key, keyIV[keyBytes:]) - stream.XORKeyStream(parameter, parameter) - return nil -} - -// Handle returns the handle value of the session. -// If the session is created with Policy (instead of PolicySession) this will be -// TPM_RH_NULL. -func (s *policySession) Handle() TPMHandle { - return s.handle -} diff --git a/vendor/github.com/google/go-tpm/tpm2/structures.go b/vendor/github.com/google/go-tpm/tpm2/structures.go deleted file mode 100644 index 7fe0d3c8c3..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/structures.go +++ /dev/null @@ -1,3150 +0,0 @@ -// Package tpm2 defines all the TPM 2.0 structures together to avoid import cycles -package tpm2 - -import ( - "bytes" - "crypto" - "crypto/elliptic" - "encoding/binary" - "reflect" - - // Register the relevant hash implementations. - _ "crypto/sha1" - _ "crypto/sha256" - _ "crypto/sha512" - "fmt" -) - -// TPMCmdHeader is the header structure in front of any TPM command. -// It is described in Part 1, Architecture. -type TPMCmdHeader struct { - marshalByReflection - Tag TPMISTCommandTag - Length uint32 - CommandCode TPMCC -} - -// TPMRspHeader is the header structure in front of any TPM response. -// It is described in Part 1, Architecture. -type TPMRspHeader struct { - marshalByReflection - Tag TPMISTCommandTag - Length uint32 - ResponseCode TPMRC -} - -// TPMAlgorithmID represents a TPM_ALGORITHM_ID -// this is the 1.2 compatible form of the TPM_ALG_ID -// See definition in Part 2, Structures, section 5.3. -type TPMAlgorithmID uint32 - -// TPMModifierIndicator represents a TPM_MODIFIER_INDICATOR. -// See definition in Part 2, Structures, section 5.3. -type TPMModifierIndicator uint32 - -// TPMAuthorizationSize represents a TPM_AUTHORIZATION_SIZE. -// the authorizationSize parameter in a command -// See definition in Part 2, Structures, section 5.3. -type TPMAuthorizationSize uint32 - -// TPMParameterSize represents a TPM_PARAMETER_SIZE. -// the parameterSize parameter in a command -// See definition in Part 2, Structures, section 5.3. -type TPMParameterSize uint32 - -// TPMKeySize represents a TPM_KEY_SIZE. -// a key size in octets -// See definition in Part 2, Structures, section 5.3. -type TPMKeySize uint16 - -// TPMKeyBits represents a TPM_KEY_BITS. -// a key size in bits -// See definition in Part 2, Structures, section 5.3. -type TPMKeyBits uint16 - -// TPMGenerated represents a TPM_GENERATED. -// See definition in Part 2: Structures, section 6.2. -type TPMGenerated uint32 - -// Generated values come from Part 2: Structures, section 6.2. -const ( - TPMGeneratedValue TPMGenerated = 0xff544347 -) - -// Check verifies that a TPMGenerated value is correct, and returns an error -// otherwise. -func (g TPMGenerated) Check() error { - if g != TPMGeneratedValue { - return fmt.Errorf("TPM_GENERATED value should be 0x%x, was 0x%x", TPMGeneratedValue, g) - } - return nil -} - -// Curve returns the elliptic.Curve associated with a TPMECCCurve. -func (c TPMECCCurve) Curve() (elliptic.Curve, error) { - switch c { - case TPMECCNistP224: - return elliptic.P224(), nil - case TPMECCNistP256: - return elliptic.P256(), nil - case TPMECCNistP384: - return elliptic.P384(), nil - case TPMECCNistP521: - return elliptic.P521(), nil - default: - return nil, fmt.Errorf("unsupported ECC curve: %v", c) - } -} - -// HandleValue returns the handle value. This behavior is intended to satisfy -// an interface that can be implemented by other, more complex types as well. -func (h TPMHandle) HandleValue() uint32 { - return uint32(h) -} - -// KnownName returns the TPM Name associated with the handle, if it can be known -// based only on the handle. This depends upon the value of the handle: -// only PCR, session, and permanent values have known constant Names. -// See definition in part 1: Architecture, section 16. -func (h TPMHandle) KnownName() *TPM2BName { - switch (byte)(h >> 24) { - case 0x00, 0x02, 0x03, 0x40: - result := make([]byte, 4) - binary.BigEndian.PutUint32(result, h.HandleValue()) - return &TPM2BName{Buffer: result} - default: - return nil - } -} - -// TPMAAlgorithm represents a TPMA_ALGORITHM. -// See definition in Part 2: Structures, section 8.2. -type TPMAAlgorithm struct { - bitfield32 - marshalByReflection - // SET (1): an asymmetric algorithm with public and private portions - // CLEAR (0): not an asymmetric algorithm - Asymmetric bool `gotpm:"bit=0"` - // SET (1): a symmetric block cipher - // CLEAR (0): not a symmetric block cipher - Symmetric bool `gotpm:"bit=1"` - // SET (1): a hash algorithm - // CLEAR (0): not a hash algorithm - Hash bool `gotpm:"bit=2"` - // SET (1): an algorithm that may be used as an object type - // CLEAR (0): an algorithm that is not used as an object type - Object bool `gotpm:"bit=3"` - // SET (1): a signing algorithm. The setting of asymmetric, - // symmetric, and hash will indicate the type of signing algorithm. - // CLEAR (0): not a signing algorithm - Signing bool `gotpm:"bit=8"` - // SET (1): an encryption/decryption algorithm. The setting of - // asymmetric, symmetric, and hash will indicate the type of - // encryption/decryption algorithm. - // CLEAR (0): not an encryption/decryption algorithm - Encrypting bool `gotpm:"bit=9"` - // SET (1): a method such as a key derivative function (KDF) - // CLEAR (0): not a method - Method bool `gotpm:"bit=10"` -} - -// TPMAObject represents a TPMA_OBJECT. -// See definition in Part 2: Structures, section 8.3.2. -type TPMAObject struct { - bitfield32 - marshalByReflection - // SET (1): The hierarchy of the object, as indicated by its - // Qualified Name, may not change. - // CLEAR (0): The hierarchy of the object may change as a result - // of this object or an ancestor key being duplicated for use in - // another hierarchy. - FixedTPM bool `gotpm:"bit=1"` - // SET (1): Previously saved contexts of this object may not be - // loaded after Startup(CLEAR). - // CLEAR (0): Saved contexts of this object may be used after a - // Shutdown(STATE) and subsequent Startup(). - STClear bool `gotpm:"bit=2"` - // SET (1): The parent of the object may not change. - // CLEAR (0): The parent of the object may change as the result of - // a TPM2_Duplicate() of the object. - FixedParent bool `gotpm:"bit=4"` - // SET (1): Indicates that, when the object was created with - // TPM2_Create() or TPM2_CreatePrimary(), the TPM generated all of - // the sensitive data other than the authValue. - // CLEAR (0): A portion of the sensitive data, other than the - // authValue, was provided by the caller. - SensitiveDataOrigin bool `gotpm:"bit=5"` - // SET (1): Approval of USER role actions with this object may be - // with an HMAC session or with a password using the authValue of - // the object or a policy session. - // CLEAR (0): Approval of USER role actions with this object may - // only be done with a policy session. - UserWithAuth bool `gotpm:"bit=6"` - // SET (1): Approval of ADMIN role actions with this object may - // only be done with a policy session. - // CLEAR (0): Approval of ADMIN role actions with this object may - // be with an HMAC session or with a password using the authValue - // of the object or a policy session. - AdminWithPolicy bool `gotpm:"bit=7"` - // SET (1): The object is not subject to dictionary attack - // protections. - // CLEAR (0): The object is subject to dictionary attack - // protections. - NoDA bool `gotpm:"bit=10"` - // SET (1): If the object is duplicated, then symmetricAlg shall - // not be TPM_ALG_NULL and newParentHandle shall not be - // TPM_RH_NULL. - // CLEAR (0): The object may be duplicated without an inner - // wrapper on the private portion of the object and the new parent - // may be TPM_RH_NULL. - EncryptedDuplication bool `gotpm:"bit=11"` - // SET (1): Key usage is restricted to manipulate structures of - // known format; the parent of this key shall have restricted SET. - // CLEAR (0): Key usage is not restricted to use on special - // formats. - Restricted bool `gotpm:"bit=16"` - // SET (1): The private portion of the key may be used to decrypt. - // CLEAR (0): The private portion of the key may not be used to - // decrypt. - Decrypt bool `gotpm:"bit=17"` - // SET (1): For a symmetric cipher object, the private portion of - // the key may be used to encrypt. For other objects, the private - // portion of the key may be used to sign. - // CLEAR (0): The private portion of the key may not be used to - // sign or encrypt. - SignEncrypt bool `gotpm:"bit=18"` - // SET (1): An asymmetric key that may not be used to sign with - // TPM2_Sign() CLEAR (0): A key that may be used with TPM2_Sign() - // if sign is SET - // NOTE: This attribute only has significance if sign is SET. - X509Sign bool `gotpm:"bit=19"` -} - -// TPMASession represents a TPMA_SESSION. -// See definition in Part 2: Structures, section 8.4. -type TPMASession struct { - bitfield8 - marshalByReflection - // SET (1): In a command, this setting indicates that the session - // is to remain active after successful completion of the command. - // In a response, it indicates that the session is still active. - // If SET in the command, this attribute shall be SET in the response. - // CLEAR (0): In a command, this setting indicates that the TPM should - // close the session and flush any related context when the command - // completes successfully. In a response, it indicates that the - // session is closed and the context is no longer active. - // This attribute has no meaning for a password authorization and the - // TPM will allow any setting of the attribute in the command and SET - // the attribute in the response. - ContinueSession bool `gotpm:"bit=0"` - // SET (1): In a command, this setting indicates that the command - // should only be executed if the session is exclusive at the start of - // the command. In a response, it indicates that the session is - // exclusive. This setting is only allowed if the audit attribute is - // SET (TPM_RC_ATTRIBUTES). - // CLEAR (0): In a command, indicates that the session need not be - // exclusive at the start of the command. In a response, indicates that - // the session is not exclusive. - AuditExclusive bool `gotpm:"bit=1"` - // SET (1): In a command, this setting indicates that the audit digest - // of the session should be initialized and the exclusive status of the - // session SET. This setting is only allowed if the audit attribute is - // SET (TPM_RC_ATTRIBUTES). - // CLEAR (0): In a command, indicates that the audit digest should not - // be initialized. This bit is always CLEAR in a response. - AuditReset bool `gotpm:"bit=2"` - // SET (1): In a command, this setting indicates that the first - // parameter in the command is symmetrically encrypted using the - // parameter encryption scheme described in TPM 2.0 Part 1. The TPM will - // decrypt the parameter after performing any HMAC computations and - // before unmarshaling the parameter. In a response, the attribute is - // copied from the request but has no effect on the response. - // CLEAR (0): Session not used for encryption. - // For a password authorization, this attribute will be CLEAR in both the - // command and response. - Decrypt bool `gotpm:"bit=5"` - // SET (1): In a command, this setting indicates that the TPM should use - // this session to encrypt the first parameter in the response. In a - // response, it indicates that the attribute was set in the command and - // that the TPM used the session to encrypt the first parameter in the - // response using the parameter encryption scheme described in TPM 2.0 - // Part 1. - // CLEAR (0): Session not used for encryption. - // For a password authorization, this attribute will be CLEAR in both the - // command and response. - Encrypt bool `gotpm:"bit=6"` - // SET (1): In a command or response, this setting indicates that the - // session is for audit and that auditExclusive and auditReset have - // meaning. This session may also be used for authorization, encryption, - // or decryption. The encrypted and encrypt fields may be SET or CLEAR. - // CLEAR (0): Session is not used for audit. - // If SET in the command, then this attribute will be SET in the response. - Audit bool `gotpm:"bit=7"` -} - -// TPMALocality represents a TPMA_LOCALITY. -// See definition in Part 2: Structures, section 8.5. -type TPMALocality struct { - bitfield8 - marshalByReflection - TPMLocZero bool `gotpm:"bit=0"` - TPMLocOne bool `gotpm:"bit=1"` - TPMLocTwo bool `gotpm:"bit=2"` - TPMLocThree bool `gotpm:"bit=3"` - TPMLocFour bool `gotpm:"bit=4"` - // If any of these bits is set, an extended locality is indicated - Extended uint8 `gotpm:"bit=7:5"` -} - -// TPMACC represents a TPMA_CC. -// See definition in Part 2: Structures, section 8.9. -type TPMACC struct { - bitfield32 - marshalByReflection - // indicates the command being selected - CommandIndex uint16 `gotpm:"bit=15:0"` - // SET (1): indicates that the command may write to NV - // CLEAR (0): indicates that the command does not write to NV - NV bool `gotpm:"bit=22"` - // SET (1): This command could flush any number of loaded contexts. - // CLEAR (0): no additional changes other than indicated by the flushed attribute - Extensive bool `gotpm:"bit=23"` - // SET (1): The context associated with any transient handle in the command will be flushed when this command completes. - // CLEAR (0): No context is flushed as a side effect of this command. - Flushed bool `gotpm:"bit=24"` - // indicates the number of the handles in the handle area for this command - CHandles uint8 `gotpm:"bit=27:25"` - // SET (1): indicates the presence of the handle area in the response - RHandle bool `gotpm:"bit=28"` - // SET (1): indicates that the command is vendor-specific - // CLEAR (0): indicates that the command is defined in a version of this specification - V bool `gotpm:"bit=29"` -} - -// TPMAACT represents a TPMA_ACT. -// See definition in Part 2: Structures, section 8.12. -type TPMAACT struct { - bitfield32 - marshalByReflection - // SET (1): The ACT has signaled - // CLEAR (0): The ACT has not signaled - Signaled bool `gotpm:"bit=0"` - // SET (1): The ACT signaled bit is preserved over a power cycle - // CLEAR (0): The ACT signaled bit is not preserved over a power cycle - PreserveSignaled bool `gotpm:"bit=1"` -} - -// TPMIYesNo represents a TPMI_YES_NO. -// See definition in Part 2: Structures, section 9.2. -// Use native bool for TPMI_YES_NO; encoding/binary already treats this as 8 bits wide. -type TPMIYesNo = bool - -// TPMIDHObject represents a TPMI_DH_OBJECT. -// See definition in Part 2: Structures, section 9.3. -type TPMIDHObject = TPMHandle - -// TPMIDHEntity represents a TPMI_DH_ENTITY. -// See definition in Part 2: Structures, section 9.6. -type TPMIDHEntity = TPMHandle - -// TPMISHAuthSession represents a TPMI_SH_AUTH_SESSION. -// See definition in Part 2: Structures, section 9.8. -type TPMISHAuthSession = TPMHandle - -// TPMISHHMAC represents a TPMI_SH_HMAC. -// See definition in Part 2: Structures, section 9.9. -type TPMISHHMAC = TPMHandle - -// TPMISHPolicy represents a TPMI_SH_POLICY. -// See definition in Part 2: Structures, section 9.10. -type TPMISHPolicy = TPMHandle - -// TPMIDHContext represents a TPMI_DH_CONTEXT. -// See definition in Part 2: Structures, section 9.11. -type TPMIDHContext = TPMHandle - -// TPMIDHSaved represents a TPMI_DH_SAVED. -// See definition in Part 2: Structures, section 9.12. -type TPMIDHSaved = TPMHandle - -// TPMIRHHierarchy represents a TPMI_RH_HIERARCHY. -// See definition in Part 2: Structures, section 9.13. -type TPMIRHHierarchy = TPMHandle - -// TPMIRHEnables represents a TPMI_RH_ENABLES. -// See definition in Part 2: Structures, section 9.14. -type TPMIRHEnables = TPMHandle - -// TPMIRHHierarchyAuth represents a TPMI_RH_HIERARCHY_AUTH. -// See definition in Part 2: Structures, section 9.15. -type TPMIRHHierarchyAuth = TPMHandle - -// TPMIRHHierarchyPolicy represents a TPMI_RH_HIERARCHY_POLICY. -// See definition in Part 2: Structures, section 9.16. -type TPMIRHHierarchyPolicy = TPMHandle - -// TPMIRHPlatform represents a TPMI_RH_PLATFORM. -// See definition in Part 2: Structures, section 9.17. -type TPMIRHPlatform = TPMHandle - -// TPMIRHOwner represents a TPMI_RH_OWNER. -// See definition in Part 2: Structures, section 9.18. -type TPMIRHOwner = TPMHandle - -// TPMIRHEndorsement represents a TPMI_RH_ENDORSEMENT. -// See definition in Part 2: Structures, section 9.19. -type TPMIRHEndorsement = TPMHandle - -// TPMIRHProvision represents a TPMI_RH_PROVISION. -// See definition in Part 2: Structures, section 9.20. -type TPMIRHProvision = TPMHandle - -// TPMIRHClear represents a TPMI_RH_CLEAR. -// See definition in Part 2: Structures, section 9.21. -type TPMIRHClear = TPMHandle - -// TPMIRHNVAuth represents a TPMI_RH_NV_AUTH. -// See definition in Part 2: Structures, section 9.22. -type TPMIRHNVAuth = TPMHandle - -// TPMIRHLockout represents a TPMI_RH_LOCKOUT. -// See definition in Part 2: Structures, section 9.23. -type TPMIRHLockout = TPMHandle - -// TPMIRHNVIndex represents a TPMI_RH_NV_INDEX. -// See definition in Part 2: Structures, section 9.24. -type TPMIRHNVIndex = TPMHandle - -// TPMIRHAC represents a TPMI_RH_AC. -// See definition in Part 2: Structures, section 9.25. -type TPMIRHAC = TPMHandle - -// TPMIRHACT represents a TPMI_RH_ACT. -// See definition in Part 2: Structures, section 9.26. -type TPMIRHACT = TPMHandle - -// TPMIAlgHash represents a TPMI_ALG_HASH. -// See definition in Part 2: Structures, section 9.27. -type TPMIAlgHash = TPMAlgID - -// Hash returns the crypto.Hash associated with a TPMIAlgHash. -func (a TPMIAlgHash) Hash() (crypto.Hash, error) { - switch TPMAlgID(a) { - case TPMAlgSHA1: - return crypto.SHA1, nil - case TPMAlgSHA256: - return crypto.SHA256, nil - case TPMAlgSHA384: - return crypto.SHA384, nil - case TPMAlgSHA512: - return crypto.SHA512, nil - } - return crypto.SHA256, fmt.Errorf("unsupported hash algorithm: %v", a) -} - -// TPMIAlgSym represents a TPMI_ALG_SYM. -// See definition in Part 2: Structures, section 9.29. -type TPMIAlgSym = TPMAlgID - -// TPMIAlgSymObject represents a TPMI_ALG_SYM_OBJECT. -// See definition in Part 2: Structures, section 9.30. -type TPMIAlgSymObject = TPMAlgID - -// TPMIAlgSymMode represents a TPMI_ALG_SYM_MODE. -// See definition in Part 2: Structures, section 9.31. -type TPMIAlgSymMode = TPMAlgID - -// TPMIAlgKDF represents a TPMI_ALG_KDF. -// See definition in Part 2: Structures, section 9.32. -type TPMIAlgKDF = TPMAlgID - -// TPMIAlgSigScheme represents a TPMI_ALG_SIG_SCHEME. -// See definition in Part 2: Structures, section 9.33. -type TPMIAlgSigScheme = TPMAlgID - -// TPMISTCommandTag represents a TPMI_ST_COMMAND_TAG. -// See definition in Part 2: Structures, section 9.35. -type TPMISTCommandTag = TPMST - -// TPMSEmpty represents a TPMS_EMPTY. -// See definition in Part 2: Structures, section 10.1. -type TPMSEmpty struct { - marshalByReflection -} - -// TPMTHA represents a TPMT_HA. -// See definition in Part 2: Structures, section 10.3.2. -type TPMTHA struct { - marshalByReflection - // selector of the hash contained in the digest that implies the size of the digest - HashAlg TPMIAlgHash `gotpm:"nullable"` - // the digest data - // NOTE: For convenience, this is not implemented as a union. - Digest []byte -} - -// TPM2BDigest represents a TPM2B_DIGEST. -// See definition in Part 2: Structures, section 10.4.2. -type TPM2BDigest TPM2BData - -// TPM2BData represents a TPM2B_DATA. -// See definition in Part 2: Structures, section 10.4.3. -type TPM2BData struct { - marshalByReflection - // size in octets of the buffer field; may be 0 - Buffer []byte `gotpm:"sized"` -} - -// TPM2BNonce represents a TPM2B_NONCE. -// See definition in Part 2: Structures, section 10.4.4. -type TPM2BNonce TPM2BDigest - -// TPM2BEvent represents a TPM2B_EVENT. -// See definition in Part 2: Structures, section 10.4.7. -type TPM2BEvent TPM2BData - -// TPM2BTimeout represents a TPM2B_TIMEOUT. -// See definition in Part 2: Structures, section 10.4.10. -type TPM2BTimeout TPM2BData - -// TPM2BAuth represents a TPM2B_AUTH. -// See definition in Part 2: Structures, section 10.4.5. -type TPM2BAuth TPM2BDigest - -// TPM2BOperand represents a TPM2B_Operand. -// See definition in Part 2: Structures, section 10.4.6. -type TPM2BOperand TPM2BDigest - -// TPM2BMaxBuffer represents a TPM2B_MAX_BUFFER. -// See definition in Part 2: Structures, section 10.4.8. -type TPM2BMaxBuffer TPM2BData - -// TPM2BMaxNVBuffer represents a TPM2B_MAX_NV_BUFFER. -// See definition in Part 2: Structures, section 10.4.9. -type TPM2BMaxNVBuffer TPM2BData - -// TPM2BName represents a TPM2B_NAME. -// See definition in Part 2: Structures, section 10.5.3. -// NOTE: This structure does not contain a TPMUName, because that union -// is not tagged with a selector. Instead, TPM2B_Name is flattened and -// all TPMDirect helpers that deal with names will deal with them as so. -type TPM2BName TPM2BData - -// TPMSPCRSelection represents a TPMS_PCR_SELECTION. -// See definition in Part 2: Structures, section 10.6.2. -type TPMSPCRSelection struct { - marshalByReflection - Hash TPMIAlgHash - PCRSelect []byte `gotpm:"sized8"` -} - -// TPMTTKCreation represents a TPMT_TK_CREATION. -// See definition in Part 2: Structures, section 10.7.3. -type TPMTTKCreation struct { - marshalByReflection - // ticket structure tag - Tag TPMST - // the hierarchy containing name - Hierarchy TPMIRHHierarchy - // This shall be the HMAC produced using a proof value of hierarchy. - Digest TPM2BDigest -} - -// TPMTTKVerified represents a TPMT_TK_Verified. -// See definition in Part 2: Structures, section 10.7.4. -type TPMTTKVerified struct { - marshalByReflection - // ticket structure tag - Tag TPMST - // the hierarchy containing keyName - Hierarchy TPMIRHHierarchy - // This shall be the HMAC produced using a proof value of hierarchy. - Digest TPM2BDigest -} - -// TPMTTKAuth represents a TPMT_TK_AUTH. -// See definition in Part 2: Structures, section 10.7.5. -type TPMTTKAuth struct { - marshalByReflection - // ticket structure tag - Tag TPMST - // the hierarchy of the object used to produce the ticket - Hierarchy TPMIRHHierarchy `gotpm:"nullable"` - // This shall be the HMAC produced using a proof value of hierarchy. - Digest TPM2BDigest -} - -// TPMTTKHashCheck represents a TPMT_TK_HASHCHECK. -// See definition in Part 2: Structures, section 10.7.6. -type TPMTTKHashCheck struct { - marshalByReflection - // ticket structure tag - Tag TPMST - // the hierarchy - Hierarchy TPMIRHHierarchy `gotpm:"nullable"` - // This shall be the HMAC produced using a proof value of hierarchy. - Digest TPM2BDigest -} - -// TPMSAlgProperty represents a TPMS_ALG_PROPERTY. -// See definition in Part 2: Structures, section 10.8.1. -type TPMSAlgProperty struct { - marshalByReflection - // an algorithm identifier - Alg TPMAlgID - // the attributes of the algorithm - AlgProperties TPMAAlgorithm -} - -// TPMSTaggedProperty represents a TPMS_TAGGED_PROPERTY. -// See definition in Part 2: Structures, section 10.8.2. -type TPMSTaggedProperty struct { - marshalByReflection - // a property identifier - Property TPMPT - // the value of the property - Value uint32 -} - -// TPMSTaggedPCRSelect represents a TPMS_TAGGED_PCR_SELECT. -// See definition in Part 2: Structures, section 10.8.3. -type TPMSTaggedPCRSelect struct { - marshalByReflection - // the property identifier - Tag TPMPTPCR - // the bit map of PCR with the identified property - PCRSelect []byte `gotpm:"sized8"` -} - -// TPMSTaggedPolicy represents a TPMS_TAGGED_POLICY. -// See definition in Part 2: Structures, section 10.8.4. -type TPMSTaggedPolicy struct { - marshalByReflection - // a permanent handle - Handle TPMHandle - // the policy algorithm and hash - PolicyHash TPMTHA -} - -// TPMSACTData represents a TPMS_ACT_DATA. -// See definition in Part 2: Structures, section 10.8.5. -type TPMSACTData struct { - marshalByReflection - // a permanent handle - Handle TPMHandle - // the current timeout of the ACT - Timeout uint32 - // the state of the ACT - Attributes TPMAACT -} - -// TPMLCC represents a TPML_CC. -// See definition in Part 2: Structures, section 10.9.1. -type TPMLCC struct { - marshalByReflection - CommandCodes []TPMCC `gotpm:"list"` -} - -// TPMLCCA represents a TPML_CCA. -// See definition in Part 2: Structures, section 10.9.2. -type TPMLCCA struct { - marshalByReflection - CommandAttributes []TPMACC `gotpm:"list"` -} - -// TPMLAlg represents a TPML_ALG. -// See definition in Part 2: Structures, section 10.9.3. -type TPMLAlg struct { - marshalByReflection - Algorithms []TPMAlgID `gotpm:"list"` -} - -// TPMLHandle represents a TPML_HANDLE. -// See definition in Part 2: Structures, section 10.9.4. -type TPMLHandle struct { - marshalByReflection - Handle []TPMHandle `gotpm:"list"` -} - -// TPMLDigest represents a TPML_DIGEST. -// See definition in Part 2: Structures, section 10.9.5. -type TPMLDigest struct { - marshalByReflection - // a list of digests - Digests []TPM2BDigest `gotpm:"list"` -} - -// TPMLDigestValues represents a TPML_DIGEST_VALUES. -// See definition in Part 2: Structures, section 10.9.6. -type TPMLDigestValues struct { - marshalByReflection - // a list of tagged digests - Digests []TPMTHA `gotpm:"list"` -} - -// TPMLPCRSelection represents a TPML_PCR_SELECTION. -// See definition in Part 2: Structures, section 10.9.7. -type TPMLPCRSelection struct { - marshalByReflection - PCRSelections []TPMSPCRSelection `gotpm:"list"` -} - -// TPMLAlgProperty represents a TPML_ALG_PROPERTY. -// See definition in Part 2: Structures, section 10.9.8. -type TPMLAlgProperty struct { - marshalByReflection - AlgProperties []TPMSAlgProperty `gotpm:"list"` -} - -// TPMLTaggedTPMProperty represents a TPML_TAGGED_TPM_PROPERTY. -// See definition in Part 2: Structures, section 10.9.9. -type TPMLTaggedTPMProperty struct { - marshalByReflection - TPMProperty []TPMSTaggedProperty `gotpm:"list"` -} - -// TPMLTaggedPCRProperty represents a TPML_TAGGED_PCR_PROPERTY. -// See definition in Part 2: Structures, section 10.9.10. -type TPMLTaggedPCRProperty struct { - marshalByReflection - PCRProperty []TPMSTaggedPCRSelect `gotpm:"list"` -} - -// TPMLECCCurve represents a TPML_ECC_CURVE. -// See definition in Part 2: Structures, section 10.9.11. -type TPMLECCCurve struct { - marshalByReflection - ECCCurves []TPMECCCurve `gotpm:"list"` -} - -// TPMLTaggedPolicy represents a TPML_TAGGED_POLICY. -// See definition in Part 2: Structures, section 10.9.12. -type TPMLTaggedPolicy struct { - marshalByReflection - Policies []TPMSTaggedPolicy `gotpm:"list"` -} - -// TPMLACTData represents a TPML_ACT_DATA. -// See definition in Part 2: Structures, section 10.9.13. -type TPMLACTData struct { - marshalByReflection - ACTData []TPMSACTData `gotpm:"list"` -} - -// TPMUCapabilities represents a TPMU_CAPABILITIES. -// See definition in Part 2: Structures, section 10.10.1. -type TPMUCapabilities struct { - selector TPMCap - contents Marshallable -} - -// CapabilitiesContents is a type constraint representing the possible contents of TPMUCapabilities. -type CapabilitiesContents interface { - Marshallable - *TPMLAlgProperty | *TPMLHandle | *TPMLCCA | *TPMLCC | *TPMLPCRSelection | *TPMLTaggedTPMProperty | - *TPMLTaggedPCRProperty | *TPMLECCCurve | *TPMLTaggedPolicy | *TPMLACTData -} - -// create implements the unmarshallableWithHint interface. -func (u *TPMUCapabilities) create(hint int64) (reflect.Value, error) { - switch TPMCap(hint) { - case TPMCapAlgs: - contents := TPMLAlgProperty{} - u.contents = &contents - u.selector = TPMCap(hint) - return reflect.ValueOf(&contents), nil - case TPMCapHandles: - contents := TPMLHandle{} - u.contents = &contents - u.selector = TPMCap(hint) - return reflect.ValueOf(&contents), nil - case TPMCapCommands: - contents := TPMLCCA{} - u.contents = &contents - u.selector = TPMCap(hint) - return reflect.ValueOf(&contents), nil - case TPMCapPPCommands, TPMCapAuditCommands: - contents := TPMLCC{} - u.contents = &contents - u.selector = TPMCap(hint) - return reflect.ValueOf(&contents), nil - case TPMCapPCRs: - contents := TPMLPCRSelection{} - u.contents = &contents - u.selector = TPMCap(hint) - return reflect.ValueOf(&contents), nil - case TPMCapTPMProperties: - contents := TPMLTaggedTPMProperty{} - u.contents = &contents - u.selector = TPMCap(hint) - return reflect.ValueOf(&contents), nil - case TPMCapPCRProperties: - contents := TPMLTaggedPCRProperty{} - u.contents = &contents - u.selector = TPMCap(hint) - return reflect.ValueOf(&contents), nil - case TPMCapECCCurves: - contents := TPMLECCCurve{} - u.contents = &contents - u.selector = TPMCap(hint) - return reflect.ValueOf(&contents), nil - case TPMCapAuthPolicies: - contents := TPMLTaggedPolicy{} - u.contents = &contents - u.selector = TPMCap(hint) - return reflect.ValueOf(&contents), nil - case TPMCapACT: - contents := TPMLACTData{} - u.contents = &contents - u.selector = TPMCap(hint) - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// get implements the marshallableWithHint interface. -func (u TPMUCapabilities) get(hint int64) (reflect.Value, error) { - if u.selector != 0 && hint != int64(u.selector) { - return reflect.ValueOf(nil), fmt.Errorf("incorrect union tag %v, is %v", hint, u.selector) - } - switch TPMCap(hint) { - case TPMCapAlgs: - contents := TPMLAlgProperty{} - if u.contents != nil { - contents = *u.contents.(*TPMLAlgProperty) - } - return reflect.ValueOf(&contents), nil - case TPMCapHandles: - contents := TPMLHandle{} - if u.contents != nil { - contents = *u.contents.(*TPMLHandle) - } - return reflect.ValueOf(&contents), nil - case TPMCapCommands: - contents := TPMLCCA{} - if u.contents != nil { - contents = *u.contents.(*TPMLCCA) - } - return reflect.ValueOf(&contents), nil - case TPMCapPPCommands, TPMCapAuditCommands: - contents := TPMLCC{} - if u.contents != nil { - contents = *u.contents.(*TPMLCC) - } - return reflect.ValueOf(&contents), nil - case TPMCapPCRs: - contents := TPMLPCRSelection{} - if u.contents != nil { - contents = *u.contents.(*TPMLPCRSelection) - } - return reflect.ValueOf(&contents), nil - case TPMCapTPMProperties: - contents := TPMLTaggedTPMProperty{} - if u.contents != nil { - contents = *u.contents.(*TPMLTaggedTPMProperty) - } - return reflect.ValueOf(&contents), nil - case TPMCapPCRProperties: - contents := TPMLTaggedPCRProperty{} - if u.contents != nil { - contents = *u.contents.(*TPMLTaggedPCRProperty) - } - return reflect.ValueOf(&contents), nil - case TPMCapECCCurves: - contents := TPMLECCCurve{} - if u.contents != nil { - contents = *u.contents.(*TPMLECCCurve) - } - return reflect.ValueOf(&contents), nil - case TPMCapAuthPolicies: - contents := TPMLTaggedPolicy{} - if u.contents != nil { - contents = *u.contents.(*TPMLTaggedPolicy) - } - return reflect.ValueOf(&contents), nil - case TPMCapACT: - contents := TPMLACTData{} - if u.contents != nil { - contents = *u.contents.(*TPMLACTData) - } - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// NewTPMUCapabilities instantiates a TPMUCapabilities with the given contents. -func NewTPMUCapabilities[C CapabilitiesContents](selector TPMCap, contents C) TPMUCapabilities { - return TPMUCapabilities{ - selector: selector, - contents: contents, - } -} - -// Algorithms returns the 'algorithms' member of the union. -func (u *TPMUCapabilities) Algorithms() (*TPMLAlgProperty, error) { - if u.selector == TPMCapAlgs { - return u.contents.(*TPMLAlgProperty), nil - } - return nil, fmt.Errorf("did not contain algorithms (selector value was %v)", u.selector) -} - -// Handles returns the 'handles' member of the union. -func (u *TPMUCapabilities) Handles() (*TPMLHandle, error) { - if u.selector == TPMCapHandles { - return u.contents.(*TPMLHandle), nil - } - return nil, fmt.Errorf("did not contain handles (selector value was %v)", u.selector) -} - -// Command returns the 'command' member of the union. -func (u *TPMUCapabilities) Command() (*TPMLCCA, error) { - if u.selector == TPMCapCommands { - return u.contents.(*TPMLCCA), nil - } - return nil, fmt.Errorf("did not contain command (selector value was %v)", u.selector) -} - -// PPCommands returns the 'ppCommands' member of the union. -func (u *TPMUCapabilities) PPCommands() (*TPMLCC, error) { - if u.selector == TPMCapPPCommands { - return u.contents.(*TPMLCC), nil - } - return nil, fmt.Errorf("did not contain ppCommands (selector value was %v)", u.selector) -} - -// AuditCommands returns the 'auditCommands' member of the union. -func (u *TPMUCapabilities) AuditCommands() (*TPMLCC, error) { - if u.selector == TPMCapAuditCommands { - return u.contents.(*TPMLCC), nil - } - return nil, fmt.Errorf("did not contain auditCommands (selector value was %v)", u.selector) -} - -// AssignedPCR returns the 'assignedPCR' member of the union. -func (u *TPMUCapabilities) AssignedPCR() (*TPMLPCRSelection, error) { - if u.selector == TPMCapPCRs { - return u.contents.(*TPMLPCRSelection), nil - } - return nil, fmt.Errorf("did not contain assignedPCR (selector value was %v)", u.selector) -} - -// TPMProperties returns the 'tpmProperties' member of the union. -func (u *TPMUCapabilities) TPMProperties() (*TPMLTaggedTPMProperty, error) { - if u.selector == TPMCapTPMProperties { - return u.contents.(*TPMLTaggedTPMProperty), nil - } - return nil, fmt.Errorf("did not contain tpmProperties (selector value was %v)", u.selector) -} - -// PCRProperties returns the 'pcrProperties' member of the union. -func (u *TPMUCapabilities) PCRProperties() (*TPMLTaggedPCRProperty, error) { - if u.selector == TPMCapPCRProperties { - return u.contents.(*TPMLTaggedPCRProperty), nil - } - return nil, fmt.Errorf("did not contain pcrProperties (selector value was %v)", u.selector) -} - -// ECCCurves returns the 'eccCurves' member of the union. -func (u *TPMUCapabilities) ECCCurves() (*TPMLECCCurve, error) { - if u.selector == TPMCapECCCurves { - return u.contents.(*TPMLECCCurve), nil - } - return nil, fmt.Errorf("did not contain eccCurves (selector value was %v)", u.selector) -} - -// AuthPolicies returns the 'authPolicies' member of the union. -func (u *TPMUCapabilities) AuthPolicies() (*TPMLTaggedPolicy, error) { - if u.selector == TPMCapAuthPolicies { - return u.contents.(*TPMLTaggedPolicy), nil - } - return nil, fmt.Errorf("did not contain authPolicies (selector value was %v)", u.selector) -} - -// ACTData returns the 'actData' member of the union. -func (u *TPMUCapabilities) ACTData() (*TPMLACTData, error) { - if u.selector == TPMCapAuthPolicies { - return u.contents.(*TPMLACTData), nil - } - return nil, fmt.Errorf("did not contain actData (selector value was %v)", u.selector) -} - -// TPMSCapabilityData represents a TPMS_CAPABILITY_DATA. -// See definition in Part 2: Structures, section 10.10.2. -type TPMSCapabilityData struct { - marshalByReflection - // the capability - Capability TPMCap - // the capability data - Data TPMUCapabilities `gotpm:"tag=Capability"` -} - -// TPMSClockInfo represents a TPMS_CLOCK_INFO. -// See definition in Part 2: Structures, section 10.11.1. -type TPMSClockInfo struct { - marshalByReflection - // time value in milliseconds that advances while the TPM is powered - Clock uint64 - // number of occurrences of TPM Reset since the last TPM2_Clear() - ResetCount uint32 - // number of times that TPM2_Shutdown() or _TPM_Hash_Start have - // occurred since the last TPM Reset or TPM2_Clear(). - RestartCount uint32 - // no value of Clock greater than the current value of Clock has been - // previously reported by the TPM. Set to YES on TPM2_Clear(). - Safe TPMIYesNo -} - -// TPMSTimeInfo represents a TPMS_TIMEzINFO. -// See definition in Part 2: Structures, section 10.11.6. -type TPMSTimeInfo struct { - marshalByReflection - // time in milliseconds since the TIme circuit was last reset - Time uint64 - // a structure containing the clock information - ClockInfo TPMSClockInfo -} - -// TPMSTimeAttestInfo represents a TPMS_TIME_ATTEST_INFO. -// See definition in Part 2: Structures, section 10.12.2. -type TPMSTimeAttestInfo struct { - marshalByReflection - // the Time, Clock, resetCount, restartCount, and Safe indicator - Time TPMSTimeInfo - // a TPM vendor-specific value indicating the version number of the firmware - FirmwareVersion uint64 -} - -// TPMSCertifyInfo represents a TPMS_CERTIFY_INFO. -// See definition in Part 2: Structures, section 10.12.3. -type TPMSCertifyInfo struct { - marshalByReflection - // Name of the certified object - Name TPM2BName - // Qualified Name of the certified object - QualifiedName TPM2BName -} - -// TPMSQuoteInfo represents a TPMS_QUOTE_INFO. -// See definition in Part 2: Structures, section 10.12.4. -type TPMSQuoteInfo struct { - marshalByReflection - // information on algID, PCR selected and digest - PCRSelect TPMLPCRSelection - // digest of the selected PCR using the hash of the signing key - PCRDigest TPM2BDigest -} - -// TPMSCommandAuditInfo represents a TPMS_COMMAND_AUDIT_INFO. -// See definition in Part 2: Structures, section 10.12.5. -type TPMSCommandAuditInfo struct { - marshalByReflection - // the monotonic audit counter - AuditCounter uint64 - // hash algorithm used for the command audit - DigestAlg TPMAlgID - // the current value of the audit digest - AuditDigest TPM2BDigest - // digest of the command codes being audited using digestAlg - CommandDigest TPM2BDigest -} - -// TPMSSessionAuditInfo represents a TPMS_SESSION_AUDIT_INFO. -// See definition in Part 2: Structures, section 10.12.6. -type TPMSSessionAuditInfo struct { - marshalByReflection - // current exclusive status of the session - ExclusiveSession TPMIYesNo - // the current value of the session audit digest - SessionDigest TPM2BDigest -} - -// TPMSCreationInfo represents a TPMS_CREATION_INFO. -// See definition in Part 2: Structures, section 10.12.7. -type TPMSCreationInfo struct { - marshalByReflection - // Name of the object - ObjectName TPM2BName - // creationHash - CreationHash TPM2BDigest -} - -// TPMSNVCertifyInfo represents a TPMS_NV_CERTIFY_INFO. -// See definition in Part 2: Structures, section 10.12.8. -type TPMSNVCertifyInfo struct { - marshalByReflection - // Name of the NV Index - IndexName TPM2BName - // the offset parameter of TPM2_NV_Certify() - Offset uint16 - // contents of the NV Index - NVContents TPM2BData -} - -// TPMSNVDigestCertifyInfo represents a TPMS_NV_DIGEST_CERTIFY_INFO. -// See definition in Part 2: Structures, section 10.12.9. -type TPMSNVDigestCertifyInfo struct { - marshalByReflection - // Name of the NV Index - IndexName TPM2BName - // hash of the contents of the index - NVDigest TPM2BDigest -} - -// TPMISTAttest represents a TPMI_ST_ATTEST. -// See definition in Part 2: Structures, section 10.12.10. -type TPMISTAttest = TPMST - -// TPMUAttest represents a TPMU_ATTEST. -// See definition in Part 2: Structures, section 10.12.11. -type TPMUAttest struct { - selector TPMST - contents Marshallable -} - -// AttestContents is a type constraint representing the possible contents of TPMUAttest. -type AttestContents interface { - Marshallable - *TPMSNVCertifyInfo | *TPMSCommandAuditInfo | *TPMSSessionAuditInfo | *TPMSCertifyInfo | - *TPMSQuoteInfo | *TPMSTimeAttestInfo | *TPMSCreationInfo | *TPMSNVDigestCertifyInfo -} - -// create implements the unmarshallableWithHint interface. -func (u *TPMUAttest) create(hint int64) (reflect.Value, error) { - switch TPMST(hint) { - case TPMSTAttestNV: - contents := TPMSNVCertifyInfo{} - u.contents = &contents - u.selector = TPMST(hint) - return reflect.ValueOf(&contents), nil - case TPMSTAttestCommandAudit: - contents := TPMSCommandAuditInfo{} - u.contents = &contents - u.selector = TPMST(hint) - return reflect.ValueOf(&contents), nil - case TPMSTAttestSessionAudit: - contents := TPMSSessionAuditInfo{} - u.contents = &contents - u.selector = TPMST(hint) - return reflect.ValueOf(&contents), nil - case TPMSTAttestCertify: - contents := TPMSCertifyInfo{} - u.contents = &contents - u.selector = TPMST(hint) - return reflect.ValueOf(&contents), nil - case TPMSTAttestQuote: - contents := TPMSQuoteInfo{} - u.contents = &contents - u.selector = TPMST(hint) - return reflect.ValueOf(&contents), nil - case TPMSTAttestTime: - contents := TPMSTimeAttestInfo{} - u.contents = &contents - u.selector = TPMST(hint) - return reflect.ValueOf(&contents), nil - case TPMSTAttestCreation: - contents := TPMSCreationInfo{} - u.contents = &contents - u.selector = TPMST(hint) - return reflect.ValueOf(&contents), nil - case TPMSTAttestNVDigest: - contents := TPMSNVDigestCertifyInfo{} - u.contents = &contents - u.selector = TPMST(hint) - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// get implements the marshallableWithHint interface. -func (u TPMUAttest) get(hint int64) (reflect.Value, error) { - if u.selector != 0 && hint != int64(u.selector) { - return reflect.ValueOf(nil), fmt.Errorf("incorrect union tag %v, is %v", hint, u.selector) - } - switch TPMST(hint) { - case TPMSTAttestNV: - contents := TPMSNVCertifyInfo{} - if u.contents != nil { - contents = *u.contents.(*TPMSNVCertifyInfo) - } - return reflect.ValueOf(&contents), nil - case TPMSTAttestCommandAudit: - contents := TPMSCommandAuditInfo{} - if u.contents != nil { - contents = *u.contents.(*TPMSCommandAuditInfo) - } - return reflect.ValueOf(&contents), nil - case TPMSTAttestSessionAudit: - contents := TPMSSessionAuditInfo{} - if u.contents != nil { - contents = *u.contents.(*TPMSSessionAuditInfo) - } - return reflect.ValueOf(&contents), nil - case TPMSTAttestCertify: - contents := TPMSCertifyInfo{} - if u.contents != nil { - contents = *u.contents.(*TPMSCertifyInfo) - } - return reflect.ValueOf(&contents), nil - case TPMSTAttestQuote: - contents := TPMSQuoteInfo{} - if u.contents != nil { - contents = *u.contents.(*TPMSQuoteInfo) - } - return reflect.ValueOf(&contents), nil - case TPMSTAttestTime: - contents := TPMSTimeAttestInfo{} - if u.contents != nil { - contents = *u.contents.(*TPMSTimeAttestInfo) - } - return reflect.ValueOf(&contents), nil - case TPMSTAttestCreation: - contents := TPMSCreationInfo{} - if u.contents != nil { - contents = *u.contents.(*TPMSCreationInfo) - } - return reflect.ValueOf(&contents), nil - case TPMSTAttestNVDigest: - contents := TPMSNVDigestCertifyInfo{} - if u.contents != nil { - contents = *u.contents.(*TPMSNVDigestCertifyInfo) - } - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// NewTPMUAttest instantiates a TPMUAttest with the given contents. -func NewTPMUAttest[C AttestContents](selector TPMST, contents C) TPMUAttest { - return TPMUAttest{ - selector: selector, - contents: contents, - } -} - -// Certify returns the 'certify' member of the union. -func (u *TPMUAttest) Certify() (*TPMSCertifyInfo, error) { - if u.selector == TPMSTAttestCertify { - return u.contents.(*TPMSCertifyInfo), nil - } - return nil, fmt.Errorf("did not contain certify (selector value was %v)", u.selector) -} - -// Creation returns the 'creation' member of the union. -func (u *TPMUAttest) Creation() (*TPMSCreationInfo, error) { - if u.selector == TPMSTAttestCreation { - return u.contents.(*TPMSCreationInfo), nil - } - return nil, fmt.Errorf("did not contain creation (selector value was %v)", u.selector) -} - -// Quote returns the 'quote' member of the union. -func (u *TPMUAttest) Quote() (*TPMSQuoteInfo, error) { - if u.selector == TPMSTAttestQuote { - return u.contents.(*TPMSQuoteInfo), nil - } - return nil, fmt.Errorf("did not contain quote (selector value was %v)", u.selector) -} - -// CommandAudit returns the 'commandAudit' member of the union. -func (u *TPMUAttest) CommandAudit() (*TPMSCommandAuditInfo, error) { - if u.selector == TPMSTAttestCommandAudit { - return u.contents.(*TPMSCommandAuditInfo), nil - } - return nil, fmt.Errorf("did not contain commandAudit (selector value was %v)", u.selector) -} - -// SessionAudit returns the 'sessionAudit' member of the union. -func (u *TPMUAttest) SessionAudit() (*TPMSSessionAuditInfo, error) { - if u.selector == TPMSTAttestSessionAudit { - return u.contents.(*TPMSSessionAuditInfo), nil - } - return nil, fmt.Errorf("did not contain sessionAudit (selector value was %v)", u.selector) -} - -// Time returns the 'time' member of the union. -func (u *TPMUAttest) Time() (*TPMSTimeAttestInfo, error) { - if u.selector == TPMSTAttestTime { - return u.contents.(*TPMSTimeAttestInfo), nil - } - return nil, fmt.Errorf("did not contain time (selector value was %v)", u.selector) -} - -// NV returns the 'nv' member of the union. -func (u *TPMUAttest) NV() (*TPMSNVCertifyInfo, error) { - if u.selector == TPMSTAttestNV { - return u.contents.(*TPMSNVCertifyInfo), nil - } - return nil, fmt.Errorf("did not contain nv (selector value was %v)", u.selector) -} - -// NVDigest returns the 'nvDigest' member of the union. -func (u *TPMUAttest) NVDigest() (*TPMSNVDigestCertifyInfo, error) { - if u.selector == TPMSTAttestNVDigest { - return u.contents.(*TPMSNVDigestCertifyInfo), nil - } - return nil, fmt.Errorf("did not contain nvDigest (selector value was %v)", u.selector) -} - -// TPMSAttest represents a TPMS_ATTEST. -// See definition in Part 2: Structures, section 10.12.12. -type TPMSAttest struct { - marshalByReflection - // the indication that this structure was created by a TPM (always TPM_GENERATED_VALUE) - Magic TPMGenerated `gotpm:"check"` - // type of the attestation structure - Type TPMISTAttest - // Qualified Name of the signing key - QualifiedSigner TPM2BName - // external information supplied by caller - ExtraData TPM2BData - // Clock, resetCount, restartCount, and Safe - ClockInfo TPMSClockInfo - // TPM-vendor-specific value identifying the version number of the firmware - FirmwareVersion uint64 - // the type-specific attestation information - Attested TPMUAttest `gotpm:"tag=Type"` -} - -// TPM2BAttest represents a TPM2B_ATTEST. -// See definition in Part 2: Structures, section 10.12.13. -type TPM2BAttest = TPM2B[TPMSAttest, *TPMSAttest] - -// TPMSAuthCommand represents a TPMS_AUTH_COMMAND. -// See definition in Part 2: Structures, section 10.13.2. -type TPMSAuthCommand struct { - marshalByReflection - Handle TPMISHAuthSession - Nonce TPM2BNonce - Attributes TPMASession - Authorization TPM2BData -} - -// TPMSAuthResponse represents a TPMS_AUTH_RESPONSE. -// See definition in Part 2: Structures, section 10.13.3. -type TPMSAuthResponse struct { - marshalByReflection - Nonce TPM2BNonce - Attributes TPMASession - Authorization TPM2BData -} - -// TPMUSymKeyBits represents a TPMU_SYM_KEY_BITS. -// See definition in Part 2: Structures, section 11.1.3. -type TPMUSymKeyBits struct { - selector TPMAlgID - contents Marshallable -} - -// SymKeyBitsContents is a type constraint representing the possible contents of TPMUSymKeyBits. -type SymKeyBitsContents interface { - TPMKeyBits | TPMAlgID -} - -// create implements the unmarshallableWithHint interface. -func (u *TPMUSymKeyBits) create(hint int64) (reflect.Value, error) { - switch TPMAlgID(hint) { - case TPMAlgAES: - var contents boxed[TPMKeyBits] - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgXOR: - var contents boxed[TPMAlgID] - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// get implements the marshallableWithHint interface. -func (u TPMUSymKeyBits) get(hint int64) (reflect.Value, error) { - if u.selector != 0 && hint != int64(u.selector) { - return reflect.ValueOf(nil), fmt.Errorf("incorrect union tag %v, is %v", hint, u.selector) - } - switch TPMAlgID(hint) { - case TPMAlgAES: - var contents boxed[TPMKeyBits] - if u.contents != nil { - contents = *u.contents.(*boxed[TPMKeyBits]) - } - return reflect.ValueOf(&contents), nil - case TPMAlgXOR: - var contents boxed[TPMAlgID] - if u.contents != nil { - contents = *u.contents.(*boxed[TPMAlgID]) - } - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// NewTPMUSymKeyBits instantiates a TPMUSymKeyBits with the given contents. -func NewTPMUSymKeyBits[C SymKeyBitsContents](selector TPMAlgID, contents C) TPMUSymKeyBits { - boxed := box(&contents) - return TPMUSymKeyBits{ - selector: selector, - contents: &boxed, - } -} - -// AES returns the 'aes' member of the union. -func (u *TPMUSymKeyBits) AES() (*TPMKeyBits, error) { - if u.selector == TPMAlgAES { - value := u.contents.(*boxed[TPMKeyBits]).unbox() - return value, nil - } - return nil, fmt.Errorf("did not contain aes (selector value was %v)", u.selector) -} - -// XOR returns the 'xor' member of the union. -func (u *TPMUSymKeyBits) XOR() (*TPMAlgID, error) { - if u.selector == TPMAlgXOR { - value := u.contents.(*boxed[TPMAlgID]).unbox() - return value, nil - } - return nil, fmt.Errorf("did not contain xor (selector value was %v)", u.selector) -} - -// TPMUSymMode represents a TPMU_SYM_MODE. -// See definition in Part 2: Structures, section 11.1.4. -type TPMUSymMode struct { - selector TPMAlgID - contents Marshallable -} - -// SymModeContents is a type constraint representing the possible contents of TPMUSymMode. -type SymModeContents interface { - TPMIAlgSymMode | TPMSEmpty -} - -// create implements the unmarshallableWithHint interface. -func (u *TPMUSymMode) create(hint int64) (reflect.Value, error) { - switch TPMAlgID(hint) { - case TPMAlgAES: - var contents boxed[TPMAlgID] - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgXOR: - var contents boxed[TPMSEmpty] - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// get implements the marshallableWithHint interface. -func (u TPMUSymMode) get(hint int64) (reflect.Value, error) { - if u.selector != 0 && hint != int64(u.selector) { - return reflect.ValueOf(nil), fmt.Errorf("incorrect union tag %v, is %v", hint, u.selector) - } - switch TPMAlgID(hint) { - case TPMAlgAES: - var contents boxed[TPMAlgID] - if u.contents != nil { - contents = *u.contents.(*boxed[TPMAlgID]) - } - return reflect.ValueOf(&contents), nil - case TPMAlgXOR: - var contents boxed[TPMSEmpty] - if u.contents != nil { - contents = *u.contents.(*boxed[TPMSEmpty]) - } - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// NewTPMUSymMode instantiates a TPMUSymMode with the given contents. -func NewTPMUSymMode[C SymModeContents](selector TPMAlgID, contents C) TPMUSymMode { - boxed := box(&contents) - return TPMUSymMode{ - selector: selector, - contents: &boxed, - } -} - -// AES returns the 'aes' member of the union. -func (u *TPMUSymMode) AES() (*TPMIAlgSymMode, error) { - if u.selector == TPMAlgAES { - value := u.contents.(*boxed[TPMIAlgSymMode]).unbox() - return value, nil - } - return nil, fmt.Errorf("did not contain aes (selector value was %v)", u.selector) -} - -// TPMUSymDetails represents a TPMU_SYM_DETAILS. -// See definition in Part 2: Structures, section 11.1.5. -type TPMUSymDetails struct { - selector TPMAlgID - contents Marshallable -} - -// SymDetailsContents is a type constraint representing the possible contents of TPMUSymDetails. -type SymDetailsContents interface { - TPMSEmpty -} - -// create implements the unmarshallableWithHint interface. -func (u *TPMUSymDetails) create(hint int64) (reflect.Value, error) { - switch TPMAlgID(hint) { - case TPMAlgAES: - var contents boxed[TPMSEmpty] - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgXOR: - var contents boxed[TPMSEmpty] - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// get implements the marshallableWithHint interface. -func (u TPMUSymDetails) get(hint int64) (reflect.Value, error) { - if u.selector != 0 && hint != int64(u.selector) { - return reflect.ValueOf(nil), fmt.Errorf("incorrect union tag %v, is %v", hint, u.selector) - } - switch TPMAlgID(hint) { - case TPMAlgAES, TPMAlgXOR: - var contents boxed[TPMSEmpty] - if u.contents != nil { - contents = *u.contents.(*boxed[TPMSEmpty]) - } - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// NewTPMUSymDetails instantiates a TPMUSymDetails with the given contents. -func NewTPMUSymDetails[C SymDetailsContents](selector TPMAlgID, contents C) TPMUSymMode { - boxed := box(&contents) - return TPMUSymMode{ - selector: selector, - contents: &boxed, - } -} - -// TPMTSymDef represents a TPMT_SYM_DEF. -// See definition in Part 2: Structures, section 11.1.6. -type TPMTSymDef struct { - marshalByReflection - // indicates a symmetric algorithm - Algorithm TPMIAlgSym `gotpm:"nullable"` - // the key size - KeyBits TPMUSymKeyBits `gotpm:"tag=Algorithm"` - // the mode for the key - Mode TPMUSymMode `gotpm:"tag=Algorithm"` - // contains the additional algorithm details - Details TPMUSymDetails `gotpm:"tag=Algorithm"` -} - -// TPMTSymDefObject represents a TPMT_SYM_DEF_OBJECT. -// See definition in Part 2: Structures, section 11.1.7. -type TPMTSymDefObject struct { - marshalByReflection - // selects a symmetric block cipher - // When used in the parameter area of a parent object, this shall - // be a supported block cipher and not TPM_ALG_NULL - Algorithm TPMIAlgSymObject `gotpm:"nullable"` - // the key size - KeyBits TPMUSymKeyBits `gotpm:"tag=Algorithm"` - // default mode - // When used in the parameter area of a parent object, this shall - // be TPM_ALG_CFB. - Mode TPMUSymMode `gotpm:"tag=Algorithm"` - // contains the additional algorithm details, if any - Details TPMUSymDetails `gotpm:"tag=Algorithm"` -} - -// TPM2BSymKey represents a TPM2B_SYM_KEY. -// See definition in Part 2: Structures, section 11.1.8. -type TPM2BSymKey TPM2BData - -// TPMSSymCipherParms represents a TPMS_SYMCIPHER_PARMS. -// See definition in Part 2: Structures, section 11.1.9. -type TPMSSymCipherParms struct { - marshalByReflection - // a symmetric block cipher - Sym TPMTSymDefObject -} - -// TPM2BLabel represents a TPM2B_LABEL. -// See definition in Part 2: Structures, section 11.1.10. -type TPM2BLabel TPM2BData - -// TPMSDerive represents a TPMS_DERIVE. -// See definition in Part 2: Structures, section 11.1.11. -type TPMSDerive struct { - marshalByReflection - Label TPM2BLabel - Context TPM2BLabel -} - -// TPM2BDerive represents a TPM2B_DERIVE. -// See definition in Part 2: Structures, section 11.1.12. -type TPM2BDerive = TPM2B[TPMSDerive, *TPMSDerive] - -// TPMUSensitiveCreate represents a TPMU_SENSITIVE_CREATE. -// See definition in Part 2: Structures, section 11.1.13. -type TPMUSensitiveCreate struct { - contents Marshallable -} - -// SensitiveCreateContents is a type constraint representing the possible contents of TPMUSensitiveCreate. -type SensitiveCreateContents interface { - Marshallable - *TPM2BDerive | *TPM2BSensitiveData -} - -// marshal implements the Marshallable interface. -func (u TPMUSensitiveCreate) marshal(buf *bytes.Buffer) { - if u.contents != nil { - buf.Write(Marshal(u.contents)) - } else { - // If this is a zero-valued structure, marshal a default TPM2BSensitiveData. - var defaultValue TPM2BSensitiveData - buf.Write(Marshal(&defaultValue)) - } -} - -// NewTPMUSensitiveCreate instantiates a TPMUSensitiveCreate with the given contents. -func NewTPMUSensitiveCreate[C SensitiveCreateContents](contents C) TPMUSensitiveCreate { - return TPMUSensitiveCreate{contents: contents} -} - -// TPM2BSensitiveData represents a TPM2B_SENSITIVE_DATA. -// See definition in Part 2: Structures, section 11.1.14. -type TPM2BSensitiveData TPM2BData - -// TPMSSensitiveCreate represents a TPMS_SENSITIVE_CREATE. -// See definition in Part 2: Structures, section 11.1.15. -type TPMSSensitiveCreate struct { - marshalByReflection - // the USER auth secret value. - UserAuth TPM2BAuth - // data to be sealed, a key, or derivation values. - Data TPMUSensitiveCreate -} - -// TPM2BSensitiveCreate represents a TPM2B_SENSITIVE_CREATE. -// See definition in Part 2: Structures, section 11.1.16. -// This is a structure instead of an alias to TPM2B[TPMSSensitiveCreate], -// because it has custom marshalling logic for zero-valued parameters. -type TPM2BSensitiveCreate struct { - Sensitive *TPMSSensitiveCreate -} - -// Quirk: When this structure is zero-valued, we need to marshal -// a 2B-wrapped zero-valued TPMS_SENSITIVE_CREATE instead of -// [0x00, 0x00] (a zero-valued 2B). -func (c TPM2BSensitiveCreate) marshal(buf *bytes.Buffer) { - var marshalled TPM2B[TPMSSensitiveCreate, *TPMSSensitiveCreate] - if c.Sensitive != nil { - marshalled = New2B(*c.Sensitive) - } else { - // If no value was provided (i.e., this is a zero-valued structure), - // provide an 2B containing a zero-valued TPMS_SensitiveCreate. - marshalled = New2B(TPMSSensitiveCreate{ - Data: NewTPMUSensitiveCreate(&TPM2BSensitiveData{}), - }) - } - marshalled.marshal(buf) -} - -// TPMSSchemeHash represents a TPMS_SCHEME_HASH. -// See definition in Part 2: Structures, section 11.1.17. -type TPMSSchemeHash struct { - marshalByReflection - // the hash algorithm used to digest the message - HashAlg TPMIAlgHash -} - -// TPMSSchemeECDAA represents a TPMS_SCHEME_ECDAA. -// See definition in Part 2: Structures, section 11.1.18. -type TPMSSchemeECDAA struct { - marshalByReflection - // the hash algorithm used to digest the message - HashAlg TPMIAlgHash - // the counter value that is used between TPM2_Commit() - // and the sign operation - Count uint16 -} - -// TPMIAlgKeyedHashScheme represents a TPMI_ALG_KEYEDHASH_SCHEME. -// See definition in Part 2: Structures, section 11.1.19. -type TPMIAlgKeyedHashScheme = TPMAlgID - -// TPMSSchemeHMAC represents a TPMS_SCHEME_HMAC. -// See definition in Part 2: Structures, section 11.1.20. -type TPMSSchemeHMAC TPMSSchemeHash - -// TPMSSchemeXOR represents a TPMS_SCHEME_XOR. -// See definition in Part 2: Structures, section 11.1.21. -type TPMSSchemeXOR struct { - marshalByReflection - // the hash algorithm used to digest the message - HashAlg TPMIAlgHash - // the key derivation function - KDF TPMIAlgKDF -} - -// TPMUSchemeKeyedHash represents a TPMU_SCHEME_KEYEDHASH. -// See definition in Part 2: Structures, section 11.1.22. -type TPMUSchemeKeyedHash struct { - selector TPMAlgID - contents Marshallable -} - -// SchemeKeyedHashContents is a type constraint representing the possible contents of TPMUSchemeKeyedHash. -type SchemeKeyedHashContents interface { - Marshallable - *TPMSSchemeHMAC | *TPMSSchemeXOR -} - -// create implements the unmarshallableWithHint interface. -func (u *TPMUSchemeKeyedHash) create(hint int64) (reflect.Value, error) { - switch TPMAlgID(hint) { - case TPMAlgHMAC: - var contents TPMSSchemeHMAC - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgXOR: - var contents TPMSSchemeXOR - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// get implements the marshallableWithHint interface. -func (u TPMUSchemeKeyedHash) get(hint int64) (reflect.Value, error) { - if u.selector != 0 && hint != int64(u.selector) { - return reflect.ValueOf(nil), fmt.Errorf("incorrect union tag %v, is %v", hint, u.selector) - } - switch TPMAlgID(hint) { - case TPMAlgHMAC: - var contents TPMSSchemeHMAC - if u.contents != nil { - contents = *u.contents.(*TPMSSchemeHMAC) - } - return reflect.ValueOf(&contents), nil - case TPMAlgXOR: - var contents TPMSSchemeXOR - if u.contents != nil { - contents = *u.contents.(*TPMSSchemeXOR) - } - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// NewTPMUSchemeKeyedHash instantiates a TPMUSchemeKeyedHash with the given contents. -func NewTPMUSchemeKeyedHash[C SchemeKeyedHashContents](selector TPMAlgID, contents C) TPMUSchemeKeyedHash { - return TPMUSchemeKeyedHash{ - selector: selector, - contents: contents, - } -} - -// HMAC returns the 'hmac' member of the union. -func (u *TPMUSchemeKeyedHash) HMAC() (*TPMSSchemeHMAC, error) { - if u.selector == TPMAlgHMAC { - value := u.contents.(*TPMSSchemeHMAC) - return value, nil - } - return nil, fmt.Errorf("did not contain hmac (selector value was %v)", u.selector) -} - -// XOR returns the 'xor' member of the union. -func (u *TPMUSchemeKeyedHash) XOR() (*TPMSSchemeXOR, error) { - if u.selector == TPMAlgXOR { - value := u.contents.(*TPMSSchemeXOR) - return value, nil - } - return nil, fmt.Errorf("did not contain xor (selector value was %v)", u.selector) -} - -// TPMTKeyedHashScheme represents a TPMT_KEYEDHASH_SCHEME. -// See definition in Part 2: Structures, section 11.1.23. -type TPMTKeyedHashScheme struct { - marshalByReflection - Scheme TPMIAlgKeyedHashScheme `gotpm:"nullable"` - Details TPMUSchemeKeyedHash `gotpm:"tag=Scheme"` -} - -// TPMSSigSchemeRSASSA represents a TPMS_SIG_SCHEME_RSASSA. -// See definition in Part 2: Structures, section 11.2.1.2. -type TPMSSigSchemeRSASSA TPMSSchemeHash - -// TPMSSigSchemeRSAPSS represents a TPMS_SIG_SCHEME_RSAPSS. -// See definition in Part 2: Structures, section 11.2.1.2. -type TPMSSigSchemeRSAPSS TPMSSchemeHash - -// TPMSSigSchemeECDSA represents a TPMS_SIG_SCHEME_ECDSA. -// See definition in Part 2: Structures, section 11.2.1.3. -type TPMSSigSchemeECDSA TPMSSchemeHash - -// TPMUSigScheme represents a TPMU_SIG_SCHEME. -// See definition in Part 2: Structures, section 11.2.1.4. -type TPMUSigScheme struct { - selector TPMAlgID - contents Marshallable -} - -// SigSchemeContents is a type constraint representing the possible contents of TPMUSigScheme. -type SigSchemeContents interface { - Marshallable - *TPMSSchemeHMAC | *TPMSSchemeHash | *TPMSSchemeECDAA -} - -// create implements the unmarshallableWithHint interface. -func (u *TPMUSigScheme) create(hint int64) (reflect.Value, error) { - switch TPMAlgID(hint) { - case TPMAlgHMAC: - var contents TPMSSchemeHMAC - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgRSASSA, TPMAlgRSAPSS, TPMAlgECDSA: - var contents TPMSSchemeHash - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgECDAA: - var contents TPMSSchemeECDAA - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// get implements the marshallableWithHint interface. -func (u TPMUSigScheme) get(hint int64) (reflect.Value, error) { - if u.selector != 0 && hint != int64(u.selector) { - return reflect.ValueOf(nil), fmt.Errorf("incorrect union tag %v, is %v", hint, u.selector) - } - switch TPMAlgID(hint) { - case TPMAlgHMAC: - var contents TPMSSchemeHMAC - if u.contents != nil { - contents = *u.contents.(*TPMSSchemeHMAC) - } - return reflect.ValueOf(&contents), nil - case TPMAlgRSASSA, TPMAlgRSAPSS, TPMAlgECDSA: - var contents TPMSSchemeHash - if u.contents != nil { - contents = *u.contents.(*TPMSSchemeHash) - } - return reflect.ValueOf(&contents), nil - case TPMAlgECDAA: - var contents TPMSSchemeECDAA - if u.contents != nil { - contents = *u.contents.(*TPMSSchemeECDAA) - } - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// NewTPMUSigScheme instantiates a TPMUSigScheme with the given contents. -func NewTPMUSigScheme[C SigSchemeContents](selector TPMAlgID, contents C) TPMUSigScheme { - return TPMUSigScheme{ - selector: selector, - contents: contents, - } -} - -// HMAC returns the 'hmac' member of the union. -func (u *TPMUSigScheme) HMAC() (*TPMSSchemeHMAC, error) { - if u.selector == TPMAlgHMAC { - return u.contents.(*TPMSSchemeHMAC), nil - } - return nil, fmt.Errorf("did not contain hmac (selector value was %v)", u.selector) -} - -// RSASSA returns the 'rsassa' member of the union. -func (u *TPMUSigScheme) RSASSA() (*TPMSSchemeHash, error) { - if u.selector == TPMAlgRSASSA { - return u.contents.(*TPMSSchemeHash), nil - } - return nil, fmt.Errorf("did not contain rsassa (selector value was %v)", u.selector) -} - -// RSAPSS returns the 'rsapss' member of the union. -func (u *TPMUSigScheme) RSAPSS() (*TPMSSchemeHash, error) { - if u.selector == TPMAlgRSAPSS { - return u.contents.(*TPMSSchemeHash), nil - } - return nil, fmt.Errorf("did not contain rsapss (selector value was %v)", u.selector) -} - -// ECDSA returns the 'ecdsa' member of the union. -func (u *TPMUSigScheme) ECDSA() (*TPMSSchemeHash, error) { - if u.selector == TPMAlgECDSA { - return u.contents.(*TPMSSchemeHash), nil - } - return nil, fmt.Errorf("did not contain ecdsa (selector value was %v)", u.selector) -} - -// ECDAA returns the 'ecdaa' member of the union. -func (u *TPMUSigScheme) ECDAA() (*TPMSSchemeECDAA, error) { - if u.selector == TPMAlgECDAA { - return u.contents.(*TPMSSchemeECDAA), nil - } - return nil, fmt.Errorf("did not contain ecdaa (selector value was %v)", u.selector) -} - -// TPMTSigScheme represents a TPMT_SIG_SCHEME. -// See definition in Part 2: Structures, section 11.2.1.5. -type TPMTSigScheme struct { - marshalByReflection - Scheme TPMIAlgSigScheme `gotpm:"nullable"` - Details TPMUSigScheme `gotpm:"tag=Scheme"` -} - -// TPMSEncSchemeRSAES represents a TPMS_ENC_SCHEME_RSAES. -// See definition in Part 2: Structures, section 11.2.2.2. -type TPMSEncSchemeRSAES TPMSEmpty - -// TPMSEncSchemeOAEP represents a TPMS_ENC_SCHEME_OAEP. -// See definition in Part 2: Structures, section 11.2.2.2. -type TPMSEncSchemeOAEP TPMSSchemeHash - -// TPMSKeySchemeECDH represents a TPMS_KEY_SCHEME_ECDH. -// See definition in Part 2: Structures, section 11.2.2.3. -type TPMSKeySchemeECDH TPMSSchemeHash - -// TPMSKDFSchemeMGF1 represents a TPMS_KDF_SCHEME_MGF1. -// See definition in Part 2: Structures, section 11.2.3.1. -type TPMSKDFSchemeMGF1 TPMSSchemeHash - -// TPMSKDFSchemeECDH represents a TPMS_KDF_SCHEME_ECDH. -// See definition in Part 2: Structures, section 11.2.3.1. -type TPMSKDFSchemeECDH TPMSSchemeHash - -// TPMSKDFSchemeKDF1SP80056A represents a TPMS_KDF_SCHEME_KDF1SP80056A. -// See definition in Part 2: Structures, section 11.2.3.1. -type TPMSKDFSchemeKDF1SP80056A TPMSSchemeHash - -// TPMSKDFSchemeKDF2 represents a TPMS_KDF_SCHEME_KDF2. -// See definition in Part 2: Structures, section 11.2.3.1. -type TPMSKDFSchemeKDF2 TPMSSchemeHash - -// TPMSKDFSchemeKDF1SP800108 represents a TPMS_KDF_SCHEME_KDF1SP800108. -// See definition in Part 2: Structures, section 11.2.3.1. -type TPMSKDFSchemeKDF1SP800108 TPMSSchemeHash - -// TPMUKDFScheme represents a TPMU_KDF_SCHEME. -// See definition in Part 2: Structures, section 11.2.3.2. -type TPMUKDFScheme struct { - selector TPMAlgID - contents Marshallable -} - -// KDFSchemeContents is a type constraint representing the possible contents of TPMUKDFScheme. -type KDFSchemeContents interface { - Marshallable - *TPMSKDFSchemeMGF1 | *TPMSKDFSchemeECDH | *TPMSKDFSchemeKDF1SP80056A | - *TPMSKDFSchemeKDF2 | *TPMSKDFSchemeKDF1SP800108 -} - -// create implements the unmarshallableWithHint interface. -func (u *TPMUKDFScheme) create(hint int64) (reflect.Value, error) { - switch TPMAlgID(hint) { - case TPMAlgMGF1: - var contents TPMSKDFSchemeMGF1 - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgECDH: - var contents TPMSKDFSchemeECDH - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgKDF1SP80056A: - var contents TPMSKDFSchemeKDF1SP80056A - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgKDF2: - var contents TPMSKDFSchemeKDF2 - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgKDF1SP800108: - var contents TPMSKDFSchemeKDF1SP800108 - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// get implements the marshallableWithHint interface. -func (u TPMUKDFScheme) get(hint int64) (reflect.Value, error) { - if u.selector != 0 && hint != int64(u.selector) { - return reflect.ValueOf(nil), fmt.Errorf("incorrect union tag %v, is %v", hint, u.selector) - } - switch TPMAlgID(hint) { - case TPMAlgMGF1: - var contents TPMSKDFSchemeMGF1 - if u.contents != nil { - contents = *u.contents.(*TPMSKDFSchemeMGF1) - } - return reflect.ValueOf(&contents), nil - case TPMAlgECDH: - var contents TPMSKDFSchemeECDH - if u.contents != nil { - contents = *u.contents.(*TPMSKDFSchemeECDH) - } - return reflect.ValueOf(&contents), nil - case TPMAlgKDF1SP80056A: - var contents TPMSKDFSchemeKDF1SP80056A - if u.contents != nil { - contents = *u.contents.(*TPMSKDFSchemeKDF1SP80056A) - } - return reflect.ValueOf(&contents), nil - case TPMAlgKDF2: - var contents TPMSKDFSchemeKDF2 - if u.contents != nil { - contents = *u.contents.(*TPMSKDFSchemeKDF2) - } - return reflect.ValueOf(&contents), nil - - case TPMAlgKDF1SP800108: - var contents TPMSKDFSchemeKDF1SP800108 - if u.contents != nil { - contents = *u.contents.(*TPMSKDFSchemeKDF1SP800108) - } - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// NewTPMUKDFScheme instantiates a TPMUKDFScheme with the given contents. -func NewTPMUKDFScheme[C KDFSchemeContents](selector TPMAlgID, contents C) TPMUKDFScheme { - return TPMUKDFScheme{ - selector: selector, - contents: contents, - } -} - -// MGF1 returns the 'mgf1' member of the union. -func (u *TPMUKDFScheme) MGF1() (*TPMSKDFSchemeMGF1, error) { - if u.selector == TPMAlgMGF1 { - return u.contents.(*TPMSKDFSchemeMGF1), nil - } - return nil, fmt.Errorf("did not contain mgf1 (selector value was %v)", u.selector) -} - -// ECDH returns the 'ecdh' member of the union. -func (u *TPMUKDFScheme) ECDH() (*TPMSKDFSchemeECDH, error) { - if u.selector == TPMAlgECDH { - return u.contents.(*TPMSKDFSchemeECDH), nil - } - return nil, fmt.Errorf("did not contain ecdh (selector value was %v)", u.selector) -} - -// KDF1SP80056A returns the 'kdf1sp80056a' member of the union. -func (u *TPMUKDFScheme) KDF1SP80056A() (*TPMSKDFSchemeKDF1SP80056A, error) { - if u.selector == TPMAlgMGF1 { - return u.contents.(*TPMSKDFSchemeKDF1SP80056A), nil - } - return nil, fmt.Errorf("did not contain kdf1sp80056a (selector value was %v)", u.selector) -} - -// KDF2 returns the 'kdf2' member of the union. -func (u *TPMUKDFScheme) KDF2() (*TPMSKDFSchemeKDF2, error) { - if u.selector == TPMAlgMGF1 { - return u.contents.(*TPMSKDFSchemeKDF2), nil - } - return nil, fmt.Errorf("did not contain mgf1 (selector value was %v)", u.selector) -} - -// KDF1SP800108 returns the 'kdf1sp800108' member of the union. -func (u *TPMUKDFScheme) KDF1SP800108() (*TPMSKDFSchemeKDF1SP800108, error) { - if u.selector == TPMAlgMGF1 { - return u.contents.(*TPMSKDFSchemeKDF1SP800108), nil - } - return nil, fmt.Errorf("did not contain kdf1sp800108 (selector value was %v)", u.selector) -} - -// TPMTKDFScheme represents a TPMT_KDF_SCHEME. -// See definition in Part 2: Structures, section 11.2.3.3. -type TPMTKDFScheme struct { - marshalByReflection - // scheme selector - Scheme TPMIAlgKDF `gotpm:"nullable"` - // scheme parameters - Details TPMUKDFScheme `gotpm:"tag=Scheme"` -} - -// TPMUAsymScheme represents a TPMU_ASYM_SCHEME. -// See definition in Part 2: Structures, section 11.2.3.5. -type TPMUAsymScheme struct { - selector TPMAlgID - contents Marshallable -} - -// AsymSchemeContents is a type constraint representing the possible contents of TPMUAsymScheme. -type AsymSchemeContents interface { - Marshallable - *TPMSSigSchemeRSASSA | *TPMSEncSchemeRSAES | *TPMSSigSchemeRSAPSS | *TPMSEncSchemeOAEP | - *TPMSSigSchemeECDSA | *TPMSKeySchemeECDH | *TPMSSchemeECDAA -} - -// create implements the unmarshallableWithHint interface. -func (u *TPMUAsymScheme) create(hint int64) (reflect.Value, error) { - switch TPMAlgID(hint) { - case TPMAlgRSASSA: - var contents TPMSSigSchemeRSASSA - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgRSAES: - var contents TPMSEncSchemeRSAES - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgRSAPSS: - var contents TPMSSigSchemeRSAPSS - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgOAEP: - var contents TPMSEncSchemeOAEP - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgECDSA: - var contents TPMSSigSchemeECDSA - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgECDH: - var contents TPMSKeySchemeECDH - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgECDAA: - var contents TPMSSchemeECDAA - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// get implements the marshallableWithHint interface. -func (u TPMUAsymScheme) get(hint int64) (reflect.Value, error) { - if u.selector != 0 && hint != int64(u.selector) { - return reflect.ValueOf(nil), fmt.Errorf("incorrect union tag %v, is %v", hint, u.selector) - } - switch TPMAlgID(hint) { - case TPMAlgRSASSA: - var contents TPMSSigSchemeRSASSA - if u.contents != nil { - contents = *u.contents.(*TPMSSigSchemeRSASSA) - } - return reflect.ValueOf(&contents), nil - case TPMAlgRSAES: - var contents TPMSEncSchemeRSAES - if u.contents != nil { - contents = *u.contents.(*TPMSEncSchemeRSAES) - } - return reflect.ValueOf(&contents), nil - case TPMAlgRSAPSS: - var contents TPMSSigSchemeRSAPSS - if u.contents != nil { - contents = *u.contents.(*TPMSSigSchemeRSAPSS) - } - return reflect.ValueOf(&contents), nil - case TPMAlgOAEP: - var contents TPMSEncSchemeOAEP - if u.contents != nil { - contents = *u.contents.(*TPMSEncSchemeOAEP) - } - return reflect.ValueOf(&contents), nil - case TPMAlgECDSA: - var contents TPMSSigSchemeECDSA - if u.contents != nil { - contents = *u.contents.(*TPMSSigSchemeECDSA) - } - return reflect.ValueOf(&contents), nil - case TPMAlgECDH: - var contents TPMSKeySchemeECDH - if u.contents != nil { - contents = *u.contents.(*TPMSKeySchemeECDH) - } - return reflect.ValueOf(&contents), nil - case TPMAlgECDAA: - var contents TPMSSchemeECDAA - if u.contents != nil { - contents = *u.contents.(*TPMSSchemeECDAA) - } - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// NewTPMUAsymScheme instantiates a TPMUAsymScheme with the given contents. -func NewTPMUAsymScheme[C AsymSchemeContents](selector TPMAlgID, contents C) TPMUAsymScheme { - return TPMUAsymScheme{ - selector: selector, - contents: contents, - } -} - -// RSASSA returns the 'rsassa' member of the union. -func (u *TPMUAsymScheme) RSASSA() (*TPMSSigSchemeRSASSA, error) { - if u.selector == TPMAlgRSASSA { - return u.contents.(*TPMSSigSchemeRSASSA), nil - } - return nil, fmt.Errorf("did not contain rsassa (selector value was %v)", u.selector) -} - -// RSAES returns the 'rsaes' member of the union. -func (u *TPMUAsymScheme) RSAES() (*TPMSEncSchemeRSAES, error) { - if u.selector == TPMAlgRSAES { - return u.contents.(*TPMSEncSchemeRSAES), nil - } - return nil, fmt.Errorf("did not contain rsaes (selector value was %v)", u.selector) -} - -// RSAPSS returns the 'rsapss' member of the union. -func (u *TPMUAsymScheme) RSAPSS() (*TPMSSigSchemeRSAPSS, error) { - if u.selector == TPMAlgRSAPSS { - return u.contents.(*TPMSSigSchemeRSAPSS), nil - } - return nil, fmt.Errorf("did not contain rsapss (selector value was %v)", u.selector) -} - -// OAEP returns the 'oaep' member of the union. -func (u *TPMUAsymScheme) OAEP() (*TPMSEncSchemeOAEP, error) { - if u.selector == TPMAlgOAEP { - return u.contents.(*TPMSEncSchemeOAEP), nil - } - return nil, fmt.Errorf("did not contain oaep (selector value was %v)", u.selector) -} - -// ECDSA returns the 'ecdsa' member of the union. -func (u *TPMUAsymScheme) ECDSA() (*TPMSSigSchemeECDSA, error) { - if u.selector == TPMAlgECDSA { - return u.contents.(*TPMSSigSchemeECDSA), nil - } - return nil, fmt.Errorf("did not contain rsassa (selector value was %v)", u.selector) -} - -// ECDH returns the 'ecdh' member of the union. -func (u *TPMUAsymScheme) ECDH() (*TPMSKeySchemeECDH, error) { - if u.selector == TPMAlgRSASSA { - return u.contents.(*TPMSKeySchemeECDH), nil - } - return nil, fmt.Errorf("did not contain ecdh (selector value was %v)", u.selector) -} - -// ECDAA returns the 'ecdaa' member of the union. -func (u *TPMUAsymScheme) ECDAA() (*TPMSSchemeECDAA, error) { - if u.selector == TPMAlgECDAA { - return u.contents.(*TPMSSchemeECDAA), nil - } - return nil, fmt.Errorf("did not contain rsassa (selector value was %v)", u.selector) -} - -// TPMIAlgRSAScheme represents a TPMI_ALG_RSA_SCHEME. -// See definition in Part 2: Structures, section 11.2.4.1. -type TPMIAlgRSAScheme = TPMAlgID - -// TPMTRSAScheme represents a TPMT_RSA_SCHEME. -// See definition in Part 2: Structures, section 11.2.4.2. -type TPMTRSAScheme struct { - marshalByReflection - // scheme selector - Scheme TPMIAlgRSAScheme `gotpm:"nullable"` - // scheme parameters - Details TPMUAsymScheme `gotpm:"tag=Scheme"` -} - -// TPM2BPublicKeyRSA represents a TPM2B_PUBLIC_KEY_RSA. -// See definition in Part 2: Structures, section 11.2.4.5. -type TPM2BPublicKeyRSA TPM2BData - -// TPMIRSAKeyBits represents a TPMI_RSA_KEY_BITS. -// See definition in Part 2: Structures, section 11.2.4.6. -type TPMIRSAKeyBits = TPMKeyBits - -// TPM2BPrivateKeyRSA representsa a TPM2B_PRIVATE_KEY_RSA. -// See definition in Part 2: Structures, section 11.2.4.7. -type TPM2BPrivateKeyRSA TPM2BData - -// TPM2BECCParameter represents a TPM2B_ECC_PARAMETER. -// See definition in Part 2: Structures, section 11.2.5.1. -type TPM2BECCParameter TPM2BData - -// TPMSECCPoint represents a TPMS_ECC_POINT. -// See definition in Part 2: Structures, section 11.2.5.2. -type TPMSECCPoint struct { - marshalByReflection - // X coordinate - X TPM2BECCParameter - // Y coordinate - Y TPM2BECCParameter -} - -// TPM2BECCPoint represents a TPM2B_ECC_POINT. -// See definition in Part 2: Structures, section 11.2.5.3. -type TPM2BECCPoint = TPM2B[TPMSECCPoint, *TPMSECCPoint] - -// TPMIAlgECCScheme represents a TPMI_ALG_ECC_SCHEME. -// See definition in Part 2: Structures, section 11.2.5.4. -type TPMIAlgECCScheme = TPMAlgID - -// TPMIECCCurve represents a TPMI_ECC_CURVE. -// See definition in Part 2: Structures, section 11.2.5.5. -type TPMIECCCurve = TPMECCCurve - -// TPMTECCScheme represents a TPMT_ECC_SCHEME. -// See definition in Part 2: Structures, section 11.2.5.6. -type TPMTECCScheme struct { - marshalByReflection - // scheme selector - Scheme TPMIAlgECCScheme `gotpm:"nullable"` - // scheme parameters - Details TPMUAsymScheme `gotpm:"tag=Scheme"` -} - -// TPMSSignatureRSA represents a TPMS_SIGNATURE_RSA. -// See definition in Part 2: Structures, section 11.3.1. -type TPMSSignatureRSA struct { - marshalByReflection - // the hash algorithm used to digest the message - Hash TPMIAlgHash - // The signature is the size of a public key. - Sig TPM2BPublicKeyRSA -} - -// TPMSSignatureECC represents a TPMS_SIGNATURE_ECC. -// See definition in Part 2: Structures, section 11.3.2. -type TPMSSignatureECC struct { - marshalByReflection - // the hash algorithm used in the signature process - Hash TPMIAlgHash - SignatureR TPM2BECCParameter - SignatureS TPM2BECCParameter -} - -// TPMUSignature represents a TPMU_SIGNATURE. -// See definition in Part 2: Structures, section 11.3.3. -type TPMUSignature struct { - selector TPMAlgID - contents Marshallable -} - -// SignatureContents is a type constraint representing the possible contents of TPMUSignature. -type SignatureContents interface { - Marshallable - *TPMTHA | *TPMSSignatureRSA | *TPMSSignatureECC -} - -// create implements the unmarshallableWithHint interface. -func (u *TPMUSignature) create(hint int64) (reflect.Value, error) { - switch TPMAlgID(hint) { - case TPMAlgHMAC: - var contents TPMTHA - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgRSASSA, TPMAlgRSAPSS: - var contents TPMSSignatureRSA - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgECDSA, TPMAlgECDAA: - var contents TPMSSignatureECC - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// get implements the marshallableWithHint interface. -func (u TPMUSignature) get(hint int64) (reflect.Value, error) { - if u.selector != 0 && hint != int64(u.selector) { - return reflect.ValueOf(nil), fmt.Errorf("incorrect union tag %v, is %v", hint, u.selector) - } - switch TPMAlgID(hint) { - case TPMAlgHMAC: - var contents TPMTHA - if u.contents != nil { - contents = *u.contents.(*TPMTHA) - } - return reflect.ValueOf(&contents), nil - case TPMAlgRSASSA, TPMAlgRSAPSS: - var contents TPMSSignatureRSA - if u.contents != nil { - contents = *u.contents.(*TPMSSignatureRSA) - } - return reflect.ValueOf(&contents), nil - case TPMAlgECDSA, TPMAlgECDAA: - var contents TPMSSignatureECC - if u.contents != nil { - contents = *u.contents.(*TPMSSignatureECC) - } - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// NewTPMUSignature instantiates a TPMUSignature with the given contents. -func NewTPMUSignature[C SignatureContents](selector TPMAlgID, contents C) TPMUSignature { - return TPMUSignature{ - selector: selector, - contents: contents, - } -} - -// HMAC returns the 'hmac' member of the union. -func (u *TPMUSignature) HMAC() (*TPMTHA, error) { - if u.selector == TPMAlgHMAC { - return u.contents.(*TPMTHA), nil - } - return nil, fmt.Errorf("did not contain hmac (selector value was %v)", u.selector) -} - -// RSASSA returns the 'rsassa' member of the union. -func (u *TPMUSignature) RSASSA() (*TPMSSignatureRSA, error) { - if u.selector == TPMAlgRSASSA { - return u.contents.(*TPMSSignatureRSA), nil - } - return nil, fmt.Errorf("did not contain rsassa (selector value was %v)", u.selector) -} - -// RSAPSS returns the 'rsapss' member of the union. -func (u *TPMUSignature) RSAPSS() (*TPMSSignatureRSA, error) { - if u.selector == TPMAlgRSAPSS { - return u.contents.(*TPMSSignatureRSA), nil - } - return nil, fmt.Errorf("did not contain rsapss (selector value was %v)", u.selector) -} - -// ECDSA returns the 'ecdsa' member of the union. -func (u *TPMUSignature) ECDSA() (*TPMSSignatureECC, error) { - if u.selector == TPMAlgECDSA { - return u.contents.(*TPMSSignatureECC), nil - } - return nil, fmt.Errorf("did not contain ecdsa (selector value was %v)", u.selector) -} - -// ECDAA returns the 'ecdaa' member of the union. -func (u *TPMUSignature) ECDAA() (*TPMSSignatureECC, error) { - if u.selector == TPMAlgRSASSA { - return u.contents.(*TPMSSignatureECC), nil - } - return nil, fmt.Errorf("did not contain ecdaa (selector value was %v)", u.selector) -} - -// TPMTSignature represents a TPMT_SIGNATURE. -// See definition in Part 2: Structures, section 11.3.4. -type TPMTSignature struct { - marshalByReflection - // selector of the algorithm used to construct the signature - SigAlg TPMIAlgSigScheme `gotpm:"nullable"` - // This shall be the actual signature information. - Signature TPMUSignature `gotpm:"tag=SigAlg"` -} - -// TPM2BEncryptedSecret represents a TPM2B_ENCRYPTED_SECRET. -// See definition in Part 2: Structures, section 11.4.33. -type TPM2BEncryptedSecret TPM2BData - -// TPMIAlgPublic represents a TPMI_ALG_PUBLIC. -// See definition in Part 2: Structures, section 12.2.2. -type TPMIAlgPublic = TPMAlgID - -// TPMUPublicID represents a TPMU_PUBLIC_ID. -// See definition in Part 2: Structures, section 12.2.3.2. -type TPMUPublicID struct { - selector TPMAlgID - contents Marshallable -} - -// PublicIDContents is a type constraint representing the possible contents of TPMUPublicID. -type PublicIDContents interface { - Marshallable - *TPM2BDigest | *TPM2BPublicKeyRSA | *TPMSECCPoint -} - -// create implements the unmarshallableWithHint interface. -func (u *TPMUPublicID) create(hint int64) (reflect.Value, error) { - switch TPMAlgID(hint) { - case TPMAlgKeyedHash: - var contents TPM2BDigest - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgSymCipher: - var contents TPM2BDigest - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgRSA: - var contents TPM2BPublicKeyRSA - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgECC: - var contents TPMSECCPoint - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// get implements the marshallableWithHint interface. -func (u TPMUPublicID) get(hint int64) (reflect.Value, error) { - if u.selector != 0 && hint != int64(u.selector) { - return reflect.ValueOf(nil), fmt.Errorf("incorrect union tag %v, is %v", hint, u.selector) - } - switch TPMAlgID(hint) { - case TPMAlgKeyedHash: - var contents TPM2BDigest - if u.contents != nil { - contents = *u.contents.(*TPM2BDigest) - } - return reflect.ValueOf(&contents), nil - case TPMAlgSymCipher: - var contents TPM2BDigest - if u.contents != nil { - contents = *u.contents.(*TPM2BDigest) - } - return reflect.ValueOf(&contents), nil - case TPMAlgRSA: - var contents TPM2BPublicKeyRSA - if u.contents != nil { - contents = *u.contents.(*TPM2BPublicKeyRSA) - } - return reflect.ValueOf(&contents), nil - case TPMAlgECC: - var contents TPMSECCPoint - if u.contents != nil { - contents = *u.contents.(*TPMSECCPoint) - } - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// NewTPMUPublicID instantiates a TPMUPublicID with the given contents. -func NewTPMUPublicID[C PublicIDContents](selector TPMAlgID, contents C) TPMUPublicID { - return TPMUPublicID{ - selector: selector, - contents: contents, - } -} - -// KeyedHash returns the 'keyedHash' member of the union. -func (u *TPMUPublicID) KeyedHash() (*TPM2BDigest, error) { - if u.selector == TPMAlgKeyedHash { - return u.contents.(*TPM2BDigest), nil - } - return nil, fmt.Errorf("did not contain keyedHash (selector value was %v)", u.selector) -} - -// SymCipher returns the 'symCipher' member of the union. -func (u *TPMUPublicID) SymCipher() (*TPM2BDigest, error) { - if u.selector == TPMAlgSymCipher { - return u.contents.(*TPM2BDigest), nil - } - return nil, fmt.Errorf("did not contain symCipher (selector value was %v)", u.selector) -} - -// RSA returns the 'rsa' member of the union. -func (u *TPMUPublicID) RSA() (*TPM2BPublicKeyRSA, error) { - if u.selector == TPMAlgRSA { - return u.contents.(*TPM2BPublicKeyRSA), nil - } - return nil, fmt.Errorf("did not contain rsa (selector value was %v)", u.selector) -} - -// ECC returns the 'ecc' member of the union. -func (u *TPMUPublicID) ECC() (*TPMSECCPoint, error) { - if u.selector == TPMAlgECC { - return u.contents.(*TPMSECCPoint), nil - } - return nil, fmt.Errorf("did not contain ecc (selector value was %v)", u.selector) -} - -// TPMSKeyedHashParms represents a TPMS_KEYEDHASH_PARMS. -// See definition in Part 2: Structures, section 12.2.3.3. -type TPMSKeyedHashParms struct { - marshalByReflection - // Indicates the signing method used for a keyedHash signing - // object. This field also determines the size of the data field - // for a data object created with TPM2_Create() or - // TPM2_CreatePrimary(). - Scheme TPMTKeyedHashScheme -} - -// TPMSRSAParms represents a TPMS_RSA_PARMS. -// See definition in Part 2: Structures, section 12.2.3.5. -type TPMSRSAParms struct { - marshalByReflection - // for a restricted decryption key, shall be set to a supported - // symmetric algorithm, key size, and mode. - // if the key is not a restricted decryption key, this field shall - // be set to TPM_ALG_NULL. - Symmetric TPMTSymDefObject - // scheme.scheme shall be: - // for an unrestricted signing key, either TPM_ALG_RSAPSS - // TPM_ALG_RSASSA or TPM_ALG_NULL - // for a restricted signing key, either TPM_ALG_RSAPSS or - // TPM_ALG_RSASSA - // for an unrestricted decryption key, TPM_ALG_RSAES, TPM_ALG_OAEP, - // or TPM_ALG_NULL unless the object also has the sign attribute - // for a restricted decryption key, TPM_ALG_NULL - Scheme TPMTRSAScheme - // number of bits in the public modulus - KeyBits TPMIRSAKeyBits - // the public exponent - // A prime number greater than 2. - Exponent uint32 -} - -// TPMSECCParms represents a TPMS_ECC_PARMS. -// See definition in Part 2: Structures, section 12.2.3.6. -type TPMSECCParms struct { - marshalByReflection - // for a restricted decryption key, shall be set to a supported - // symmetric algorithm, key size. and mode. - // if the key is not a restricted decryption key, this field shall - // be set to TPM_ALG_NULL. - Symmetric TPMTSymDefObject - // If the sign attribute of the key is SET, then this shall be a - // valid signing scheme. - Scheme TPMTECCScheme - // ECC curve ID - CurveID TPMIECCCurve - // an optional key derivation scheme for generating a symmetric key - // from a Z value - // If the kdf parameter associated with curveID is not TPM_ALG_NULL - // then this is required to be NULL. - KDF TPMTKDFScheme -} - -// TPMUPublicParms represents a TPMU_PUBLIC_PARMS. -// See definition in Part 2: Structures, section 12.2.3.7. -type TPMUPublicParms struct { - selector TPMAlgID - contents Marshallable -} - -// PublicParmsContents is a type constraint representing the possible contents of TPMUPublicParms. -type PublicParmsContents interface { - Marshallable - *TPMSKeyedHashParms | *TPMSSymCipherParms | *TPMSRSAParms | - *TPMSECCParms -} - -// create implements the unmarshallableWithHint interface. -func (u *TPMUPublicParms) create(hint int64) (reflect.Value, error) { - switch TPMAlgID(hint) { - case TPMAlgKeyedHash: - var contents TPMSKeyedHashParms - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgSymCipher: - var contents TPMSSymCipherParms - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgRSA: - var contents TPMSRSAParms - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgECC: - var contents TPMSECCParms - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// get implements the marshallableWithHint interface. -func (u TPMUPublicParms) get(hint int64) (reflect.Value, error) { - if u.selector != 0 && hint != int64(u.selector) { - return reflect.ValueOf(nil), fmt.Errorf("incorrect union tag %v, is %v", hint, u.selector) - } - switch TPMAlgID(hint) { - case TPMAlgKeyedHash: - var contents TPMSKeyedHashParms - if u.contents != nil { - contents = *u.contents.(*TPMSKeyedHashParms) - } - return reflect.ValueOf(&contents), nil - case TPMAlgSymCipher: - var contents TPMSSymCipherParms - if u.contents != nil { - contents = *u.contents.(*TPMSSymCipherParms) - } - return reflect.ValueOf(&contents), nil - case TPMAlgRSA: - var contents TPMSRSAParms - if u.contents != nil { - contents = *u.contents.(*TPMSRSAParms) - } - return reflect.ValueOf(&contents), nil - case TPMAlgECC: - var contents TPMSECCParms - if u.contents != nil { - contents = *u.contents.(*TPMSECCParms) - } - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// NewTPMUPublicParms instantiates a TPMUPublicParms with the given contents. -func NewTPMUPublicParms[C PublicParmsContents](selector TPMAlgID, contents C) TPMUPublicParms { - return TPMUPublicParms{ - selector: selector, - contents: contents, - } -} - -// KeyedHashDetail returns the 'keyedHashDetail' member of the union. -func (u *TPMUPublicParms) KeyedHashDetail() (*TPMSKeyedHashParms, error) { - if u.selector == TPMAlgKeyedHash { - return u.contents.(*TPMSKeyedHashParms), nil - } - return nil, fmt.Errorf("did not contain keyedHashDetail (selector value was %v)", u.selector) -} - -// SymDetail returns the 'symDetail' member of the union. -func (u *TPMUPublicParms) SymDetail() (*TPMSSymCipherParms, error) { - if u.selector == TPMAlgSymCipher { - return u.contents.(*TPMSSymCipherParms), nil - } - return nil, fmt.Errorf("did not contain symDetail (selector value was %v)", u.selector) -} - -// RSADetail returns the 'rsaDetail' member of the union. -func (u *TPMUPublicParms) RSADetail() (*TPMSRSAParms, error) { - if u.selector == TPMAlgRSA { - return u.contents.(*TPMSRSAParms), nil - } - return nil, fmt.Errorf("did not contain rsaDetail (selector value was %v)", u.selector) -} - -// ECCDetail returns the 'eccDetail' member of the union. -func (u *TPMUPublicParms) ECCDetail() (*TPMSECCParms, error) { - if u.selector == TPMAlgECC { - return u.contents.(*TPMSECCParms), nil - } - return nil, fmt.Errorf("did not contain eccDetail (selector value was %v)", u.selector) -} - -// TPMTPublic represents a TPMT_PUBLIC. -// See definition in Part 2: Structures, section 12.2.4. -type TPMTPublic struct { - marshalByReflection - // “algorithm” associated with this object - Type TPMIAlgPublic - // algorithm used for computing the Name of the object - NameAlg TPMIAlgHash - // attributes that, along with type, determine the manipulations - // of this object - ObjectAttributes TPMAObject - // optional policy for using this key - // The policy is computed using the nameAlg of the object. - AuthPolicy TPM2BDigest - // the algorithm or structure details - Parameters TPMUPublicParms `gotpm:"tag=Type"` - // the unique identifier of the structure - // For an asymmetric key, this would be the public key. - Unique TPMUPublicID `gotpm:"tag=Type"` -} - -// TPM2BPublic represents a TPM2B_PUBLIC. -// See definition in Part 2: Structures, section 12.2.5. -type TPM2BPublic = TPM2B[TPMTPublic, *TPMTPublic] - -// TPM2BTemplate represents a TPM2B_TEMPLATE. -// See definition in Part 2: Structures, section 12.2.6. -type TPM2BTemplate TPM2BData - -// TemplateContents is a type constraint representing the possible contents of TPMUTemplate. -type TemplateContents interface { - Marshallable - *TPMTPublic | *TPMTTemplate -} - -// TPMTTemplate represents a TPMT_TEMPLATE. It is not defined in the spec. -// It represents the alternate form of TPMT_PUBLIC for TPM2B_TEMPLATE as -// described in Part 2: Structures, 12.2.6. -type TPMTTemplate struct { - marshalByReflection - // “algorithm” associated with this object - Type TPMIAlgPublic - // algorithm used for computing the Name of the object - NameAlg TPMIAlgHash - // attributes that, along with type, determine the manipulations - // of this object - ObjectAttributes TPMAObject - // optional policy for using this key - // The policy is computed using the nameAlg of the object. - AuthPolicy TPM2BDigest - // the algorithm or structure details - Parameters TPMUPublicParms `gotpm:"tag=Type"` - // the derivation parameters - Unique TPMSDerive -} - -// New2BTemplate creates a TPM2BTemplate with the given data. -func New2BTemplate[C TemplateContents](data C) TPM2BTemplate { - return TPM2BTemplate{ - Buffer: Marshal(data), - } -} - -// TPMUSensitiveComposite represents a TPMU_SENSITIVE_COMPOSITE. -// See definition in Part 2: Structures, section 12.3.2.3. -type TPMUSensitiveComposite struct { - selector TPMAlgID - contents Marshallable -} - -// SensitiveCompositeContents is a type constraint representing the possible contents of TPMUSensitiveComposite. -type SensitiveCompositeContents interface { - Marshallable - *TPM2BPrivateKeyRSA | *TPM2BECCParameter | *TPM2BSensitiveData | *TPM2BSymKey -} - -// create implements the unmarshallableWithHint interface. -func (u *TPMUSensitiveComposite) create(hint int64) (reflect.Value, error) { - switch TPMAlgID(hint) { - case TPMAlgRSA: - var contents TPM2BPrivateKeyRSA - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgECC: - var contents TPM2BECCParameter - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgKeyedHash: - var contents TPM2BSensitiveData - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - case TPMAlgSymCipher: - var contents TPM2BSymKey - u.contents = &contents - u.selector = TPMAlgID(hint) - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// get implements the marshallableWithHint interface. -func (u TPMUSensitiveComposite) get(hint int64) (reflect.Value, error) { - if u.selector != 0 && hint != int64(u.selector) { - return reflect.ValueOf(nil), fmt.Errorf("incorrect union tag %v, is %v", hint, u.selector) - } - switch TPMAlgID(hint) { - case TPMAlgRSA: - var contents TPM2BPrivateKeyRSA - if u.contents != nil { - contents = *u.contents.(*TPM2BPrivateKeyRSA) - } - return reflect.ValueOf(&contents), nil - case TPMAlgECC: - var contents TPM2BECCParameter - if u.contents != nil { - contents = *u.contents.(*TPM2BECCParameter) - } - return reflect.ValueOf(&contents), nil - case TPMAlgKeyedHash: - var contents TPM2BSensitiveData - if u.contents != nil { - contents = *u.contents.(*TPM2BSensitiveData) - } - return reflect.ValueOf(&contents), nil - case TPMAlgSymCipher: - var contents TPM2BSymKey - if u.contents != nil { - contents = *u.contents.(*TPM2BSymKey) - } - return reflect.ValueOf(&contents), nil - } - return reflect.ValueOf(nil), fmt.Errorf("no union member for tag %v", hint) -} - -// NewTPMUSensitiveComposite instantiates a TPMUSensitiveComposite with the given contents. -func NewTPMUSensitiveComposite[C SensitiveCompositeContents](selector TPMAlgID, contents C) TPMUSensitiveComposite { - return TPMUSensitiveComposite{ - selector: selector, - contents: contents, - } -} - -// RSA returns the 'rsa' member of the union. -func (u *TPMUKDFScheme) RSA() (*TPM2BPrivateKeyRSA, error) { - if u.selector == TPMAlgRSA { - return u.contents.(*TPM2BPrivateKeyRSA), nil - } - return nil, fmt.Errorf("did not contain rsa (selector value was %v)", u.selector) -} - -// ECC returns the 'ecc' member of the union. -func (u *TPMUKDFScheme) ECC() (*TPM2BECCParameter, error) { - if u.selector == TPMAlgECC { - return u.contents.(*TPM2BECCParameter), nil - } - return nil, fmt.Errorf("did not contain ecc (selector value was %v)", u.selector) -} - -// Bits returns the 'bits' member of the union. -func (u *TPMUKDFScheme) Bits() (*TPM2BSensitiveData, error) { - if u.selector == TPMAlgKeyedHash { - return u.contents.(*TPM2BSensitiveData), nil - } - return nil, fmt.Errorf("did not contain bits (selector value was %v)", u.selector) -} - -// Sym returns the 'sym' member of the union. -func (u *TPMUKDFScheme) Sym() (*TPM2BSymKey, error) { - if u.selector == TPMAlgSymCipher { - return u.contents.(*TPM2BSymKey), nil - } - return nil, fmt.Errorf("did not contain sym (selector value was %v)", u.selector) -} - -// TPMTSensitive represents a TPMT_SENSITIVE. -// See definition in Part 2: Structures, section 12.3.2.4. -type TPMTSensitive struct { - marshalByReflection - // identifier for the sensitive area - SensitiveType TPMIAlgPublic - // user authorization data - AuthValue TPM2BAuth - // for a parent object, the optional protection seed; for other objects, - // the obfuscation value - SeedValue TPM2BDigest - // the type-specific private data - Sensitive TPMUSensitiveComposite `gotpm:"tag=SensitiveType"` -} - -// TPM2BSensitive represents a TPM2B_SENSITIVE. -// See definition in Part 2: Structures, section 12.3.3. -type TPM2BSensitive = TPM2B[TPMTSensitive, *TPMTSensitive] - -// TPM2BPrivate represents a TPM2B_PRIVATE. -// See definition in Part 2: Structures, section 12.3.7. -type TPM2BPrivate TPM2BData - -// TPMSCreationData represents a TPMS_CREATION_DATA. -// See definition in Part 2: Structures, section 15.1. -type TPMSCreationData struct { - marshalByReflection - // list indicating the PCR included in pcrDigest - PCRSelect TPMLPCRSelection - // digest of the selected PCR using nameAlg of the object for which - // this structure is being created - PCRDigest TPM2BDigest - // the locality at which the object was created - Locality TPMALocality - // nameAlg of the parent - ParentNameAlg TPMAlgID - // Name of the parent at time of creation - ParentName TPM2BName - // Qualified Name of the parent at the time of creation - ParentQualifiedName TPM2BName - // association with additional information added by the key - OutsideInfo TPM2BData -} - -// TPM2BIDObject represents a TPM2B_ID_OBJECT. -// See definition in Part 2: Structures, section 12.4.3. -type TPM2BIDObject TPM2BData - -// TPMANV represents a TPMA_NV. -// See definition in Part 2: Structures, section 13.4. -type TPMANV struct { - bitfield32 - marshalByReflection - // SET (1): The Index data can be written if Platform Authorization is - // provided. - // CLEAR (0): Writing of the Index data cannot be authorized with - // Platform Authorization. - PPWrite bool `gotpm:"bit=0"` - // SET (1): The Index data can be written if Owner Authorization is - // provided. - // CLEAR (0): Writing of the Index data cannot be authorized with Owner - // Authorization. - OwnerWrite bool `gotpm:"bit=1"` - // SET (1): Authorizations to change the Index contents that require - // USER role may be provided with an HMAC session or password. - // CLEAR (0): Authorizations to change the Index contents that require - // USER role may not be provided with an HMAC session or password. - AuthWrite bool `gotpm:"bit=2"` - // SET (1): Authorizations to change the Index contents that require - // USER role may be provided with a policy session. - // CLEAR (0): Authorizations to change the Index contents that require - // USER role may not be provided with a policy session. - PolicyWrite bool `gotpm:"bit=3"` - // The type of the index. - NT TPMNT `gotpm:"bit=7:4"` - // SET (1): Index may not be deleted unless the authPolicy is satisfied - // using TPM2_NV_UndefineSpaceSpecial(). - // CLEAR (0): Index may be deleted with proper platform or owner - // authorization using TPM2_NV_UndefineSpace(). - PolicyDelete bool `gotpm:"bit=10"` - // SET (1): Index cannot be written. - // CLEAR (0): Index can be written. - WriteLocked bool `gotpm:"bit=11"` - // SET (1): A partial write of the Index data is not allowed. The write - // size shall match the defined space size. - // CLEAR (0): Partial writes are allowed. This setting is required if - // the .dataSize of the Index is larger than NV_MAX_BUFFER_SIZE for the - // implementation. - WriteAll bool `gotpm:"bit=12"` - // SET (1): TPM2_NV_WriteLock() may be used to prevent further writes - // to this location. - // CLEAR (0): TPM2_NV_WriteLock() does not block subsequent writes if - // TPMA_NV_WRITE_STCLEAR is also CLEAR. - WriteDefine bool `gotpm:"bit=13"` - // SET (1): TPM2_NV_WriteLock() may be used to prevent further writes - // to this location until the next TPM Reset or TPM Restart. - // CLEAR (0): TPM2_NV_WriteLock() does not block subsequent writes if - // TPMA_NV_WRITEDEFINE is also CLEAR. - WriteSTClear bool `gotpm:"bit=14"` - // SET (1): If TPM2_NV_GlobalWriteLock() is successful, - // TPMA_NV_WRITELOCKED is set. - // CLEAR (0): TPM2_NV_GlobalWriteLock() has no effect on the writing of - // the data at this Index. - GlobalLock bool `gotpm:"bit=15"` - // SET (1): The Index data can be read if Platform Authorization is - // provided. - // CLEAR (0): Reading of the Index data cannot be authorized with - // Platform Authorization. - PPRead bool `gotpm:"bit=16"` - // SET (1): The Index data can be read if Owner Authorization is - // provided. - // CLEAR (0): Reading of the Index data cannot be authorized with Owner - // Authorization. - OwnerRead bool `gotpm:"bit=17"` - // SET (1): The Index data may be read if the authValue is provided. - // CLEAR (0): Reading of the Index data cannot be authorized with the - // Index authValue. - AuthRead bool `gotpm:"bit=18"` - // SET (1): The Index data may be read if the authPolicy is satisfied. - // CLEAR (0): Reading of the Index data cannot be authorized with the - // Index authPolicy. - PolicyRead bool `gotpm:"bit=19"` - // SET (1): Authorization failures of the Index do not affect the DA - // logic and authorization of the Index is not blocked when the TPM is - // in Lockout mode. - // CLEAR (0): Authorization failures of the Index will increment the - // authorization failure counter and authorizations of this Index are - // not allowed when the TPM is in Lockout mode. - NoDA bool `gotpm:"bit=25"` - // SET (1): NV Index state is only required to be saved when the TPM - // performs an orderly shutdown (TPM2_Shutdown()). - // CLEAR (0): NV Index state is required to be persistent after the - // command to update the Index completes successfully (that is, the NV - // update is synchronous with the update command). - Orderly bool `gotpm:"bit=26"` - // SET (1): TPMA_NV_WRITTEN for the Index is CLEAR by TPM Reset or TPM - // Restart. - // CLEAR (0): TPMA_NV_WRITTEN is not changed by TPM Restart. - ClearSTClear bool `gotpm:"bit=27"` - // SET (1): Reads of the Index are blocked until the next TPM Reset or - // TPM Restart. - // CLEAR (0): Reads of the Index are allowed if proper authorization is - // provided. - ReadLocked bool `gotpm:"bit=28"` - // SET (1): Index has been written. - // CLEAR (0): Index has not been written. - Written bool `gotpm:"bit=29"` - // SET (1): This Index may be undefined with Platform Authorization - // but not with Owner Authorization. - // CLEAR (0): This Index may be undefined using Owner Authorization but - // not with Platform Authorization. - PlatformCreate bool `gotpm:"bit=30"` - // SET (1): TPM2_NV_ReadLock() may be used to SET TPMA_NV_READLOCKED - // for this Index. - // CLEAR (0): TPM2_NV_ReadLock() has no effect on this Index. - ReadSTClear bool `gotpm:"bit=31"` -} - -// TPMSNVPublic represents a TPMS_NV_PUBLIC. -// See definition in Part 2: Structures, section 13.5. -type TPMSNVPublic struct { - marshalByReflection - // the handle of the data area - NVIndex TPMIRHNVIndex - // hash algorithm used to compute the name of the Index and used for - // the authPolicy. For an extend index, the hash algorithm used for the - // extend. - NameAlg TPMIAlgHash - // the Index attributes - Attributes TPMANV - // optional access policy for the Index - AuthPolicy TPM2BDigest - // the size of the data area - DataSize uint16 -} - -// TPM2BNVPublic represents a TPM2B_NV_PUBLIC. -// See definition in Part 2: Structures, section 13.6. -type TPM2BNVPublic = TPM2B[TPMSNVPublic, *TPMSNVPublic] - -// TPM2BContextSensitive represents a TPM2B_CONTEXT_SENSITIVE -// See definition in Part 2: Structures, section 14.2. -type TPM2BContextSensitive TPM2BData - -// TPMSContextData represents a TPMS_CONTEXT_DATA -// See definition in Part 2: Structures, section 14.3. -type TPMSContextData struct { - marshalByReflection - // the integrity value - Integrity TPM2BDigest - // the sensitive area - Encrypted TPM2BContextSensitive -} - -// TPM2BContextData represents a TPM2B_CONTEXT_DATA -// See definition in Part 2: Structures, section 14.4. -// Represented here as a flat buffer because how a TPM chooses -// to represent its context data is implementation-dependent. -type TPM2BContextData TPM2BData - -// TPMSContext represents a TPMS_CONTEXT -// See definition in Part 2: Structures, section 14.5. -type TPMSContext struct { - marshalByReflection - // the sequence number of the context - Sequence uint64 - // a handle indicating if the context is a session, object, or sequence object - SavedHandle TPMIDHSaved - // the hierarchy of the context - Hierarchy TPMIRHHierarchy - // the context data and integrity HMAC - ContextBlob TPM2BContextData -} - -type tpm2bCreationData = TPM2B[TPMSCreationData, *TPMSCreationData] diff --git a/vendor/github.com/google/go-tpm/tpm2/templates.go b/vendor/github.com/google/go-tpm/tpm2/templates.go deleted file mode 100644 index a0cfa811c4..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/templates.go +++ /dev/null @@ -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), - }, - }, - ), - } -) diff --git a/vendor/github.com/google/go-tpm/tpm2/tpm2.go b/vendor/github.com/google/go-tpm/tpm2/tpm2.go deleted file mode 100644 index ad354bbf5c..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/tpm2.go +++ /dev/null @@ -1,1752 +0,0 @@ -// Package tpm2 contains TPM 2.0 commands and structures. -package tpm2 - -import ( - "bytes" - "encoding/binary" - - "github.com/google/go-tpm/tpm2/transport" -) - -// handle represents a TPM handle as comprehended in Part 3: Commands. -// In the context of TPM commands, handles are special parameters for which -// there is a known associated name. -// This is not an exported interface, because the reflection logic has special -// behavior for AuthHandle, due to the fact that referencing Session from this -// interface would break the ability to make TPMHandle implement it. -type handle interface { - // HandleValue is the numeric concrete handle value in the TPM. - HandleValue() uint32 - // KnownName is the TPM Name of the associated entity. See Part 1, section 16. - KnownName() *TPM2BName -} - -// NamedHandle represents an associated pairing of TPM handle and known Name. -type NamedHandle struct { - Handle TPMHandle - Name TPM2BName -} - -// HandleValue implements the handle interface. -func (h NamedHandle) HandleValue() uint32 { - return h.Handle.HandleValue() -} - -// KnownName implements the handle interface. -func (h NamedHandle) KnownName() *TPM2BName { - return &h.Name -} - -// AuthHandle allows the caller to add an authorization session onto a handle. -type AuthHandle struct { - Handle TPMHandle - Name TPM2BName - Auth Session -} - -// HandleValue implements the handle interface. -func (h AuthHandle) HandleValue() uint32 { - return h.Handle.HandleValue() -} - -// KnownName implements the handle interface. -// If Name is not provided (i.e., only Auth), then rely on the underlying -// TPMHandle. -func (h AuthHandle) KnownName() *TPM2BName { - if len(h.Name.Buffer) != 0 { - return &h.Name - } - return h.Handle.KnownName() -} - -// Command is an interface for any TPM command, parameterized by its response -// type. -type Command[R any, PR *R] interface { - // The TPM command code associated with this command. - Command() TPMCC - // Executes the command and returns the response. - Execute(t transport.TPM, s ...Session) (PR, error) -} - -// PolicyCommand is a TPM command that can be part of a TPM policy. -type PolicyCommand interface { - // Update updates the given policy hash according to the command - // parameters. - Update(policy *PolicyCalculator) error -} - -// Shutdown is the input to TPM2_Shutdown. -// See definition in Part 3, Commands, section 9.4. -type Shutdown struct { - // TPM_SU_CLEAR or TPM_SU_STATE - ShutdownType TPMSU -} - -// Command implements the Command interface. -func (Shutdown) Command() TPMCC { return TPMCCShutdown } - -// Execute executes the command and returns the response. -func (cmd Shutdown) Execute(t transport.TPM, s ...Session) (*ShutdownResponse, error) { - var rsp ShutdownResponse - err := execute[ShutdownResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// ShutdownResponse is the response from TPM2_Shutdown. -type ShutdownResponse struct{} - -// Startup is the input to TPM2_Startup. -// See definition in Part 3, Commands, section 9.3. -type Startup struct { - // TPM_SU_CLEAR or TPM_SU_STATE - StartupType TPMSU -} - -// Command implements the Command interface. -func (Startup) Command() TPMCC { return TPMCCStartup } - -// Execute executes the command and returns the response. -func (cmd Startup) Execute(t transport.TPM, s ...Session) (*StartupResponse, error) { - var rsp StartupResponse - err := execute[StartupResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// StartupResponse is the response from TPM2_Startup. -type StartupResponse struct{} - -// StartAuthSession is the input to TPM2_StartAuthSession. -// See definition in Part 3, Commands, section 11.1 -type StartAuthSession struct { - // handle of a loaded decrypt key used to encrypt salt - // may be TPM_RH_NULL - TPMKey handle `gotpm:"handle,nullable"` - // entity providing the authValue - // may be TPM_RH_NULL - Bind handle `gotpm:"handle,nullable"` - // initial nonceCaller, sets nonceTPM size for the session - // shall be at least 16 octets - NonceCaller TPM2BNonce - // value encrypted according to the type of tpmKey - // If tpmKey is TPM_RH_NULL, this shall be the Empty Buffer. - EncryptedSalt TPM2BEncryptedSecret - // indicates the type of the session; simple HMAC or policy (including - // a trial policy) - SessionType TPMSE - // the algorithm and key size for parameter encryption - // may select transport.TPM_ALG_NULL - Symmetric TPMTSymDef - // hash algorithm to use for the session - // Shall be a hash algorithm supported by the TPM and not transport.TPM_ALG_NULL - AuthHash TPMIAlgHash -} - -// Command implements the Command interface. -func (StartAuthSession) Command() TPMCC { return TPMCCStartAuthSession } - -// Execute executes the command and returns the response. -func (cmd StartAuthSession) Execute(t transport.TPM, s ...Session) (*StartAuthSessionResponse, error) { - var rsp StartAuthSessionResponse - if err := execute[StartAuthSessionResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// StartAuthSessionResponse is the response from TPM2_StartAuthSession. -type StartAuthSessionResponse struct { - // handle for the newly created session - SessionHandle TPMISHAuthSession `gotpm:"handle"` - // the initial nonce from the TPM, used in the computation of the sessionKey - NonceTPM TPM2BNonce -} - -// Create is the input to TPM2_Create. -// See definition in Part 3, Commands, section 12.1 -type Create struct { - // handle of parent for new object - ParentHandle handle `gotpm:"handle,auth"` - // the sensitive data - InSensitive TPM2BSensitiveCreate - // the public template - InPublic TPM2BPublic - // data that will be included in the creation data for this - // object to provide permanent, verifiable linkage between this - // object and some object owner data - OutsideInfo TPM2BData - // PCR that will be used in creation data - CreationPCR TPMLPCRSelection -} - -// Command implements the Command interface. -func (Create) Command() TPMCC { return TPMCCCreate } - -// Execute executes the command and returns the response. -func (cmd Create) Execute(t transport.TPM, s ...Session) (*CreateResponse, error) { - var rsp CreateResponse - if err := execute[CreateResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// CreateResponse is the response from TPM2_Create. -type CreateResponse struct { - // the private portion of the object - OutPrivate TPM2BPrivate - // the public portion of the created object - OutPublic TPM2BPublic - // contains a TPMS_CREATION_DATA - CreationData tpm2bCreationData - // digest of creationData using nameAlg of outPublic - CreationHash TPM2BDigest - // ticket used by TPM2_CertifyCreation() to validate that the - // creation data was produced by the TPM. - CreationTicket TPMTTKCreation -} - -// Load is the input to TPM2_Load. -// See definition in Part 3, Commands, section 12.2 -type Load struct { - // handle of parent for new object - ParentHandle handle `gotpm:"handle,auth"` - // the private portion of the object - InPrivate TPM2BPrivate - // the public portion of the object - InPublic TPM2BPublic -} - -// Command implements the Command interface. -func (Load) Command() TPMCC { return TPMCCLoad } - -// Execute executes the command and returns the response. -func (cmd Load) Execute(t transport.TPM, s ...Session) (*LoadResponse, error) { - var rsp LoadResponse - if err := execute[LoadResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// LoadResponse is the response from TPM2_Load. -type LoadResponse struct { - // handle of type TPM_HT_TRANSIENT for loaded object - ObjectHandle TPMHandle `gotpm:"handle"` - // Name of the loaded object - Name TPM2BName -} - -// LoadExternal is the input to TPM2_LoadExternal. -// See definition in Part 3, Commands, section 12.3 -type LoadExternal struct { - // the sensitive portion of the object (optional) - InPrivate TPM2BSensitive `gotpm:"optional"` - // the public portion of the object - InPublic TPM2BPublic - // hierarchy with which the object area is associated - Hierarchy TPMIRHHierarchy `gotpm:"nullable"` -} - -// Command implements the Command interface. -func (LoadExternal) Command() TPMCC { return TPMCCLoadExternal } - -// Execute executes the command and returns the response. -func (cmd LoadExternal) Execute(t transport.TPM, s ...Session) (*LoadExternalResponse, error) { - var rsp LoadExternalResponse - if err := execute[LoadExternalResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// LoadExternalResponse is the response from TPM2_LoadExternal. -type LoadExternalResponse struct { - // handle of type TPM_HT_TRANSIENT for loaded object - ObjectHandle TPMHandle `gotpm:"handle"` - // Name of the loaded object - Name TPM2BName -} - -// ReadPublic is the input to TPM2_ReadPublic. -// See definition in Part 3, Commands, section 12.4 -type ReadPublic struct { - // TPM handle of an object - ObjectHandle TPMIDHObject `gotpm:"handle"` -} - -// Command implements the Command interface. -func (ReadPublic) Command() TPMCC { return TPMCCReadPublic } - -// Execute executes the command and returns the response. -func (cmd ReadPublic) Execute(t transport.TPM, s ...Session) (*ReadPublicResponse, error) { - var rsp ReadPublicResponse - if err := execute[ReadPublicResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// ReadPublicResponse is the response from TPM2_ReadPublic. -type ReadPublicResponse struct { - // structure containing the public area of an object - OutPublic TPM2BPublic - // name of object - Name TPM2BName - // the Qualified Name of the object - QualifiedName TPM2BName -} - -// ActivateCredential is the input to TPM2_ActivateCredential. -// See definition in Part 3, Commands, section 12.5. -type ActivateCredential struct { - // handle of the object associated with certificate in credentialBlob - ActivateHandle handle `gotpm:"handle,auth"` - // loaded key used to decrypt the TPMS_SENSITIVE in credentialBlob - KeyHandle handle `gotpm:"handle,auth"` - // the credential - CredentialBlob TPM2BIDObject - // keyHandle algorithm-dependent encrypted seed that protects credentialBlob - Secret TPM2BEncryptedSecret -} - -// Command implements the Command interface. -func (ActivateCredential) Command() TPMCC { return TPMCCActivateCredential } - -// Execute executes the command and returns the response. -func (cmd ActivateCredential) Execute(t transport.TPM, s ...Session) (*ActivateCredentialResponse, error) { - var rsp ActivateCredentialResponse - if err := execute[ActivateCredentialResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// ActivateCredentialResponse is the response from TPM2_ActivateCredential. -type ActivateCredentialResponse struct { - // the decrypted certificate information - CertInfo TPM2BDigest -} - -// MakeCredential is the input to TPM2_MakeCredential. -// See definition in Part 3, Commands, section 12.6. -type MakeCredential struct { - // loaded public area, used to encrypt the sensitive area containing the credential key - Handle TPMIDHObject `gotpm:"handle"` - // the credential information - Credential TPM2BDigest - // Name of the object to which the credential applies - ObjectNamae TPM2BName -} - -// Command implements the Command interface. -func (MakeCredential) Command() TPMCC { return TPMCCMakeCredential } - -// Execute executes the command and returns the response. -func (cmd MakeCredential) Execute(t transport.TPM, s ...Session) (*MakeCredentialResponse, error) { - var rsp MakeCredentialResponse - if err := execute[MakeCredentialResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// MakeCredentialResponse is the response from TPM2_MakeCredential. -type MakeCredentialResponse struct { - // the credential - CredentialBlob TPM2BIDObject - // handle algorithm-dependent data that wraps the key that encrypts credentialBlob - Secret TPM2BEncryptedSecret -} - -// Unseal is the input to TPM2_Unseal. -// See definition in Part 3, Commands, section 12.7 -type Unseal struct { - ItemHandle handle `gotpm:"handle,auth"` -} - -// Command implements the Command interface. -func (Unseal) Command() TPMCC { return TPMCCUnseal } - -// Execute executes the command and returns the response. -func (cmd Unseal) Execute(t transport.TPM, s ...Session) (*UnsealResponse, error) { - var rsp UnsealResponse - if err := execute[UnsealResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// UnsealResponse is the response from TPM2_Unseal. -type UnsealResponse struct { - OutData TPM2BSensitiveData -} - -// CreateLoaded is the input to TPM2_CreateLoaded. -// See definition in Part 3, Commands, section 12.9 -type CreateLoaded struct { - // Handle of a transient storage key, a persistent storage key, - // TPM_RH_ENDORSEMENT, TPM_RH_OWNER, TPM_RH_PLATFORM+{PP}, or TPM_RH_NULL - ParentHandle handle `gotpm:"handle,auth,nullable"` - // the sensitive data, see TPM 2.0 Part 1 Sensitive Values - InSensitive TPM2BSensitiveCreate - // the public template - InPublic TPM2BTemplate -} - -// Command implements the Command interface. -func (CreateLoaded) Command() TPMCC { return TPMCCCreateLoaded } - -// Execute executes the command and returns the response. -func (cmd CreateLoaded) Execute(t transport.TPM, s ...Session) (*CreateLoadedResponse, error) { - var rsp CreateLoadedResponse - if err := execute[CreateLoadedResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// CreateLoadedResponse is the response from TPM2_CreateLoaded. -type CreateLoadedResponse struct { - // handle of type TPM_HT_TRANSIENT for loaded object - ObjectHandle TPMHandle `gotpm:"handle"` - // the sensitive area of the object (optional) - OutPrivate TPM2BPrivate `gotpm:"optional"` - // the public portion of the created object - OutPublic TPM2BPublic - // the name of the created object - Name TPM2BName -} - -// ECDHZGen is the input to TPM2_ECDHZGen. -// See definition in Part 3, Commands, section 14.5 -type ECDHZGen struct { - // handle of a loaded ECC key - KeyHandle handle `gotpm:"handle,auth"` - // a public key - InPoint TPM2BECCPoint -} - -// Command implements the Command interface. -func (ECDHZGen) Command() TPMCC { return TPMCCECDHZGen } - -// Execute executes the command and returns the response. -func (cmd ECDHZGen) Execute(t transport.TPM, s ...Session) (*ECDHZGenResponse, error) { - var rsp ECDHZGenResponse - if err := execute[ECDHZGenResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// ECDHZGenResponse is the response from TPM2_ECDHZGen. -type ECDHZGenResponse struct { - // X and Y coordinates of the product of the multiplication - OutPoint TPM2BECCPoint -} - -// Hash is the input to TPM2_Hash. -// See definition in Part 3, Commands, section 15.4 -type Hash struct { - //data to be hashed - Data TPM2BMaxBuffer - // algorithm for the hash being computed - shall not be TPM_ALH_NULL - HashAlg TPMIAlgHash - // hierarchy to use for the ticket (TPM_RH_NULL_allowed) - Hierarchy TPMIRHHierarchy `gotpm:"nullable"` -} - -// Command implements the Command interface. -func (Hash) Command() TPMCC { return TPMCCHash } - -// Execute executes the command and returns the response. -func (cmd Hash) Execute(t transport.TPM, s ...Session) (*HashResponse, error) { - var rsp HashResponse - if err := execute[HashResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// HashResponse is the response from TPM2_Hash. -type HashResponse struct { - // results - OutHash TPM2BDigest - // ticket indicating that the sequence of octets used to - // compute outDigest did not start with TPM_GENERATED_VALUE - Validation TPMTTKHashCheck -} - -// GetRandom is the input to TPM2_GetRandom. -// See definition in Part 3, Commands, section 16.1 -type GetRandom struct { - // number of octets to return - BytesRequested uint16 -} - -// Command implements the Command interface. -func (GetRandom) Command() TPMCC { return TPMCCGetRandom } - -// Execute executes the command and returns the response. -func (cmd GetRandom) Execute(t transport.TPM, s ...Session) (*GetRandomResponse, error) { - var rsp GetRandomResponse - if err := execute[GetRandomResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// GetRandomResponse is the response from TPM2_GetRandom. -type GetRandomResponse struct { - // the random octets - RandomBytes TPM2BDigest -} - -// HashSequenceStart is the input to TPM2_HashSequenceStart. -// See definition in Part 3, Commands, section 17.3 -type HashSequenceStart struct { - // authorization value for subsequent use of the sequence - Auth TPM2BAuth - // the hash algorithm to use for the hash sequence - // An Event Sequence starts if this is TPM_ALG_NULL. - HashAlg TPMIAlgHash -} - -// Command implements the Command interface. -func (HashSequenceStart) Command() TPMCC { return TPMCCHashSequenceStart } - -// Execute executes the command and returns the response. -func (cmd HashSequenceStart) Execute(t transport.TPM, s ...Session) (*HashSequenceStartResponse, error) { - var rsp HashSequenceStartResponse - if err := execute[HashSequenceStartResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// HashSequenceStartResponse is the response from TPM2_StartHashSequence. -type HashSequenceStartResponse struct { - // a handle to reference the sequence - SequenceHandle TPMIDHObject -} - -// SequenceUpdate is the input to TPM2_SequenceUpdate. -// See definition in Part 3, Commands, section 17.4 -type SequenceUpdate struct { - // handle for the sequence object - SequenceHandle handle `gotpm:"handle,auth"` - // data to be added to hash - Buffer TPM2BMaxBuffer -} - -// Command implements the Command interface. -func (SequenceUpdate) Command() TPMCC { return TPMCCSequenceUpdate } - -// Execute executes the command and returns the response. -func (cmd SequenceUpdate) Execute(t transport.TPM, s ...Session) (*SequenceUpdateResponse, error) { - var rsp SequenceUpdateResponse - if err := execute[SequenceUpdateResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// SequenceUpdateResponse is the response from TPM2_SequenceUpdate. -type SequenceUpdateResponse struct{} - -// SequenceComplete is the input to TPM2_SequenceComplete. -// See definition in Part 3, Commands, section 17.5 -type SequenceComplete struct { - // authorization for the sequence - SequenceHandle handle `gotpm:"handle,auth"` - // data to be added to the hash/HMAC - Buffer TPM2BMaxBuffer - // hierarchy of the ticket for a hash - Hierarchy TPMIRHHierarchy `gotpm:"nullable"` -} - -// Command implements the Command interface. -func (SequenceComplete) Command() TPMCC { return TPMCCSequenceComplete } - -// Execute executes the command and returns the response. -func (cmd SequenceComplete) Execute(t transport.TPM, s ...Session) (*SequenceCompleteResponse, error) { - var rsp SequenceCompleteResponse - if err := execute[SequenceCompleteResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// SequenceCompleteResponse is the response from TPM2_SequenceComplete. -type SequenceCompleteResponse struct { - // the returned HMAC or digest in a sized buffer - Result TPM2BDigest - // ticket indicating that the sequence of octets used to - // compute outDigest did not start with TPM_GENERATED_VALUE - Validation TPMTTKHashCheck -} - -// Certify is the input to TPM2_Certify. -// See definition in Part 3, Commands, section 18.2. -type Certify struct { - // handle of the object to be certified - ObjectHandle handle `gotpm:"handle,auth"` - // handle of the key used to sign the attestation structure - SignHandle handle `gotpm:"handle,auth"` - // user provided qualifying data - QualifyingData TPM2BData - // signing scheme to use if the scheme for signHandle is TPM_ALG_NULL - InScheme TPMTSigScheme -} - -// Command implements the Command interface. -func (Certify) Command() TPMCC { return TPMCCCertify } - -// Execute executes the command and returns the response. -func (cmd Certify) Execute(t transport.TPM, s ...Session) (*CertifyResponse, error) { - var rsp CertifyResponse - if err := execute[CertifyResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// CertifyResponse is the response from TPM2_Certify. -type CertifyResponse struct { - // the structure that was signed - CertifyInfo TPM2BAttest - // the asymmetric signature over certifyInfo using the key referenced by signHandle - Signature TPMTSignature -} - -// CertifyCreation is the input to TPM2_CertifyCreation. -// See definition in Part 3, Commands, section 18.3. -type CertifyCreation struct { - // handle of the key that will sign the attestation block - SignHandle handle `gotpm:"handle,auth"` - // the object associated with the creation data - ObjectHandle handle `gotpm:"handle"` - // user-provided qualifying data - QualifyingData TPM2BData - // hash of the creation data produced by TPM2_Create() or TPM2_CreatePrimary() - CreationHash TPM2BDigest - // signing scheme to use if the scheme for signHandle is TPM_ALG_NULL - InScheme TPMTSigScheme - // ticket produced by TPM2_Create() or TPM2_CreatePrimary() - CreationTicket TPMTTKCreation -} - -// Command implements the Command interface. -func (CertifyCreation) Command() TPMCC { return TPMCCCertifyCreation } - -// Execute executes the command and returns the response. -func (cmd CertifyCreation) Execute(t transport.TPM, s ...Session) (*CertifyCreationResponse, error) { - var rsp CertifyCreationResponse - if err := execute[CertifyCreationResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// CertifyCreationResponse is the response from TPM2_CertifyCreation. -type CertifyCreationResponse struct { - // the structure that was signed - CertifyInfo TPM2BAttest - // the signature over certifyInfo - Signature TPMTSignature -} - -// Quote is the input to TPM2_Quote. -// See definition in Part 3, Commands, section 18.4 -type Quote struct { - // handle of key that will perform signature - SignHandle handle `gotpm:"handle,auth"` - // data supplied by the caller - QualifyingData TPM2BData - // signing scheme to use if the scheme for signHandle is TPM_ALG_NULL - InScheme TPMTSigScheme - // PCR set to quote - PCRSelect TPMLPCRSelection -} - -// Command implements the Command interface. -func (Quote) Command() TPMCC { return TPMCCQuote } - -// Execute executes the command and returns the response. -func (cmd Quote) Execute(t transport.TPM, s ...Session) (*QuoteResponse, error) { - var rsp QuoteResponse - if err := execute[QuoteResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// QuoteResponse is the response from TPM2_Quote. -type QuoteResponse struct { - // the quoted information - Quoted TPM2BAttest - // the signature over quoted - Signature TPMTSignature -} - -// GetSessionAuditDigest is the input to TPM2_GetSessionAuditDigest. -// See definition in Part 3, Commands, section 18.5 -type GetSessionAuditDigest struct { - // handle of the privacy administrator (TPM_RH_ENDORSEMENT) - PrivacyAdminHandle handle `gotpm:"handle,auth"` - // handle of the signing key - SignHandle handle `gotpm:"handle,auth"` - // handle of the audit session - SessionHandle handle `gotpm:"handle"` - // user-provided qualifying data – may be zero-length - QualifyingData TPM2BData - // signing scheme to use if the scheme for signHandle is TPM_ALG_NULL - InScheme TPMTSigScheme -} - -// Command implements the Command interface. -func (GetSessionAuditDigest) Command() TPMCC { return TPMCCGetSessionAuditDigest } - -// Execute executes the command and returns the response. -func (cmd GetSessionAuditDigest) Execute(t transport.TPM, s ...Session) (*GetSessionAuditDigestResponse, error) { - var rsp GetSessionAuditDigestResponse - if err := execute[GetSessionAuditDigestResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// GetSessionAuditDigestResponse is the response from -// TPM2_GetSessionAuditDigest. -type GetSessionAuditDigestResponse struct { - // the audit information that was signed - AuditInfo TPM2BAttest - // the signature over auditInfo - Signature TPMTSignature -} - -// Commit is the input to TPM2_Commit. -// See definition in Part 3, Commands, section 19.2. -type Commit struct { - // handle of the key that will be used in the signing operation - SignHandle handle `gotpm:"handle,auth"` - // a point (M) on the curve used by signHandle - P1 TPM2BECCPoint - // octet array used to derive x-coordinate of a base point - S2 TPM2BSensitiveData - // y coordinate of the point associated with s2 - Y2 TPM2BECCParameter -} - -// Command implements the Command interface. -func (Commit) Command() TPMCC { return TPMCCCommit } - -// Execute executes the command and returns the response. -func (cmd Commit) Execute(t transport.TPM, s ...Session) (*CommitResponse, error) { - var rsp CommitResponse - if err := execute[CommitResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - - return &rsp, nil -} - -// CommitResponse is the response from TPM2_Commit. -type CommitResponse struct { - // ECC point K ≔ [ds](x2, y2) - K TPM2BECCPoint - // ECC point L ≔ [r](x2, y2) - L TPM2BECCPoint - // ECC point E ≔ [r]P1 - E TPM2BECCPoint - // least-significant 16 bits of commitCount - Counter uint16 -} - -// VerifySignature is the input to TPM2_VerifySignature. -// See definition in Part 3, Commands, section 20.1 -type VerifySignature struct { - // handle of public key that will be used in the validation - KeyHandle handle `gotpm:"handle"` - // digest of the signed message - Digest TPM2BDigest - // signature to be tested - Signature TPMTSignature -} - -// Command implements the Command interface. -func (VerifySignature) Command() TPMCC { return TPMCCVerifySignature } - -// Execute executes the command and returns the response. -func (cmd VerifySignature) Execute(t transport.TPM, s ...Session) (*VerifySignatureResponse, error) { - var rsp VerifySignatureResponse - if err := execute[VerifySignatureResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// VerifySignatureResponse is the response from TPM2_VerifySignature. -type VerifySignatureResponse struct { - Validation TPMTTKVerified -} - -// Sign is the input to TPM2_Sign. -// See definition in Part 3, Commands, section 20.2. -type Sign struct { - // Handle of key that will perform signing - KeyHandle handle `gotpm:"handle,auth"` - // digest to be signed - Digest TPM2BDigest - // signing scheme to use if the scheme for keyHandle is TPM_ALG_NULL - InScheme TPMTSigScheme `gotpm:"nullable"` - // proof that digest was created by the TPM. - // If keyHandle is not a restricted signing key, then this - // may be a NULL Ticket with tag = TPM_ST_CHECKHASH. - Validation TPMTTKHashCheck -} - -// Command implements the Command interface. -func (Sign) Command() TPMCC { return TPMCCSign } - -// Execute executes the command and returns the response. -func (cmd Sign) Execute(t transport.TPM, s ...Session) (*SignResponse, error) { - var rsp SignResponse - if err := execute[SignResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// SignResponse is the response from TPM2_Sign. -type SignResponse struct { - // the signature - Signature TPMTSignature -} - -// PCRExtend is the input to TPM2_PCR_Extend. -// See definition in Part 3, Commands, section 22.2 -type PCRExtend struct { - // handle of the PCR - PCRHandle handle `gotpm:"handle,auth"` - // list of tagged digest values to be extended - Digests TPMLDigestValues -} - -// Command implements the Command interface. -func (PCRExtend) Command() TPMCC { return TPMCCPCRExtend } - -// Execute executes the command and returns the response. -func (cmd PCRExtend) Execute(t transport.TPM, s ...Session) (*PCRExtendResponse, error) { - var rsp PCRExtendResponse - err := execute[PCRExtendResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// PCRExtendResponse is the response from TPM2_PCR_Extend. -type PCRExtendResponse struct{} - -// PCREvent is the input to TPM2_PCR_Event. -// See definition in Part 3, Commands, section 22.3 -type PCREvent struct { - // Handle of the PCR - PCRHandle handle `gotpm:"handle,auth"` - // Event data in sized buffer - EventData TPM2BEvent -} - -// Command implements the Command interface. -func (PCREvent) Command() TPMCC { return TPMCCPCREvent } - -// Execute executes the command and returns the response. -func (cmd PCREvent) Execute(t transport.TPM, s ...Session) (*PCREventResponse, error) { - var rsp PCREventResponse - err := execute[PCREventResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// PCREventResponse is the response from TPM2_PCR_Event. -type PCREventResponse struct{} - -// PCRRead is the input to TPM2_PCR_Read. -// See definition in Part 3, Commands, section 22.4 -type PCRRead struct { - // The selection of PCR to read - PCRSelectionIn TPMLPCRSelection -} - -// Command implements the Command interface. -func (PCRRead) Command() TPMCC { return TPMCCPCRRead } - -// Execute executes the command and returns the response. -func (cmd PCRRead) Execute(t transport.TPM, s ...Session) (*PCRReadResponse, error) { - var rsp PCRReadResponse - if err := execute[PCRReadResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// PCRReadResponse is the response from TPM2_PCR_Read. -type PCRReadResponse struct { - // the current value of the PCR update counter - PCRUpdateCounter uint32 - // the PCR in the returned list - PCRSelectionOut TPMLPCRSelection - // the contents of the PCR indicated in pcrSelectOut-> pcrSelection[] as tagged digests - PCRValues TPMLDigest -} - -// PCRReset is the input to TPM2_PCRReset. -// See definition in Part 3, Commands, section 22.8. -type PCRReset struct { - // the PCR to reset - PCRHandle handle `gotpm:"handle,auth"` -} - -// Command implements the Command interface. -func (PCRReset) Command() TPMCC { return TPMCCPCRReset } - -// Execute executes the command and returns the response. -func (cmd PCRReset) Execute(t transport.TPM, s ...Session) (*PCRResetResponse, error) { - var rsp PCRResetResponse - if err := execute[PCRResetResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// PCRResetResponse is the response from TPM2_PCRReset. -type PCRResetResponse struct{} - -// PolicySigned is the input to TPM2_PolicySigned. -// See definition in Part 3, Commands, section 23.3. -type PolicySigned struct { - // handle for an entity providing the authorization - AuthObject handle `gotpm:"handle"` - // handle for the policy session being extended - PolicySession handle `gotpm:"handle"` - // the policy nonce for the session - NonceTPM TPM2BNonce - // digest of the command parameters to which this authorization is limited - CPHashA TPM2BDigest - // a reference to a policy relating to the authorization – may be the Empty Buffer - PolicyRef TPM2BNonce - // time when authorization will expire, measured in seconds from the time - // that nonceTPM was generated - Expiration int32 - // signed authorization (not optional) - Auth TPMTSignature -} - -// Command implements the Command interface. -func (PolicySigned) Command() TPMCC { return TPMCCPolicySigned } - -// Execute executes the command and returns the response. -func (cmd PolicySigned) Execute(t transport.TPM, s ...Session) (*PolicySignedResponse, error) { - var rsp PolicySignedResponse - if err := execute[PolicySignedResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// policyUpdate implements the PolicyUpdate helper for the several TPM policy -// commands as described in Part 3, 23.2.3. -func policyUpdate(policy *PolicyCalculator, cc TPMCC, arg2, arg3 []byte) error { - if err := policy.Update(cc, arg2); err != nil { - return err - } - return policy.Update(arg3) -} - -// Update implements the PolicyCommand interface. -func (cmd PolicySigned) Update(policy *PolicyCalculator) error { - return policyUpdate(policy, TPMCCPolicySigned, cmd.AuthObject.KnownName().Buffer, cmd.PolicyRef.Buffer) -} - -// PolicySignedResponse is the response from TPM2_PolicySigned. -type PolicySignedResponse struct { - // implementation-specific time value used to indicate to the TPM when the ticket expires - Timeout TPM2BTimeout - // produced if the command succeeds and expiration in the command was non-zero - PolicyTicket TPMTTKAuth -} - -// PolicySecret is the input to TPM2_PolicySecret. -// See definition in Part 3, Commands, section 23.4. -type PolicySecret struct { - // handle for an entity providing the authorization - AuthHandle handle `gotpm:"handle,auth"` - // handle for the policy session being extended - PolicySession handle `gotpm:"handle"` - // the policy nonce for the session - NonceTPM TPM2BNonce - // digest of the command parameters to which this authorization is limited - CPHashA TPM2BDigest - // a reference to a policy relating to the authorization – may be the Empty Buffer - PolicyRef TPM2BNonce - // time when authorization will expire, measured in seconds from the time - // that nonceTPM was generated - Expiration int32 -} - -// Command implements the Command interface. -func (PolicySecret) Command() TPMCC { return TPMCCPolicySecret } - -// Execute executes the command and returns the response. -func (cmd PolicySecret) Execute(t transport.TPM, s ...Session) (*PolicySecretResponse, error) { - var rsp PolicySecretResponse - if err := execute[PolicySecretResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// Update implements the PolicyCommand interface. -func (cmd PolicySecret) Update(policy *PolicyCalculator) { - policyUpdate(policy, TPMCCPolicySecret, cmd.AuthHandle.KnownName().Buffer, cmd.PolicyRef.Buffer) -} - -// PolicySecretResponse is the response from TPM2_PolicySecret. -type PolicySecretResponse struct { - // implementation-specific time value used to indicate to the TPM when the ticket expires - Timeout TPM2BTimeout - // produced if the command succeeds and expiration in the command was non-zero - PolicyTicket TPMTTKAuth -} - -// PolicyOr is the input to TPM2_PolicyOR. -// See definition in Part 3, Commands, section 23.6. -type PolicyOr struct { - // handle for the policy session being extended - PolicySession handle `gotpm:"handle"` - // the list of hashes to check for a match - PHashList TPMLDigest -} - -// Command implements the Command interface. -func (PolicyOr) Command() TPMCC { return TPMCCPolicyOR } - -// Execute executes the command and returns the response. -func (cmd PolicyOr) Execute(t transport.TPM, s ...Session) (*PolicyOrResponse, error) { - var rsp PolicyOrResponse - err := execute[PolicyOrResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// Update implements the PolicyCommand interface. -func (cmd PolicyOr) Update(policy *PolicyCalculator) error { - policy.Reset() - var digests bytes.Buffer - for _, digest := range cmd.PHashList.Digests { - digests.Write(digest.Buffer) - } - return policy.Update(TPMCCPolicyOR, digests.Bytes()) -} - -// PolicyOrResponse is the response from TPM2_PolicyOr. -type PolicyOrResponse struct{} - -// PolicyPCR is the input to TPM2_PolicyPCR. -// See definition in Part 3, Commands, section 23.7. -type PolicyPCR struct { - // handle for the policy session being extended - PolicySession handle `gotpm:"handle"` - // expected digest value of the selected PCR using the - // hash algorithm of the session; may be zero length - PcrDigest TPM2BDigest - // the PCR to include in the check digest - Pcrs TPMLPCRSelection -} - -// Command implements the Command interface. -func (PolicyPCR) Command() TPMCC { return TPMCCPolicyPCR } - -// Execute executes the command and returns the response. -func (cmd PolicyPCR) Execute(t transport.TPM, s ...Session) (*PolicyPCRResponse, error) { - var rsp PolicyPCRResponse - err := execute[PolicyPCRResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// Update implements the PolicyCommand interface. -func (cmd PolicyPCR) Update(policy *PolicyCalculator) error { - return policy.Update(TPMCCPolicyPCR, cmd.Pcrs, cmd.PcrDigest.Buffer) -} - -// PolicyPCRResponse is the response from TPM2_PolicyPCR. -type PolicyPCRResponse struct{} - -// PolicyNV is the input to TPM2_PolicyNV. -// See definition in Part 3, Commands, section 23.9. -type PolicyNV struct { - // handle indicating the source of the authorization value - AuthHandle handle `gotpm:"handle,auth"` - // the NV Index of the area to read - NVIndex handle `gotpm:"handle"` - // handle for the policy session being extended - PolicySession handle `gotpm:"handle"` - // the second operand - OperandB TPM2BOperand - // the octet offset in the NV Index for the start of operand A - Offset uint16 - // the comparison to make - Operation TPMEO -} - -// Command implements the Command interface. -func (PolicyNV) Command() TPMCC { return TPMCCPolicyNV } - -// Execute executes the command and returns the response. -func (cmd PolicyNV) Execute(t transport.TPM, s ...Session) (*PolicyNVResponse, error) { - var rsp PolicyNVResponse - err := execute[PolicyNVResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// Update implements the PolicyCommand interface. -func (cmd PolicyNV) Update(policy *PolicyCalculator) error { - alg, err := policy.alg.Hash() - if err != nil { - return err - } - h := alg.New() - h.Write(cmd.OperandB.Buffer) - binary.Write(h, binary.BigEndian, cmd.Offset) - binary.Write(h, binary.BigEndian, cmd.Operation) - args := h.Sum(nil) - return policy.Update(TPMCCPolicyNV, args, cmd.NVIndex.KnownName().Buffer) -} - -// PolicyNVResponse is the response from TPM2_PolicyPCR. -type PolicyNVResponse struct{} - -// PolicyCommandCode is the input to TPM2_PolicyCommandCode. -// See definition in Part 3, Commands, section 23.11. -type PolicyCommandCode struct { - // handle for the policy session being extended - PolicySession handle `gotpm:"handle"` - // the allowed commandCode - Code TPMCC -} - -// Command implements the Command interface. -func (PolicyCommandCode) Command() TPMCC { return TPMCCPolicyCommandCode } - -// Execute executes the command and returns the response. -func (cmd PolicyCommandCode) Execute(t transport.TPM, s ...Session) (*PolicyCommandCodeResponse, error) { - var rsp PolicyCommandCodeResponse - err := execute[PolicyCommandCodeResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// Update implements the PolicyCommand interface. -func (cmd PolicyCommandCode) Update(policy *PolicyCalculator) error { - return policy.Update(TPMCCPolicyCommandCode, cmd.Code) -} - -// PolicyCommandCodeResponse is the response from TPM2_PolicyCommandCode. -type PolicyCommandCodeResponse struct{} - -// PolicyCPHash is the input to TPM2_PolicyCpHash. -// See definition in Part 3, Commands, section 23.13. -type PolicyCPHash struct { - // handle for the policy session being extended - PolicySession handle `gotpm:"handle"` - // the cpHash added to the policy - CPHashA TPM2BDigest -} - -// Command implements the Command interface. -func (PolicyCPHash) Command() TPMCC { return TPMCCPolicyCpHash } - -// Execute executes the command and returns the response. -func (cmd PolicyCPHash) Execute(t transport.TPM, s ...Session) (*PolicyCPHashResponse, error) { - var rsp PolicyCPHashResponse - err := execute[PolicyCPHashResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// Update implements the PolicyCommand interface. -func (cmd PolicyCPHash) Update(policy *PolicyCalculator) error { - return policy.Update(TPMCCPolicyCpHash, cmd.CPHashA.Buffer) -} - -// PolicyCPHashResponse is the response from TPM2_PolicyCpHash. -type PolicyCPHashResponse struct{} - -// PolicyAuthorize is the input to TPM2_PolicySigned. -// See definition in Part 3, Commands, section 23.16. -type PolicyAuthorize struct { - // handle for the policy session being extended - PolicySession handle `gotpm:"handle"` - // digest of the policy being approved - ApprovedPolicy TPM2BDigest - // a policy qualifier - PolicyRef TPM2BDigest - // Name of a key that can sign a policy addition - KeySign TPM2BName - // ticket validating that approvedPolicy and policyRef were signed by keySign - CheckTicket TPMTTKVerified -} - -// Command implements the Command interface. -func (PolicyAuthorize) Command() TPMCC { return TPMCCPolicyAuthorize } - -// Execute executes the command and returns the response. -func (cmd PolicyAuthorize) Execute(t transport.TPM, s ...Session) (*PolicyAuthorizeResponse, error) { - var rsp PolicyAuthorizeResponse - err := execute[PolicyAuthorizeResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// Update implements the PolicyCommand interface. -func (cmd PolicyAuthorize) Update(policy *PolicyCalculator) error { - return policyUpdate(policy, TPMCCPolicyAuthorize, cmd.KeySign.Buffer, cmd.PolicyRef.Buffer) -} - -// PolicyAuthorizeResponse is the response from TPM2_PolicyAuthorize. -type PolicyAuthorizeResponse struct{} - -// PolicyGetDigest is the input to TPM2_PolicyGetDigest. -// See definition in Part 3, Commands, section 23.19. -type PolicyGetDigest struct { - // handle for the policy session - PolicySession handle `gotpm:"handle"` -} - -// Command implements the Command interface. -func (PolicyGetDigest) Command() TPMCC { return TPMCCPolicyGetDigest } - -// Execute executes the command and returns the response. -func (cmd PolicyGetDigest) Execute(t transport.TPM, s ...Session) (*PolicyGetDigestResponse, error) { - var rsp PolicyGetDigestResponse - if err := execute[PolicyGetDigestResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// PolicyGetDigestResponse is the response from TPM2_PolicyGetDigest. -type PolicyGetDigestResponse struct { - // the current value of the policySession→policyDigest - PolicyDigest TPM2BDigest -} - -// PolicyNVWritten is the input to TPM2_PolicyNvWritten. -// See definition in Part 3, Commands, section 23.20. -type PolicyNVWritten struct { - // handle for the policy session being extended - PolicySession handle `gotpm:"handle"` - // YES if NV Index is required to have been written - // NO if NV Index is required not to have been written - WrittenSet TPMIYesNo -} - -// Command implements the Command interface. -func (PolicyNVWritten) Command() TPMCC { return TPMCCPolicyNvWritten } - -// Execute executes the command and returns the response. -func (cmd PolicyNVWritten) Execute(t transport.TPM, s ...Session) (*PolicyNVWrittenResponse, error) { - var rsp PolicyNVWrittenResponse - if err := execute[PolicyNVWrittenResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// Update implements the PolicyCommand interface. -func (cmd PolicyNVWritten) Update(policy *PolicyCalculator) error { - return policy.Update(TPMCCPolicyNvWritten, cmd.WrittenSet) -} - -// PolicyNVWrittenResponse is the response from TPM2_PolicyNvWritten. -type PolicyNVWrittenResponse struct { -} - -// PolicyAuthorizeNV is the input to TPM2_PolicyAuthorizeNV. -// See definition in Part 3, Commands, section 23.22. -type PolicyAuthorizeNV struct { - // handle indicating the source of the authorization value - AuthHandle handle `gotpm:"handle,auth"` - // the NV Index of the area to read - NVIndex handle `gotpm:"handle"` - // handle for the policy session being extended - PolicySession handle `gotpm:"handle"` -} - -// Command implements the Command interface. -func (PolicyAuthorizeNV) Command() TPMCC { return TPMCCPolicyAuthorizeNV } - -// Execute executes the command and returns the response. -func (cmd PolicyAuthorizeNV) Execute(t transport.TPM, s ...Session) (*PolicyAuthorizeNVResponse, error) { - var rsp PolicyAuthorizeNVResponse - err := execute[PolicyAuthorizeNVResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// Update implements the PolicyCommand interface. -func (cmd PolicyAuthorizeNV) Update(policy *PolicyCalculator) error { - policy.Reset() - return policy.Update(TPMCCPolicyAuthorizeNV, cmd.NVIndex.KnownName().Buffer) -} - -// PolicyAuthorizeNVResponse is the response from TPM2_PolicyAuthorizeNV. -type PolicyAuthorizeNVResponse struct{} - -// CreatePrimary is the input to TPM2_CreatePrimary. -// See definition in Part 3, Commands, section 24.1 -type CreatePrimary struct { - // TPM_RH_ENDORSEMENT, TPM_RH_OWNER, TPM_RH_PLATFORM+{PP}, - // or TPM_RH_NULL - PrimaryHandle handle `gotpm:"handle,auth"` - // the sensitive data - InSensitive TPM2BSensitiveCreate - // the public template - InPublic TPM2BPublic - // data that will be included in the creation data for this - // object to provide permanent, verifiable linkage between this - // object and some object owner data - OutsideInfo TPM2BData - // PCR that will be used in creation data - CreationPCR TPMLPCRSelection -} - -// Command implements the Command interface. -func (CreatePrimary) Command() TPMCC { return TPMCCCreatePrimary } - -// Execute executes the command and returns the response. -func (cmd CreatePrimary) Execute(t transport.TPM, s ...Session) (*CreatePrimaryResponse, error) { - var rsp CreatePrimaryResponse - if err := execute[CreatePrimaryResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// CreatePrimaryResponse is the response from TPM2_CreatePrimary. -type CreatePrimaryResponse struct { - // handle of type TPM_HT_TRANSIENT for created Primary Object - ObjectHandle TPMHandle `gotpm:"handle"` - // the public portion of the created object - OutPublic TPM2BPublic - // contains a TPMS_CREATION_DATA - CreationData tpm2bCreationData - // digest of creationData using nameAlg of outPublic - CreationHash TPM2BDigest - // ticket used by TPM2_CertifyCreation() to validate that the - // creation data was produced by the TPM. - CreationTicket TPMTTKCreation - // the name of the created object - Name TPM2BName -} - -// Clear is the input to TPM2_Clear. -// See definition in Part 3, Commands, section 24.6 -type Clear struct { - // TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP} - AuthHandle handle `gotpm:"handle,auth"` -} - -// Command implements the Command interface. -func (Clear) Command() TPMCC { return TPMCCClear } - -// Execute executes the command and returns the response. -func (cmd Clear) Execute(t transport.TPM, s ...Session) (*ClearResponse, error) { - var rsp ClearResponse - err := execute[ClearResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// ClearResponse is the response from TPM2_Clear. -type ClearResponse struct{} - -// ContextSave is the input to TPM2_ContextSave. -// See definition in Part 3, Commands, section 28.2 -type ContextSave struct { - // handle of the resource to save - SaveHandle TPMIDHContext -} - -// Command implements the Command interface. -func (ContextSave) Command() TPMCC { return TPMCCContextSave } - -// Execute executes the command and returns the response. -func (cmd ContextSave) Execute(t transport.TPM, s ...Session) (*ContextSaveResponse, error) { - var rsp ContextSaveResponse - if err := execute[ContextSaveResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// ContextSaveResponse is the response from TPM2_ContextSave. -type ContextSaveResponse struct { - Context TPMSContext -} - -// ContextLoad is the input to TPM2_ContextLoad. -// See definition in Part 3, Commands, section 28.3 -type ContextLoad struct { - // the context blob - Context TPMSContext -} - -// Command implements the Command interface. -func (ContextLoad) Command() TPMCC { return TPMCCContextLoad } - -// Execute executes the command and returns the response. -func (cmd ContextLoad) Execute(t transport.TPM, s ...Session) (*ContextLoadResponse, error) { - var rsp ContextLoadResponse - if err := execute[ContextLoadResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// ContextLoadResponse is the response from TPM2_ContextLoad. -type ContextLoadResponse struct { - // the handle assigned to the resource after it has been successfully loaded - LoadedHandle TPMIDHContext -} - -// FlushContext is the input to TPM2_FlushContext. -// See definition in Part 3, Commands, section 28.4 -type FlushContext struct { - // the handle of the item to flush - FlushHandle handle `gotpm:"handle"` -} - -// Command implements the Command interface. -func (FlushContext) Command() TPMCC { return TPMCCFlushContext } - -// Execute executes the command and returns the response. -func (cmd FlushContext) Execute(t transport.TPM, s ...Session) (*FlushContextResponse, error) { - var rsp FlushContextResponse - err := execute[FlushContextResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// FlushContextResponse is the response from TPM2_FlushContext. -type FlushContextResponse struct{} - -// GetCapability is the input to TPM2_GetCapability. -// See definition in Part 3, Commands, section 30.2 -type GetCapability struct { - // group selection; determines the format of the response - Capability TPMCap - // further definition of information - Property uint32 - // number of properties of the indicated type to return - PropertyCount uint32 -} - -// Command implements the Command interface. -func (GetCapability) Command() TPMCC { return TPMCCGetCapability } - -// Execute executes the command and returns the response. -func (cmd GetCapability) Execute(t transport.TPM, s ...Session) (*GetCapabilityResponse, error) { - var rsp GetCapabilityResponse - if err := execute[GetCapabilityResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// GetCapabilityResponse is the response from TPM2_GetCapability. -type GetCapabilityResponse struct { - // flag to indicate if there are more values of this type - MoreData TPMIYesNo - // the capability data - CapabilityData TPMSCapabilityData -} - -// NVDefineSpace is the input to TPM2_NV_DefineSpace. -// See definition in Part 3, Commands, section 31.3. -type NVDefineSpace struct { - // TPM_RH_OWNER or TPM_RH_PLATFORM+{PP} - AuthHandle handle `gotpm:"handle,auth"` - // the authorization value - Auth TPM2BAuth - // the public parameters of the NV area - PublicInfo TPM2BNVPublic -} - -// Command implements the Command interface. -func (NVDefineSpace) Command() TPMCC { return TPMCCNVDefineSpace } - -// Execute executes the command and returns the response. -func (cmd NVDefineSpace) Execute(t transport.TPM, s ...Session) (*NVDefineSpaceResponse, error) { - var rsp NVDefineSpaceResponse - err := execute[NVDefineSpaceResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// NVDefineSpaceResponse is the response from TPM2_NV_DefineSpace. -type NVDefineSpaceResponse struct{} - -// NVUndefineSpace is the input to TPM2_NV_UndefineSpace. -// See definition in Part 3, Commands, section 31.4. -type NVUndefineSpace struct { - // TPM_RH_OWNER or TPM_RH_PLATFORM+{PP} - AuthHandle handle `gotpm:"handle,auth"` - // the NV Index to remove from NV space - NVIndex handle `gotpm:"handle"` -} - -// Command implements the Command interface. -func (NVUndefineSpace) Command() TPMCC { return TPMCCNVUndefineSpace } - -// Execute executes the command and returns the response. -func (cmd NVUndefineSpace) Execute(t transport.TPM, s ...Session) (*NVUndefineSpaceResponse, error) { - var rsp NVUndefineSpaceResponse - err := execute[NVUndefineSpaceResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// NVUndefineSpaceResponse is the response from TPM2_NV_UndefineSpace. -type NVUndefineSpaceResponse struct{} - -// NVUndefineSpaceSpecial is the input to TPM2_NV_UndefineSpaceSpecial. -// See definition in Part 3, Commands, section 31.5. -type NVUndefineSpaceSpecial struct { - // Index to be deleted - NVIndex handle `gotpm:"handle,auth"` - // TPM_RH_PLATFORM+{PP} - Platform handle `gotpm:"handle,auth"` -} - -// Command implements the Command interface. -func (NVUndefineSpaceSpecial) Command() TPMCC { return TPMCCNVUndefineSpaceSpecial } - -// Execute executes the command and returns the response. -func (cmd NVUndefineSpaceSpecial) Execute(t transport.TPM, s ...Session) (*NVUndefineSpaceSpecialResponse, error) { - var rsp NVUndefineSpaceSpecialResponse - err := execute[NVUndefineSpaceSpecialResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// NVUndefineSpaceSpecialResponse is the response from TPM2_NV_UndefineSpaceSpecial. -type NVUndefineSpaceSpecialResponse struct{} - -// NVReadPublic is the input to TPM2_NV_ReadPublic. -// See definition in Part 3, Commands, section 31.6. -type NVReadPublic struct { - // the NV index - NVIndex handle `gotpm:"handle"` -} - -// Command implements the Command interface. -func (NVReadPublic) Command() TPMCC { return TPMCCNVReadPublic } - -// Execute executes the command and returns the response. -func (cmd NVReadPublic) Execute(t transport.TPM, s ...Session) (*NVReadPublicResponse, error) { - var rsp NVReadPublicResponse - if err := execute[NVReadPublicResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// NVReadPublicResponse is the response from TPM2_NV_ReadPublic. -type NVReadPublicResponse struct { - NVPublic TPM2BNVPublic - NVName TPM2BName -} - -// NVWrite is the input to TPM2_NV_Write. -// See definition in Part 3, Commands, section 31.7. -type NVWrite struct { - // handle indicating the source of the authorization value - AuthHandle handle `gotpm:"handle,auth"` - // the NV index of the area to write - NVIndex handle `gotpm:"handle"` - // the data to write - Data TPM2BMaxNVBuffer - // the octet offset into the NV Area - Offset uint16 -} - -// Command implements the Command interface. -func (NVWrite) Command() TPMCC { return TPMCCNVWrite } - -// Execute executes the command and returns the response. -func (cmd NVWrite) Execute(t transport.TPM, s ...Session) (*NVWriteResponse, error) { - var rsp NVWriteResponse - err := execute[NVWriteResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// NVWriteResponse is the response from TPM2_NV_Write. -type NVWriteResponse struct{} - -// NVIncrement is the input to TPM2_NV_Increment. -// See definition in Part 3, Commands, section 31.8. -type NVIncrement struct { - // handle indicating the source of the authorization value - AuthHandle handle `gotpm:"handle,auth"` - // the NV index of the area to write - NVIndex handle `gotpm:"handle"` -} - -// Command implements the Command interface. -func (NVIncrement) Command() TPMCC { return TPMCCNVIncrement } - -// Execute executes the command and returns the response. -func (cmd NVIncrement) Execute(t transport.TPM, s ...Session) (*NVIncrementResponse, error) { - var rsp NVIncrementResponse - err := execute[NVIncrementResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// NVIncrementResponse is the response from TPM2_NV_Increment. -type NVIncrementResponse struct{} - -// NVWriteLock is the input to TPM2_NV_WriteLock. -// See definition in Part 3, Commands, section 31.11. -type NVWriteLock struct { - // handle indicating the source of the authorization value - AuthHandle handle `gotpm:"handle,auth"` - // the NV index of the area to lock - NVIndex handle `gotpm:"handle"` -} - -// Command implements the Command interface. -func (NVWriteLock) Command() TPMCC { return TPMCCNVWriteLock } - -// Execute executes the command and returns the response. -func (cmd NVWriteLock) Execute(t transport.TPM, s ...Session) (*NVWriteLockResponse, error) { - var rsp NVWriteLockResponse - err := execute[NVWriteLockResponse](t, cmd, &rsp, s...) - if err != nil { - return nil, err - } - return &rsp, nil -} - -// NVWriteLockResponse is the response from TPM2_NV_WriteLock. -type NVWriteLockResponse struct{} - -// NVRead is the input to TPM2_NV_Read. -// See definition in Part 3, Commands, section 31.13. -type NVRead struct { - // handle indicating the source of the authorization value - AuthHandle handle `gotpm:"handle,auth"` - // the NV index to read - NVIndex handle `gotpm:"handle"` - // number of octets to read - Size uint16 - // octet offset into the NV area - Offset uint16 -} - -// Command implements the Command interface. -func (NVRead) Command() TPMCC { return TPMCCNVRead } - -// Execute executes the command and returns the response. -func (cmd NVRead) Execute(t transport.TPM, s ...Session) (*NVReadResponse, error) { - var rsp NVReadResponse - if err := execute[NVReadResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// NVReadResponse is the response from TPM2_NV_Read. -type NVReadResponse struct { - // the data read - Data TPM2BMaxNVBuffer -} - -// NVCertify is the input to TPM2_NV_Certify. -// See definition in Part 3, Commands, section 31.16. -type NVCertify struct { - // handle of the key used to sign the attestation structure - SignHandle handle `gotpm:"handle,auth"` - // handle indicating the source of the authorization value - AuthHandle handle `gotpm:"handle,auth"` - // Index for the area to be certified - NVIndex handle `gotpm:"handle"` - // user-provided qualifying data - QualifyingData TPM2BData - // signing scheme to use if the scheme for signHandle is TPM_ALG_NULL - InScheme TPMTSigScheme `gotpm:"nullable"` - // number of octets to certify - Size uint16 - // octet offset into the NV area - Offset uint16 -} - -// Command implements the Command interface. -func (NVCertify) Command() TPMCC { return TPMCCNVCertify } - -// Execute executes the command and returns the response. -func (cmd NVCertify) Execute(t transport.TPM, s ...Session) (*NVCertifyResponse, error) { - var rsp NVCertifyResponse - if err := execute[NVCertifyResponse](t, cmd, &rsp, s...); err != nil { - return nil, err - } - return &rsp, nil -} - -// NVCertifyResponse is the response from TPM2_NV_Read. -type NVCertifyResponse struct { - // the structure that was signed - CertifyInfo TPM2BAttest - // the asymmetric signature over certifyInfo using the key referenced by signHandle - Signature TPMTSignature -} diff --git a/vendor/github.com/google/go-tpm/tpm2/tpm2b.go b/vendor/github.com/google/go-tpm/tpm2/tpm2b.go deleted file mode 100644 index f5af16ab5f..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/tpm2b.go +++ /dev/null @@ -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 -} diff --git a/vendor/github.com/google/go-tpm/tpm2/transport/open_other.go b/vendor/github.com/google/go-tpm/tpm2/transport/open_other.go deleted file mode 100644 index 83fb0eeb2e..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/transport/open_other.go +++ /dev/null @@ -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 -} diff --git a/vendor/github.com/google/go-tpm/tpm2/transport/open_windows.go b/vendor/github.com/google/go-tpm/tpm2/transport/open_windows.go deleted file mode 100644 index 001ee8e7bd..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/transport/open_windows.go +++ /dev/null @@ -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 -} diff --git a/vendor/github.com/google/go-tpm/tpm2/transport/tpm.go b/vendor/github.com/google/go-tpm/tpm2/transport/tpm.go deleted file mode 100644 index 95a63f48ac..0000000000 --- a/vendor/github.com/google/go-tpm/tpm2/transport/tpm.go +++ /dev/null @@ -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() -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 1996c12cdb..d3733663e4 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -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