Merge "third_party/go/src/github.com/cosnicolaou/llog: Update to latest version."
diff --git a/go/src/golang.org/x/crypto/README.google b/go/src/golang.org/x/crypto/README.google
index 2fd2c7f..64b4cac 100644
--- a/go/src/golang.org/x/crypto/README.google
+++ b/go/src/golang.org/x/crypto/README.google
@@ -1,5 +1,5 @@
-URL: https://go.googlesource.com/crypto/+archive/02a186af8b62cb007f392270669b91be5527d39c.tar.gz
-Version: 602a186af8b62cb007f392270669b91be5527d39c
+URL: https://go.googlesource.com/crypto/+archive/81bf7719a6b7ce9b665598222362b50122dfc13b.tar.gz
+Version: 81bf7719a6b7ce9b665598222362b50122dfc13b
 License: New BSD
 License File: LICENSE
 
diff --git a/go/src/golang.org/x/crypto/ocsp/ocsp.go b/go/src/golang.org/x/crypto/ocsp/ocsp.go
index 602fefa..1850e1b 100644
--- a/go/src/golang.org/x/crypto/ocsp/ocsp.go
+++ b/go/src/golang.org/x/crypto/ocsp/ocsp.go
@@ -87,7 +87,7 @@
 type singleResponse struct {
 	CertID     certID
 	Good       asn1.Flag   `asn1:"tag:0,optional"`
-	Revoked    revokedInfo `asn1:"explicit,tag:1,optional"`
+	Revoked    revokedInfo `asn1:"tag:1,optional"`
 	Unknown    asn1.Flag   `asn1:"tag:2,optional"`
 	ThisUpdate time.Time   `asn1:"generalized"`
 	NextUpdate time.Time   `asn1:"generalized,explicit,tag:0,optional"`
diff --git a/go/src/golang.org/x/crypto/openpgp/keys.go b/go/src/golang.org/x/crypto/openpgp/keys.go
index fe12cfa..bfe3260 100644
--- a/go/src/golang.org/x/crypto/openpgp/keys.go
+++ b/go/src/golang.org/x/crypto/openpgp/keys.go
@@ -464,15 +464,20 @@
 func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) {
 	currentTime := config.Now()
 
+	bits := defaultRSAKeyBits
+	if config != nil && config.RSABits != 0 {
+		bits = config.RSABits
+	}
+
 	uid := packet.NewUserId(name, comment, email)
 	if uid == nil {
 		return nil, errors.InvalidArgumentError("user id field contained invalid characters")
 	}
-	signingPriv, err := rsa.GenerateKey(config.Random(), defaultRSAKeyBits)
+	signingPriv, err := rsa.GenerateKey(config.Random(), bits)
 	if err != nil {
 		return nil, err
 	}
-	encryptingPriv, err := rsa.GenerateKey(config.Random(), defaultRSAKeyBits)
+	encryptingPriv, err := rsa.GenerateKey(config.Random(), bits)
 	if err != nil {
 		return nil, err
 	}
diff --git a/go/src/golang.org/x/crypto/openpgp/packet/config.go b/go/src/golang.org/x/crypto/openpgp/packet/config.go
index d977cde..c76eecc 100644
--- a/go/src/golang.org/x/crypto/openpgp/packet/config.go
+++ b/go/src/golang.org/x/crypto/openpgp/packet/config.go
@@ -43,6 +43,9 @@
 	// use a value that is at least 65536. See RFC 4880 Section
 	// 3.7.1.3.
 	S2KCount int
+	// RSABits is the number of bits in new RSA keys made with NewEntity.
+	// If zero, then 2048 bit keys are created.
+	RSABits int
 }
 
 func (c *Config) Random() io.Reader {
diff --git a/go/src/golang.org/x/crypto/openpgp/packet/opaque.go b/go/src/golang.org/x/crypto/openpgp/packet/opaque.go
index f2e00b9..456d807 100644
--- a/go/src/golang.org/x/crypto/openpgp/packet/opaque.go
+++ b/go/src/golang.org/x/crypto/openpgp/packet/opaque.go
@@ -6,9 +6,10 @@
 
 import (
 	"bytes"
-	"golang.org/x/crypto/openpgp/errors"
 	"io"
 	"io/ioutil"
+
+	"golang.org/x/crypto/openpgp/errors"
 )
 
 // OpaquePacket represents an OpenPGP packet as raw, unparsed data. This is
@@ -138,7 +139,7 @@
 			uint32(contents[4])
 		contents = contents[5:]
 	}
-	if subLen > uint32(len(contents)) {
+	if subLen > uint32(len(contents)) || subLen == 0 {
 		goto Truncated
 	}
 	subPacket.SubType = contents[0]
diff --git a/go/src/golang.org/x/crypto/openpgp/packet/private_key.go b/go/src/golang.org/x/crypto/openpgp/packet/private_key.go
index 9685a34..cddecfa 100644
--- a/go/src/golang.org/x/crypto/openpgp/packet/private_key.go
+++ b/go/src/golang.org/x/crypto/openpgp/packet/private_key.go
@@ -263,6 +263,9 @@
 	rsaPriv.Primes = make([]*big.Int, 2)
 	rsaPriv.Primes[0] = new(big.Int).SetBytes(p)
 	rsaPriv.Primes[1] = new(big.Int).SetBytes(q)
+	if err := rsaPriv.Validate(); err != nil {
+		return err
+	}
 	rsaPriv.Precompute()
 	pk.PrivateKey = rsaPriv
 	pk.Encrypted = false
diff --git a/go/src/golang.org/x/crypto/openpgp/packet/private_key_test.go b/go/src/golang.org/x/crypto/openpgp/packet/private_key_test.go
index 6a6197a..25c8931 100644
--- a/go/src/golang.org/x/crypto/openpgp/packet/private_key_test.go
+++ b/go/src/golang.org/x/crypto/openpgp/packet/private_key_test.go
@@ -56,6 +56,11 @@
 	}
 }
 
+func TestIssue11505(t *testing.T) {
+	// parsing a rsa private key with p or q == 1 used to panic due to a divide by zero
+	_, _ = Read(readerFromHex("9c3004303030300100000011303030000000000000010130303030303030303030303030303030303030303030303030303030303030303030303030303030303030"))
+}
+
 // Generated with `gpg --export-secret-keys "Test Key 2"`
 const privKeyRSAHex = "9501fe044cc349a8010400b70ca0010e98c090008d45d1ee8f9113bd5861fd57b88bacb7c68658747663f1e1a3b5a98f32fda6472373c024b97359cd2efc88ff60f77751adfbf6af5e615e6a1408cfad8bf0cea30b0d5f53aa27ad59089ba9b15b7ebc2777a25d7b436144027e3bcd203909f147d0e332b240cf63d3395f5dfe0df0a6c04e8655af7eacdf0011010001fe0303024a252e7d475fd445607de39a265472aa74a9320ba2dac395faa687e9e0336aeb7e9a7397e511b5afd9dc84557c80ac0f3d4d7bfec5ae16f20d41c8c84a04552a33870b930420e230e179564f6d19bb153145e76c33ae993886c388832b0fa042ddda7f133924f3854481533e0ede31d51278c0519b29abc3bf53da673e13e3e1214b52413d179d7f66deee35cac8eacb060f78379d70ef4af8607e68131ff529439668fc39c9ce6dfef8a5ac234d234802cbfb749a26107db26406213ae5c06d4673253a3cbee1fcbae58d6ab77e38d6e2c0e7c6317c48e054edadb5a40d0d48acb44643d998139a8a66bb820be1f3f80185bc777d14b5954b60effe2448a036d565c6bc0b915fcea518acdd20ab07bc1529f561c58cd044f723109b93f6fd99f876ff891d64306b5d08f48bab59f38695e9109c4dec34013ba3153488ce070268381ba923ee1eb77125b36afcb4347ec3478c8f2735b06ef17351d872e577fa95d0c397c88c71b59629a36aec"
 
diff --git a/go/src/golang.org/x/crypto/openpgp/packet/public_key_v3.go b/go/src/golang.org/x/crypto/openpgp/packet/public_key_v3.go
index 1641248..26337f5 100644
--- a/go/src/golang.org/x/crypto/openpgp/packet/public_key_v3.go
+++ b/go/src/golang.org/x/crypto/openpgp/packet/public_key_v3.go
@@ -95,6 +95,11 @@
 		return
 	}
 
