Skip to content

Commit f5a2eab

Browse files
FiloSottilegopherbot
authored andcommitted
ssh: use curve25519.X25519 instead of curve25519.ScalarMult
This lets us surface an error message instead of panicking if running in fips140=only mode, where ECDH on X25519 returns an error. Updates golang/go#75061 Change-Id: I6a6a6964c0591f3dca2dc946c99d44364314a3ab Reviewed-on: https://go-review.googlesource.com/c/crypto/+/696995 Reviewed-by: Carlos Amedee <[email protected]> Reviewed-by: David Chase <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Filippo Valsorda <[email protected]> Reviewed-by: Nicola Murino <[email protected]>
1 parent 44ecf3a commit f5a2eab

File tree

1 file changed

+14
-17
lines changed

1 file changed

+14
-17
lines changed

ssh/kex.go

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
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-
466467
func (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

Comments
 (0)