Skip to content

Commit

Permalink
Bump go to 1.22 and golangci-lint to 1.56.2 (#353)
Browse files Browse the repository at this point in the history
* Bump go to 1.22 and golangci-lint to 1.56.2

* Use single assignment of ECC curve in test
  • Loading branch information
nckrss authored Apr 11, 2024
1 parent 08987ce commit 6b2397c
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 56 deletions.
15 changes: 1 addition & 14 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,4 @@ lint_task:
- GOOS: linux
- GOOS: windows
lint_script:
golangci-lint run
-D errcheck
-E stylecheck
-E goimports
-E misspell
-E revive
--exclude-use-default=false
--exclude stutters
--exclude underscores
--exclude unexported-return
--max-same-issues=0
--max-issues-per-linter=0
./tpmutil/...
./tpm2/...
golangci-lint run ./tpmutil/... ./tpm2/...
21 changes: 21 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
linters:
disable:
- errcheck
enable:
- stylecheck
- goimports
- misspell
- revive
linters-settings:
revive:
rules:
- name: dot-imports
disabled: true
issues:
exclude-use-default: false
exclude:
- stutters
- underscores
- unexported-return
max-issues-per-linter: 0
max-same-issues: 0
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
FROM golang:1.21
FROM golang:1.22
# We need OpenSSL headers to build the simulator
RUN apt-get update && apt-get install -y \
libssl-dev \
&& rm -rf /var/lib/apt/lists/*
# We need golangci-lint for linting
ARG VERSION=1.52.2
ARG VERSION=1.56.2
RUN curl -SL \
https://github.com/golangci/golangci-lint/releases/download/v${VERSION}/golangci-lint-${VERSION}-linux-amd64.tar.gz \
--output golangci.tar.gz \
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/google/go-tpm

go 1.20
go 1.22

require (
github.com/google/go-cmp v0.5.9
Expand Down
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-sev-guest v0.6.1 h1:NajHkAaLqN9/aW7bCFSUplUMtDgk2+HcN7jC2btFtk0=
github.com/google/go-sev-guest v0.6.1/go.mod h1:UEi9uwoPbLdKGl1QHaq1G8pfCbQ4QP0swWX4J0k6r+Q=
github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc=
github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc=
github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ=
github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
63 changes: 48 additions & 15 deletions tpm2/crypto.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package tpm2

import (
"crypto/ecdh"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rsa"
"fmt"
"math/big"
)

Expand All @@ -21,23 +24,53 @@ func RSAPub(parms *TPMSRSAParms, pub *TPM2BPublicKeyRSA) (*rsa.PublicKey, error)
return &result, nil
}

// ECDHPub is a convenience wrapper around the necessary info to perform point
// multiplication with the elliptic package.
type ECDHPub struct {
Curve elliptic.Curve
X, Y *big.Int
}
// ECDHPubKey converts a TPM ECC public key into one recognized by the ecdh package
func ECDHPubKey(curve ecdh.Curve, pub *TPMSECCPoint) (*ecdh.PublicKey, error) {

// ECCPub converts a TPM ECC public key into one recognized by the elliptic
// package's point-multiplication functions, for use in ECDH.
func ECCPub(parms *TPMSECCParms, pub *TPMSECCPoint) (*ECDHPub, error) {
curve, err := parms.CurveID.Curve()
if err != nil {
return nil, err
var c elliptic.Curve
switch curve {
case ecdh.P256():
c = elliptic.P256()
case ecdh.P384():
c = elliptic.P384()
case ecdh.P521():
c = elliptic.P521()
default:
return nil, fmt.Errorf("unknown curve: %v", curve)
}
return &ECDHPub{
Curve: curve,

pubKey := ecdsa.PublicKey{
Curve: c,
X: big.NewInt(0).SetBytes(pub.X.Buffer),
Y: big.NewInt(0).SetBytes(pub.Y.Buffer),
}, nil
}

return pubKey.ECDH()
}

// ECCPoint returns an uncompressed ECC Point
func ECCPoint(pubKey *ecdh.PublicKey) (*big.Int, *big.Int, error) {
b := pubKey.Bytes()
size, err := elementLength(pubKey.Curve())
if err != nil {
return nil, nil, fmt.Errorf("ECCPoint: %w", err)
}
return big.NewInt(0).SetBytes(b[1 : size+1]),
big.NewInt(0).SetBytes(b[size+1:]), nil
}

func elementLength(c ecdh.Curve) (int, error) {
switch c {
case ecdh.P256():
// crypto/internal/nistec/fiat.p256ElementLen
return 32, nil
case ecdh.P384():
// crypto/internal/nistec/fiat.p384ElementLen
return 48, nil
case ecdh.P521():
// crypto/internal/nistec/fiat.p521ElementLen
return 66, nil
default:
return 0, fmt.Errorf("unknown element length for curve: %v", c)
}
}
4 changes: 2 additions & 2 deletions tpm2/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -839,9 +839,9 @@ func marshalParameter[R any](buf *bytes.Buffer, cmd Command[R, *R], i int) error
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)
}

return marshal(buf, parm)
}

// cmdParameters returns the parameters area of the command.
Expand Down
34 changes: 20 additions & 14 deletions tpm2/sessions.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/elliptic"
"crypto/hmac"
"crypto/rand"
"crypto/rsa"
Expand Down Expand Up @@ -425,24 +424,31 @@ func getEncryptedSaltRSA(nameAlg TPMIAlgHash, parms *TPMSRSAParms, pub *TPM2BPub

// Part 1, 19.6.13
func getEncryptedSaltECC(nameAlg TPMIAlgHash, parms *TPMSECCParms, pub *TPMSECCPoint) (*TPM2BEncryptedSecret, []byte, error) {
curve, err := parms.CurveID.Curve()
curve, err := parms.CurveID.ECDHCurve()
if err != nil {
return nil, nil, fmt.Errorf("could not encrypt salt to ECC key: %w", err)
return nil, nil, fmt.Errorf("ecc salt: param curve: %w", err)
}
eccPub, err := ECCPub(parms, pub)
eccPub, err := ECDHPubKey(curve, pub)
if err != nil {
return nil, nil, fmt.Errorf("could not encrypt salt to ECC key: %w", err)
return nil, nil, fmt.Errorf("ecc salt: unmarshalling tpm ecc key: %w", err)
}
ephPriv, ephPubX, ephPubY, err := elliptic.GenerateKey(curve, rand.Reader)

// Generate new ECDH key
ephPriv, err := curve.GenerateKey(rand.Reader)
if err != nil {
return nil, nil, fmt.Errorf("ecc salt: generating ecc private key: %w", err)
}
ephPubX, ephPubY, err := ECCPoint(ephPriv.PublicKey())
if err != nil {
return nil, nil, fmt.Errorf("ecc salt: ecc pubkey: %w", err)
}

// Calculate Z (ECDH key * TPM pub)
z, err := ephPriv.ECDH(eccPub)
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)
return nil, nil, fmt.Errorf("ecc salt: z calc: %w", err)
}

ha, err := nameAlg.Hash()
if err != nil {
return nil, nil, err
Expand Down
15 changes: 15 additions & 0 deletions tpm2/structures.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package tpm2
import (
"bytes"
"crypto"
"crypto/ecdh"
"crypto/elliptic"
"encoding/binary"
"reflect"
Expand Down Expand Up @@ -96,6 +97,20 @@ func (c TPMECCCurve) Curve() (elliptic.Curve, error) {
}
}

// ECDHCurve returns the ecdh.Curve associated with a TPMECCCurve.
func (c TPMECCCurve) ECDHCurve() (ecdh.Curve, error) {
switch c {
case TPMECCNistP256:
return ecdh.P256(), nil
case TPMECCNistP384:
return ecdh.P384(), nil
case TPMECCNistP521:
return ecdh.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 {
Expand Down
27 changes: 19 additions & 8 deletions tpm2/test/ecdh_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package tpm2test

import (
"crypto/elliptic"
"crypto/ecdh"
"crypto/rand"
"math/big"
"testing"

"github.com/google/go-cmp/cmp"
Expand Down Expand Up @@ -57,6 +56,9 @@ func TestECDH(t *testing.T) {
}),
}

// 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)
Expand All @@ -69,24 +71,33 @@ func TestECDH(t *testing.T) {
if err != nil {
t.Fatalf("%v", err)
}
tpmX := big.NewInt(0).SetBytes(tpmPub.X.Buffer)
tpmY := big.NewInt(0).SetBytes(tpmPub.Y.Buffer)
tpmPubKey, err := ECDHPubKey(curve, tpmPub)
if err != nil {
t.Fatalf("could not unmarshall pubkey: %v", err)
}

// Create a SW ECDH key
priv, x, y, err := elliptic.GenerateKey(elliptic.P256(), rand.Reader)
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, zy := elliptic.P256().ScalarMult(tpmX, tpmY, priv)
zx, err := swPriv.ECDH(tpmPubKey)
if err != nil {
t.Fatalf("ecdh exchange: %v", err)
}

z := TPMSECCPoint{
X: TPM2BECCParameter{Buffer: zx.FillBytes(make([]byte, 32))},
Y: TPM2BECCParameter{Buffer: zy.FillBytes(make([]byte, 32))},
X: TPM2BECCParameter{Buffer: zx},
}

// Calculate Z based on TPM priv * SW pub
Expand Down

0 comments on commit 6b2397c

Please sign in to comment.