+	// RFC 4880 Section 12.2 requires the low 8 bytes of the
+	// modulus to form the key id.
+	if len(pk.n.bytes) < 8 {
+		return errors.StructuralError("v3 public key modulus is too short")
+	}
 	if len(pk.e.bytes) > 3 {
 		err = errors.UnsupportedError("large public exponent")
 		return
diff --git a/go/src/golang.org/x/crypto/openpgp/read_test.go b/go/src/golang.org/x/crypto/openpgp/read_test.go
index 03bf5d8..3d74ea3 100644
--- a/go/src/golang.org/x/crypto/openpgp/read_test.go
+++ b/go/src/golang.org/x/crypto/openpgp/read_test.go
@@ -8,11 +8,12 @@
 	"bytes"
 	_ "crypto/sha512"
 	"encoding/hex"
-	"golang.org/x/crypto/openpgp/errors"
 	"io"
 	"io/ioutil"
 	"strings"
 	"testing"
+
+	"golang.org/x/crypto/openpgp/errors"
 )
 
 func readerFromHex(s string) io.Reader {
@@ -368,6 +369,35 @@
 	}
 }
 
+func testReadMessageError(t *testing.T, messageHex string) {
+	buf, err := hex.DecodeString(messageHex)
+	if err != nil {
+		t.Errorf("hex.DecodeString(): %v", err)
+	}
+
+	kr, err := ReadKeyRing(new(bytes.Buffer))
+	if err != nil {
+		t.Errorf("ReadKeyring(): %v", err)
+	}
+
+	_, err = ReadMessage(bytes.NewBuffer(buf), kr,
+		func([]Key, bool) ([]byte, error) {
+			return []byte("insecure"), nil
+		}, nil)
+
+	if err == nil {
+		t.Errorf("ReadMessage(): Unexpected nil error")
+	}
+}
+
+func TestIssue11503(t *testing.T) {
+	testReadMessageError(t, "8c040402000aa430aa8228b9248b01fc899a91197130303030")
+}
+
+func TestIssue11504(t *testing.T) {
+	testReadMessageError(t, "9303000130303030303030303030983002303030303030030000000130")
+}
+
 const testKey1KeyId = 0xA34D7E18C20C31BB
 const testKey3KeyId = 0x338934250CCC0360
 
diff --git a/go/src/golang.org/x/crypto/openpgp/write_test.go b/go/src/golang.org/x/crypto/openpgp/write_test.go
index 9f8c358..8e9a335 100644
--- a/go/src/golang.org/x/crypto/openpgp/write_test.go
+++ b/go/src/golang.org/x/crypto/openpgp/write_test.go
@@ -10,6 +10,8 @@
 	"io/ioutil"
 	"testing"
 	"time"
+
+	"golang.org/x/crypto/openpgp/packet"
 )
 
 func TestSignDetached(t *testing.T) {
@@ -53,11 +55,34 @@
 		return
 	}
 
+	// Check bit-length with no config.
 	e, err := NewEntity("Test User", "test", "test@example.com", nil)
 	if err != nil {
 		t.Errorf("failed to create entity: %s", err)
 		return
 	}
+	bl, err := e.PrimaryKey.BitLength()
+	if err != nil {
+		t.Errorf("failed to find bit length: %s", err)
+	}
+	if int(bl) != defaultRSAKeyBits {
+		t.Errorf("BitLength %v, expected %v", defaultRSAKeyBits)
+	}
+
+	// Check bit-length with a config.
+	cfg := &packet.Config{RSABits: 1024}
+	e, err = NewEntity("Test User", "test", "test@example.com", cfg)
+	if err != nil {
+		t.Errorf("failed to create entity: %s", err)
+		return
+	}
+	bl, err = e.PrimaryKey.BitLength()
+	if err != nil {
+		t.Errorf("failed to find bit length: %s", err)
+	}
+	if int(bl) != cfg.RSABits {
+		t.Errorf("BitLength %v, expected %v", bl, cfg.RSABits)
+	}
 
 	w := bytes.NewBuffer(nil)
 	if err := e.SerializePrivate(w, nil); err != nil {
diff --git a/go/src/golang.org/x/crypto/poly1305/poly1305_arm.s b/go/src/golang.org/x/crypto/poly1305/poly1305_arm.s
index c9ceaeb..c153867 100644
--- a/go/src/golang.org/x/crypto/poly1305/poly1305_arm.s
+++ b/go/src/golang.org/x/crypto/poly1305/poly1305_arm.s
@@ -47,6 +47,16 @@
   MOVM.IA.W (R13), [R4-R11]
   RET
 
+#define MOVW_UNALIGNED(Rsrc, Rdst, Rtmp, offset) \
+  MOVBU (offset+0)(Rsrc), Rtmp; \
+  MOVBU Rtmp, (offset+0)(Rdst); \
+  MOVBU (offset+1)(Rsrc), Rtmp; \
+  MOVBU Rtmp, (offset+1)(Rdst); \
+  MOVBU (offset+2)(Rsrc), Rtmp; \
+  MOVBU Rtmp, (offset+2)(Rdst); \
+  MOVBU (offset+3)(Rsrc), Rtmp; \
+  MOVBU Rtmp, (offset+3)(Rdst)
+
 TEXT poly1305_blocks_armv6<>(SB),4,$-4
   MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13)
   SUB $128, R13
@@ -66,7 +76,19 @@
   CMP $16, R12
   BLO poly1305_blocks_armv6_done
 poly1305_blocks_armv6_mainloop:
+  WORD $0xe31e0003 // TST R14, #3 not working see issue 5921
+  BEQ poly1305_blocks_armv6_mainloop_aligned
+  ADD $48, R13, g
+  MOVW_UNALIGNED(R14, g, R0, 0)
+  MOVW_UNALIGNED(R14, g, R0, 4)
+  MOVW_UNALIGNED(R14, g, R0, 8)
+  MOVW_UNALIGNED(R14, g, R0, 12)
+  MOVM.IA (g), [R0-R3]
+  ADD $16, R14
+  B poly1305_blocks_armv6_mainloop_loaded
+poly1305_blocks_armv6_mainloop_aligned:
   MOVM.IA.W (R14), [R0-R3]
+poly1305_blocks_armv6_mainloop_loaded:
   MOVW R0>>26, g
   MOVW R1>>20, R11
   MOVW R2>>14, R12
@@ -174,6 +196,16 @@
   MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14]
   RET
 
+#define MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp) \
+  MOVBU.P 1(Rsrc), Rtmp; \
+  MOVBU.P Rtmp, 1(Rdst); \
+  MOVBU.P 1(Rsrc), Rtmp; \
+  MOVBU.P Rtmp, 1(Rdst)
+
+#define MOVWP_UNALIGNED(Rsrc, Rdst, Rtmp) \
+  MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp); \
+  MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp)
+
 TEXT poly1305_finish_ext_armv6<>(SB),4,$-4
   MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13)
   SUB $16, R13, R13
@@ -189,16 +221,32 @@
   MOVW R0, 4(R13)
   MOVW R0, 8(R13)
   MOVW R0, 12(R13)
+  WORD $0xe3110003 // TST R1, #3 not working see issue 5921
+  BEQ poly1305_finish_ext_armv6_aligned
   WORD $0xe3120008 // TST R2, #8 not working see issue 5921
   BEQ poly1305_finish_ext_armv6_skip8
-  MOVM.IA.W (R1), [g-R11]
-  MOVM.IA.W [g-R11], (R9)
+  MOVWP_UNALIGNED(R1, R9, g)
+  MOVWP_UNALIGNED(R1, R9, g)
 poly1305_finish_ext_armv6_skip8:
   WORD $0xe3120004 // TST $4, R2 not working see issue 5921
   BEQ poly1305_finish_ext_armv6_skip4
+  MOVWP_UNALIGNED(R1, R9, g)
+poly1305_finish_ext_armv6_skip4:
+  WORD $0xe3120002 // TST $2, R2 not working see issue 5921
+  BEQ poly1305_finish_ext_armv6_skip2
+  MOVHUP_UNALIGNED(R1, R9, g)
+  B poly1305_finish_ext_armv6_skip2
+poly1305_finish_ext_armv6_aligned:
+  WORD $0xe3120008 // TST R2, #8 not working see issue 5921
+  BEQ poly1305_finish_ext_armv6_skip8_aligned
+  MOVM.IA.W (R1), [g-R11]
+  MOVM.IA.W [g-R11], (R9)
+poly1305_finish_ext_armv6_skip8_aligned:
+  WORD $0xe3120004 // TST $4, R2 not working see issue 5921
+  BEQ poly1305_finish_ext_armv6_skip4_aligned
   MOVW.P 4(R1), g
   MOVW.P g, 4(R9)
