func (c *Conn) clientHandshake() error { if err := c.writeMessage(c.config.EphKey.Public); err != nil { return err } serverHelloBox, err := c.readMessage(0) if err != nil { return err } if _, err := c.readCrypter.DecryptBox(serverHelloBox, 2); err != nil { return err } c.writeCrypter.ChainVar = c.readCrypter.ChainVar clientHello, _ := c.writeCrypter.EncryptBox(nil, c.config.EphKey, nil, c.config.PadLen, 4) if err := c.writeMessage(clientHello[c.config.Cipher.DHLen():]); err != nil { return err } kdfExtra := append(c.config.Cipher.AppendName(make([]byte, 0, 25)), 6) contexts := box.DeriveKey(c.writeCrypter.ChainVar, make([]byte, box.CVLen), kdfExtra, c.config.Cipher.CCLen()*2) c.writeCrypter.SetContext(contexts[:c.config.Cipher.CCLen()]) c.readCrypter.SetContext(contexts[c.config.Cipher.CCLen():]) return nil }
func (c *Conn) serverHandshake() error { keyLen, _ := c.config.Cipher.KeyLen() peerEphKey, err := c.readMessage(uint32(keyLen)) if err != nil { return err } if len(peerEphKey) != keyLen { return errors.New("pipe: client key too short") } c.peerEphKey.Public = make([]byte, keyLen) copy(c.peerEphKey.Public, peerEphKey) serverHello, _ := c.writeCrypter.EncryptBox(nil, c.config.EphKey, nil, c.config.PadLen, 2) if err := c.writeMessage(serverHello); err != nil { return err } c.readCrypter.ChainVar = c.writeCrypter.ChainVar c.readBuf.Reset() c.readBuf.Write(peerEphKey) clientHelloBox, err := c.readMessage(0) if err != nil { return err } if _, err := c.readCrypter.DecryptBox(clientHelloBox, 4); err != nil { return err } kdfExtra := append(c.config.Cipher.AppendName(make([]byte, 0, 25)), 6) contexts := box.DeriveKey(c.readCrypter.ChainVar, make([]byte, box.CVLen), kdfExtra, c.config.Cipher.CCLen()*2) c.readCrypter.SetContext(contexts[:c.config.Cipher.CCLen()]) c.writeCrypter.SetContext(contexts[c.config.Cipher.CCLen():]) return nil }