github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/p2p/rlpx/rlpx.go (about)

     1  // Copyright 2020 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Package rlpx implements the RLPx transport protocol.
    18  package rlpx
    19  
    20  import (
    21  	"bytes"
    22  	"crypto/aes"
    23  	"crypto/cipher"
    24  	"crypto/ecdsa"
    25  	"crypto/hmac"
    26  	"crypto/rand"
    27  	"encoding/binary"
    28  	"errors"
    29  	"fmt"
    30  	"hash"
    31  	"io"
    32  	mrand "math/rand"
    33  	"net"
    34  	"time"
    35  
    36  	"github.com/ethereum/go-ethereum/crypto"
    37  	"github.com/ethereum/go-ethereum/crypto/ecies"
    38  	"github.com/ethereum/go-ethereum/rlp"
    39  	"github.com/golang/snappy"
    40  	"golang.org/x/crypto/sha3"
    41  )
    42  
    43  // Conn is an RLPx network connection. It wraps a low-level network connection. The
    44  // underlying connection should not be used for other activity when it is wrapped by Conn.
    45  //
    46  // Before sending messages, a handshake must be performed by calling the Handshake method.
    47  // This type is not generally safe for concurrent use, but reading and writing of messages
    48  // may happen concurrently after the handshake.
    49  type Conn struct {
    50  	dialDest *ecdsa.PublicKey
    51  	conn     net.Conn
    52  	session  *sessionState
    53  
    54  	// These are the buffers for snappy compression.
    55  	// Compression is enabled if they are non-nil.
    56  	snappyReadBuffer  []byte
    57  	snappyWriteBuffer []byte
    58  }
    59  
    60  // sessionState contains the session keys.
    61  type sessionState struct {
    62  	enc cipher.Stream
    63  	dec cipher.Stream
    64  
    65  	egressMAC  hashMAC
    66  	ingressMAC hashMAC
    67  	rbuf       readBuffer
    68  	wbuf       writeBuffer
    69  }
    70  
    71  // hashMAC holds the state of the RLPx v4 MAC contraption.
    72  type hashMAC struct {
    73  	cipher     cipher.Block
    74  	hash       hash.Hash
    75  	aesBuffer  [16]byte
    76  	hashBuffer [32]byte
    77  	seedBuffer [32]byte
    78  }
    79  
    80  func newHashMAC(cipher cipher.Block, h hash.Hash) hashMAC {
    81  	m := hashMAC{cipher: cipher, hash: h}
    82  	if cipher.BlockSize() != len(m.aesBuffer) {
    83  		panic(fmt.Errorf("invalid MAC cipher block size %d", cipher.BlockSize()))
    84  	}
    85  	if h.Size() != len(m.hashBuffer) {
    86  		panic(fmt.Errorf("invalid MAC digest size %d", h.Size()))
    87  	}
    88  	return m
    89  }
    90  
    91  // NewConn wraps the given network connection. If dialDest is non-nil, the connection
    92  // behaves as the initiator during the handshake.
    93  func NewConn(conn net.Conn, dialDest *ecdsa.PublicKey) *Conn {
    94  	return &Conn{
    95  		dialDest: dialDest,
    96  		conn:     conn,
    97  	}
    98  }
    99  
   100  // SetSnappy enables or disables snappy compression of messages. This is usually called
   101  // after the devp2p Hello message exchange when the negotiated version indicates that
   102  // compression is available on both ends of the connection.
   103  func (c *Conn) SetSnappy(snappy bool) {
   104  	if snappy {
   105  		c.snappyReadBuffer = []byte{}
   106  		c.snappyWriteBuffer = []byte{}
   107  	} else {
   108  		c.snappyReadBuffer = nil
   109  		c.snappyWriteBuffer = nil
   110  	}
   111  }
   112  
   113  // SetReadDeadline sets the deadline for all future read operations.
   114  func (c *Conn) SetReadDeadline(time time.Time) error {
   115  	return c.conn.SetReadDeadline(time)
   116  }
   117  
   118  // SetWriteDeadline sets the deadline for all future write operations.
   119  func (c *Conn) SetWriteDeadline(time time.Time) error {
   120  	return c.conn.SetWriteDeadline(time)
   121  }
   122  
   123  // SetDeadline sets the deadline for all future read and write operations.
   124  func (c *Conn) SetDeadline(time time.Time) error {
   125  	return c.conn.SetDeadline(time)
   126  }
   127  
   128  // Read reads a message from the connection.
   129  // The returned data buffer is valid until the next call to Read.
   130  func (c *Conn) Read() (code uint64, data []byte, wireSize int, err error) {
   131  	if c.session == nil {
   132  		panic("can't ReadMsg before handshake")
   133  	}
   134  
   135  	frame, err := c.session.readFrame(c.conn)
   136  	if err != nil {
   137  		return 0, nil, 0, err
   138  	}
   139  	code, data, err = rlp.SplitUint64(frame)
   140  	if err != nil {
   141  		return 0, nil, 0, fmt.Errorf("invalid message code: %v", err)
   142  	}
   143  	wireSize = len(data)
   144  
   145  	// If snappy is enabled, verify and decompress message.
   146  	if c.snappyReadBuffer != nil {
   147  		var actualSize int
   148  		actualSize, err = snappy.DecodedLen(data)
   149  		if err != nil {
   150  			return code, nil, 0, err
   151  		}
   152  		if actualSize > maxUint24 {
   153  			return code, nil, 0, errPlainMessageTooLarge
   154  		}
   155  		c.snappyReadBuffer = growslice(c.snappyReadBuffer, actualSize)
   156  		data, err = snappy.Decode(c.snappyReadBuffer, data)
   157  	}
   158  	return code, data, wireSize, err
   159  }
   160  
   161  func (h *sessionState) readFrame(conn io.Reader) ([]byte, error) {
   162  	h.rbuf.reset()
   163  
   164  	// Read the frame header.
   165  	header, err := h.rbuf.read(conn, 32)
   166  	if err != nil {
   167  		return nil, err
   168  	}
   169  
   170  	// Verify header MAC.
   171  	wantHeaderMAC := h.ingressMAC.computeHeader(header[:16])
   172  	if !hmac.Equal(wantHeaderMAC, header[16:]) {
   173  		return nil, errors.New("bad header MAC")
   174  	}
   175  
   176  	// Decrypt the frame header to get the frame size.
   177  	h.dec.XORKeyStream(header[:16], header[:16])
   178  	fsize := readUint24(header[:16])
   179  	// Frame size rounded up to 16 byte boundary for padding.
   180  	rsize := fsize
   181  	if padding := fsize % 16; padding > 0 {
   182  		rsize += 16 - padding
   183  	}
   184  
   185  	// Read the frame content.
   186  	frame, err := h.rbuf.read(conn, int(rsize))
   187  	if err != nil {
   188  		return nil, err
   189  	}
   190  
   191  	// Validate frame MAC.
   192  	frameMAC, err := h.rbuf.read(conn, 16)
   193  	if err != nil {
   194  		return nil, err
   195  	}
   196  	wantFrameMAC := h.ingressMAC.computeFrame(frame)
   197  	if !hmac.Equal(wantFrameMAC, frameMAC) {
   198  		return nil, errors.New("bad frame MAC")
   199  	}
   200  
   201  	// Decrypt the frame data.
   202  	h.dec.XORKeyStream(frame, frame)
   203  	return frame[:fsize], nil
   204  }
   205  
   206  // Write writes a message to the connection.
   207  //
   208  // Write returns the written size of the message data. This may be less than or equal to
   209  // len(data) depending on whether snappy compression is enabled.
   210  func (c *Conn) Write(code uint64, data []byte) (uint32, error) {
   211  	if c.session == nil {
   212  		panic("can't WriteMsg before handshake")
   213  	}
   214  	if len(data) > maxUint24 {
   215  		return 0, errPlainMessageTooLarge
   216  	}
   217  	if c.snappyWriteBuffer != nil {
   218  		// Ensure the buffer has sufficient size.
   219  		// Package snappy will allocate its own buffer if the provided
   220  		// one is smaller than MaxEncodedLen.
   221  		c.snappyWriteBuffer = growslice(c.snappyWriteBuffer, snappy.MaxEncodedLen(len(data)))
   222  		data = snappy.Encode(c.snappyWriteBuffer, data)
   223  	}
   224  
   225  	wireSize := uint32(len(data))
   226  	err := c.session.writeFrame(c.conn, code, data)
   227  	return wireSize, err
   228  }
   229  
   230  func (h *sessionState) writeFrame(conn io.Writer, code uint64, data []byte) error {
   231  	h.wbuf.reset()
   232  
   233  	// Write header.
   234  	fsize := rlp.IntSize(code) + len(data)
   235  	if fsize > maxUint24 {
   236  		return errPlainMessageTooLarge
   237  	}
   238  	header := h.wbuf.appendZero(16)
   239  	putUint24(uint32(fsize), header)
   240  	copy(header[3:], zeroHeader)
   241  	h.enc.XORKeyStream(header, header)
   242  
   243  	// Write header MAC.
   244  	h.wbuf.Write(h.egressMAC.computeHeader(header))
   245  
   246  	// Encode and encrypt the frame data.
   247  	offset := len(h.wbuf.data)
   248  	h.wbuf.data = rlp.AppendUint64(h.wbuf.data, code)
   249  	h.wbuf.Write(data)
   250  	if padding := fsize % 16; padding > 0 {
   251  		h.wbuf.appendZero(16 - padding)
   252  	}
   253  	framedata := h.wbuf.data[offset:]
   254  	h.enc.XORKeyStream(framedata, framedata)
   255  
   256  	// Write frame MAC.
   257  	h.wbuf.Write(h.egressMAC.computeFrame(framedata))
   258  
   259  	_, err := conn.Write(h.wbuf.data)
   260  	return err
   261  }
   262  
   263  // computeHeader computes the MAC of a frame header.
   264  func (m *hashMAC) computeHeader(header []byte) []byte {
   265  	sum1 := m.hash.Sum(m.hashBuffer[:0])
   266  	return m.compute(sum1, header)
   267  }
   268  
   269  // computeFrame computes the MAC of framedata.
   270  func (m *hashMAC) computeFrame(framedata []byte) []byte {
   271  	m.hash.Write(framedata)
   272  	seed := m.hash.Sum(m.seedBuffer[:0])
   273  	return m.compute(seed, seed[:16])
   274  }
   275  
   276  // compute computes the MAC of a 16-byte 'seed'.
   277  //
   278  // To do this, it encrypts the current value of the hash state, then XORs the ciphertext
   279  // with seed. The obtained value is written back into the hash state and hash output is
   280  // taken again. The first 16 bytes of the resulting sum are the MAC value.
   281  //
   282  // This MAC construction is a horrible, legacy thing.
   283  func (m *hashMAC) compute(sum1, seed []byte) []byte {
   284  	if len(seed) != len(m.aesBuffer) {
   285  		panic("invalid MAC seed")
   286  	}
   287  
   288  	m.cipher.Encrypt(m.aesBuffer[:], sum1)
   289  	for i := range m.aesBuffer {
   290  		m.aesBuffer[i] ^= seed[i]
   291  	}
   292  	m.hash.Write(m.aesBuffer[:])
   293  	sum2 := m.hash.Sum(m.hashBuffer[:0])
   294  	return sum2[:16]
   295  }
   296  
   297  // Handshake performs the handshake. This must be called before any data is written
   298  // or read from the connection.
   299  func (c *Conn) Handshake(prv *ecdsa.PrivateKey) (*ecdsa.PublicKey, error) {
   300  	var (
   301  		sec Secrets
   302  		err error
   303  		h   handshakeState
   304  	)
   305  	if c.dialDest != nil {
   306  		sec, err = h.runInitiator(c.conn, prv, c.dialDest)
   307  	} else {
   308  		sec, err = h.runRecipient(c.conn, prv)
   309  	}
   310  	if err != nil {
   311  		return nil, err
   312  	}
   313  	c.InitWithSecrets(sec)
   314  	c.session.rbuf = h.rbuf
   315  	c.session.wbuf = h.wbuf
   316  	return sec.remote, err
   317  }
   318  
   319  // InitWithSecrets injects connection secrets as if a handshake had
   320  // been performed. This cannot be called after the handshake.
   321  func (c *Conn) InitWithSecrets(sec Secrets) {
   322  	if c.session != nil {
   323  		panic("can't handshake twice")
   324  	}
   325  	macc, err := aes.NewCipher(sec.MAC)
   326  	if err != nil {
   327  		panic("invalid MAC secret: " + err.Error())
   328  	}
   329  	encc, err := aes.NewCipher(sec.AES)
   330  	if err != nil {
   331  		panic("invalid AES secret: " + err.Error())
   332  	}
   333  	// we use an all-zeroes IV for AES because the key used
   334  	// for encryption is ephemeral.
   335  	iv := make([]byte, encc.BlockSize())
   336  	c.session = &sessionState{
   337  		enc:        cipher.NewCTR(encc, iv),
   338  		dec:        cipher.NewCTR(encc, iv),
   339  		egressMAC:  newHashMAC(macc, sec.EgressMAC),
   340  		ingressMAC: newHashMAC(macc, sec.IngressMAC),
   341  	}
   342  }
   343  
   344  // Close closes the underlying network connection.
   345  func (c *Conn) Close() error {
   346  	return c.conn.Close()
   347  }
   348  
   349  // Constants for the handshake.
   350  const (
   351  	sskLen = 16                     // ecies.MaxSharedKeyLength(pubKey) / 2
   352  	sigLen = crypto.SignatureLength // elliptic S256
   353  	pubLen = 64                     // 512 bit pubkey in uncompressed representation without format byte
   354  	shaLen = 32                     // hash length (for nonce etc)
   355  
   356  	eciesOverhead = 65 /* pubkey */ + 16 /* IV */ + 32 /* MAC */
   357  )
   358  
   359  var (
   360  	// this is used in place of actual frame header data.
   361  	// TODO: replace this when Msg contains the protocol type code.
   362  	zeroHeader = []byte{0xC2, 0x80, 0x80}
   363  
   364  	// errPlainMessageTooLarge is returned if a decompressed message length exceeds
   365  	// the allowed 24 bits (i.e. length >= 16MB).
   366  	errPlainMessageTooLarge = errors.New("message length >= 16MB")
   367  )
   368  
   369  // Secrets represents the connection secrets which are negotiated during the handshake.
   370  type Secrets struct {
   371  	AES, MAC              []byte
   372  	EgressMAC, IngressMAC hash.Hash
   373  	remote                *ecdsa.PublicKey
   374  }
   375  
   376  // handshakeState contains the state of the encryption handshake.
   377  type handshakeState struct {
   378  	initiator            bool
   379  	remote               *ecies.PublicKey  // remote-pubk
   380  	initNonce, respNonce []byte            // nonce
   381  	randomPrivKey        *ecies.PrivateKey // ecdhe-random
   382  	remoteRandomPub      *ecies.PublicKey  // ecdhe-random-pubk
   383  
   384  	rbuf readBuffer
   385  	wbuf writeBuffer
   386  }
   387  
   388  // RLPx v4 handshake auth (defined in EIP-8).
   389  type authMsgV4 struct {
   390  	Signature       [sigLen]byte
   391  	InitiatorPubkey [pubLen]byte
   392  	Nonce           [shaLen]byte
   393  	Version         uint
   394  
   395  	// Ignore additional fields (forward-compatibility)
   396  	Rest []rlp.RawValue `rlp:"tail"`
   397  }
   398  
   399  // RLPx v4 handshake response (defined in EIP-8).
   400  type authRespV4 struct {
   401  	RandomPubkey [pubLen]byte
   402  	Nonce        [shaLen]byte
   403  	Version      uint
   404  
   405  	// Ignore additional fields (forward-compatibility)
   406  	Rest []rlp.RawValue `rlp:"tail"`
   407  }
   408  
   409  // runRecipient negotiates a session token on conn.
   410  // it should be called on the listening side of the connection.
   411  //
   412  // prv is the local client's private key.
   413  func (h *handshakeState) runRecipient(conn io.ReadWriter, prv *ecdsa.PrivateKey) (s Secrets, err error) {
   414  	authMsg := new(authMsgV4)
   415  	authPacket, err := h.readMsg(authMsg, prv, conn)
   416  	if err != nil {
   417  		return s, err
   418  	}
   419  	if err := h.handleAuthMsg(authMsg, prv); err != nil {
   420  		return s, err
   421  	}
   422  
   423  	authRespMsg, err := h.makeAuthResp()
   424  	if err != nil {
   425  		return s, err
   426  	}
   427  	authRespPacket, err := h.sealEIP8(authRespMsg)
   428  	if err != nil {
   429  		return s, err
   430  	}
   431  	if _, err = conn.Write(authRespPacket); err != nil {
   432  		return s, err
   433  	}
   434  
   435  	return h.secrets(authPacket, authRespPacket)
   436  }
   437  
   438  func (h *handshakeState) handleAuthMsg(msg *authMsgV4, prv *ecdsa.PrivateKey) error {
   439  	// Import the remote identity.
   440  	rpub, err := importPublicKey(msg.InitiatorPubkey[:])
   441  	if err != nil {
   442  		return err
   443  	}
   444  	h.initNonce = msg.Nonce[:]
   445  	h.remote = rpub
   446  
   447  	// Generate random keypair for ECDH.
   448  	// If a private key is already set, use it instead of generating one (for testing).
   449  	if h.randomPrivKey == nil {
   450  		h.randomPrivKey, err = ecies.GenerateKey(rand.Reader, crypto.S256(), nil)
   451  		if err != nil {
   452  			return err
   453  		}
   454  	}
   455  
   456  	// Check the signature.
   457  	token, err := h.staticSharedSecret(prv)
   458  	if err != nil {
   459  		return err
   460  	}
   461  	signedMsg := xor(token, h.initNonce)
   462  	remoteRandomPub, err := crypto.Ecrecover(signedMsg, msg.Signature[:])
   463  	if err != nil {
   464  		return err
   465  	}
   466  	h.remoteRandomPub, _ = importPublicKey(remoteRandomPub)
   467  	return nil
   468  }
   469  
   470  // secrets is called after the handshake is completed.
   471  // It extracts the connection secrets from the handshake values.
   472  func (h *handshakeState) secrets(auth, authResp []byte) (Secrets, error) {
   473  	ecdheSecret, err := h.randomPrivKey.GenerateShared(h.remoteRandomPub, sskLen, sskLen)
   474  	if err != nil {
   475  		return Secrets{}, err
   476  	}
   477  
   478  	// derive base secrets from ephemeral key agreement
   479  	sharedSecret := crypto.Keccak256(ecdheSecret, crypto.Keccak256(h.respNonce, h.initNonce))
   480  	aesSecret := crypto.Keccak256(ecdheSecret, sharedSecret)
   481  	s := Secrets{
   482  		remote: h.remote.ExportECDSA(),
   483  		AES:    aesSecret,
   484  		MAC:    crypto.Keccak256(ecdheSecret, aesSecret),
   485  	}
   486  
   487  	// setup sha3 instances for the MACs
   488  	mac1 := sha3.NewLegacyKeccak256()
   489  	mac1.Write(xor(s.MAC, h.respNonce))
   490  	mac1.Write(auth)
   491  	mac2 := sha3.NewLegacyKeccak256()
   492  	mac2.Write(xor(s.MAC, h.initNonce))
   493  	mac2.Write(authResp)
   494  	if h.initiator {
   495  		s.EgressMAC, s.IngressMAC = mac1, mac2
   496  	} else {
   497  		s.EgressMAC, s.IngressMAC = mac2, mac1
   498  	}
   499  
   500  	return s, nil
   501  }
   502  
   503  // staticSharedSecret returns the static shared secret, the result
   504  // of key agreement between the local and remote static node key.
   505  func (h *handshakeState) staticSharedSecret(prv *ecdsa.PrivateKey) ([]byte, error) {
   506  	return ecies.ImportECDSA(prv).GenerateShared(h.remote, sskLen, sskLen)
   507  }
   508  
   509  // runInitiator negotiates a session token on conn.
   510  // it should be called on the dialing side of the connection.
   511  //
   512  // prv is the local client's private key.
   513  func (h *handshakeState) runInitiator(conn io.ReadWriter, prv *ecdsa.PrivateKey, remote *ecdsa.PublicKey) (s Secrets, err error) {
   514  	h.initiator = true
   515  	h.remote = ecies.ImportECDSAPublic(remote)
   516  
   517  	authMsg, err := h.makeAuthMsg(prv)
   518  	if err != nil {
   519  		return s, err
   520  	}
   521  	authPacket, err := h.sealEIP8(authMsg)
   522  	if err != nil {
   523  		return s, err
   524  	}
   525  
   526  	if _, err = conn.Write(authPacket); err != nil {
   527  		return s, err
   528  	}
   529  
   530  	authRespMsg := new(authRespV4)
   531  	authRespPacket, err := h.readMsg(authRespMsg, prv, conn)
   532  	if err != nil {
   533  		return s, err
   534  	}
   535  	if err := h.handleAuthResp(authRespMsg); err != nil {
   536  		return s, err
   537  	}
   538  
   539  	return h.secrets(authPacket, authRespPacket)
   540  }
   541  
   542  // makeAuthMsg creates the initiator handshake message.
   543  func (h *handshakeState) makeAuthMsg(prv *ecdsa.PrivateKey) (*authMsgV4, error) {
   544  	// Generate random initiator nonce.
   545  	h.initNonce = make([]byte, shaLen)
   546  	_, err := rand.Read(h.initNonce)
   547  	if err != nil {
   548  		return nil, err
   549  	}
   550  	// Generate random keypair to for ECDH.
   551  	h.randomPrivKey, err = ecies.GenerateKey(rand.Reader, crypto.S256(), nil)
   552  	if err != nil {
   553  		return nil, err
   554  	}
   555  
   556  	// Sign known message: static-shared-secret ^ nonce
   557  	token, err := h.staticSharedSecret(prv)
   558  	if err != nil {
   559  		return nil, err
   560  	}
   561  	signed := xor(token, h.initNonce)
   562  	signature, err := crypto.Sign(signed, h.randomPrivKey.ExportECDSA())
   563  	if err != nil {
   564  		return nil, err
   565  	}
   566  
   567  	msg := new(authMsgV4)
   568  	copy(msg.Signature[:], signature)
   569  	copy(msg.InitiatorPubkey[:], crypto.FromECDSAPub(&prv.PublicKey)[1:])
   570  	copy(msg.Nonce[:], h.initNonce)
   571  	msg.Version = 4
   572  	return msg, nil
   573  }
   574  
   575  func (h *handshakeState) handleAuthResp(msg *authRespV4) (err error) {
   576  	h.respNonce = msg.Nonce[:]
   577  	h.remoteRandomPub, err = importPublicKey(msg.RandomPubkey[:])
   578  	return err
   579  }
   580  
   581  func (h *handshakeState) makeAuthResp() (msg *authRespV4, err error) {
   582  	// Generate random nonce.
   583  	h.respNonce = make([]byte, shaLen)
   584  	if _, err = rand.Read(h.respNonce); err != nil {
   585  		return nil, err
   586  	}
   587  
   588  	msg = new(authRespV4)
   589  	copy(msg.Nonce[:], h.respNonce)
   590  	copy(msg.RandomPubkey[:], exportPubkey(&h.randomPrivKey.PublicKey))
   591  	msg.Version = 4
   592  	return msg, nil
   593  }
   594  
   595  // readMsg reads an encrypted handshake message, decoding it into msg.
   596  func (h *handshakeState) readMsg(msg interface{}, prv *ecdsa.PrivateKey, r io.Reader) ([]byte, error) {
   597  	h.rbuf.reset()
   598  	h.rbuf.grow(512)
   599  
   600  	// Read the size prefix.
   601  	prefix, err := h.rbuf.read(r, 2)
   602  	if err != nil {
   603  		return nil, err
   604  	}
   605  	size := binary.BigEndian.Uint16(prefix)
   606  
   607  	// Read the handshake packet.
   608  	packet, err := h.rbuf.read(r, int(size))
   609  	if err != nil {
   610  		return nil, err
   611  	}
   612  	dec, err := ecies.ImportECDSA(prv).Decrypt(packet, nil, prefix)
   613  	if err != nil {
   614  		return nil, err
   615  	}
   616  	// Can't use rlp.DecodeBytes here because it rejects
   617  	// trailing data (forward-compatibility).
   618  	s := rlp.NewStream(bytes.NewReader(dec), 0)
   619  	err = s.Decode(msg)
   620  	return h.rbuf.data[:len(prefix)+len(packet)], err
   621  }
   622  
   623  // sealEIP8 encrypts a handshake message.
   624  func (h *handshakeState) sealEIP8(msg interface{}) ([]byte, error) {
   625  	h.wbuf.reset()
   626  
   627  	// Write the message plaintext.
   628  	if err := rlp.Encode(&h.wbuf, msg); err != nil {
   629  		return nil, err
   630  	}
   631  	// Pad with random amount of data. the amount needs to be at least 100 bytes to make
   632  	// the message distinguishable from pre-EIP-8 handshakes.
   633  	h.wbuf.appendZero(mrand.Intn(100) + 100)
   634  
   635  	prefix := make([]byte, 2)
   636  	binary.BigEndian.PutUint16(prefix, uint16(len(h.wbuf.data)+eciesOverhead))
   637  
   638  	enc, err := ecies.Encrypt(rand.Reader, h.remote, h.wbuf.data, nil, prefix)
   639  	return append(prefix, enc...), err
   640  }
   641  
   642  // importPublicKey unmarshals 512 bit public keys.
   643  func importPublicKey(pubKey []byte) (*ecies.PublicKey, error) {
   644  	var pubKey65 []byte
   645  	switch len(pubKey) {
   646  	case 64:
   647  		// add 'uncompressed key' flag
   648  		pubKey65 = append([]byte{0x04}, pubKey...)
   649  	case 65:
   650  		pubKey65 = pubKey
   651  	default:
   652  		return nil, fmt.Errorf("invalid public key length %v (expect 64/65)", len(pubKey))
   653  	}
   654  	// TODO: fewer pointless conversions
   655  	pub, err := crypto.UnmarshalPubkey(pubKey65)
   656  	if err != nil {
   657  		return nil, err
   658  	}
   659  	return ecies.ImportECDSAPublic(pub), nil
   660  }
   661  
   662  func exportPubkey(pub *ecies.PublicKey) []byte {
   663  	if pub == nil {
   664  		panic("nil pubkey")
   665  	}
   666  	if curve, ok := pub.Curve.(crypto.EllipticCurve); ok {
   667  		return curve.Marshal(pub.X, pub.Y)[1:]
   668  	}
   669  	return []byte{}
   670  }
   671  
   672  func xor(one, other []byte) (xor []byte) {
   673  	xor = make([]byte, len(one))
   674  	for i := 0; i < len(one); i++ {
   675  		xor[i] = one[i] ^ other[i]
   676  	}
   677  	return xor
   678  }