-poly1305_finish_ext_armv6_skip4:
+poly1305_finish_ext_armv6_skip4_aligned:
   WORD $0xe3120002 // TST $2, R2 not working see issue 5921
   BEQ poly1305_finish_ext_armv6_skip2
   MOVHU.P 2(R1), g
diff --git a/go/src/golang.org/x/crypto/poly1305/poly1305_test.go b/go/src/golang.org/x/crypto/poly1305/poly1305_test.go
index 2c6d1bc..b3e9231 100644
--- a/go/src/golang.org/x/crypto/poly1305/poly1305_test.go
+++ b/go/src/golang.org/x/crypto/poly1305/poly1305_test.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"testing"
+	"unsafe"
 )
 
 var testData = []struct {
@@ -34,41 +35,52 @@
 	},
 }
 
-func TestSum(t *testing.T) {
+func testSum(t *testing.T, unaligned bool) {
 	var out [16]byte
 	var key [32]byte
 
 	for i, v := range testData {
+		in := v.in
+		if unaligned {
+			in = unalignBytes(in)
+		}
 		copy(key[:], v.k)
-		Sum(&out, v.in, &key)
+		Sum(&out, in, &key)
 		if !bytes.Equal(out[:], v.correct) {
 			t.Errorf("%d: expected %x, got %x", i, v.correct, out[:])
 		}
 	}
 }
 
-func Benchmark1K(b *testing.B) {
-	b.StopTimer()
+func TestSum(t *testing.T)          { testSum(t, false) }
+func TestSumUnaligned(t *testing.T) { testSum(t, true) }
+
+func benchmark(b *testing.B, size int, unaligned bool) {
 	var out [16]byte
 	var key [32]byte
-	in := make([]byte, 1024)
+	in := make([]byte, size)
+	if unaligned {
+		in = unalignBytes(in)
+	}
 	b.SetBytes(int64(len(in)))
-	b.StartTimer()
-
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		Sum(&out, in, &key)
 	}
 }
 
-func Benchmark64(b *testing.B) {
-	b.StopTimer()
-	var out [16]byte
-	var key [32]byte
-	in := make([]byte, 64)
-	b.SetBytes(int64(len(in)))
-	b.StartTimer()
+func Benchmark64(b *testing.B)          { benchmark(b, 64, false) }
+func Benchmark1K(b *testing.B)          { benchmark(b, 1024, false) }
+func Benchmark64Unaligned(b *testing.B) { benchmark(b, 64, true) }
+func Benchmark1KUnaligned(b *testing.B) { benchmark(b, 1024, true) }
 
-	for i := 0; i < b.N; i++ {
-		Sum(&out, in, &key)
+func unalignBytes(in []byte) []byte {
+	out := make([]byte, len(in)+1)
+	if uintptr(unsafe.Pointer(&out[0]))&(unsafe.Alignof(uint32(0))-1) == 0 {
+		out = out[1:]
+	} else {
+		out = out[:len(in)]
 	}
+	copy(out, in)
+	return out
 }
diff --git a/go/src/golang.org/x/crypto/sha3/keccakKats.json.deflate b/go/src/golang.org/x/crypto/sha3/keccakKats.json.deflate
deleted file mode 100644
index 62e85ae..0000000
--- a/go/src/golang.org/x/crypto/sha3/keccakKats.json.deflate
+++ /dev/null
Binary files differ
diff --git a/go/src/golang.org/x/crypto/ssh/agent/client.go b/go/src/golang.org/x/crypto/ssh/agent/client.go
index f5527e8..8c856a0 100644
--- a/go/src/golang.org/x/crypto/ssh/agent/client.go
+++ b/go/src/golang.org/x/crypto/ssh/agent/client.go
@@ -36,9 +36,8 @@
 	// in [PROTOCOL.agent] section 2.6.2.
 	Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error)
 
-	// Add adds a private key to the agent. If a certificate
-	// is given, that certificate is added as public key.
-	Add(s interface{}, cert *ssh.Certificate, comment string) error
+	// Add adds a private key to the agent.
+	Add(key AddedKey) error
 
 	// Remove removes all identities with the given public key.
 	Remove(key ssh.PublicKey) error
@@ -56,6 +55,24 @@
 	Signers() ([]ssh.Signer, error)
 }
 
+// AddedKey describes an SSH key to be added to an Agent.
+type AddedKey struct {
+	// PrivateKey must be a *rsa.PrivateKey, *dsa.PrivateKey or
+	// *ecdsa.PrivateKey, which will be inserted into the agent.
+	PrivateKey interface{}
+	// Certificate, if not nil, is communicated to the agent and will be
+	// stored with the key.
+	Certificate *ssh.Certificate
+	// Comment is an optional, free-form string.
+	Comment string
+	// LifetimeSecs, if not zero, is the number of seconds that the
+	// agent will store the key for.
+	LifetimeSecs uint32
+	// ConfirmBeforeUse, if true, requests that the agent confirm with the
+	// user before each use of this key.
+	ConfirmBeforeUse bool
+}
+
 // See [PROTOCOL.agent], section 3.
 const (
 	agentRequestV1Identities = 1
@@ -368,36 +385,39 @@
 }
 
 type rsaKeyMsg struct {
-	Type     string `sshtype:"17"`
-	N        *big.Int
-	E        *big.Int
-	D        *big.Int
-	Iqmp     *big.Int // IQMP = Inverse Q Mod P
-	P        *big.Int
-	Q        *big.Int
-	Comments string
+	Type        string `sshtype:"17"`
+	N           *big.Int
+	E           *big.Int
+	D           *big.Int
+	Iqmp        *big.Int // IQMP = Inverse Q Mod P
+	P           *big.Int
+	Q           *big.Int
+	Comments    string
+	Constraints []byte `ssh:"rest"`
 }
 
 type dsaKeyMsg struct {
-	Type     string `sshtype:"17"`
-	P        *big.Int
-	Q        *big.Int
-	G        *big.Int
-	Y        *big.Int
-	X        *big.Int
-	Comments string
+	Type        string `sshtype:"17"`
+	P           *big.Int
+	Q           *big.Int
+	G           *big.Int
+	Y           *big.Int
+	X           *big.Int
+	Comments    string
+	Constraints []byte `ssh:"rest"`
 }
 
 type ecdsaKeyMsg struct {
-	Type     string `sshtype:"17"`
-	Curve    string
-	KeyBytes []byte
-	D        *big.Int
-	Comments string
+	Type        string `sshtype:"17"`
+	Curve       string
+	KeyBytes    []byte
+	D           *big.Int
+	Comments    string
+	Constraints []byte `ssh:"rest"`
 }
 
 // Insert adds a private key to the agent.
-func (c *client) insertKey(s interface{}, comment string) error {
+func (c *client) insertKey(s interface{}, comment string, constraints []byte) error {
 	var req []byte
 	switch k := s.(type) {
 	case *rsa.PrivateKey:
@@ -406,37 +426,46 @@
 		}
 		k.Precompute()
 		req = ssh.Marshal(rsaKeyMsg{
-			Type:     ssh.KeyAlgoRSA,
-			N:        k.N,
-			E:        big.NewInt(int64(k.E)),
-			D:        k.D,
-			Iqmp:     k.Precomputed.Qinv,
-			P:        k.Primes[0],
-			Q:        k.Primes[1],
-			Comments: comment,
+			Type:        ssh.KeyAlgoRSA,
+			N:           k.N,
+			E:           big.NewInt(int64(k.E)),
+			D:           k.D,
+			Iqmp:        k.Precomputed.Qinv,
+			P:           k.Primes[0],
+			Q:           k.Primes[1],
+			Comments:    comment,
+			Constraints: constraints,
 		})
 	case *dsa.PrivateKey:
 		req = ssh.Marshal(dsaKeyMsg{
-			Type:     ssh.KeyAlgoDSA,
-			P:        k.P,
-			Q:        k.Q,
-			G:        k.G,
-			Y:        k.Y,
-			X:        k.X,
-			Comments: comment,
+			Type:        ssh.KeyAlgoDSA,
+			P:           k.P,
+			Q:           k.Q,
+			G:           k.G,
+			Y:           k.Y,
+			X:           k.X,
+			Comments:    comment,
+			Constraints: constraints,
 		})
 	case *ecdsa.PrivateKey:
 		nistID := fmt.Sprintf("nistp%d", k.Params().BitSize)
 		req = ssh.Marshal(ecdsaKeyMsg{
-			Type:     "ecdsa-sha2-" + nistID,
-			Curve:    nistID,
-			KeyBytes: elliptic.Marshal(k.Curve, k.X, k.Y),
-			D:        k.D,
-			Comments: comment,
+			Type:        "ecdsa-sha2-" + nistID,
+			Curve:       nistID,
+			KeyBytes:    elliptic.Marshal(k.Curve, k.X, k.Y),
+			D:           k.D,
+			Comments:    comment,
+			Constraints: constraints,
 		})
 	default:
 		return fmt.Errorf("agent: unsupported key type %T", s)
 	}
+
+	// if constraints are present then the message type needs to be changed.
+	if len(constraints) != 0 {
+		req[0] = agentAddIdConstrained
+	}
+
 	resp, err := c.call(req)
 	if err != nil {
 		return err
@@ -448,40 +477,57 @@
 }
 
 type rsaCertMsg struct {
-	Type      string `sshtype:"17"`
-	CertBytes []byte
-	D         *big.Int
-	Iqmp      *big.Int // IQMP = Inverse Q Mod P
-	P         *big.Int
-	Q         *big.Int
-	Comments  string
+	Type        string `sshtype:"17"`
+	CertBytes   []byte
+	D           *big.Int
+	Iqmp        *big.Int // IQMP = Inverse Q Mod P
+	P           *big.Int
+	Q           *big.Int
+	Comments    string
+	Constraints []byte `ssh:"rest"`
 }
 
 type dsaCertMsg struct {
-	Type      string `sshtype:"17"`
-	CertBytes []byte
-	X         *big.Int
-	Comments  string
+	Type        string `sshtype:"17"`
+	CertBytes   []byte
+	X           *big.Int
+	Comments    string
+	Constraints []byte `ssh:"rest"`
 }
 
 type ecdsaCertMsg struct {
-	Type      string `sshtype:"17"`
-	CertBytes []byte
-	D         *big.Int
-	Comments  string
+	Type        string `sshtype:"17"`
+	CertBytes   []byte
+	D           *big.Int
+	Comments    string
+	Constraints []byte `ssh:"rest"`
 }
 
 // Insert adds a private key to the agent. If a certificate is given,
 // that certificate is added instead as public key.
-func (c *client) Add(s interface{}, cert *ssh.Certificate, comment string) error {
-	if cert == nil {
-		return c.insertKey(s, comment)
+func (c *client) Add(key AddedKey) error {
+	var constraints []byte
+
+	if secs := key.LifetimeSecs; secs != 0 {
+		constraints = append(constraints, agentConstrainLifetime)
+
+		var secsBytes [4]byte
+		binary.BigEndian.PutUint32(secsBytes[:], secs)
+		constraints = append(constraints, secsBytes[:]...)
+	}
+
+	if key.ConfirmBeforeUse {
+		constraints = append(constraints, agentConstrainConfirm)
+	}
+
+	if cert := key.Certificate; cert == nil {
+		return c.insertKey(key.PrivateKey, key.Comment, constraints)
 	} else {
-		return c.insertCert(s, cert, comment)
+		return c.insertCert(key.PrivateKey, cert, key.Comment, constraints)
 	}
 }
 
-func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string) error {
+func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string, constraints []byte) error {
 	var req []byte
 	switch k := s.(type) {
 	case *rsa.PrivateKey:
@@ -490,13 +536,14 @@
 		}
 		k.Precompute()
 		req = ssh.Marshal(rsaCertMsg{
-			Type:      cert.Type(),
-			CertBytes: cert.Marshal(),
-			D:         k.D,
-			Iqmp:      k.Precomputed.Qinv,
-			P:         k.Primes[0],
-			Q:         k.Primes[1],
-			Comments:  comment,
+			Type:        cert.Type(),
+			CertBytes:   cert.Marshal(),
+			D:           k.D,
+			Iqmp:        k.Precomputed.Qinv,
+			P:           k.Primes[0],
+			Q:           k.Primes[1],
+			Comments:    comment,
+			Constraints: constraints,
 		})
 	case *dsa.PrivateKey:
 		req = ssh.Marshal(dsaCertMsg{
@@ -516,6 +563,11 @@
 		return fmt.Errorf("agent: unsupported key type %T", s)
 	}
 
+	// if constraints are present then the message type needs to be changed.
+	if len(constraints) != 0 {
+		req[0] = agentAddIdConstrained
+	}
+
 	signer, err := ssh.NewSignerFromKey(s)
 	if err != nil {
 		return err
diff --git a/go/src/golang.org/x/crypto/ssh/agent/client_test.go b/go/src/golang.org/x/crypto/ssh/agent/client_test.go
index 80e2c2c..ec7198d 100644
--- a/go/src/golang.org/x/crypto/ssh/agent/client_test.go
+++ b/go/src/golang.org/x/crypto/ssh/agent/client_test.go
@@ -78,14 +78,14 @@
 	}
 }
 
-func testAgent(t *testing.T, key interface{}, cert *ssh.Certificate) {
+func testAgent(t *testing.T, key interface{}, cert *ssh.Certificate, lifetimeSecs uint32) {
 	agent, _, cleanup := startAgent(t)
 	defer cleanup()
 
-	testAgentInterface(t, agent, key, cert)
+	testAgentInterface(t, agent, key, cert, lifetimeSecs)
 }
 
-func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Certificate) {
+func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Certificate, lifetimeSecs uint32) {
 	signer, err := ssh.NewSignerFromKey(key)
 	if err != nil {
 		t.Fatalf("NewSignerFromKey(%T): %v", key, err)
@@ -100,10 +100,15 @@
 	// Attempt to insert the key, with certificate if specified.
 	var pubKey ssh.PublicKey
 	if cert != nil {
-		err = agent.Add(key, cert, "comment")
+		err = agent.Add(AddedKey{
+			PrivateKey:   key,
+			Certificate:  cert,
+			Comment:      "comment",
+			LifetimeSecs: lifetimeSecs,
+		})
 		pubKey = cert
 	} else {
-		err = agent.Add(key, nil, "comment")
+		err = agent.Add(AddedKey{PrivateKey: key, Comment: "comment", LifetimeSecs: lifetimeSecs})
 		pubKey = signer.PublicKey()
 	}
 	if err != nil {
@@ -135,7 +140,7 @@
 
 func TestAgent(t *testing.T) {
 	for _, keyType := range []string{"rsa", "dsa", "ecdsa"} {
-		testAgent(t, testPrivateKeys[keyType], nil)
+		testAgent(t, testPrivateKeys[keyType], nil, 0)
 	}
 }
 
@@ -147,7 +152,11 @@
 	}
 	cert.SignCert(rand.Reader, testSigners["ecdsa"])
 
-	testAgent(t, testPrivateKeys["rsa"], cert)
+	testAgent(t, testPrivateKeys["rsa"], cert, 0)
+}
+
+func TestConstraints(t *testing.T) {
+	testAgent(t, testPrivateKeys["rsa"], nil, 3600 /* lifetime in seconds */)
 }
 
 // netPipe is analogous to net.Pipe, but it uses a real net.Conn, and
@@ -185,7 +194,7 @@
 	agent, _, cleanup := startAgent(t)
 	defer cleanup()
 
-	if err := agent.Add(testPrivateKeys["rsa"], nil, "comment"); err != nil {
+	if err := agent.Add(AddedKey{PrivateKey: testPrivateKeys["rsa"], Comment: "comment"}); err != nil {
 		t.Errorf("Add: %v", err)
 	}
 
@@ -223,10 +232,10 @@
 }
 
 func testLockAgent(agent Agent, t *testing.T) {
-	if err := agent.Add(testPrivateKeys["rsa"], nil, "comment 1"); err != nil {
+	if err := agent.Add(AddedKey{PrivateKey: testPrivateKeys["rsa"], Comment: "comment 1"}); err != nil {
 		t.Errorf("Add: %v", err)
 	}
-	if err := agent.Add(testPrivateKeys["dsa"], nil, "comment dsa"); err != nil {
+	if err := agent.Add(AddedKey{PrivateKey: testPrivateKeys["dsa"], Comment: "comment dsa"}); err != nil {
 		t.Errorf("Add: %v", err)
 	}
 	if keys, err := agent.List(); err != nil {
diff --git a/go/src/golang.org/x/crypto/ssh/agent/keyring.go b/go/src/golang.org/x/crypto/ssh/agent/keyring.go
index 8ac2009..11b72df 100644
--- a/go/src/golang.org/x/crypto/ssh/agent/keyring.go
+++ b/go/src/golang.org/x/crypto/ssh/agent/keyring.go
@@ -125,27 +125,28 @@
 }
 
 // Insert adds a private key to the keyring. If a certificate
-// is given, that certificate is added as public key.
-func (r *keyring) Add(priv interface{}, cert *ssh.Certificate, comment string) error {
+// is given, that certificate is added as public key. Note that
+// any constraints given are ignored.
+func (r *keyring) Add(key AddedKey) error {
 	r.mu.Lock()
 	defer r.mu.Unlock()
 	if r.locked {
 		return errLocked
 	}
-	signer, err := ssh.NewSignerFromKey(priv)
+	signer, err := ssh.NewSignerFromKey(key.PrivateKey)
 
 	if err != nil {
 		return err
 	}
 
-	if cert != nil {
+	if cert := key.Certificate; cert != nil {
 		signer, err = ssh.NewCertSigner(cert, signer)
 		if err != nil {
 			return err
 		}
 	}
 
-	r.keys = append(r.keys, privKey{signer, comment})
+	r.keys = append(r.keys, privKey{signer, key.Comment})
 
 	return nil
 }
diff --git a/go/src/golang.org/x/crypto/ssh/agent/server.go b/go/src/golang.org/x/crypto/ssh/agent/server.go
index be9df0e..b21a201 100644
--- a/go/src/golang.org/x/crypto/ssh/agent/server.go
+++ b/go/src/golang.org/x/crypto/ssh/agent/server.go
@@ -167,7 +167,7 @@
 		}
 		priv.Precompute()
 
-		return s.agent.Add(&priv, nil, k.Comments)
+		return s.agent.Add(AddedKey{PrivateKey: &priv, Comment: k.Comments})
 	}
 	return fmt.Errorf("not implemented: %s", record.Type)
 }
diff --git a/go/src/golang.org/x/crypto/ssh/agent/server_test.go b/go/src/golang.org/x/crypto/ssh/agent/server_test.go
index def5f8c..ef0ab29 100644
--- a/go/src/golang.org/x/crypto/ssh/agent/server_test.go
+++ b/go/src/golang.org/x/crypto/ssh/agent/server_test.go
@@ -21,7 +21,7 @@
 
 	go ServeAgent(NewKeyring(), c2)
 
-	testAgentInterface(t, client, testPrivateKeys["rsa"], nil)
+	testAgentInterface(t, client, testPrivateKeys["rsa"], nil, 0)
 }
 
 func TestLockServer(t *testing.T) {
@@ -72,6 +72,6 @@
 	go ssh.DiscardRequests(reqs)
 
 	agentClient := NewClient(ch)
-	testAgentInterface(t, agentClient, testPrivateKeys["rsa"], nil)
+	testAgentInterface(t, agentClient, testPrivateKeys["rsa"], nil, 0)
 	conn.Close()
 }
diff --git a/go/src/golang.org/x/crypto/ssh/certs_test.go b/go/src/golang.org/x/crypto/ssh/certs_test.go
index d6c4a33..c5f2e53 100644
--- a/go/src/golang.org/x/crypto/ssh/certs_test.go
+++ b/go/src/golang.org/x/crypto/ssh/certs_test.go
@@ -186,15 +186,15 @@
 		defer c1.Close()
 		defer c2.Close()
 
+		errc := make(chan error)
+
 		go func() {
 			conf := ServerConfig{
 				NoClientAuth: true,
 			}
 			conf.AddHostKey(certSigner)
 			_, _, _, err := NewServerConn(c1, &conf)
-			if err != nil {
-				t.Fatalf("NewServerConn: %v", err)
-			}
+			errc <- err
 		}()
 
 		config := &ClientConfig{
@@ -207,5 +207,10 @@
 		if (err == nil) != succeed {
 			t.Fatalf("NewClientConn(%q): %v", name, err)
 		}
+
+		err = <-errc
+		if (err == nil) != succeed {
+			t.Fatalf("NewServerConn(%q): %v", name, err)
+		}
 	}
 }
diff --git a/go/src/golang.org/x/crypto/ssh/client.go b/go/src/golang.org/x/crypto/ssh/client.go
index 72bd27f..0b9fbe5 100644
--- a/go/src/golang.org/x/crypto/ssh/client.go
+++ b/go/src/golang.org/x/crypto/ssh/client.go
@@ -203,4 +203,11 @@
 	// ClientVersion contains the version identification string that will
 	// be used for the connection. If empty, a reasonable default is used.
 	ClientVersion string
+
+	// HostKeyAlgorithms lists the key types that the client will
+	// accept from the server as host key, in order of
+	// preference. If empty, a reasonable default is used. Any
+	// string returned from PublicKey.Type method may be used, or
+	// any of the CertAlgoXxxx and KeyAlgoXxxx constants.
+	HostKeyAlgorithms []string
 }
diff --git a/go/src/golang.org/x/crypto/ssh/common.go b/go/src/golang.org/x/crypto/ssh/common.go
index 0a9df1f..1aef9c0 100644
--- a/go/src/golang.org/x/crypto/ssh/common.go
+++ b/go/src/golang.org/x/crypto/ssh/common.go
@@ -33,6 +33,7 @@
 // supportedKexAlgos specifies the supported key-exchange algorithms in
 // preference order.
 var supportedKexAlgos = []string{
+	kexAlgoCurve25519SHA256,
 	// P384 and P521 are not constant-time yet, but since we don't
 	// reuse ephemeral keys, using them for ECDH should be OK.
 	kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
diff --git a/go/src/golang.org/x/crypto/ssh/handshake.go b/go/src/golang.org/x/crypto/ssh/handshake.go
index a1e2c23..12633c8 100644
--- a/go/src/golang.org/x/crypto/ssh/handshake.go
+++ b/go/src/golang.org/x/crypto/ssh/handshake.go
@@ -59,7 +59,14 @@
 	serverVersion []byte
 	clientVersion []byte
 
-	hostKeys []Signer // If hostKeys are given, we are the server.
+	// hostKeys is non-empty if we are the server. In that case,
+	// it contains all host keys that can be used to sign the
+	// connection.
+	hostKeys []Signer
+
+	// hostKeyAlgorithms is non-empty if we are the client. In that case,
+	// we accept these key types from the server as host key.
+	hostKeyAlgorithms []string
 
 	// On read error, incoming is closed, and readError is set.
 	incoming  chan []byte
@@ -98,6 +105,11 @@
 	t.dialAddress = dialAddr
 	t.remoteAddr = addr
 	t.hostKeyCallback = config.HostKeyCallback
+	if config.HostKeyAlgorithms != nil {
+		t.hostKeyAlgorithms = config.HostKeyAlgorithms
+	} else {
+		t.hostKeyAlgorithms = supportedHostKeyAlgos
+	}
 	go t.readLoop()
 	return t
 }
@@ -141,6 +153,14 @@
 		}
 		t.incoming <- p
 	}
+
+	// If we can't read, declare the writing part dead too.
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	if t.writeError == nil {
+		t.writeError = t.readError
+	}
+	t.cond.Broadcast()
 }
 
 func (t *handshakeTransport) readOnePacket() ([]byte, error) {
@@ -234,7 +254,7 @@
 				msg.ServerHostKeyAlgos, k.PublicKey().Type())
 		}
 	} else {
-		msg.ServerHostKeyAlgos = supportedHostKeyAlgos
+		msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
 	}
 	packet := Marshal(msg)
 
