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 }