Skip to content

Commit 0c808de

Browse files
committed
Expose BIP324CipherSuite AAD via transport classes
1 parent 9842320 commit 0c808de

5 files changed

+31
-13
lines changed

src/net.cpp

+11-5
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ bool CNode::ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete)
674674
// decompose a transport agnostic CNetMessage from the deserializer
675675
bool reject_message{false};
676676
bool disconnect{false};
677-
CNetMessage msg = m_deserializer->GetMessage(time, reject_message, disconnect);
677+
CNetMessage msg = m_deserializer->GetMessage(time, reject_message, disconnect, {});
678678

679679
if (disconnect) {
680680
// v2 p2p incorrect MAC tag. Disconnect from peer.
@@ -772,7 +772,10 @@ const uint256& V1TransportDeserializer::GetMessageHash() const
772772
return data_hash;
773773
}
774774

775-
CNetMessage V1TransportDeserializer::GetMessage(const std::chrono::microseconds time, bool& reject_message, bool& disconnect)
775+
CNetMessage V1TransportDeserializer::GetMessage(const std::chrono::microseconds time,
776+
bool& reject_message,
777+
bool& disconnect,
778+
Span<const std::byte> aad)
776779
{
777780
// Initialize out parameter
778781
reject_message = false;
@@ -877,7 +880,10 @@ int V2TransportDeserializer::readData(Span<const uint8_t> pkt_bytes)
877880
return copy_bytes;
878881
}
879882

880-
CNetMessage V2TransportDeserializer::GetMessage(const std::chrono::microseconds time, bool& reject_message, bool& disconnect)
883+
CNetMessage V2TransportDeserializer::GetMessage(const std::chrono::microseconds time,
884+
bool& reject_message,
885+
bool& disconnect,
886+
Span<const std::byte> aad)
881887
{
882888
const size_t min_contents_size = 1; // BIP324 1-byte message type id is the minimum contents
883889

@@ -896,7 +902,7 @@ CNetMessage V2TransportDeserializer::GetMessage(const std::chrono::microseconds
896902

897903
BIP324HeaderFlags flags;
898904
size_t msg_type_size = 1; // at least one byte needed for message type
899-
if (m_cipher_suite->Crypt({},
905+
if (m_cipher_suite->Crypt(aad,
900906
Span{reinterpret_cast<const std::byte*>(vRecv.data() + BIP324_LENGTH_FIELD_LEN), BIP324_HEADER_LEN + m_contents_size + RFC8439_EXPANSION},
901907
Span{reinterpret_cast<std::byte*>(vRecv.data()), m_contents_size}, flags, false)) {
902908
// MAC check was successful
@@ -984,7 +990,7 @@ bool V2TransportSerializer::prepareForTransport(CSerializedNetMsg& msg, std::vec
984990

985991
BIP324HeaderFlags flags{BIP324_NONE};
986992
// encrypt the payload, this should always succeed (controlled buffers, don't check the MAC during encrypting)
987-
auto success = m_cipher_suite->Crypt({},
993+
auto success = m_cipher_suite->Crypt(msg.aad,
988994
Span{reinterpret_cast<const std::byte*>(msg.data.data()), contents_size},
989995
Span{reinterpret_cast<std::byte*>(msg.data.data()), encrypted_pkt_size},
990996
flags, true);

src/net.h

+13-3
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ struct CSerializedNetMsg {
125125
}
126126

127127
std::vector<unsigned char> data;
128+
std::vector<std::byte> aad; // associated authenticated data for encrypted BIP324 (v2) transport
128129
std::string m_type;
129130
};
130131

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

@@ -324,7 +328,10 @@ class V1TransportDeserializer final : public TransportDeserializer
324328
}
325329
return ret;
326330
}
327-
CNetMessage GetMessage(std::chrono::microseconds time, bool& reject_message, bool& disconnect) override;
331+
CNetMessage GetMessage(std::chrono::microseconds time,
332+
bool& reject_message,
333+
bool& disconnect,
334+
Span<const std::byte> aad) override;
328335
};
329336

330337
/** V2TransportDeserializer is a transport deserializer after BIP324 */
@@ -382,7 +389,10 @@ class V2TransportDeserializer final : public TransportDeserializer
382389
}
383390
return ret;
384391
}
385-
CNetMessage GetMessage(const std::chrono::microseconds time, bool& reject_message, bool& disconnect) override;
392+
CNetMessage GetMessage(const std::chrono::microseconds time,
393+
bool& reject_message,
394+
bool& disconnect,
395+
Span<const std::byte> aad) override;
386396
};
387397

388398
/** 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)