@@ -253,10 +273,12 @@
 
 func (t *handshakeTransport) writePacket(p []byte) error {
 	t.mu.Lock()
+	defer t.mu.Unlock()
+
 	if t.writtenSinceKex > t.config.RekeyThreshold {
 		t.sendKexInitLocked()
 	}
-	for t.sentInitMsg != nil {
+	for t.sentInitMsg != nil && t.writeError == nil {
 		t.cond.Wait()
 	}
 	if t.writeError != nil {
@@ -264,17 +286,14 @@
 	}
 	t.writtenSinceKex += uint64(len(p))
 
-	var err error
 	switch p[0] {
 	case msgKexInit:
-		err = errors.New("ssh: only handshakeTransport can send kexInit")
+		return errors.New("ssh: only handshakeTransport can send kexInit")
 	case msgNewKeys:
-		err = errors.New("ssh: only handshakeTransport can send newKeys")
+		return errors.New("ssh: only handshakeTransport can send newKeys")
 	default:
-		err = t.conn.writePacket(p)
+		return t.conn.writePacket(p)
 	}
-	t.mu.Unlock()
-	return err
 }
 
 func (t *handshakeTransport) Close() error {
diff --git a/go/src/golang.org/x/crypto/ssh/handshake_test.go b/go/src/golang.org/x/crypto/ssh/handshake_test.go
index 613c498..b86d369 100644
--- a/go/src/golang.org/x/crypto/ssh/handshake_test.go
+++ b/go/src/golang.org/x/crypto/ssh/handshake_test.go
@@ -7,8 +7,12 @@
 import (
 	"bytes"
 	"crypto/rand"
+	"errors"
 	"fmt"
 	"net"
+	"runtime"
+	"strings"
+	"sync"
 	"testing"
 )
 
@@ -68,6 +72,7 @@
 
 	serverConf := &ServerConfig{}
 	serverConf.AddHostKey(testSigners["ecdsa"])
+	serverConf.AddHostKey(testSigners["rsa"])
 	serverConf.SetDefaults()
 	server = newServerTransport(trS, v, v, serverConf)
 
@@ -75,6 +80,9 @@
 }
 
 func TestHandshakeBasic(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("see golang.org/issue/7237")
+	}
 	checker := &testChecker{}
 	trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr")
 	if err != nil {
@@ -309,3 +317,99 @@
 
 	<-sync.called
 }
+
+// errorKeyingTransport generates errors after a given number of
+// read/write operations.
+type errorKeyingTransport struct {
+	packetConn
+	readLeft, writeLeft int
+}
+
+func (n *errorKeyingTransport) prepareKeyChange(*algorithms, *kexResult) error {
+	return nil
+}
+func (n *errorKeyingTransport) getSessionID() []byte {
+	return nil
+}
+
+func (n *errorKeyingTransport) writePacket(packet []byte) error {
+	if n.writeLeft == 0 {
+		n.Close()
+		return errors.New("barf")
+	}
+
+	n.writeLeft--
+	return n.packetConn.writePacket(packet)
+}
+
+func (n *errorKeyingTransport) readPacket() ([]byte, error) {
+	if n.readLeft == 0 {
+		n.Close()
+		return nil, errors.New("barf")
+	}
+
+	n.readLeft--
+	return n.packetConn.readPacket()
+}
+
+func TestHandshakeErrorHandlingRead(t *testing.T) {
+	for i := 0; i < 20; i++ {
+		testHandshakeErrorHandlingN(t, i, -1)
+	}
+}
+
+func TestHandshakeErrorHandlingWrite(t *testing.T) {
+	for i := 0; i < 20; i++ {
+		testHandshakeErrorHandlingN(t, -1, i)
+	}
+}
+
+// testHandshakeErrorHandlingN runs handshakes, injecting errors. If
+// handshakeTransport deadlocks, the go runtime will detect it and
+// panic.
+func testHandshakeErrorHandlingN(t *testing.T, readLimit, writeLimit int) {
+	msg := Marshal(&serviceRequestMsg{strings.Repeat("x", int(minRekeyThreshold)/4)})
+
+	a, b := memPipe()
+	defer a.Close()
+	defer b.Close()
+
+	key := testSigners["ecdsa"]
+	serverConf := Config{RekeyThreshold: minRekeyThreshold}
+	serverConf.SetDefaults()
+	serverConn := newHandshakeTransport(&errorKeyingTransport{a, readLimit, writeLimit}, &serverConf, []byte{'a'}, []byte{'b'})
+	serverConn.hostKeys = []Signer{key}
+	go serverConn.readLoop()
+
+	clientConf := Config{RekeyThreshold: 10 * minRekeyThreshold}
+	clientConf.SetDefaults()
+	clientConn := newHandshakeTransport(&errorKeyingTransport{b, -1, -1}, &clientConf, []byte{'a'}, []byte{'b'})
+	clientConn.hostKeyAlgorithms = []string{key.PublicKey().Type()}
+	go clientConn.readLoop()
+
+	var wg sync.WaitGroup
+	wg.Add(4)
+
+	for _, hs := range []packetConn{serverConn, clientConn} {
+		go func(c packetConn) {
+			for {
+				err := c.writePacket(msg)
+				if err != nil {
+					break
+				}
+			}
+			wg.Done()
+		}(hs)
+		go func(c packetConn) {
+			for {
+				_, err := c.readPacket()
+				if err != nil {
+					break
+				}
+			}
+			wg.Done()
+		}(hs)
+	}
+
+	wg.Wait()
+}
diff --git a/go/src/golang.org/x/crypto/ssh/kex.go b/go/src/golang.org/x/crypto/ssh/kex.go
index 6a835c7..ea19d53 100644
--- a/go/src/golang.org/x/crypto/ssh/kex.go
+++ b/go/src/golang.org/x/crypto/ssh/kex.go
@@ -8,18 +8,22 @@
 	"crypto"
 	"crypto/ecdsa"
 	"crypto/elliptic"
+	"crypto/subtle"
 	"crypto/rand"
 	"errors"
 	"io"
 	"math/big"
+
+	"golang.org/x/crypto/curve25519"
 )
 
 const (
-	kexAlgoDH1SHA1  = "diffie-hellman-group1-sha1"
-	kexAlgoDH14SHA1 = "diffie-hellman-group14-sha1"
-	kexAlgoECDH256  = "ecdh-sha2-nistp256"
-	kexAlgoECDH384  = "ecdh-sha2-nistp384"
-	kexAlgoECDH521  = "ecdh-sha2-nistp521"
+	kexAlgoDH1SHA1          = "diffie-hellman-group1-sha1"
+	kexAlgoDH14SHA1         = "diffie-hellman-group14-sha1"
+	kexAlgoECDH256          = "ecdh-sha2-nistp256"
+	kexAlgoECDH384          = "ecdh-sha2-nistp384"
+	kexAlgoECDH521          = "ecdh-sha2-nistp521"
+	kexAlgoCurve25519SHA256 = "curve25519-sha256@libssh.org"
 )
 
 // kexResult captures the outcome of a key exchange.
