Skip to content

Commit f019556

Browse files
committed
Expose BIP324CipherSuite AAD via transport classes
1 parent 16eeb43 commit f019556

5 files changed

+31
-13
lines changed

src/net.cpp

+11-5
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ bool CNode::ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete)
691691
// decompose a transport agnostic CNetMessage from the deserializer
692692
bool reject_message{false};
693693
bool disconnect{false};
694-
CNetMessage msg = m_deserializer->GetMessage(time, reject_message, disconnect);
694+
CNetMessage msg = m_deserializer->GetMessage(time, reject_message, disconnect, {});
695695

696696
if (disconnect) {
697697
// v2 p2p incorrect MAC tag. Disconnect from peer.
@@ -789,7 +789,10 @@ const uint256& V1TransportDeserializer::GetMessageHash() const
789789
return data_hash;
790790
}
791791

792-
CNetMessage V1TransportDeserializer::GetMessage(const std::chrono::microseconds time, bool& reject_message, bool& disconnect)
792+
CNetMessage V1TransportDeserializer::GetMessage(const std::chrono::microseconds time,
793+
bool& reject_message,
794+
bool& disconnect,
795+
Span<const std::byte> aad)
793796
{
794797
// Initialize out parameter
795798
reject_message = false;
@@ -894,7 +897,10 @@ int V2TransportDeserializer::readData(Span<const uint8_t> pkt_bytes)
894897
return copy_bytes;
895898
}
896899

897-
CNetMessage V2TransportDeserializer::GetMessage(const std::chrono::microseconds time, bool& reject_message, bool& disconnect)
900+
CNetMessage V2TransportDeserializer::GetMessage(const std::chrono::microseconds time,
901+
bool& reject_message,
902+
bool& disconnect,
903+
Span<const std::byte> aad)
898904
{
899905
const size_t min_contents_size = 1; // BIP324 1-byte message type id is the minimum contents
900906

@@ -913,7 +919,7 @@ CNetMessage V2TransportDeserializer::GetMessage(const std::chrono::microseconds
913919

914920
BIP324HeaderFlags flags;
915921
size_t msg_type_size = 1; // at least one byte needed for message type
916-
if (m_cipher_suite->Crypt({},
922+
if (m_cipher_suite->Crypt(aad,
917923
Span{reinterpret_cast<const std::byte*>(vRecv.data() + BIP324_LENGTH_FIELD_LEN), BIP324_HEADER_LEN + m_contents_size + RFC8439_EXPANSION},
918924
Span{reinterpret_cast<std::byte*>(vRecv.data()), m_contents_size}, flags, false)) {
919925
// MAC check was successful
@@ -1006,7 +1012,7 @@ bool V2TransportSerializer::prepareForTransport(CSerializedNetMsg& msg, std::vec
10061012

10071013
BIP324HeaderFlags flags{BIP324_NONE};
10081014
// encrypt the payload, this should always succeed (controlled buffers, don't check the MAC during encrypting)
1009-
auto success = m_cipher_suite->Crypt({},
1015+
auto success = m_cipher_suite->Crypt(msg.aad,
10101016
Span{reinterpret_cast<const std::byte*>(msg.data.data()), contents_size},
10111017
Span{reinterpret_cast<std::byte*>(msg.data.data()), encrypted_pkt_size},
10121018
flags, true);

src/net.h

+13-3
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ struct CSerializedNetMsg {
127127
}
128128

129129
std::vector<unsigned char> data;
130+
std::vector<std::byte> aad; // associated authenticated data for encrypted BIP324 (v2) transport
130131
std::string m_type;
131132
};
132133

@@ -262,7 +263,10 @@ class TransportDeserializer {
262263
/** read and deserialize data, advances msg_bytes data pointer */
263264
virtual int Read(Span<const uint8_t>& msg_bytes) = 0;
264265
// decomposes a message from the context
265-
virtual CNetMessage GetMessage(std::chrono::microseconds time, bool& reject_message, bool& disconnect) = 0;
266+
virtual CNetMessage GetMessage(std::chrono::microseconds time,
267+
bool& reject_message,
268+
bool& disconnect,
269+
Span<const std::byte> aad) = 0;
266270
virtual ~TransportDeserializer() {}
267271
};
268272

@@ -326,7 +330,10 @@ class V1TransportDeserializer final : public TransportDeserializer
326330
}
327331
return ret;
328332
}
329-
CNetMessage GetMessage(std::chrono::microseconds time, bool& reject_message, bool& disconnect) override;
333+
CNetMessage GetMessage(std::chrono::microseconds time,
334+
bool& reject_message,
335+
bool& disconnect,
336+
Span<const std::byte> aad) override;
330337
};
331338

332339
/** V2TransportDeserializer is a transport deserializer after BIP324 */
@@ -384,7 +391,10 @@ class V2TransportDeserializer final : public TransportDeserializer
384391
}
385392
return ret;
386393
}
387-
CNetMessage GetMessage(const std::chrono::microseconds time, bool& reject_message, bool& disconnect) override;
394+
CNetMessage GetMessage(const std::chrono::microseconds time,
395+
bool& reject_message,
396+
bool& disconnect,
397+
Span<const std::byte> aad) override;
388398
};
389399

