Skip to content

Commit

Permalink
Add support for encoding Signatures
Browse files Browse the repository at this point in the history
Some functions in tpm2 expect an encoded TPMT_SIGNATURE.
Here, we add an Encode method on the Signature type
to support these functions.
  • Loading branch information
alexmwu committed Apr 15, 2021
1 parent d331077 commit c7dc278
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
21 changes: 21 additions & 0 deletions tpm2/structures.go
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,27 @@ type Signature struct {
ECC *SignatureECC
}

// Encode serializes a Signature structure in TPM wire format.
func (s Signature) Encode() ([]byte, error) {
head, err := tpmutil.Pack(s.Alg)
if err != nil {
return nil, fmt.Errorf("encoding Alg: %v", err)
}
var signature []byte
switch s.Alg {
case AlgRSASSA, AlgRSAPSS:
if signature, err = tpmutil.Pack(s.RSA); err != nil {
return nil, fmt.Errorf("encoding RSA: %v", err)
}
case AlgECDSA:
signature, err = tpmutil.Pack(s.ECC.HashAlg, tpmutil.U16Bytes(s.ECC.R.Bytes()), tpmutil.U16Bytes(s.ECC.S.Bytes()))
if err != nil {
return nil, fmt.Errorf("encoding ECC: %v", err)
}
}
return concat(head, signature)
}

// DecodeSignature decodes a serialized TPMT_SIGNATURE structure.
func DecodeSignature(in *bytes.Buffer) (*Signature, error) {
var sig Signature
Expand Down
65 changes: 65 additions & 0 deletions tpm2/test/tpm2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ import (
"crypto/rsa"
"crypto/sha1"
"crypto/sha256"
"encoding/binary"
"flag"
"fmt"
"hash"
"io"
"math/big"
"reflect"
"strings"
"testing"
Expand Down Expand Up @@ -1182,6 +1184,69 @@ func TestEncodeDecodePublicDefaultRSAExponent(t *testing.T) {
}
}

func TestEncodeDecodeSignature(t *testing.T) {
randRSASig := func() []byte {
// Key size 2048 bits
var size uint16 = 256
sizeU16 := make([]byte, 2)
binary.BigEndian.PutUint16(sizeU16, size)
key := make([]byte, size)
rand.Read(key)
return append(sizeU16, key...)
}

run := func(t *testing.T, s Signature) {
e, err := s.Encode()
if err != nil {
t.Fatalf("Signature{%+v}.Encode() returned error: %v", s, err)
}
d, err := DecodeSignature(bytes.NewBuffer(e))
if err != nil {
t.Fatalf("DecodeSignature{%v} returned error: %v", e, err)
}
if !reflect.DeepEqual(s, *d) {
t.Errorf("got decoded value:\n%v\nwant:\n%v", d, s)
}
}
t.Run("RSASSA", func(t *testing.T) {
run(t, Signature{
Alg: AlgRSASSA,
RSA: &SignatureRSA{
HashAlg: AlgSHA256,
Signature: randRSASig(),
},
})
})
t.Run("RSAPSS", func(t *testing.T) {
run(t, Signature{
Alg: AlgRSAPSS,
RSA: &SignatureRSA{
HashAlg: AlgSHA256,
Signature: randRSASig(),
},
})
})
t.Run("ECDSA", func(t *testing.T) {
// Key size 256 bits
size := 32
randBytes := make([]byte, size)
rand.Read(randBytes)
r := big.NewInt(0).SetBytes(randBytes)

rand.Read(randBytes)
s := big.NewInt(0).SetBytes(randBytes)

run(t, Signature{
Alg: AlgECDSA,
ECC: &SignatureECC{
HashAlg: AlgSHA256,
R: r,
S: s,
},
})
})
}

func TestCreateKeyWithSensitive(t *testing.T) {
rw := openTPM(t)
defer rw.Close()
Expand Down

0 comments on commit c7dc278

Please sign in to comment.