@@ -383,4 +387,140 @@
 	kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()}
 	kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()}
 	kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()}
+	kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{}
+}
+
+// curve25519sha256 implements the curve25519-sha256@libssh.org key
+// agreement protocol, as described in
+// https://git.libssh.org/projects/libssh.git/tree/doc/curve25519-sha256@libssh.org.txt
+type curve25519sha256 struct{}
+
+type curve25519KeyPair struct {
+	priv [32]byte
+	pub  [32]byte
+}
+
+func (kp *curve25519KeyPair) generate(rand io.Reader) error {
+	if _, err := io.ReadFull(rand, kp.priv[:]); err != nil {
+		return err
+	}
+	curve25519.ScalarBaseMult(&kp.pub, &kp.priv)
+	return nil
+}
+
+// curve25519Zeros is just an array of 32 zero bytes so that we have something
+// convenient to compare against in order to reject curve25519 points with the
+// wrong order.
+var curve25519Zeros [32]byte
+
+func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {
+	var kp curve25519KeyPair
+	if err := kp.generate(rand); err != nil {
+		return nil, err
+	}
+	if err := c.writePacket(Marshal(&kexECDHInitMsg{kp.pub[:]})); err != nil {
+		return nil, err
+	}
+
+	packet, err := c.readPacket()
+	if err != nil {
+		return nil, err
+	}
+
+	var reply kexECDHReplyMsg
+	if err = Unmarshal(packet, &reply); err != nil {
+		return nil, err
+	}
+	if len(reply.EphemeralPubKey) != 32 {
+		return nil, errors.New("ssh: peer's curve25519 public value has wrong length")
+	}
+
+	var servPub, secret [32]byte
+	copy(servPub[:], reply.EphemeralPubKey)
+	curve25519.ScalarMult(&secret, &kp.priv, &servPub)
+	if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {
+		return nil, errors.New("ssh: peer's curve25519 public value has wrong order")
+	}
+
+	h := crypto.SHA256.New()
+	magics.write(h)
+	writeString(h, reply.HostKey)
+	writeString(h, kp.pub[:])
+	writeString(h, reply.EphemeralPubKey)
+
+	kInt := new(big.Int).SetBytes(secret[:])
+	K := make([]byte, intLength(kInt))
+	marshalInt(K, kInt)
+	h.Write(K)
+
+	return &kexResult{
+		H:         h.Sum(nil),
+		K:         K,
+		HostKey:   reply.HostKey,
+		Signature: reply.Signature,
+		Hash:      crypto.SHA256,
+	}, nil
+}
+
+func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
+	packet, err := c.readPacket()
+	if err != nil {
+		return
+	}
+	var kexInit kexECDHInitMsg
+	if err = Unmarshal(packet, &kexInit); err != nil {
+		return
+	}
+
+	if len(kexInit.ClientPubKey) != 32 {
+		return nil, errors.New("ssh: peer's curve25519 public value has wrong length")
+	}
+
+	var kp curve25519KeyPair
+	if err := kp.generate(rand); err != nil {
+		return nil, err
+	}
+
+	var clientPub, secret [32]byte
+	copy(clientPub[:], kexInit.ClientPubKey)
+	curve25519.ScalarMult(&secret, &kp.priv, &clientPub)
+	if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {
+		return nil, errors.New("ssh: peer's curve25519 public value has wrong order")
+	}
+
+	hostKeyBytes := priv.PublicKey().Marshal()
+
+	h := crypto.SHA256.New()
+	magics.write(h)
+	writeString(h, hostKeyBytes)
+	writeString(h, kexInit.ClientPubKey)
+	writeString(h, kp.pub[:])
+
+	kInt := new(big.Int).SetBytes(secret[:])
+	K := make([]byte, intLength(kInt))
+	marshalInt(K, kInt)
+	h.Write(K)
+
+	H := h.Sum(nil)
+
+	sig, err := signAndMarshal(priv, rand, H)
+	if err != nil {
+		return nil, err
+	}
+
+	reply := kexECDHReplyMsg{
+		EphemeralPubKey: kp.pub[:],
+		HostKey:         hostKeyBytes,
+		Signature:       sig,
+	}
+	if err := c.writePacket(Marshal(&reply)); err != nil {
+		return nil, err
+	}
+	return &kexResult{
+		H:         H,
+		K:         K,
+		HostKey:   hostKeyBytes,
+		Signature: sig,
+		Hash:      crypto.SHA256,
+	}, nil
 }
