diff --git a/direct/structures/internal/structures.go b/direct/structures/internal/structures.go index be75d7a7..78af6ed0 100644 --- a/direct/structures/internal/structures.go +++ b/direct/structures/internal/structures.go @@ -1101,13 +1101,18 @@ type TPMSSigSchemeRSAPSS TPMSSchemeHash // See definition in Part 2: Structures, section 11.2.1.3. type TPMSSigSchemeECDSA TPMSSchemeHash +// TPMSSigSchemeECDAA represents a TPMS_SIG_SCHEME_ECDAA. +// See definition in Part 2: Structures, section 11.2.1.3. +type TPMSSigSchemeECDAA TPMSSchemeECDAA + // TPMUSigScheme represents a TPMU_SIG_SCHEME. // See definition in Part 2: Structures, section 11.2.1.4. type TPMUSigScheme struct { - HMAC *TPMSSchemeHMAC `gotpm:"selector=0x0005"` // TPM_ALG_HMAC - RSASSA *TPMSSchemeHash `gotpm:"selector=0x0014"` // TPM_ALG_RSASSA - RSAPSS *TPMSSchemeHash `gotpm:"selector=0x0016"` // TPM_ALG_RSAPSS - ECDSA *TPMSSchemeHash `gotpm:"selector=0x0018"` // TPM_ALG_ECDSA + HMAC *TPMSSchemeHMAC `gotpm:"selector=0x0005"` // TPM_ALG_HMAC + RSASSA *TPMSSchemeHash `gotpm:"selector=0x0014"` // TPM_ALG_RSASSA + RSAPSS *TPMSSchemeHash `gotpm:"selector=0x0016"` // TPM_ALG_RSAPSS + ECDSA *TPMSSchemeHash `gotpm:"selector=0x0018"` // TPM_ALG_ECDSA + ECDAA *TPMSSchemeECDAA `gotpm:"selector=0x001a"` // TPM_ALG_ECDAA } // TPMTSigScheme represents a TPMT_SIG_SCHEME. @@ -1178,6 +1183,7 @@ type TPMUAsymScheme struct { OAEP *TPMSEncSchemeOAEP `gotpm:"selector=0x0017"` // TPM_ALG_OAEP ECDSA *TPMSSigSchemeECDSA `gotpm:"selector=0x0018"` // TPM_ALG_ECDSA ECDH *TPMSKeySchemeECDH `gotpm:"selector=0x0019"` // TPM_ALG_ECDH + ECDAA *TPMSSigSchemeECDAA `gotpm:"selector=0x001a"` // TPM_ALG_ECDAA } // TPMIAlgRSAScheme represents a TPMI_ALG_RSA_SCHEME. @@ -1218,6 +1224,12 @@ type TPMSECCPoint struct { Y TPM2BECCParameter } +// TPM2BECCPoint represents a TPM2B_ECC_POINT. +// See definition in Part 2: Structures, section 11.2.5.3. +type TPM2BECCPoint struct { + Point TPMSECCPoint `gotpm:"sized"` +} + // TPMIAlgECCScheme represents a TPMI_ALG_ECC_SCHEME. // See definition in Part 2: Structures, section 11.2.5.4. type TPMIAlgECCScheme = TPMAlgID diff --git a/direct/structures/tpm2b/tpm2b.go b/direct/structures/tpm2b/tpm2b.go index 4a71f325..5c88863b 100644 --- a/direct/structures/tpm2b/tpm2b.go +++ b/direct/structures/tpm2b/tpm2b.go @@ -82,6 +82,10 @@ type PrivateKeyRSA = internal.TPM2BPrivateKeyRSA // See definition in Part 2: Structures, section 11.2.5.1. type ECCParameter = internal.TPM2BECCParameter +// ECCPoint represents a TPM2B_ECC_POINT. +// See definition in Part 2: Structures, section 11.2.5.3 +type ECCPoint = internal.TPM2BECCPoint + // EncryptedSecret represents a TPM2B_ENCRYPTED_SECRET. // See definition in Part 2: Structures, section 11.4.33. type EncryptedSecret = internal.TPM2BEncryptedSecret diff --git a/direct/structures/tpms/tpms.go b/direct/structures/tpms/tpms.go index dec26397..d5d36de3 100644 --- a/direct/structures/tpms/tpms.go +++ b/direct/structures/tpms/tpms.go @@ -127,6 +127,10 @@ type SigSchemeRSAPSS = internal.TPMSSigSchemeRSAPSS // See definition in Part 2: Structures, section 11.2.1.3. type SigSchemeECDSA = internal.TPMSSigSchemeECDSA +// SigSchemeECDAA represents a TPMS_SIG_SCHEME_ECDAA. +// See definition in Part 2: Structures, section 11.2.1.3. +type SigSchemeECDAA = internal.TPMSSigSchemeECDAA + // EncSchemeRSAES represents a TPMS_ENC_SCHEME_RSAES. // See definition in Part 2: Structures, section 11.2.2.2. type EncSchemeRSAES = internal.TPMSEncSchemeRSAES diff --git a/direct/tpm2/commit_test.go b/direct/tpm2/commit_test.go new file mode 100644 index 00000000..5f325a15 --- /dev/null +++ b/direct/tpm2/commit_test.go @@ -0,0 +1,117 @@ +package tpm2 + +import ( + "testing" + + "github.com/google/go-tpm/direct/structures/tpm" + "github.com/google/go-tpm/direct/structures/tpm2b" + "github.com/google/go-tpm/direct/structures/tpma" + "github.com/google/go-tpm/direct/structures/tpms" + "github.com/google/go-tpm/direct/structures/tpmt" + "github.com/google/go-tpm/direct/structures/tpmu" + "github.com/google/go-tpm/direct/transport/simulator" +) + +func TestCommit(t *testing.T) { + thetpm, err := simulator.OpenSimulator() + if err != nil { + t.Fatalf("could not connect to TPM simulator: %v", err) + } + + defer thetpm.Close() + + password := []byte("hello") + + create := CreateLoaded{ + ParentHandle: tpm.RHOwner, + InSensitive: tpm2b.SensitiveCreate{ + Sensitive: tpms.SensitiveCreate{ + UserAuth: tpm2b.Auth{ + Buffer: password, + }, + }, + }, + InPublic: tpm2b.Template{ + Template: tpmt.Public{ + Type: tpm.AlgECC, + NameAlg: tpm.AlgSHA256, + ObjectAttributes: tpma.Object{ + FixedTPM: true, + FixedParent: true, + UserWithAuth: true, + SensitiveDataOrigin: true, + SignEncrypt: true, + }, + Parameters: tpmu.PublicParms{ + ECCDetail: &tpms.ECCParms{ + Symmetric: tpmt.SymDefObject{ + Algorithm: tpm.AlgNull, + }, + Scheme: tpmt.ECCScheme{ + Scheme: tpm.AlgECDAA, + Details: tpmu.AsymScheme{ + ECDAA: &tpms.SigSchemeECDAA{ + HashAlg: tpm.AlgSHA256, + }, + }, + }, + CurveID: tpm.ECCBNP256, + KDF: tpmt.KDFScheme{ + Scheme: tpm.AlgNull, + }, + }, + }, + }, + }, + } + + rspCP, err := create.Execute(thetpm) + if err != nil { + t.Fatalf("could not create key: %v", err) + } + + flushContextCP := FlushContext{FlushHandle: rspCP.ObjectHandle} + defer flushContextCP.Execute(thetpm) + + commit := Commit{ + SignHandle: AuthHandle{ + Handle: rspCP.ObjectHandle, + Name: rspCP.Name, + Auth: PasswordAuth(password), + }, + P1: tpm2b.ECCPoint{ + Point: tpms.ECCPoint{ + X: tpm2b.ECCParameter{ + Buffer: []byte{1}, + }, + Y: tpm2b.ECCParameter{ + Buffer: []byte{2}, + }, + }, + }, + S2: tpm2b.SensitiveData{ + Buffer: []byte{}, + }, + Y2: tpm2b.ECCParameter{ + Buffer: []byte{}, + }, + } + + resp, err := commit.Execute(thetpm) + if err != nil { + t.Fatalf("could not commit: %v", err) + } + + firstCounter := resp.Counter + + resp, err = commit.Execute(thetpm) + if err != nil { + t.Fatalf("could not commit: %v", err) + } + + secondCounter := resp.Counter + + if firstCounter+1 != secondCounter { + t.Fatalf("counter did not increment") + } +} diff --git a/direct/tpm2/tpm2.go b/direct/tpm2/tpm2.go index 703e917e..0c709e13 100644 --- a/direct/tpm2/tpm2.go +++ b/direct/tpm2/tpm2.go @@ -377,7 +377,7 @@ type CreateLoadedResponse struct { // handle of type TPM_HT_TRANSIENT for loaded object ObjectHandle tpm.Handle `gotpm:"handle"` // the sensitive area of the object (optional) - OutPrivate *tpm2b.Private `gotpm:"optional"` + OutPrivate tpm2b.Private `gotpm:"optional"` // the public portion of the created object OutPublic tpm2b.Public // the name of the created object @@ -694,6 +694,47 @@ type GetSessionAuditDigestResponse struct { // Response implements the Response interface. func (*GetSessionAuditDigestResponse) Response() tpm.CC { return tpm.CCGetSessionAuditDigest } +// 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 tpm2b.ECCPoint + // octet array used to derive x-coordinate of a base point + S2 tpm2b.SensitiveData + // y coordinate of the point associated with s2 + Y2 tpm2b.ECCParameter +} + +// Command implements the Command interface. +func (*Commit) Command() tpm.CC { return tpm.CCCommit } + +// 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(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 tpm2b.ECCPoint + // ECC point L ≔ [r](x2, y2) + L tpm2b.ECCPoint + // ECC point E ≔ [r]P1 + E tpm2b.ECCPoint + // least-significant 16 bits of commitCount + Counter uint16 +} + +// Response implements the Response interface. +func (*CommitResponse) Response() tpm.CC { return tpm.CCCommit } + // VerifySignature is the input to TPM2_VerifySignature. // See definition in Part 3, Commands, section 20.1 type VerifySignature struct {