390400
/** The TransportSerializer prepares messages for the network transport

src/test/fuzz/p2p_transport_serialization.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ FUZZ_TARGET_INIT(p2p_transport_serialization, initialize_p2p_transport_serializa
7070
const std::chrono::microseconds m_time{std::numeric_limits<int64_t>::max()};
7171
bool reject_message{false};
7272
bool disconnect{false};
73-
CNetMessage msg = deserializer.GetMessage(m_time, reject_message, disconnect);
73+
CNetMessage msg = deserializer.GetMessage(m_time, reject_message, disconnect, {});
7474
assert(msg.m_type.size() <= CMessageHeader::COMMAND_SIZE);
7575
assert(msg.m_raw_message_size <= mutable_msg_bytes.size());
7676
assert(msg.m_raw_message_size == CMessageHeader::HEADER_SIZE + msg.m_message_size);

src/test/fuzz/p2p_v2_transport_serialization.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ FUZZ_TARGET(p2p_v2_transport_serialization)
4040

4141
// There is no sense in providing a mac assist if the length is incorrect.
4242
bool mac_assist = length_assist && fdp.ConsumeBool();
43+
auto aad = fdp.ConsumeBytes<std::byte>(fdp.ConsumeIntegralInRange(0, 1024));
4344
auto encrypted_packet = fdp.ConsumeRemainingBytes<uint8_t>();
4445
bool is_decoy_packet{false};
4546

@@ -53,15 +54,15 @@ FUZZ_TARGET(p2p_v2_transport_serialization)
5354

5455
if (mac_assist) {
5556
std::array<std::byte, RFC8439_EXPANSION> tag;
56-
ComputeRFC8439Tag(GetPoly1305Key(c20), {},
57+
ComputeRFC8439Tag(GetPoly1305Key(c20), aad,
5758
{reinterpret_cast<std::byte*>(encrypted_packet.data()) + BIP324_LENGTH_FIELD_LEN,
5859
encrypted_packet.size() - BIP324_LENGTH_FIELD_LEN - RFC8439_EXPANSION},
5960
tag);
6061
memcpy(encrypted_packet.data() + encrypted_packet.size() - RFC8439_EXPANSION, tag.data(), RFC8439_EXPANSION);
6162

6263
std::vector<std::byte> dec_header_and_contents(
6364
encrypted_packet.size() - BIP324_LENGTH_FIELD_LEN - RFC8439_EXPANSION);
64-
RFC8439Decrypt({}, key_P, nonce,
65+
RFC8439Decrypt(aad, key_P, nonce,
6566
{reinterpret_cast<std::byte*>(encrypted_packet.data() + BIP324_LENGTH_FIELD_LEN),
6667
encrypted_packet.size() - BIP324_LENGTH_FIELD_LEN},
6768
dec_header_and_contents);
@@ -81,7 +82,7 @@ FUZZ_TARGET(p2p_v2_transport_serialization)
8182
const std::chrono::microseconds m_time{std::numeric_limits<int64_t>::max()};
8283
bool reject_message{true};
8384
bool disconnect{true};
84-
CNetMessage result{deserializer.GetMessage(m_time, reject_message, disconnect)};
85+
CNetMessage result{deserializer.GetMessage(m_time, reject_message, disconnect, aad)};
8586

8687
if (mac_assist) {
8788
assert(!disconnect);
@@ -102,6 +103,7 @@ FUZZ_TARGET(p2p_v2_transport_serialization)
102103

103104
std::vector<unsigned char> header;
104105
auto msg = CNetMsgMaker{result.m_recv.GetVersion()}.Make(result.m_type, MakeUCharSpan(result.m_recv));
106+
msg.aad = aad;
105107
// if decryption succeeds, encryption must succeed
106108
assert(serializer.prepareForTransport(msg, header));
107109
}

src/test/net_tests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ void message_serialize_deserialize_test(bool v2, const std::vector<CSerializedNe
953953

954954
bool reject_message{true};
955955
bool disconnect{true};
956-
CNetMessage result{deserializer->GetMessage(GetTime<std::chrono::microseconds>(), reject_message, disconnect)};
956+
CNetMessage result{deserializer->GetMessage(GetTime<std::chrono::microseconds>(), reject_message, disconnect, {})};
957957
BOOST_CHECK(!reject_message);
958958
BOOST_CHECK(!disconnect);
959959
BOOST_CHECK_EQUAL(result.m_type, msg_orig.m_type);

0 commit comments

Comments
 (0)