diff --git a/go/src/golang.org/x/crypto/ssh/kex_test.go b/go/src/golang.org/x/crypto/ssh/kex_test.go
index 0db5f9b..12ca0ac 100644
--- a/go/src/golang.org/x/crypto/ssh/kex_test.go
+++ b/go/src/golang.org/x/crypto/ssh/kex_test.go
@@ -26,10 +26,12 @@
 		var magics handshakeMagics
 		go func() {
 			r, e := kex.Client(a, rand.Reader, &magics)
+			a.Close()
 			c <- kexResultErr{r, e}
 		}()
 		go func() {
 			r, e := kex.Server(b, rand.Reader, &magics, testSigners["ecdsa"])
+			b.Close()
 			s <- kexResultErr{r, e}
 		}()
 
diff --git a/go/src/golang.org/x/crypto/ssh/mempipe_test.go b/go/src/golang.org/x/crypto/ssh/mempipe_test.go
index 92519dd..8697cd6 100644
--- a/go/src/golang.org/x/crypto/ssh/mempipe_test.go
+++ b/go/src/golang.org/x/crypto/ssh/mempipe_test.go
@@ -76,7 +76,7 @@
 	return &t1, &t2
 }
 
-func TestmemPipe(t *testing.T) {
+func TestMemPipe(t *testing.T) {
 	a, b := memPipe()
 	if err := a.writePacket([]byte{42}); err != nil {
 		t.Fatalf("writePacket: %v", err)
diff --git a/go/src/golang.org/x/crypto/ssh/session_test.go b/go/src/golang.org/x/crypto/ssh/session_test.go
index 7ce44f5..f7f0f76 100644
--- a/go/src/golang.org/x/crypto/ssh/session_test.go
+++ b/go/src/golang.org/x/crypto/ssh/session_test.go
@@ -718,3 +718,57 @@
 		t.Fatalf("NewServerConn attempted to Read() from Conn while configuration is missing authentication method")
 	}
 }
+
+func TestHostKeyAlgorithms(t *testing.T) {
+	serverConf := &ServerConfig{
+		NoClientAuth: true,
+	}
+	serverConf.AddHostKey(testSigners["rsa"])
+	serverConf.AddHostKey(testSigners["ecdsa"])
+
+	connect := func(clientConf *ClientConfig, want string) {
+		var alg string
+		clientConf.HostKeyCallback = func(h string, a net.Addr, key PublicKey) error {
+			alg = key.Type()
+			return nil
+		}
+		c1, c2, err := netPipe()
+		if err != nil {
+			t.Fatalf("netPipe: %v", err)
+		}
+		defer c1.Close()
+		defer c2.Close()
+
+		go NewServerConn(c1, serverConf)
+		_, _, _, err = NewClientConn(c2, "", clientConf)
+		if err != nil {
+			t.Fatalf("NewClientConn: %v", err)
+		}
+		if alg != want {
+			t.Errorf("selected key algorithm %s, want %s", alg, want)
+		}
+	}
+
+	// By default, we get the preferred algorithm, which is ECDSA 256.
+
+	clientConf := &ClientConfig{}
+	connect(clientConf, KeyAlgoECDSA256)
+
+	// Client asks for RSA explicitly.
+	clientConf.HostKeyAlgorithms = []string{KeyAlgoRSA}
+	connect(clientConf, KeyAlgoRSA)
+
+	c1, c2, err := netPipe()
+	if err != nil {
+		t.Fatalf("netPipe: %v", err)
+	}
+	defer c1.Close()
+	defer c2.Close()
+
+	go NewServerConn(c1, serverConf)
+	clientConf.HostKeyAlgorithms = []string{"nonexistent-hostkey-algo"}
+	_, _, _, err = NewClientConn(c2, "", clientConf)
+	if err == nil {
+		t.Fatal("succeeded connecting with unknown hostkey algorithm")
+	}
+}
diff --git a/go/src/golang.org/x/crypto/ssh/tcpip.go b/go/src/golang.org/x/crypto/ssh/tcpip.go
index 4ecad0b..6151241 100644
--- a/go/src/golang.org/x/crypto/ssh/tcpip.go
+++ b/go/src/golang.org/x/crypto/ssh/tcpip.go
@@ -355,6 +355,9 @@
 		lport: uint32(lport),
 	}
 	ch, in, err := c.OpenChannel("direct-tcpip", Marshal(&msg))
