github.com/decred/dcrlnd@v0.7.6/brontide/noise.go (about)

     1  package brontide
     2  
     3  import (
     4  	"crypto/cipher"
     5  	"crypto/sha256"
     6  	"encoding/binary"
     7  	"errors"
     8  	"fmt"
     9  	"io"
    10  	"math"
    11  	"time"
    12  
    13  	"golang.org/x/crypto/chacha20poly1305"
    14  	"golang.org/x/crypto/hkdf"
    15  
    16  	"github.com/decred/dcrd/dcrec/secp256k1/v4"
    17  	"github.com/decred/dcrlnd/keychain"
    18  )
    19  
    20  const (
    21  	// protocolName is the precise instantiation of the Noise protocol
    22  	// handshake at the center of Brontide. This value will be used as part
    23  	// of the prologue. If the initiator and responder aren't using the
    24  	// exact same string for this value, along with prologue of the Decred
    25  	// network, then the initial handshake will fail.
    26  	protocolName = "Noise_XK_secp256k1_ChaChaPoly_SHA256"
    27  
    28  	// macSize is the length in bytes of the tags generated by poly1305.
    29  	macSize = 16
    30  
    31  	// lengthHeaderSize is the number of bytes used to prefix encode the
    32  	// length of a message payload.
    33  	lengthHeaderSize = 2
    34  
    35  	// encHeaderSize is the number of bytes required to hold an encrypted
    36  	// header and it's MAC.
    37  	encHeaderSize = lengthHeaderSize + macSize
    38  
    39  	// keyRotationInterval is the number of messages sent on a single
    40  	// cipher stream before the keys are rotated forwards.
    41  	keyRotationInterval = 1000
    42  
    43  	// handshakeReadTimeout is a read timeout that will be enforced when
    44  	// waiting for data payloads during the various acts of Brontide. If
    45  	// the remote party fails to deliver the proper payload within this
    46  	// time frame, then we'll fail the connection.
    47  	handshakeReadTimeout = time.Second * 5
    48  )
    49  
    50  var (
    51  	// ErrMaxMessageLengthExceeded is returned when a message to be written to
    52  	// the cipher session exceeds the maximum allowed message payload.
    53  	ErrMaxMessageLengthExceeded = errors.New("the generated payload exceeds " +
    54  		"the max allowed message length of (2^16)-1")
    55  
    56  	// ErrMessageNotFlushed signals that the connection cannot accept a new
    57  	// message because the prior message has not been fully flushed.
    58  	ErrMessageNotFlushed = errors.New("prior message not flushed")
    59  
    60  	// lightningPrologue is the noise prologue that is used to initialize
    61  	// the brontide noise handshake.
    62  	lightningPrologue = []byte("lightning")
    63  
    64  	// ephemeralGen is the default ephemeral key generator, used to derive a
    65  	// unique ephemeral key for each brontide handshake.
    66  	ephemeralGen = func() (*secp256k1.PrivateKey, error) {
    67  		return secp256k1.GeneratePrivateKey()
    68  	}
    69  )
    70  
    71  // TODO(roasbeef): free buffer pool?
    72  
    73  // ecdh performs an ECDH operation between pub and priv. The returned value is
    74  // the sha256 of the compressed shared point.
    75  func ecdh(pub *secp256k1.PublicKey, priv keychain.SingleKeyECDH) ([]byte, error) {
    76  	hash, err := priv.ECDH(pub)
    77  	return hash[:], err
    78  }
    79  
    80  // cipherState encapsulates the state for the AEAD which will be used to
    81  // encrypt+authenticate any payloads sent during the handshake, and messages
    82  // sent once the handshake has completed.
    83  type cipherState struct {
    84  	// nonce is the nonce passed into the chacha20-poly1305 instance for
    85  	// encryption+decryption. The nonce is incremented after each successful
    86  	// encryption/decryption.
    87  	//
    88  	// TODO(roasbeef): this should actually be 96 bit
    89  	nonce uint64
    90  
    91  	// secretKey is the shared symmetric key which will be used to
    92  	// instantiate the cipher.
    93  	//
    94  	// TODO(roasbeef): m-lock??
    95  	secretKey [32]byte
    96  
    97  	// salt is an additional secret which is used during key rotation to
    98  	// generate new keys.
    99  	salt [32]byte
   100  
   101  	// cipher is an instance of the ChaCha20-Poly1305 AEAD construction
   102  	// created using the secretKey above.
   103  	cipher cipher.AEAD
   104  }
   105  
   106  // Encrypt returns a ciphertext which is the encryption of the plainText
   107  // observing the passed associatedData within the AEAD construction.
   108  func (c *cipherState) Encrypt(associatedData, cipherText, plainText []byte) []byte {
   109  	defer func() {
   110  		c.nonce++
   111  
   112  		if c.nonce == keyRotationInterval {
   113  			c.rotateKey()
   114  		}
   115  	}()
   116  
   117  	var nonce [12]byte
   118  	binary.LittleEndian.PutUint64(nonce[4:], c.nonce)
   119  
   120  	return c.cipher.Seal(cipherText, nonce[:], plainText, associatedData)
   121  }
   122  
   123  // Decrypt attempts to decrypt the passed ciphertext observing the specified
   124  // associatedData within the AEAD construction. In the case that the final MAC
   125  // check fails, then a non-nil error will be returned.
   126  func (c *cipherState) Decrypt(associatedData, plainText, cipherText []byte) ([]byte, error) {
   127  	defer func() {
   128  		c.nonce++
   129  
   130  		if c.nonce == keyRotationInterval {
   131  			c.rotateKey()
   132  		}
   133  	}()
   134  
   135  	var nonce [12]byte
   136  	binary.LittleEndian.PutUint64(nonce[4:], c.nonce)
   137  
   138  	return c.cipher.Open(plainText, nonce[:], cipherText, associatedData)
   139  }
   140  
   141  // InitializeKey initializes the secret key and AEAD cipher scheme based off of
   142  // the passed key.
   143  func (c *cipherState) InitializeKey(key [32]byte) {
   144  	c.secretKey = key
   145  	c.nonce = 0
   146  
   147  	// Safe to ignore the error here as our key is properly sized
   148  	// (32-bytes).
   149  	c.cipher, _ = chacha20poly1305.New(c.secretKey[:])
   150  }
   151  
   152  // InitializeKeyWithSalt is identical to InitializeKey however it also sets the
   153  // cipherState's salt field which is used for key rotation.
   154  func (c *cipherState) InitializeKeyWithSalt(salt, key [32]byte) {
   155  	c.salt = salt
   156  	c.InitializeKey(key)
   157  }
   158  
   159  // rotateKey rotates the current encryption/decryption key for this cipherState
   160  // instance. Key rotation is performed by ratcheting the current key forward
   161  // using an HKDF invocation with the cipherState's salt as the salt, and the
   162  // current key as the input.
   163  func (c *cipherState) rotateKey() {
   164  	var (
   165  		info    []byte
   166  		nextKey [32]byte
   167  	)
   168  
   169  	oldKey := c.secretKey
   170  	h := hkdf.New(sha256.New, oldKey[:], c.salt[:], info)
   171  
   172  	// hkdf(ck, k, zero)
   173  	// |
   174  	// | \
   175  	// |  \
   176  	// ck  k'
   177  	h.Read(c.salt[:])
   178  	h.Read(nextKey[:])
   179  
   180  	c.InitializeKey(nextKey)
   181  }
   182  
   183  // symmetricState encapsulates a cipherState object and houses the ephemeral
   184  // handshake digest state. This struct is used during the handshake to derive
   185  // new shared secrets based off of the result of ECDH operations. Ultimately,
   186  // the final key yielded by this struct is the result of an incremental
   187  // Triple-DH operation.
   188  type symmetricState struct {
   189  	cipherState
   190  
   191  	// chainingKey is used as the salt to the HKDF function to derive a new
   192  	// chaining key as well as a new tempKey which is used for
   193  	// encryption/decryption.
   194  	chainingKey [32]byte
   195  
   196  	// tempKey is the latter 32 bytes resulted from the latest HKDF
   197  	// iteration. This key is used to encrypt/decrypt any handshake
   198  	// messages or payloads sent until the next DH operation is executed.
   199  	tempKey [32]byte
   200  
   201  	// handshakeDigest is the cumulative hash digest of all handshake
   202  	// messages sent from start to finish. This value is never transmitted
   203  	// to the other side, but will be used as the AD when
   204  	// encrypting/decrypting messages using our AEAD construction.
   205  	handshakeDigest [32]byte
   206  }
   207  
   208  // mixKey implements a basic HKDF-based key ratchet. This method is called
   209  // with the result of each DH output generated during the handshake process.
   210  // The first 32 bytes extract from the HKDF reader is the next chaining key,
   211  // then latter 32 bytes become the temp secret key using within any future AEAD
   212  // operations until another DH operation is performed.
   213  func (s *symmetricState) mixKey(input []byte) {
   214  	var info []byte
   215  
   216  	secret := input
   217  	salt := s.chainingKey
   218  	h := hkdf.New(sha256.New, secret, salt[:], info)
   219  
   220  	// hkdf(ck, input, zero)
   221  	// |
   222  	// | \
   223  	// |  \
   224  	// ck  k
   225  	h.Read(s.chainingKey[:])
   226  	h.Read(s.tempKey[:])
   227  
   228  	// cipher.k = temp_key
   229  	s.InitializeKey(s.tempKey)
   230  }
   231  
   232  // mixHash hashes the passed input data into the cumulative handshake digest.
   233  // The running result of this value (h) is used as the associated data in all
   234  // decryption/encryption operations.
   235  func (s *symmetricState) mixHash(data []byte) {
   236  	h := sha256.New()
   237  	h.Write(s.handshakeDigest[:])
   238  	h.Write(data)
   239  
   240  	copy(s.handshakeDigest[:], h.Sum(nil))
   241  }
   242  
   243  // EncryptAndHash returns the authenticated encryption of the passed plaintext.
   244  // When encrypting the handshake digest (h) is used as the associated data to
   245  // the AEAD cipher.
   246  func (s *symmetricState) EncryptAndHash(plaintext []byte) []byte {
   247  	ciphertext := s.Encrypt(s.handshakeDigest[:], nil, plaintext)
   248  
   249  	s.mixHash(ciphertext)
   250  
   251  	return ciphertext
   252  }
   253  
   254  // DecryptAndHash returns the authenticated decryption of the passed
   255  // ciphertext. When encrypting the handshake digest (h) is used as the
   256  // associated data to the AEAD cipher.
   257  func (s *symmetricState) DecryptAndHash(ciphertext []byte) ([]byte, error) {
   258  	plaintext, err := s.Decrypt(s.handshakeDigest[:], nil, ciphertext)
   259  	if err != nil {
   260  		return nil, err
   261  	}
   262  
   263  	s.mixHash(ciphertext)
   264  
   265  	return plaintext, nil
   266  }
   267  
   268  // InitializeSymmetric initializes the symmetric state by setting the handshake
   269  // digest (h) and the chaining key (ck) to protocol name.
   270  func (s *symmetricState) InitializeSymmetric(protocolName []byte) {
   271  	var empty [32]byte
   272  
   273  	s.handshakeDigest = sha256.Sum256(protocolName)
   274  	s.chainingKey = s.handshakeDigest
   275  	s.InitializeKey(empty)
   276  }
   277  
   278  // handshakeState encapsulates the symmetricState and keeps track of all the
   279  // public keys (static and ephemeral) for both sides during the handshake
   280  // transcript. If the handshake completes successfully, then two instances of a
   281  // cipherState are emitted: one to encrypt messages from initiator to
   282  // responder, and the other for the opposite direction.
   283  type handshakeState struct {
   284  	symmetricState
   285  
   286  	initiator bool
   287  
   288  	localStatic    keychain.SingleKeyECDH
   289  	localEphemeral keychain.SingleKeyECDH // nolint (false positive)
   290  
   291  	remoteStatic    *secp256k1.PublicKey
   292  	remoteEphemeral *secp256k1.PublicKey
   293  }
   294  
   295  // newHandshakeState returns a new instance of the handshake state initialized
   296  // with the prologue and protocol name. If this is the responder's handshake
   297  // state, then the remotePub can be nil.
   298  func newHandshakeState(initiator bool, prologue []byte,
   299  	localKey keychain.SingleKeyECDH,
   300  	remotePub *secp256k1.PublicKey) handshakeState {
   301  
   302  	h := handshakeState{
   303  		initiator:    initiator,
   304  		localStatic:  localKey,
   305  		remoteStatic: remotePub,
   306  	}
   307  
   308  	// Set the current chaining key and handshake digest to the hash of the
   309  	// protocol name, and additionally mix in the prologue. If either sides
   310  	// disagree about the prologue or protocol name, then the handshake
   311  	// will fail.
   312  	h.InitializeSymmetric([]byte(protocolName))
   313  	h.mixHash(prologue)
   314  
   315  	// In Noise_XK, the initiator should know the responder's static
   316  	// public key, therefore we include the responder's static key in the
   317  	// handshake digest. If the initiator gets this value wrong, then the
   318  	// handshake will fail.
   319  	if initiator {
   320  		h.mixHash(remotePub.SerializeCompressed())
   321  	} else {
   322  		h.mixHash(localKey.PubKey().SerializeCompressed())
   323  	}
   324  
   325  	return h
   326  }
   327  
   328  // EphemeralGenerator is a functional option that allows callers to substitute
   329  // a custom function for use when generating ephemeral keys for ActOne or
   330  // ActTwo. The function closure returned by this function can be passed into
   331  // NewBrontideMachine as a function option parameter.
   332  func EphemeralGenerator(gen func() (*secp256k1.PrivateKey, error)) func(*Machine) {
   333  	return func(m *Machine) {
   334  		m.ephemeralGen = gen
   335  	}
   336  }
   337  
   338  // Machine is a state-machine which implements Brontide: an
   339  // Authenticated-key Exchange in Three Acts. Brontide is derived from the Noise
   340  // framework, specifically implementing the Noise_XK handshake. Once the
   341  // initial 3-act handshake has completed all messages are encrypted with a
   342  // chacha20 AEAD cipher. On the wire, all messages are prefixed with an
   343  // authenticated+encrypted length field. Additionally, the encrypted+auth'd
   344  // length prefix is used as the AD when encrypting+decryption messages. This
   345  // construction provides confidentiality of packet length, avoids introducing
   346  // a padding-oracle, and binds the encrypted packet length to the packet
   347  // itself.
   348  //
   349  // The acts proceeds the following order (initiator on the left):
   350  //
   351  //	GenActOne()   ->
   352  //	                  RecvActOne()
   353  //	              <-  GenActTwo()
   354  //	RecvActTwo()
   355  //	GenActThree() ->
   356  //	                  RecvActThree()
   357  //
   358  // This exchange corresponds to the following Noise handshake:
   359  //
   360  //	<- s
   361  //	...
   362  //	-> e, es
   363  //	<- e, ee
   364  //	-> s, se
   365  type Machine struct {
   366  	sendCipher cipherState
   367  	recvCipher cipherState
   368  
   369  	ephemeralGen func() (*secp256k1.PrivateKey, error)
   370  
   371  	handshakeState
   372  
   373  	// nextCipherHeader is a static buffer that we'll use to read in the
   374  	// next ciphertext header from the wire. The header is a 2 byte length
   375  	// (of the next ciphertext), followed by a 16 byte MAC.
   376  	nextCipherHeader [encHeaderSize]byte
   377  
   378  	// nextHeaderSend holds a reference to the remaining header bytes to
   379  	// write out for a pending message. This allows us to tolerate timeout
   380  	// errors that cause partial writes.
   381  	nextHeaderSend []byte
   382  
   383  	// nextHeaderBody holds a reference to the remaining body bytes to write
   384  	// out for a pending message. This allows us to tolerate timeout errors
   385  	// that cause partial writes.
   386  	nextBodySend []byte
   387  }
   388  
   389  // NewBrontideMachine creates a new instance of the brontide state-machine. If
   390  // the responder (listener) is creating the object, then the remotePub should
   391  // be nil. The handshake state within brontide is initialized using the ascii
   392  // string "lightning" as the prologue. The last parameter is a set of variadic
   393  // arguments for adding additional options to the brontide Machine
   394  // initialization.
   395  func NewBrontideMachine(initiator bool, localKey keychain.SingleKeyECDH,
   396  	remotePub *secp256k1.PublicKey, options ...func(*Machine)) *Machine {
   397  
   398  	handshake := newHandshakeState(
   399  		initiator, lightningPrologue, localKey, remotePub,
   400  	)
   401  
   402  	m := &Machine{
   403  		handshakeState: handshake,
   404  		ephemeralGen:   ephemeralGen,
   405  	}
   406  
   407  	// With the default options established, we'll now process all the
   408  	// options passed in as parameters.
   409  	for _, option := range options {
   410  		option(m)
   411  	}
   412  
   413  	return m
   414  }
   415  
   416  const (
   417  	// HandshakeVersion is the expected version of the brontide handshake.
   418  	// Any messages that carry a different version will cause the handshake
   419  	// to abort immediately.
   420  	HandshakeVersion = byte(0)
   421  
   422  	// ActOneSize is the size of the packet sent from initiator to
   423  	// responder in ActOne. The packet consists of a handshake version, an
   424  	// ephemeral key in compressed format, and a 16-byte poly1305 tag.
   425  	//
   426  	// 1 + 33 + 16
   427  	ActOneSize = 50
   428  
   429  	// ActTwoSize is the size the packet sent from responder to initiator
   430  	// in ActTwo. The packet consists of a handshake version, an ephemeral
   431  	// key in compressed format and a 16-byte poly1305 tag.
   432  	//
   433  	// 1 + 33 + 16
   434  	ActTwoSize = 50
   435  
   436  	// ActThreeSize is the size of the packet sent from initiator to
   437  	// responder in ActThree. The packet consists of a handshake version,
   438  	// the initiators static key encrypted with strong forward secrecy and
   439  	// a 16-byte poly1035 tag.
   440  	//
   441  	// 1 + 33 + 16 + 16
   442  	ActThreeSize = 66
   443  )
   444  
   445  // GenActOne generates the initial packet (act one) to be sent from initiator
   446  // to responder. During act one the initiator generates a fresh ephemeral key,
   447  // hashes it into the handshake digest, and performs an ECDH between this key
   448  // and the responder's static key. Future payloads are encrypted with a key
   449  // derived from this result.
   450  //
   451  //	-> e, es
   452  func (b *Machine) GenActOne() ([ActOneSize]byte, error) {
   453  	var actOne [ActOneSize]byte
   454  
   455  	// e
   456  	localEphemeral, err := b.ephemeralGen()
   457  	if err != nil {
   458  		return actOne, err
   459  	}
   460  	b.localEphemeral = &keychain.PrivKeyECDH{
   461  		PrivKey: localEphemeral,
   462  	}
   463  
   464  	ephemeral := localEphemeral.PubKey().SerializeCompressed()
   465  	b.mixHash(ephemeral)
   466  
   467  	// es
   468  	s, err := ecdh(b.remoteStatic, b.localEphemeral)
   469  	if err != nil {
   470  		return actOne, err
   471  	}
   472  	b.mixKey(s[:])
   473  
   474  	authPayload := b.EncryptAndHash([]byte{})
   475  
   476  	actOne[0] = HandshakeVersion
   477  	copy(actOne[1:34], ephemeral)
   478  	copy(actOne[34:], authPayload)
   479  
   480  	return actOne, nil
   481  }
   482  
   483  // RecvActOne processes the act one packet sent by the initiator. The responder
   484  // executes the mirrored actions to that of the initiator extending the
   485  // handshake digest and deriving a new shared secret based on an ECDH with the
   486  // initiator's ephemeral key and responder's static key.
   487  func (b *Machine) RecvActOne(actOne [ActOneSize]byte) error {
   488  	var (
   489  		err error
   490  		e   [33]byte
   491  		p   [16]byte
   492  	)
   493  
   494  	// If the handshake version is unknown, then the handshake fails
   495  	// immediately.
   496  	if actOne[0] != HandshakeVersion {
   497  		return fmt.Errorf("act one: invalid handshake version: %v, "+
   498  			"only %v is valid, msg=%x", actOne[0], HandshakeVersion,
   499  			actOne[:])
   500  	}
   501  
   502  	copy(e[:], actOne[1:34])
   503  	copy(p[:], actOne[34:])
   504  
   505  	// e
   506  	b.remoteEphemeral, err = secp256k1.ParsePubKey(e[:])
   507  	if err != nil {
   508  		return err
   509  	}
   510  	b.mixHash(b.remoteEphemeral.SerializeCompressed())
   511  
   512  	// es
   513  	s, err := ecdh(b.remoteEphemeral, b.localStatic)
   514  	if err != nil {
   515  		return err
   516  	}
   517  	b.mixKey(s)
   518  
   519  	// If the initiator doesn't know our static key, then this operation
   520  	// will fail.
   521  	_, err = b.DecryptAndHash(p[:])
   522  	return err
   523  }
   524  
   525  // GenActTwo generates the second packet (act two) to be sent from the
   526  // responder to the initiator. The packet for act two is identical to that of
   527  // act one, but then results in a different ECDH operation between the
   528  // initiator's and responder's ephemeral keys.
   529  //
   530  //	<- e, ee
   531  func (b *Machine) GenActTwo() ([ActTwoSize]byte, error) {
   532  	var actTwo [ActTwoSize]byte
   533  
   534  	// e
   535  	localEphemeral, err := b.ephemeralGen()
   536  	if err != nil {
   537  		return actTwo, err
   538  	}
   539  	b.localEphemeral = &keychain.PrivKeyECDH{
   540  		PrivKey: localEphemeral,
   541  	}
   542  
   543  	ephemeral := localEphemeral.PubKey().SerializeCompressed()
   544  	b.mixHash(localEphemeral.PubKey().SerializeCompressed())
   545  
   546  	// ee
   547  	s, err := ecdh(b.remoteEphemeral, b.localEphemeral)
   548  	if err != nil {
   549  		return actTwo, err
   550  	}
   551  	b.mixKey(s)
   552  
   553  	authPayload := b.EncryptAndHash([]byte{})
   554  
   555  	actTwo[0] = HandshakeVersion
   556  	copy(actTwo[1:34], ephemeral)
   557  	copy(actTwo[34:], authPayload)
   558  
   559  	return actTwo, nil
   560  }
   561  
   562  // RecvActTwo processes the second packet (act two) sent from the responder to
   563  // the initiator. A successful processing of this packet authenticates the
   564  // initiator to the responder.
   565  func (b *Machine) RecvActTwo(actTwo [ActTwoSize]byte) error {
   566  	var (
   567  		err error
   568  		e   [33]byte
   569  		p   [16]byte
   570  	)
   571  
   572  	// If the handshake version is unknown, then the handshake fails
   573  	// immediately.
   574  	if actTwo[0] != HandshakeVersion {
   575  		return fmt.Errorf("act two: invalid handshake version: %v, "+
   576  			"only %v is valid, msg=%x", actTwo[0], HandshakeVersion,
   577  			actTwo[:])
   578  	}
   579  
   580  	copy(e[:], actTwo[1:34])
   581  	copy(p[:], actTwo[34:])
   582  
   583  	// e
   584  	b.remoteEphemeral, err = secp256k1.ParsePubKey(e[:])
   585  	if err != nil {
   586  		return err
   587  	}
   588  	b.mixHash(b.remoteEphemeral.SerializeCompressed())
   589  
   590  	// ee
   591  	s, err := ecdh(b.remoteEphemeral, b.localEphemeral)
   592  	if err != nil {
   593  		return err
   594  	}
   595  	b.mixKey(s)
   596  
   597  	_, err = b.DecryptAndHash(p[:])
   598  	return err
   599  }
   600  
   601  // GenActThree creates the final (act three) packet of the handshake. Act three
   602  // is to be sent from the initiator to the responder. The purpose of act three
   603  // is to transmit the initiator's public key under strong forward secrecy to
   604  // the responder. This act also includes the final ECDH operation which yields
   605  // the final session.
   606  //
   607  //	-> s, se
   608  func (b *Machine) GenActThree() ([ActThreeSize]byte, error) {
   609  	var actThree [ActThreeSize]byte
   610  
   611  	ourPubkey := b.localStatic.PubKey().SerializeCompressed()
   612  	ciphertext := b.EncryptAndHash(ourPubkey)
   613  
   614  	s, err := ecdh(b.remoteEphemeral, b.localStatic)
   615  	if err != nil {
   616  		return actThree, err
   617  	}
   618  	b.mixKey(s)
   619  
   620  	authPayload := b.EncryptAndHash([]byte{})
   621  
   622  	actThree[0] = HandshakeVersion
   623  	copy(actThree[1:50], ciphertext)
   624  	copy(actThree[50:], authPayload)
   625  
   626  	// With the final ECDH operation complete, derive the session sending
   627  	// and receiving keys.
   628  	b.split()
   629  
   630  	return actThree, nil
   631  }
   632  
   633  // RecvActThree processes the final act (act three) sent from the initiator to
   634  // the responder. After processing this act, the responder learns of the
   635  // initiator's static public key. Decryption of the static key serves to
   636  // authenticate the initiator to the responder.
   637  func (b *Machine) RecvActThree(actThree [ActThreeSize]byte) error {
   638  	var (
   639  		err error
   640  		s   [33 + 16]byte
   641  		p   [16]byte
   642  	)
   643  
   644  	// If the handshake version is unknown, then the handshake fails
   645  	// immediately.
   646  	if actThree[0] != HandshakeVersion {
   647  		return fmt.Errorf("act three: invalid handshake version: %v, "+
   648  			"only %v is valid, msg=%x", actThree[0], HandshakeVersion,
   649  			actThree[:])
   650  	}
   651  
   652  	copy(s[:], actThree[1:33+16+1])
   653  	copy(p[:], actThree[33+16+1:])
   654  
   655  	// s
   656  	remotePub, err := b.DecryptAndHash(s[:])
   657  	if err != nil {
   658  		return err
   659  	}
   660  	b.remoteStatic, err = secp256k1.ParsePubKey(remotePub)
   661  	if err != nil {
   662  		return err
   663  	}
   664  
   665  	// se
   666  	se, err := ecdh(b.remoteStatic, b.localEphemeral)
   667  	if err != nil {
   668  		return err
   669  	}
   670  	b.mixKey(se)
   671  
   672  	if _, err := b.DecryptAndHash(p[:]); err != nil {
   673  		return err
   674  	}
   675  
   676  	// With the final ECDH operation complete, derive the session sending
   677  	// and receiving keys.
   678  	b.split()
   679  
   680  	return nil
   681  }
   682  
   683  // split is the final wrap-up act to be executed at the end of a successful
   684  // three act handshake. This function creates two internal cipherState
   685  // instances: one which is used to encrypt messages from the initiator to the
   686  // responder, and another which is used to encrypt message for the opposite
   687  // direction.
   688  func (b *Machine) split() {
   689  	var (
   690  		empty   []byte
   691  		sendKey [32]byte
   692  		recvKey [32]byte
   693  	)
   694  
   695  	h := hkdf.New(sha256.New, empty, b.chainingKey[:], empty)
   696  
   697  	// If we're the initiator the first 32 bytes are used to encrypt our
   698  	// messages and the second 32-bytes to decrypt their messages. For the
   699  	// responder the opposite is true.
   700  	if b.initiator {
   701  		h.Read(sendKey[:])
   702  		b.sendCipher = cipherState{}
   703  		b.sendCipher.InitializeKeyWithSalt(b.chainingKey, sendKey)
   704  
   705  		h.Read(recvKey[:])
   706  		b.recvCipher = cipherState{}
   707  		b.recvCipher.InitializeKeyWithSalt(b.chainingKey, recvKey)
   708  	} else {
   709  		h.Read(recvKey[:])
   710  		b.recvCipher = cipherState{}
   711  		b.recvCipher.InitializeKeyWithSalt(b.chainingKey, recvKey)
   712  
   713  		h.Read(sendKey[:])
   714  		b.sendCipher = cipherState{}
   715  		b.sendCipher.InitializeKeyWithSalt(b.chainingKey, sendKey)
   716  	}
   717  }
   718  
   719  // WriteMessage encrypts and buffers the next message p. The ciphertext of the
   720  // message is prepended with an encrypt+auth'd length which must be used as the
   721  // AD to the AEAD construction when being decrypted by the other side.
   722  //
   723  // NOTE: This DOES NOT write the message to the wire, it should be followed by a
   724  // call to Flush to ensure the message is written.
   725  func (b *Machine) WriteMessage(p []byte) error {
   726  	// The total length of each message payload including the MAC size
   727  	// payload exceed the largest number encodable within a 16-bit unsigned
   728  	// integer.
   729  	if len(p) > math.MaxUint16 {
   730  		return ErrMaxMessageLengthExceeded
   731  	}
   732  
   733  	// If a prior message was written but it hasn't been fully flushed,
   734  	// return an error as we only support buffering of one message at a
   735  	// time.
   736  	if len(b.nextHeaderSend) > 0 || len(b.nextBodySend) > 0 {
   737  		return ErrMessageNotFlushed
   738  	}
   739  
   740  	// The full length of the packet is only the packet length, and does
   741  	// NOT include the MAC.
   742  	fullLength := uint16(len(p))
   743  
   744  	var pktLen [2]byte
   745  	binary.BigEndian.PutUint16(pktLen[:], fullLength)
   746  
   747  	// First, generate the encrypted+MAC'd length prefix for the packet.
   748  	b.nextHeaderSend = b.sendCipher.Encrypt(nil, nil, pktLen[:])
   749  
   750  	// Finally, generate the encrypted packet itself.
   751  	b.nextBodySend = b.sendCipher.Encrypt(nil, nil, p)
   752  
   753  	return nil
   754  }
   755  
   756  // Flush attempts to write a message buffered using WriteMessage to the provided
   757  // io.Writer. If no buffered message exists, this will result in a NOP.
   758  // Otherwise, it will continue to write the remaining bytes, picking up where
   759  // the byte stream left off in the event of a partial write. The number of bytes
   760  // returned reflects the number of plaintext bytes in the payload, and does not
   761  // account for the overhead of the header or MACs.
   762  //
   763  // NOTE: It is safe to call this method again iff a timeout error is returned.
   764  func (b *Machine) Flush(w io.Writer) (int, error) {
   765  	// First, write out the pending header bytes, if any exist. Any header
   766  	// bytes written will not count towards the total amount flushed.
   767  	if len(b.nextHeaderSend) > 0 {
   768  		// Write any remaining header bytes and shift the slice to point
   769  		// to the next segment of unwritten bytes. If an error is
   770  		// encountered, we can continue to write the header from where
   771  		// we left off on a subsequent call to Flush.
   772  		n, err := w.Write(b.nextHeaderSend)
   773  		b.nextHeaderSend = b.nextHeaderSend[n:]
   774  		if err != nil {
   775  			return 0, err
   776  		}
   777  	}
   778  
   779  	// Next, write the pending body bytes, if any exist. Only the number of
   780  	// bytes written that correspond to the ciphertext will be included in
   781  	// the total bytes written, bytes written as part of the MAC will not be
   782  	// counted.
   783  	var nn int
   784  	if len(b.nextBodySend) > 0 {
   785  		// Write out all bytes excluding the mac and shift the body
   786  		// slice depending on the number of actual bytes written.
   787  		n, err := w.Write(b.nextBodySend)
   788  		b.nextBodySend = b.nextBodySend[n:]
   789  
   790  		// If we partially or fully wrote any of the body's MAC, we'll
   791  		// subtract that contribution from the total amount flushed to
   792  		// preserve the abstraction of returning the number of plaintext
   793  		// bytes written by the connection.
   794  		//
   795  		// There are three possible scenarios we must handle to ensure
   796  		// the returned value is correct. In the first case, the write
   797  		// straddles both payload and MAC bytes, and we must subtract
   798  		// the number of MAC bytes written from n. In the second, only
   799  		// payload bytes are written, thus we can return n unmodified.
   800  		// The final scenario pertains to the case where only MAC bytes
   801  		// are written, none of which count towards the total.
   802  		//
   803  		//                 |-----------Payload------------|----MAC----|
   804  		// Straddle:       S---------------------------------E--------0
   805  		// Payload-only:   S------------------------E-----------------0
   806  		// MAC-only:                                        S-------E-0
   807  		start, end := n+len(b.nextBodySend), len(b.nextBodySend)
   808  		switch {
   809  
   810  		// Straddles payload and MAC bytes, subtract number of MAC bytes
   811  		// written from the actual number written.
   812  		case start > macSize && end <= macSize:
   813  			nn = n - (macSize - end)
   814  
   815  		// Only payload bytes are written, return n directly.
   816  		case start > macSize && end > macSize:
   817  			nn = n
   818  
   819  		// Only MAC bytes are written, return 0 bytes written.
   820  		default:
   821  		}
   822  
   823  		if err != nil {
   824  			return nn, err
   825  		}
   826  	}
   827  
   828  	return nn, nil
   829  }
   830  
   831  // ReadMessage attempts to read the next message from the passed io.Reader. In
   832  // the case of an authentication error, a non-nil error is returned.
   833  func (b *Machine) ReadMessage(r io.Reader) ([]byte, error) {
   834  	pktLen, err := b.ReadHeader(r)
   835  	if err != nil {
   836  		return nil, err
   837  	}
   838  
   839  	buf := make([]byte, pktLen)
   840  	return b.ReadBody(r, buf)
   841  }
   842  
   843  // ReadHeader attempts to read the next message header from the passed
   844  // io.Reader. The header contains the length of the next body including
   845  // additional overhead of the MAC. In the case of an authentication error, a
   846  // non-nil error is returned.
   847  //
   848  // NOTE: This method SHOULD NOT be used in the case that the io.Reader may be
   849  // adversarial and induce long delays. If the caller needs to set read deadlines
   850  // appropriately, it is preferred that they use the split ReadHeader and
   851  // ReadBody methods so that the deadlines can be set appropriately on each.
   852  func (b *Machine) ReadHeader(r io.Reader) (uint32, error) {
   853  	_, err := io.ReadFull(r, b.nextCipherHeader[:])
   854  	if err != nil {
   855  		return 0, err
   856  	}
   857  
   858  	// Attempt to decrypt+auth the packet length present in the stream.
   859  	//
   860  	// By passing in `nextCipherHeader` as the destination, we avoid making
   861  	// the library allocate a new buffer to decode the plaintext.
   862  	pktLenBytes, err := b.recvCipher.Decrypt(
   863  		nil, b.nextCipherHeader[:0], b.nextCipherHeader[:],
   864  	)
   865  	if err != nil {
   866  		return 0, err
   867  	}
   868  
   869  	// Compute the packet length that we will need to read off the wire.
   870  	pktLen := uint32(binary.BigEndian.Uint16(pktLenBytes)) + macSize
   871  
   872  	return pktLen, nil
   873  }
   874  
   875  // ReadBody attempts to ready the next message body from the passed io.Reader.
   876  // The provided buffer MUST be the length indicated by the packet length
   877  // returned by the preceding call to ReadHeader. In the case of an
   878  // authentication error, a non-nil error is returned.
   879  func (b *Machine) ReadBody(r io.Reader, buf []byte) ([]byte, error) {
   880  	// Next, using the length read from the packet header, read the
   881  	// encrypted packet itself into the buffer allocated by the read
   882  	// pool.
   883  	_, err := io.ReadFull(r, buf)
   884  	if err != nil {
   885  		return nil, err
   886  	}
   887  
   888  	// Finally, decrypt the message held in the buffer, and return a new
   889  	// byte slice containing the plaintext.
   890  	//
   891  	// By passing in the buf (the ciphertext) as the first argument, we end
   892  	// up re-using it as we don't force the library to allocate a new
   893  	// buffer to decode the plaintext.
   894  	return b.recvCipher.Decrypt(nil, buf[:0], buf)
   895  }
   896  
   897  // SetCurveToNil sets the 'Curve' parameter to nil on the handshakeState keys.
   898  // This allows us to log the Machine object without spammy log messages.
   899  //
   900  // NOTE(decred): this isn't needed starting from secp256k1/v4.
   901  func (b *Machine) SetCurveToNil() {
   902  }