Skip to content

Commit

Permalink
Add support for hash algorithm SM3 256
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanHsieh committed Aug 17, 2021
1 parent 32171bd commit b5a8526
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 23 deletions.
3 changes: 0 additions & 3 deletions cmds_pcr.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ func (v PCRValues) ToListAndSelection() (pcrs PCRSelectionList, digests DigestLi
func (v PCRValues) SetValuesFromListAndSelection(pcrs PCRSelectionList, digests DigestList) (int, error) {
i := 0
for _, p := range pcrs {
if !p.Hash.Supported() {
return 0, errors.New("unsupported digest algorithm")
}
if _, ok := v[p.Hash]; !ok {
v[p.Hash] = make(map[int]Digest)
}
Expand Down
13 changes: 4 additions & 9 deletions crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ import (

type NewCipherFunc func([]byte) (cipher.Block, error)

type symmetricCipher struct {
fn NewCipherFunc
blockSize int
}

var (
eccCurves = map[ECCCurve]elliptic.Curve{
ECCCurveNIST_P224: elliptic.P224(),
Expand All @@ -38,15 +33,15 @@ var (
ECCCurveNIST_P521: elliptic.P521(),
}

symmetricAlgs = map[SymAlgorithmId]*symmetricCipher{
SymAlgorithmAES: &symmetricCipher{aes.NewCipher, aes.BlockSize},
symmetricAlgs = map[SymAlgorithmId]NewCipherFunc{
SymAlgorithmAES: aes.NewCipher,
}
)

// RegisterCipher allows a go block cipher implementation to be registered for the
// specified algorithm, so binaries don't need to link against every implementation.
func RegisterCipher(alg SymAlgorithmId, fn NewCipherFunc, blockSize int) {
symmetricAlgs[alg] = &symmetricCipher{fn, blockSize}
func RegisterCipher(alg SymAlgorithmId, fn NewCipherFunc) {
symmetricAlgs[alg] = fn
}

func eccCurveToGoCurve(curve ECCCurve) elliptic.Curve {
Expand Down
60 changes: 49 additions & 11 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,20 @@ func (a HashAlgorithmId) GetHash() crypto.Hash {

// Supported determines if the TPM digest algorithm has an equivalent go crypto.Hash.
func (a HashAlgorithmId) Supported() bool {
return a.GetHash() != crypto.Hash(0)
switch a {
case HashAlgorithmSHA1:
case HashAlgorithmSHA256:
case HashAlgorithmSHA384:
case HashAlgorithmSHA512:
case HashAlgorithmSM3_256:
case HashAlgorithmSHA3_256:
case HashAlgorithmSHA3_384:
case HashAlgorithmSHA3_512:
default:
return false
}

return true
}

// Available determines if the TPM digest algorithm has an equivalent go crypto.Hash
Expand All @@ -172,7 +185,26 @@ func (a HashAlgorithmId) NewHash() hash.Hash {

// Size returns the size of the algorithm. It will panic if HashAlgorithmId.Supported returns false.
func (a HashAlgorithmId) Size() int {
return a.GetHash().Size()
switch a {
case HashAlgorithmSHA1:
return 20
case HashAlgorithmSHA256:
return 32
case HashAlgorithmSHA384:
return 48
case HashAlgorithmSHA512:
return 64
case HashAlgorithmSM3_256:
return 32
case HashAlgorithmSHA3_256:
return 32
case HashAlgorithmSHA3_384:
return 48
case HashAlgorithmSHA3_512:
return 64
default:
panic("unknown hash algorithm")
}
}

// SymAlgorithmId corresponds to the TPMI_ALG_SYM type
Expand All @@ -188,21 +220,28 @@ func (a SymAlgorithmId) Available() bool {
// is no registered go implementation of the cipher or the algorithm does not correspond
// to a symmetric cipher.
func (a SymAlgorithmId) BlockSize() int {
c, ok := symmetricAlgs[a]
if !ok {
panic("unsupported cipher")
switch a {
case SymAlgorithmTDES:
return 8
case SymAlgorithmAES:
return 16
case SymAlgorithmSM4:
return 16
case SymAlgorithmCamellia:
return 16
default:
panic("invalid symmetric algorithm")
}
return c.blockSize
}

// NewCipher constructs a new symmetric cipher with the supplied key, if there is a go
// implementation registered.
func (a SymAlgorithmId) NewCipher(key []byte) (cipher.Block, error) {
c, ok := symmetricAlgs[a]
fn, ok := symmetricAlgs[a]
if !ok {
return nil, errors.New("unavailable cipher")
}
return c.fn(key)
return fn(key)
}

// SymObjectAlgorithmId corresponds to the TPMI_ALG_SYM_OBJECT type
Expand All @@ -213,9 +252,8 @@ func (a SymObjectAlgorithmId) Available() bool {
return SymAlgorithmId(a).Available()
}

// BlockSize indicates the block size of the symmetric cipher. This will panic if there
// is no registered go implementation of the cipher or the algorithm does not correspond
// to a symmetric cipher.
// BlockSize indicates the block size of the symmetric cipher. This will panic if the
// algorithm does not correspond to a symmetric cipher.
func (a SymObjectAlgorithmId) BlockSize() int {
return SymAlgorithmId(a).BlockSize()
}
Expand Down

0 comments on commit b5a8526

Please sign in to comment.