+	if err != nil {
+		return nil, err
+	}
 	go DiscardRequests(in)
 	return ch, err
 }
diff --git a/go/src/golang.org/x/crypto/ssh/test/agent_unix_test.go b/go/src/golang.org/x/crypto/ssh/test/agent_unix_test.go
index 502e24f..f481253 100644
--- a/go/src/golang.org/x/crypto/ssh/test/agent_unix_test.go
+++ b/go/src/golang.org/x/crypto/ssh/test/agent_unix_test.go
@@ -21,7 +21,16 @@
 	defer conn.Close()
 
 	keyring := agent.NewKeyring()
-	keyring.Add(testPrivateKeys["dsa"], nil, "")
+	if err := keyring.Add(agent.AddedKey{PrivateKey: testPrivateKeys["dsa"]}); err != nil {
+		t.Fatalf("Error adding key: %s", err)
+	}
+	if err := keyring.Add(agent.AddedKey{
+		PrivateKey:       testPrivateKeys["dsa"],
+		ConfirmBeforeUse: true,
+		LifetimeSecs:     3600,
+	}); err != nil {
+		t.Fatalf("Error adding key with constraints: %s", err)
+	}
 	pub := testPublicKeys["dsa"]
 
 	sess, err := conn.NewSession()
diff --git a/go/src/golang.org/x/crypto/ssh/test/session_test.go b/go/src/golang.org/x/crypto/ssh/test/session_test.go
index fbd1044..c0e714b 100644
--- a/go/src/golang.org/x/crypto/ssh/test/session_test.go
+++ b/go/src/golang.org/x/crypto/ssh/test/session_test.go
@@ -319,3 +319,22 @@
 		}
 	}
 }
