From beedb2de174086f6772fe776322caa43b1147a69 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 23 May 2023 13:20:59 -0700 Subject: [PATCH] Explicitly set scheme for ECDSA signing My system is returning RCScheme if TPM_ALG_NULL is passed here. This should be causing the key's default scheme to be used, but for some reason it seems unhappy. Just explicitly set the scheme for now to avoid that. --- attest/key_windows.go | 2 +- attest/wrapped_tpm20.go | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/attest/key_windows.go b/attest/key_windows.go index d7b62c0a..3a3f6b2e 100644 --- a/attest/key_windows.go +++ b/attest/key_windows.go @@ -270,7 +270,7 @@ func (k *windowsAK20) sign(tb tpmBase, digest []byte, pub crypto.PublicKey, opts switch p := pub.(type) { case *ecdsa.PublicKey: - return signECDSA(rw, hnd, digest, p.Curve) + return signECDSA(rw, hnd, digest, p.Curve, opts) case *rsa.PublicKey: return signRSA(rw, hnd, digest, opts) } diff --git a/attest/wrapped_tpm20.go b/attest/wrapped_tpm20.go index 5d334f89..ceff6345 100644 --- a/attest/wrapped_tpm20.go +++ b/attest/wrapped_tpm20.go @@ -503,14 +503,28 @@ func (k *wrappedKey20) sign(tb tpmBase, digest []byte, pub crypto.PublicKey, opt } switch p := pub.(type) { case *ecdsa.PublicKey: - return signECDSA(t.rwc, k.hnd, digest, p.Curve) + return signECDSA(t.rwc, k.hnd, digest, p.Curve, opts) 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, curve elliptic.Curve) ([]byte, error) { +func signECDSA(rw io.ReadWriter, key tpmutil.Handle, digest []byte, curve elliptic.Curve, opts crypto.SignerOpts) ([]byte, error) { + var scheme *tpm2.SigScheme + + if opts != nil { + h, err := tpm2.HashToAlgorithm(opts.HashFunc()) + if err != nil { + return nil, fmt.Errorf("incorrect hash algorithm: %v", err) + } + + scheme = &tpm2.SigScheme{ + Alg: tpm2.AlgECDSA, + Hash: h, + } + } + // 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 @@ -524,7 +538,7 @@ func signECDSA(rw io.ReadWriter, key tpmutil.Handle, digest []byte, curve ellipt } digest = ret.Bytes() - sig, err := tpm2.Sign(rw, key, "", digest, nil, nil) + sig, err := tpm2.Sign(rw, key, "", digest, nil, scheme) if err != nil { return nil, fmt.Errorf("cannot sign: %v", err) }