]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.20] crypto/ecdh: explicitly reject mismatched curves in ECDH
authorRoland Shoemaker <roland@golang.org>
Tue, 31 Jan 2023 17:14:16 +0000 (09:14 -0800)
committerGopher Robot <gobot@golang.org>
Tue, 28 Feb 2023 01:46:26 +0000 (01:46 +0000)
Return an explicit error when PrivateKey.ECDH is called with a PublicKey
which uses a different Curve. Also document this requirement, even
though it is perhaps obvious.

Updates #58131.
Fixes #58498.

Change-Id: I739181a3f1283bed14fb5ee7eb78658b854d28d8
Reviewed-on: https://go-review.googlesource.com/c/go/+/464335
Reviewed-by: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Auto-Submit: Roland Shoemaker <roland@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
(cherry picked from commit 67d8916d551d22f5376e0be71d3922c9d63eaa6a)
Reviewed-on: https://go-review.googlesource.com/c/go/+/471602
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
src/crypto/ecdh/ecdh.go
src/crypto/ecdh/ecdh_test.go

index d78b4d44324c246a18ef68e19cf3e0336efcf018..74420559b5892f5983b9adcdf72b094848e6c2be 100644 (file)
@@ -10,6 +10,7 @@ import (
        "crypto"
        "crypto/internal/boring"
        "crypto/subtle"
+       "errors"
        "io"
        "sync"
 )
@@ -109,7 +110,8 @@ type PrivateKey struct {
        publicKeyOnce sync.Once
 }
 
-// ECDH performs a ECDH exchange and returns the shared secret.
+// ECDH performs a ECDH exchange and returns the shared secret. The PrivateKey
+// and PublicKey must use the same curve.
 //
 // For NIST curves, this performs ECDH as specified in SEC 1, Version 2.0,
 // Section 3.3.1, and returns the x-coordinate encoded according to SEC 1,
@@ -118,6 +120,9 @@ type PrivateKey struct {
 // For X25519, this performs ECDH as specified in RFC 7748, Section 6.1. If
 // the result is the all-zero value, ECDH returns an error.
 func (k *PrivateKey) ECDH(remote *PublicKey) ([]byte, error) {
+       if k.curve != remote.curve {
+               return nil, errors.New("crypto/ecdh: private key and public key curves do not match")
+       }
        return k.curve.ecdh(k, remote)
 }
 
index 426850a146101e0e6dfe424bd5fb7f99f46a66e4..10da95afbb4ed9c348c957d30e9b62e966fd8bc2 100644 (file)
@@ -487,3 +487,39 @@ func TestLinker(t *testing.T) {
                t.Error("no P384 symbols found in program using ecdh.P384, test is broken")
        }
 }
+
+func TestMismatchedCurves(t *testing.T) {
+       curves := []struct {
+               name  string
+               curve ecdh.Curve
+       }{
+               {"P256", ecdh.P256()},
+               {"P384", ecdh.P384()},
+               {"P521", ecdh.P521()},
+               {"X25519", ecdh.X25519()},
+       }
+
+       for _, privCurve := range curves {
+               priv, err := privCurve.curve.GenerateKey(rand.Reader)
+               if err != nil {
+                       t.Fatalf("failed to generate test key: %s", err)
+               }
+
+               for _, pubCurve := range curves {
+                       if privCurve == pubCurve {
+                               continue
+                       }
+                       t.Run(fmt.Sprintf("%s/%s", privCurve.name, pubCurve.name), func(t *testing.T) {
+                               pub, err := pubCurve.curve.GenerateKey(rand.Reader)
+                               if err != nil {
+                                       t.Fatalf("failed to generate test key: %s", err)
+                               }
+                               expected := "crypto/ecdh: private key and public key curves do not match"
+                               _, err = priv.ECDH(pub.PublicKey())
+                               if err.Error() != expected {
+                                       t.Fatalf("unexpected error: want %q, got %q", expected, err)
+                               }
+                       })
+               }
+       }
+}