+
+func TestKeyExchanges(t *testing.T) {
+	var config ssh.Config
+	config.SetDefaults()
+	kexOrder := config.KeyExchanges
+	for _, kex := range kexOrder {
+		server := newServer(t)
+		defer server.Shutdown()
+		conf := clientConfig()
+		// Don't fail if sshd doesnt have the kex.
+		conf.KeyExchanges = append([]string{kex}, kexOrder...)
+		conn, err := server.TryDial(conf)
+		if err == nil {
+			conn.Close()
+		} else {
+			t.Errorf("failed for kex %q", kex)
+		}
+	}
+}
diff --git a/go/src/golang.org/x/crypto/tea/cipher.go b/go/src/golang.org/x/crypto/tea/cipher.go
new file mode 100644
index 0000000..9c13d12
--- /dev/null
+++ b/go/src/golang.org/x/crypto/tea/cipher.go
@@ -0,0 +1,109 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package tea implements the TEA algorithm, as defined in Needham and
+// Wheeler's 1994 technical report, “TEA, a Tiny Encryption Algorithm”. See
+// http://www.cix.co.uk/~klockstone/tea.pdf for details.
+
+package tea
+
+import (
+	"crypto/cipher"
+	"encoding/binary"
+	"errors"
+)
+
+const (
+	// BlockSize is the size of a TEA block, in bytes.
+	BlockSize = 8
+
+	// KeySize is the size of a TEA key, in bytes.
+	KeySize = 16
+
+	// delta is the TEA key schedule constant.
+	delta = 0x9e3779b9
+
+	// numRounds is the standard number of rounds in TEA.
+	numRounds = 64
+)
+
+// tea is an instance of the TEA cipher with a particular key.
+type tea struct {
+	key    [16]byte
+	rounds int
+}
+
+// NewCipher returns an instance of the TEA cipher with the standard number of
+// rounds. The key argument must be 16 bytes long.
+func NewCipher(key []byte) (cipher.Block, error) {
+	return NewCipherWithRounds(key, numRounds)
+}
+
+// NewCipherWithRounds returns an instance of the TEA cipher with a given
+// number of rounds, which must be even. The key argument must be 16 bytes
+// long.
+func NewCipherWithRounds(key []byte, rounds int) (cipher.Block, error) {
+	if len(key) != 16 {
+		return nil, errors.New("tea: incorrect key size")
+	}
+
+	if rounds&1 != 0 {
+		return nil, errors.New("tea: odd number of rounds specified")
+	}
+
+	c := &tea{
+		rounds: rounds,
+	}
+	copy(c.key[:], key)
+
+	return c, nil
+}
+
+// BlockSize returns the TEA block size, which is eight bytes. It is necessary
+// to satisfy the Block interface in the package "crypto/cipher".
+func (*tea) BlockSize() int {
+	return BlockSize
+}
+
+// Encrypt encrypts the 8 byte buffer src using the key in t and stores the
+// result in dst. Note that for amounts of data larger than a block, it is not
+// safe to just call Encrypt on successive blocks; instead, use an encryption
+// mode like CBC (see crypto/cipher/cbc.go).
+func (t *tea) Encrypt(dst, src []byte) {
+	e := binary.BigEndian
+	v0, v1 := e.Uint32(src), e.Uint32(src[4:])
+	k0, k1, k2, k3 := e.Uint32(t.key[0:]), e.Uint32(t.key[4:]), e.Uint32(t.key[8:]), e.Uint32(t.key[12:])
+
+	sum := uint32(0)
+	delta := uint32(delta)
+
+	for i := 0; i < t.rounds/2; i++ {
+		sum += delta
+		v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1)
+		v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3)
+	}
+
+	e.PutUint32(dst, v0)
+	e.PutUint32(dst[4:], v1)
+}
+
+// Decrypt decrypts the 8 byte buffer src using the key in t and stores the
+// result in dst.
+func (t *tea) Decrypt(dst, src []byte) {
+	e := binary.BigEndian
+	v0, v1 := e.Uint32(src), e.Uint32(src[4:])
+	k0, k1, k2, k3 := e.Uint32(t.key[0:]), e.Uint32(t.key[4:]), e.Uint32(t.key[8:]), e.Uint32(t.key[12:])
+
+	delta := uint32(delta)
+	sum := delta * uint32(t.rounds/2) // in general, sum = delta * n
+
+	for i := 0; i < t.rounds/2; i++ {
+		v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3)
+		v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1)
+		sum -= delta
+	}
+
+	e.PutUint32(dst, v0)
+	e.PutUint32(dst[4:], v1)
+}
diff --git a/go/src/golang.org/x/crypto/tea/tea_test.go b/go/src/golang.org/x/crypto/tea/tea_test.go
new file mode 100644
index 0000000..eb98d1e
--- /dev/null
+++ b/go/src/golang.org/x/crypto/tea/tea_test.go
@@ -0,0 +1,93 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tea
+
+import (
+	"bytes"
+	"testing"
+)
+
+// A sample test key for when we just want to initialize a cipher
+var testKey = []byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}
+
+// Test that the block size for tea is correct
+func TestBlocksize(t *testing.T) {
+	c, err := NewCipher(testKey)
+	if err != nil {
+		t.Fatalf("NewCipher returned error: %s", err)
+	}
+
+	if result := c.BlockSize(); result != BlockSize {
+		t.Errorf("cipher.BlockSize returned %d, but expected %d", result, BlockSize)
+	}
+}
+
+// Test that invalid key sizes return an error
+func TestInvalidKeySize(t *testing.T) {
+	var key [KeySize + 1]byte
+
+	if _, err := NewCipher(key[:]); err == nil {
+		t.Errorf("invalid key size %d didn't result in an error.", len(key))
+	}
+
+	if _, err := NewCipher(key[:KeySize-1]); err == nil {
+		t.Errorf("invalid key size %d didn't result in an error.", KeySize-1)
+	}
+}
+
+// Test Vectors
+type teaTest struct {
+	rounds     int
+	key        []byte
+	plaintext  []byte
+	ciphertext []byte
+}
+
+var teaTests = []teaTest{
+	// These were sourced from https://github.com/froydnj/ironclad/blob/master/testing/test-vectors/tea.testvec
+	{
+		numRounds,
+		[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+		[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+		[]byte{0x41, 0xea, 0x3a, 0x0a, 0x94, 0xba, 0xa9, 0x40},
+	},
+	{
+		numRounds,
+		[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+		[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+		[]byte{0x31, 0x9b, 0xbe, 0xfb, 0x01, 0x6a, 0xbd, 0xb2},
+	},
+	{
+		16,
+		[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+		[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+		[]byte{0xed, 0x28, 0x5d, 0xa1, 0x45, 0x5b, 0x33, 0xc1},
+	},
+}
+
+// Test encryption
+func TestCipherEncrypt(t *testing.T) {
+	// Test encryption with standard 64 rounds
+	for i, test := range teaTests {
+		c, err := NewCipherWithRounds(test.key, test.rounds)
+		if err != nil {
+			t.Fatalf("#%d: NewCipher returned error: %s", i, err)
+		}
+
+		var ciphertext [BlockSize]byte
+		c.Encrypt(ciphertext[:], test.plaintext)
+
+		if !bytes.Equal(ciphertext[:], test.ciphertext) {
+			t.Errorf("#%d: incorrect ciphertext. Got %x, wanted %x", i, ciphertext, test.ciphertext)
+		}
+
+		var plaintext2 [BlockSize]byte
+		c.Decrypt(plaintext2[:], ciphertext[:])
+
+		if !bytes.Equal(plaintext2[:], test.plaintext) {
+			t.Errorf("#%d: incorrect plaintext. Got %x, wanted %x", i, plaintext2, test.plaintext)
+		}
+	}
+}