1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
package tpm2test
import (
"crypto/ecdh"
"crypto/rand"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
. "github.com/google/go-tpm/tpm2"
"github.com/google/go-tpm/tpm2/transport/simulator"
)
func TestECDH(t *testing.T) {
thetpm, err := simulator.OpenSimulator()
if err != nil {
t.Fatalf("could not connect to TPM simulator: %v", err)
}
defer thetpm.Close()
// Create a TPM ECDH key
tpmCreate := CreatePrimary{
PrimaryHandle: TPMRHOwner,
InPublic: New2B(TPMTPublic{
Type: TPMAlgECC,
NameAlg: TPMAlgSHA256,
ObjectAttributes: TPMAObject{
FixedTPM: true,
STClear: false,
FixedParent: true,
SensitiveDataOrigin: true,
UserWithAuth: true,
AdminWithPolicy: false,
NoDA: true,
EncryptedDuplication: false,
Restricted: false,
Decrypt: true,
SignEncrypt: false,
X509Sign: false,
},
Parameters: NewTPMUPublicParms(
TPMAlgECC,
&TPMSECCParms{
CurveID: TPMECCNistP256,
Scheme: TPMTECCScheme{
Scheme: TPMAlgECDH,
Details: NewTPMUAsymScheme(
TPMAlgECDH,
&TPMSKeySchemeECDH{
HashAlg: TPMAlgSHA256,
},
),
},
},
),
}),
}
// Use NIST P-256
curve := ecdh.P256()
tpmCreateRsp, err := tpmCreate.Execute(thetpm)
if err != nil {
t.Fatalf("could not create the TPM key: %v", err)
}
outPub, err := tpmCreateRsp.OutPublic.Contents()
if err != nil {
t.Fatalf("%v", err)
}
tpmPub, err := outPub.Unique.ECC()
if err != nil {
t.Fatalf("%v", err)
}
eccParms, err := outPub.Parameters.ECCDetail()
if err != nil {
t.Fatalf("%v", err)
}
tpmPubKey, err := ECDHPub(eccParms, tpmPub)
if err != nil {
t.Fatalf("could not unmarshal pubkey: %v", err)
}
// Create a SW ECDH key
swPriv, err := curve.GenerateKey(rand.Reader)
if err != nil {
t.Fatalf("could not create the SW key: %v", err)
}
x, y, err := ECCPoint(swPriv.PublicKey())
if err != nil {
t.Fatalf("could not get SW key point: %v", err)
}
swPub := TPMSECCPoint{
X: TPM2BECCParameter{Buffer: x.FillBytes(make([]byte, 32))},
Y: TPM2BECCParameter{Buffer: y.FillBytes(make([]byte, 32))},
}
// Calculate Z based on the SW priv * TPM pub
zx, err := swPriv.ECDH(tpmPubKey)
if err != nil {
t.Fatalf("ecdh exchange: %v", err)
}
z := TPMSECCPoint{
X: TPM2BECCParameter{Buffer: zx},
}
// Calculate Z based on TPM priv * SW pub
ecdh := ECDHZGen{
KeyHandle: AuthHandle{
Handle: tpmCreateRsp.ObjectHandle,
Name: tpmCreateRsp.Name,
Auth: PasswordAuth(nil),
},
InPoint: New2B(swPub),
}
ecdhRsp, err := ecdh.Execute(thetpm)
if err != nil {
t.Fatalf("ECDH_ZGen failed: %v", err)
}
outPoint, err := ecdhRsp.OutPoint.Contents()
if err != nil {
t.Fatalf("%v", err)
}
if !cmp.Equal(z.X, outPoint.X, cmpopts.IgnoreUnexported(z.X)) {
t.Errorf("want %x got %x", z, outPoint)
}
}
|