From 5238453493ea8b24420052b7a96527a0d9ec90cc Mon Sep 17 00:00:00 2001 From: Marcin Wielgoszewski Date: Tue, 15 Nov 2022 12:43:33 -0500 Subject: [PATCH] Truncate digests to the left most bits to match the bit-length of the order of the curve --- attest/wrapped_tpm20.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/attest/wrapped_tpm20.go b/attest/wrapped_tpm20.go index 11a9a3d3..5d334f89 100644 --- a/attest/wrapped_tpm20.go +++ b/attest/wrapped_tpm20.go @@ -18,6 +18,7 @@ import ( "bytes" "crypto" "crypto/ecdsa" + "crypto/elliptic" "crypto/rsa" "encoding/asn1" "errors" @@ -500,16 +501,29 @@ func (k *wrappedKey20) sign(tb tpmBase, digest []byte, pub crypto.PublicKey, opt if !ok { return nil, fmt.Errorf("expected *wrappedTPM20, got %T", tb) } - switch pub.(type) { + switch p := pub.(type) { case *ecdsa.PublicKey: - return signECDSA(t.rwc, k.hnd, digest) + return signECDSA(t.rwc, k.hnd, digest, p.Curve) case *rsa.PublicKey: return signRSA(t.rwc, k.hnd, digest, opts) } return nil, fmt.Errorf("unsupported signing key type: %T", pub) } -func signECDSA(rw io.ReadWriter, key tpmutil.Handle, digest []byte) ([]byte, error) { +func signECDSA(rw io.ReadWriter, key tpmutil.Handle, digest []byte, curve elliptic.Curve) ([]byte, error) { + // https://cs.opensource.google/go/go/+/refs/tags/go1.19.2:src/crypto/ecdsa/ecdsa.go;l=181 + orderBits := curve.Params().N.BitLen() + orderBytes := (orderBits + 7) / 8 + if len(digest) > orderBytes { + digest = digest[:orderBytes] + } + ret := new(big.Int).SetBytes(digest) + excess := len(digest)*8 - orderBits + if excess > 0 { + ret.Rsh(ret, uint(excess)) + } + digest = ret.Bytes() + sig, err := tpm2.Sign(rw, key, "", digest, nil, nil) if err != nil { return nil, fmt.Errorf("cannot sign: %v", err)