Skip to content

Commit

Permalink
Fix comments from code review
Browse files Browse the repository at this point in the history
This commit also adds a way to define the SRK template used to load the
blobs into the TPM.
  • Loading branch information
maraino committed Nov 2, 2023
1 parent 4ae4220 commit 5d3c0cf
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 35 deletions.
15 changes: 7 additions & 8 deletions tpm/tss2/encode.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package tss2

import (
"encoding/pem"
import "encoding/pem"

"github.com/google/go-tpm/legacy/tpm2"
)
// handle owner is the reserver handler TPM_RH_OWNER.
const handleOwner = 0x40000001

// TPMOption is the type used to modify a [TPMKey].
type TPMOption func(*TPMKey)
Expand All @@ -14,9 +13,9 @@ func New(pub, priv []byte, opts ...TPMOption) *TPMKey {
key := &TPMKey{
Type: oidLoadableKey,
EmptyAuth: true,
Parent: int(tpm2.HandleOwner),
PublicKey: integrityPrefix(pub),
PrivateKey: integrityPrefix(priv),
Parent: handleOwner,
PublicKey: addPrefixLength(pub),
PrivateKey: addPrefixLength(priv),
}
for _, fn := range opts {
fn(key)
Expand Down Expand Up @@ -56,7 +55,7 @@ func EncodeToMemory(pub, priv []byte, opts ...TPMOption) ([]byte, error) {
return New(pub, priv, opts...).EncodeToMemory()
}

func integrityPrefix(b []byte) []byte {
func addPrefixLength(b []byte) []byte {
s := len(b)
return append([]byte{byte(s >> 8 & 0xFF), byte(s & 0xFF)}, b...)
}
1 change: 0 additions & 1 deletion tpm/tss2/encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ MCgGBmeBBQoBA6ADAQH/AgRAAAABBAgABnB1YmxpYwQJAAdwcml2YXRl
got, err := tt.tpmKey.EncodeToMemory()
tt.assertion(t, err)
assert.Equal(t, tt.want, got)
t.Log(string(got))
})
}
}
Expand Down
81 changes: 59 additions & 22 deletions tpm/tss2/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,33 +31,55 @@ import (
"github.com/google/go-tpm/tpmutil"
)

var primaryParams = tpm2.Public{
Type: tpm2.AlgECC,
NameAlg: tpm2.AlgSHA256,
Attributes: tpm2.FlagStorageDefault,
ECCParameters: &tpm2.ECCParams{
Symmetric: &tpm2.SymScheme{
Alg: tpm2.AlgAES,
KeyBits: 128,
Mode: tpm2.AlgCFB,
var (
// 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 = tpm2.Public{
Type: tpm2.AlgECC,
NameAlg: tpm2.AlgSHA256,
Attributes: tpm2.FlagStorageDefault | tpm2.FlagNoDA,
ECCParameters: &tpm2.ECCParams{
Symmetric: &tpm2.SymScheme{
Alg: tpm2.AlgAES,
KeyBits: 128,
Mode: tpm2.AlgCFB,
},
Sign: &tpm2.SigScheme{
Alg: tpm2.AlgNull,
},
CurveID: tpm2.CurveNISTP256,
},
Sign: &tpm2.SigScheme{
Alg: tpm2.AlgNull,
}

// 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 = tpm2.Public{
Type: tpm2.AlgRSA,
NameAlg: tpm2.AlgSHA256,
Attributes: tpm2.FlagStorageDefault | tpm2.FlagNoDA,
RSAParameters: &tpm2.RSAParams{
Symmetric: &tpm2.SymScheme{
Alg: tpm2.AlgAES,
KeyBits: 128,
Mode: tpm2.AlgCFB,
},
ModulusRaw: make([]byte, 256),
KeyBits: 2048,
},
CurveID: tpm2.CurveNISTP256,
},
}
}
)

// Signer implements [crypto.Signer] using a [TPMKey].
type Signer struct {
rw io.ReadWriter
publicKey crypto.PublicKey
tpmKey *TPMKey
rw io.ReadWriter
publicKey crypto.PublicKey
tpmKey *TPMKey
srkTemplate tpm2.Public
}

