From a10e615bfd26452f55725ade970bb87b4145483d Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Mon, 10 Apr 2023 13:59:48 +0900 Subject: [PATCH] Backport ECDSA tests from wip/combined-codebase-staging Signed-off-by: Daiki Ueno --- openssl/ecdsa_test.go | 100 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 openssl/ecdsa_test.go diff --git a/openssl/ecdsa_test.go b/openssl/ecdsa_test.go new file mode 100644 index 00000000..a16c08ef --- /dev/null +++ b/openssl/ecdsa_test.go @@ -0,0 +1,100 @@ +//go:build linux && !android +// +build linux,!android + +package openssl_test + +import ( + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "testing" + + "github.com/golang-fips/openssl-fips/openssl" + "github.com/golang-fips/openssl-fips/openssl/bbig" +) + +func testAllCurves(t *testing.T, f func(*testing.T, elliptic.Curve)) { + tests := []struct { + name string + curve elliptic.Curve + }{ + {"P256", elliptic.P256()}, + {"P384", elliptic.P384()}, + {"P521", elliptic.P521()}, + } + for _, test := range tests { + curve := test.curve + t.Run(test.name, func(t *testing.T) { + t.Parallel() + f(t, curve) + }) + } +} + +func TestECDSAKeyGeneration(t *testing.T) { + testAllCurves(t, testECDSAKeyGeneration) +} + +func testECDSAKeyGeneration(t *testing.T, c elliptic.Curve) { + priv, err := generateKeyForCurve(c) + if err != nil { + t.Fatal(err) + } + if !c.IsOnCurve(priv.PublicKey.X, priv.PublicKey.Y) { + t.Errorf("public key invalid: %s", err) + } +} + +func TestECDSASignAndVerify(t *testing.T) { + testAllCurves(t, testECDSASignAndVerify) +} + +func testECDSASignAndVerify(t *testing.T, c elliptic.Curve) { + key, err := generateKeyForCurve(c) + if err != nil { + t.Fatal(err) + } + msg := []byte("hi!") + hashed := openssl.SHA256(msg) + + priv, err := openssl.NewPrivateKeyECDSA(key.Params().Name, bbig.Enc(key.X), bbig.Enc(key.Y), bbig.Enc(key.D)) + if err != nil { + t.Fatal(err) + } + pub, err := openssl.NewPublicKeyECDSA(key.Params().Name, bbig.Enc(key.X), bbig.Enc(key.Y)) + if err != nil { + t.Fatal(err) + } + signed, err := openssl.SignMarshalECDSA(priv, hashed[:]) + if err != nil { + t.Fatal(err) + } + if !openssl.VerifyECDSA(pub, hashed[:], signed) { + t.Errorf("Verify failed") + } + signed[0] ^= 0xff + if openssl.VerifyECDSA(pub, hashed[:], signed) { + t.Errorf("Verify succeeded despite intentionally invalid hash!") + } + r, s, err := openssl.HashSignECDSA(priv, msg, crypto.SHA256) + if err != nil { + t.Fatal(err) + } + if !openssl.HashVerifyECDSA(pub, msg, r, s, crypto.SHA256) { + t.Errorf("Verify failed") + } + rb := r.Bytes() + rb[0] ^= 0xff + r.SetBytes(rb) + if openssl.HashVerifyECDSA(pub, msg, r, s, crypto.SHA256) { + t.Errorf("Verify succeeded on modified signature!") + } +} + +func generateKeyForCurve(c elliptic.Curve) (*ecdsa.PrivateKey, error) { + x, y, d, err := openssl.GenerateKeyECDSA(c.Params().Name) + if err != nil { + return nil, err + } + return &ecdsa.PrivateKey{PublicKey: ecdsa.PublicKey{Curve: c, X: bbig.Dec(x), Y: bbig.Dec(y)}, D: bbig.Dec(d)}, nil +}