99 "crypto/ecdsa"
1010 "crypto/elliptic"
1111 "crypto/rand"
12- "crypto/subtle"
1312 "encoding/binary"
1413 "errors"
1514 "fmt"
@@ -454,15 +453,17 @@ func (kp *curve25519KeyPair) generate(rand io.Reader) error {
454453 if _ , err := io .ReadFull (rand , kp .priv [:]); err != nil {
455454 return err
456455 }
457- curve25519 .ScalarBaseMult (& kp .pub , & kp .priv )
456+ p , err := curve25519 .X25519 (kp .priv [:], curve25519 .Basepoint )
457+ if err != nil {
458+ return fmt .Errorf ("curve25519: %w" , err )
459+ }
460+ if len (p ) != 32 {
461+ return fmt .Errorf ("curve25519: internal error: X25519 returned %d bytes, expected 32" , len (p ))
462+ }
463+ copy (kp .pub [:], p )
458464 return nil
459465}
460466
461- // curve25519Zeros is just an array of 32 zero bytes so that we have something
462- // convenient to compare against in order to reject curve25519 points with the
463- // wrong order.
464- var curve25519Zeros [32 ]byte
465-
466467func (kex * curve25519sha256 ) Client (c packetConn , rand io.Reader , magics * handshakeMagics ) (* kexResult , error ) {
467468 var kp curve25519KeyPair
468469 if err := kp .generate (rand ); err != nil {
@@ -485,11 +486,9 @@ func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handsh
485486 return nil , errors .New ("ssh: peer's curve25519 public value has wrong length" )
486487 }
487488
488- var servPub , secret [32 ]byte
489- copy (servPub [:], reply .EphemeralPubKey )
490- curve25519 .ScalarMult (& secret , & kp .priv , & servPub )
491- if subtle .ConstantTimeCompare (secret [:], curve25519Zeros [:]) == 1 {
492- return nil , errors .New ("ssh: peer's curve25519 public value has wrong order" )
489+ secret , err := curve25519 .X25519 (kp .priv [:], reply .EphemeralPubKey )
490+ if err != nil {
491+ return nil , fmt .Errorf ("ssh: peer's curve25519 public value is not valid: %w" , err )
493492 }
494493
495494 h := crypto .SHA256 .New ()
@@ -531,11 +530,9 @@ func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handsh
531530 return nil , err
532531 }
533532
534- var clientPub , secret [32 ]byte
535- copy (clientPub [:], kexInit .ClientPubKey )
536- curve25519 .ScalarMult (& secret , & kp .priv , & clientPub )
537- if subtle .ConstantTimeCompare (secret [:], curve25519Zeros [:]) == 1 {
538- return nil , errors .New ("ssh: peer's curve25519 public value has wrong order" )
533+ secret , err := curve25519 .X25519 (kp .priv [:], kexInit .ClientPubKey )
534+ if err != nil {
535+ return nil , fmt .Errorf ("ssh: peer's curve25519 public value is not valid: %w" , err )
539536 }
540537
541538 hostKeyBytes := priv .PublicKey ().Marshal ()
0 commit comments