// CreateSigner creates a new [crypto.Signer] with the given TPM (rw) and
// [TPMKey]. The caller is responsible of opening and closing the TPM.
func CreateSigner(rw io.ReadWriter, key *TPMKey) (crypto.Signer, error) {
func CreateSigner(rw io.ReadWriter, key *TPMKey) (*Signer, error) {
switch {
case rw == nil:
return nil, fmt.Errorf("invalid TPM channel: rw cannot be nil")
Expand Down Expand Up @@ -90,20 +112,35 @@ func CreateSigner(rw io.ReadWriter, key *TPMKey) (crypto.Signer, error) {
}

Check warning on line 112 in tpm/tss2/signer.go

View check run for this annotation

Codecov / codecov/patch

tpm/tss2/signer.go#L111-L112

Added lines #L111 - L112 were not covered by tests

return &Signer{
rw: rw,
publicKey: publicKey,
tpmKey: key,
rw: rw,
publicKey: publicKey,
tpmKey: key,
srkTemplate: RSASRKTemplate,
}, nil
}

// SetSRKTemplate allows to change the Storage Primary Key (SRK) template used
// to load the the public/private blobs into an object in the TPM.
//
// It currently defaults to [RSASRKTemplate], the same used ad default in the
// [go.step.sm/crypto/tpm] package.
//
// # Experimental
//
// Notice: This API is EXPERIMENTAL and may be changed or removed in a later
// release.
func (s *Signer) SetSRKTemplate(p tpm2.Public) {
s.srkTemplate = p

Check warning on line 133 in tpm/tss2/signer.go

View check run for this annotation

Codecov / codecov/patch

tpm/tss2/signer.go#L132-L133

Added lines #L132 - L133 were not covered by tests
}

func (s *Signer) Public() crypto.PublicKey {
return s.publicKey

Check warning on line 137 in tpm/tss2/signer.go

View check run for this annotation

Codecov / codecov/patch

tpm/tss2/signer.go#L136-L137

Added lines #L136 - L137 were not covered by tests
}

func (s *Signer) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
parentHandle := tpmutil.Handle(s.tpmKey.Parent)
if !handleIsPersistent(s.tpmKey.Parent) {
parentHandle, _, err = tpm2.CreatePrimary(s.rw, parentHandle, tpm2.PCRSelection{}, "", "", primaryParams)
parentHandle, _, err = tpm2.CreatePrimary(s.rw, parentHandle, tpm2.PCRSelection{}, "", "", s.srkTemplate)
if err != nil {
return nil, fmt.Errorf("error creating primary: %w", err)
}
Expand Down
11 changes: 7 additions & 4 deletions tpm/tss2/signer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func TestSign(t *testing.T) {
assert.NoError(t, rw.Close())
})

keyHnd, _, err := tpm2.CreatePrimary(rw, tpm2.HandleOwner, tpm2.PCRSelection{}, "", "", primaryParams)
keyHnd, _, err := tpm2.CreatePrimary(rw, tpm2.HandleOwner, tpm2.PCRSelection{}, "", "", ECCSRKTemplate)
require.NoError(t, err)
t.Cleanup(func() {
assert.NoError(t, tpm2.FlushContext(rw, keyHnd))
Expand All @@ -85,6 +85,9 @@ func TestSign(t *testing.T) {
signer, err := CreateSigner(rw, New(pub, priv))
require.NoError(t, err)

// Set the ECC SRK template used for testing.
signer.SetSRKTemplate(ECCSRKTemplate)

hash := crypto.SHA256.New()
hash.Write([]byte("rulingly-quailed-cloacal-indifferentist-roughhoused-self-mad"))
sum := hash.Sum(nil)
Expand Down Expand Up @@ -139,11 +142,11 @@ func TestCreateSigner(t *testing.T) {
tests := []struct {
name string
args args
want crypto.Signer
want *Signer
assertion assert.ErrorAssertionFunc
}{
{"ok", args{&rw, key}, &Signer{
rw: &rw, publicKey: publicKey, tpmKey: key,
rw: &rw, publicKey: publicKey, tpmKey: key, srkTemplate: RSASRKTemplate,
}, assert.NoError},
{"fail rw", args{nil, key}, nil, assert.Error},
{"fail type", args{&rw, modKey(func(k *TPMKey) {
Expand Down Expand Up @@ -186,7 +189,7 @@ func TestCreateSigner(t *testing.T) {
}
b, err := p.Encode()
if assert.NoError(t, err) {
k.PublicKey = integrityPrefix(b)
k.PublicKey = addPrefixLength(b)
}
})}, nil, assert.Error},
}
Expand Down

0 comments on commit 5d3c0cf

Please sign in to comment.