diff --git a/libp2p/RLPxFrameIO.cpp b/libp2p/RLPxFrameIO.cpp index a3b3b5613..2c233c1d4 100644 --- a/libp2p/RLPxFrameIO.cpp +++ b/libp2p/RLPxFrameIO.cpp @@ -120,7 +120,7 @@ void RLPXFrameIO::writeSingleFramePacket(bytesConstRef _packet, bytes& o_bytes) if (padding) m_frameEnc.ProcessData(paddingRef.data(), paddingRef.data(), padding); bytesRef packetWithPaddingRef(o_bytes.data() + 32, _packet.size() + padding); - updateEgressMACWithEndOfFrame(packetWithPaddingRef); + updateEgressMACWithFrame(packetWithPaddingRef); bytesRef macRef(o_bytes.data() + 32 + _packet.size() + padding, h128::size); egressDigest().ref().copyTo(macRef); } @@ -140,7 +140,7 @@ bool RLPXFrameIO::authAndDecryptHeader(bytesRef io) bool RLPXFrameIO::authAndDecryptFrame(bytesRef io) { bytesRef cipherText(io.cropped(0, io.size() - h128::size)); - updateIngressMACWithEndOfFrame(cipherText); + updateIngressMACWithFrame(cipherText); bytesConstRef frameMac(io.data() + io.size() - h128::size, h128::size); if (*(h128*)frameMac.data() != ingressDigest()) return false; @@ -169,15 +169,10 @@ void RLPXFrameIO::updateEgressMACWithHeader(bytesConstRef _headerCipher) updateMAC(m_egressMac, _headerCipher.cropped(0, 16)); } -void RLPXFrameIO::updateEgressMACWithEndOfFrame(bytesConstRef _cipher) +void RLPXFrameIO::updateEgressMACWithFrame(bytesConstRef _cipher) { m_egressMac.Update(_cipher.data(), _cipher.size()); updateMAC(m_egressMac); - { - SHA3_256 prev(m_egressMac); - h128 digest; - prev.TruncatedFinal(digest.data(), h128::size); - } } void RLPXFrameIO::updateIngressMACWithHeader(bytesConstRef _headerCipher) @@ -185,15 +180,10 @@ void RLPXFrameIO::updateIngressMACWithHeader(bytesConstRef _headerCipher) updateMAC(m_ingressMac, _headerCipher.cropped(0, 16)); } -void RLPXFrameIO::updateIngressMACWithEndOfFrame(bytesConstRef _cipher) +void RLPXFrameIO::updateIngressMACWithFrame(bytesConstRef _cipher) { m_ingressMac.Update(_cipher.data(), _cipher.size()); updateMAC(m_ingressMac); - { - SHA3_256 prev(m_ingressMac); - h128 digest; - prev.TruncatedFinal(digest.data(), h128::size); - } } void RLPXFrameIO::updateMAC(SHA3_256& _mac, bytesConstRef _seed) diff --git a/libp2p/RLPxFrameIO.h b/libp2p/RLPxFrameIO.h index 2bd2218aa..3a0fd35e0 100644 --- a/libp2p/RLPxFrameIO.h +++ b/libp2p/RLPxFrameIO.h @@ -38,6 +38,10 @@ namespace p2p class RLPXHandshake; +/** + * @brief Encoder/decoder transport for RLPx connections established by RLPXHandshake. + * Managed (via shared_ptr) socket for use by RLPXHandshake and RLPXFrameIO. + */ class RLPXSocket: public std::enable_shared_from_this { public: @@ -53,48 +57,68 @@ protected: bi::tcp::socket m_socket; }; +/** + * @brief Encoder/decoder transport for RLPx connections established by RLPXHandshake. + * + * Thread Safety + * Distinct Objects: Safe. + * Shared objects: Unsafe. + */ class RLPXFrameIO { friend class Session; public: + /// Constructor. + /// Requires instance of RLPXHandshake which has completed first two phases of handshake. RLPXFrameIO(RLPXHandshake const& _init); ~RLPXFrameIO() {} + /// Encrypt _packet as RLPx frame. void writeSingleFramePacket(bytesConstRef _packet, bytes& o_bytes); - /// Authenticates and decrypts header in-place. + /// Authenticate and decrypt header in-place. bool authAndDecryptHeader(bytesRef io_cipherWithMac); - /// Authenticates and decrypts frame in-place. + /// Authenticate and decrypt frame in-place. bool authAndDecryptFrame(bytesRef io_cipherWithMac); + /// Return first 16 bytes of current digest from egress mac. h128 egressDigest(); - + + /// Return first 16 bytes of current digest from ingress mac. h128 ingressDigest(); +protected: + /// Update state of egress MAC with frame header. void updateEgressMACWithHeader(bytesConstRef _headerCipher); + + /// Update state of egress MAC with frame. + void updateEgressMACWithFrame(bytesConstRef _cipher); - void updateEgressMACWithEndOfFrame(bytesConstRef _cipher); - + /// Update state of ingress MAC with frame header. void updateIngressMACWithHeader(bytesConstRef _headerCipher); - void updateIngressMACWithEndOfFrame(bytesConstRef _cipher); + /// Update state of ingress MAC with frame. + void updateIngressMACWithFrame(bytesConstRef _cipher); -protected: bi::tcp::socket& socket() { return m_socket->ref(); } private: + /// Update state of _mac. void updateMAC(CryptoPP::SHA3_256& _mac, bytesConstRef _seed = bytesConstRef()); - CryptoPP::SecByteBlock m_frameEncKey; - CryptoPP::SecByteBlock m_frameDecKey; - CryptoPP::CTR_Mode::Encryption m_frameEnc; - CryptoPP::CTR_Mode::Encryption m_frameDec; - CryptoPP::SecByteBlock m_macEncKey; - CryptoPP::ECB_Mode::Encryption m_macEnc; - Mutex x_macEnc; - CryptoPP::SHA3_256 m_egressMac; - CryptoPP::SHA3_256 m_ingressMac; + CryptoPP::SecByteBlock m_frameEncKey; ///< Key for m_frameEnc + CryptoPP::CTR_Mode::Encryption m_frameEnc; ///< Encoder for egress plaintext. + + CryptoPP::SecByteBlock m_frameDecKey; ///< Key for m_frameDec + CryptoPP::CTR_Mode::Encryption m_frameDec; ///< Decoder for egress plaintext. + + CryptoPP::SecByteBlock m_macEncKey; /// Key for m_macEnd + CryptoPP::ECB_Mode::Encryption m_macEnc; /// One-way coder used by updateMAC for ingress and egress MAC updates. + Mutex x_macEnc; /// Mutex + + CryptoPP::SHA3_256 m_egressMac; ///< State of MAC for egress ciphertext. + CryptoPP::SHA3_256 m_ingressMac; ///< State of MAC for ingress ciphertext. std::shared_ptr m_socket; };