File tree 2 files changed +42
-1
lines changed 2 files changed +42
-1
lines changed Original file line number Diff line number Diff line change @@ -10,6 +10,7 @@ import (
10
10
"crypto"
11
11
"crypto/internal/boring"
12
12
"crypto/subtle"
13
+ "errors"
13
14
"io"
14
15
"sync"
15
16
)
@@ -109,7 +110,8 @@ type PrivateKey struct {
109
110
publicKeyOnce sync.Once
110
111
}
111
112
112
- // ECDH performs a ECDH exchange and returns the shared secret.
113
+ // ECDH performs a ECDH exchange and returns the shared secret. The PrivateKey
114
+ // and PublicKey must use the same curve.
113
115
//
114
116
// For NIST curves, this performs ECDH as specified in SEC 1, Version 2.0,
115
117
// Section 3.3.1, and returns the x-coordinate encoded according to SEC 1,
@@ -118,6 +120,9 @@ type PrivateKey struct {
118
120
// For X25519, this performs ECDH as specified in RFC 7748, Section 6.1. If
119
121
// the result is the all-zero value, ECDH returns an error.
120
122
func (k * PrivateKey ) ECDH (remote * PublicKey ) ([]byte , error ) {
123
+ if k .curve != remote .curve {
124
+ return nil , errors .New ("crypto/ecdh: private key and public key curves do not match" )
125
+ }
121
126
return k .curve .ecdh (k , remote )
122
127
}
123
128
Original file line number Diff line number Diff line change @@ -487,3 +487,39 @@ func TestLinker(t *testing.T) {
487
487
t .Error ("no P384 symbols found in program using ecdh.P384, test is broken" )
488
488
}
489
489
}
490
+
491
+ func TestMismatchedCurves (t * testing.T ) {
492
+ curves := []struct {
493
+ name string
494
+ curve ecdh.Curve
495
+ }{
496
+ {"P256" , ecdh .P256 ()},
497
+ {"P384" , ecdh .P384 ()},
498
+ {"P521" , ecdh .P521 ()},
499
+ {"X25519" , ecdh .X25519 ()},
500
+ }
501
+
502
+ for _ , privCurve := range curves {
503
+ priv , err := privCurve .curve .GenerateKey (rand .Reader )
504
+ if err != nil {
505
+ t .Fatalf ("failed to generate test key: %s" , err )
506
+ }
507
+
508
+ for _ , pubCurve := range curves {
509
+ if privCurve == pubCurve {
510
+ continue
511
+ }
512
+ t .Run (fmt .Sprintf ("%s/%s" , privCurve .name , pubCurve .name ), func (t * testing.T ) {
513
+ pub , err := pubCurve .curve .GenerateKey (rand .Reader )
514
+ if err != nil {
515
+ t .Fatalf ("failed to generate test key: %s" , err )
516
+ }
517
+ expected := "crypto/ecdh: private key and public key curves do not match"
518
+ _ , err = priv .ECDH (pub .PublicKey ())
519
+ if err .Error () != expected {
520
+ t .Fatalf ("unexpected error: want %q, got %q" , expected , err )
521
+ }
522
+ })
523
+ }
524
+ }
525
+ }
You can’t perform that action at this time.
0 commit comments