go.crypto/ssh: move interpretation of msgNewKeys into
transport.

Sending the msgNewKeys packet and setting up the key material
now happen under a lock, preventing races with concurrent
writers.

R=kardianos, agl, jpsugar, hanwenn
CC=golang-dev
https://golang.org/cl/14476043
diff --git a/ssh/kex.go b/ssh/kex.go
index e6ce6c3..a761cd8 100644
--- a/ssh/kex.go
+++ b/ssh/kex.go
@@ -35,6 +35,15 @@
 
 	// Signature of H
 	Signature []byte
+
+	// A cryptographic hash function that matches the security
+	// level of the key exchange algorithm. It is used for
+	// calculating H, and for deriving keys from H and K.
+	Hash crypto.Hash
+
+	// The session ID, which is the first H computed. This is used
+	// to signal data inside transport.
+	SessionID []byte
 }
 
 // handshakeMagics contains data that is always included in the
@@ -60,12 +69,6 @@
 	// Client runs the client-side key agreement. Caller is
 	// responsible for verifying the host key signature.
 	Client(p packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error)
-
-	// Hash returns a cryptographic hash function that matches the
-	// security level of the key exchange algorithm. It is used
-	// for calculating kexResult.H, and for deriving keys from
-	// data in kexResult.
-	Hash() crypto.Hash
 }
 
 // dhGroup is a multiplicative group suitable for implementing Diffie-Hellman key agreement.
@@ -73,10 +76,6 @@
 	g, p *big.Int
 }
 
-func (group *dhGroup) Hash() crypto.Hash {
-	return crypto.SHA1
-}
-
 func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) {
 	if theirPublic.Sign() <= 0 || theirPublic.Cmp(group.p) >= 0 {
 		return nil, errors.New("ssh: DH parameter out of bounds")
@@ -128,6 +127,7 @@
 		K:         K,
 		HostKey:   kexDHReply.HostKey,
 		Signature: kexDHReply.Signature,
+		Hash:      crypto.SHA1,
 	}, nil
 }
 
@@ -187,6 +187,7 @@
 		K:         K,
 		HostKey:   hostKeyBytes,
 		Signature: sig,
+		Hash:      crypto.SHA1,
 	}, nil
 }
 
@@ -243,6 +244,7 @@
 		K:         K,
 		HostKey:   reply.HostKey,
 		Signature: reply.Signature,
+		Hash:      ecHash(kex.curve),
 	}, nil
 }
 
@@ -354,13 +356,10 @@
 		K:         K,
 		HostKey:   reply.HostKey,
 		Signature: sig,
+		Hash:      ecHash(kex.curve),
 	}, nil
 }
 
-func (kex *ecdh) Hash() crypto.Hash {
-	return ecHash(kex.curve)
-}
-
 var kexAlgoMap = map[string]kexAlgorithm{}
 
 func init() {