Skip to content

Commit ecdc42b

Browse files
committed
Expose BIP324CipherSuite AAD via transport classes
1 parent cfe458a commit ecdc42b

5 files changed

+31
-13
lines changed

src/net.cpp

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

699699
if (disconnect) {
700700
// v2 p2p incorrect MAC tag. Disconnect from peer.
@@ -792,7 +792,10 @@ const uint256& V1TransportDeserializer::GetMessageHash() const
792792
return data_hash;
793793
}
794794

795-
CNetMessage V1TransportDeserializer::GetMessage(const std::chrono::microseconds time, bool& reject_message, bool& disconnect)
795+
CNetMessage V1TransportDeserializer::GetMessage(const std::chrono::microseconds time,
796+
bool& reject_message,
797+
bool& disconnect,
798+
Span<const std::byte> aad)
796799
{
797800
// Initialize out parameter
798801
reject_message = false;
@@ -897,7 +900,10 @@ int V2TransportDeserializer::readData(Span<const uint8_t> pkt_bytes)
897900
return copy_bytes;
898901
}
899902

900-
CNetMessage V2TransportDeserializer::GetMessage(const std::chrono::microseconds time, bool& reject_message, bool& disconnect)
903+
CNetMessage V2TransportDeserializer::GetMessage(const std::chrono::microseconds time,
904+
bool& reject_message,
905+
bool& disconnect,
906+
Span<const std::byte> aad)
901907
{
902908
const size_t min_contents_size = 1; // BIP324 1-byte message type id is the minimum contents
903909

@@ -916,7 +922,7 @@ CNetMessage V2TransportDeserializer::GetMessage(const std::chrono::microseconds
916922

917923
BIP324HeaderFlags flags;
918924
size_t msg_type_size = 1; // at least one byte needed for message type
919-
if (m_cipher_suite->Crypt({},
925+
if (m_cipher_suite->Crypt(aad,
920926
Span{reinterpret_cast<const std::byte*>(vRecv.data() + BIP324_LENGTH_FIELD_LEN), BIP324_HEADER_LEN + m_contents_size + RFC8439_EXPANSION},
921927
Span{reinterpret_cast<std::byte*>(vRecv.data()), m_contents_size}, flags, false)) {
922928
// MAC check was successful
@@ -1009,7 +1015,7 @@ bool V2TransportSerializer::prepareForTransport(CSerializedNetMsg& msg, std::vec
10091015

10101016
BIP324HeaderFlags flags{BIP324_NONE};
10111017
// encrypt the payload, this should always succeed (controlled buffers, don't check the MAC during encrypting)
1012-
auto success = m_cipher_suite->Crypt({},
1018+
auto success = m_cipher_suite->Crypt(msg.aad,
10131019
Span{reinterpret_cast<const std::byte*>(msg.data.data()), contents_size},
10141020
Span{reinterpret_cast<std::byte*>(msg.data.data()), encrypted_pkt_size},
10151021
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

@@ -270,7 +271,10 @@ class TransportDeserializer {
270271
/** read and deserialize data, advances msg_bytes data pointer */
271272
virtual int Read(Span<const uint8_t>& msg_bytes) = 0;
272273
// decomposes a message from the context
273-
virtual CNetMessage GetMessage(std::chrono::microseconds time, bool& reject_message, bool& disconnect) = 0;
274+
virtual CNetMessage GetMessage(std::chrono::microseconds time,
275+
bool& reject_message,
276+
bool& disconnect,
277+
Span<const std::byte> aad) = 0;
274278
virtual ~TransportDeserializer() {}
275279
};
276280

@@ -334,7 +338,10 @@ class V1TransportDeserializer final : public TransportDeserializer
334338
}
335339
return ret;
336340
}
337-
CNetMessage GetMessage(std::chrono::microseconds time, bool& reject_message, bool& disconnect) override;
341+
CNetMessage GetMessage(std::chrono::microseconds time,
342+
bool& reject_message,
343+
bool& disconnect,
344+
Span<const std::byte> aad) override;
338345
};
339346

340347
/** V2TransportDeserializer is a transport deserializer after BIP324 */
@@ -392,7 +399,10 @@ class V2TransportDeserializer final : public TransportDeserializer
392399
}
393400
return ret;
394401
}
395-
CNetMessage GetMessage(const std::chrono::microseconds time, bool& reject_message, bool& disconnect) override;
402+
CNetMessage GetMessage(const std::chrono::microseconds time,
403+
bool& reject_message,
404+
bool& disconnect,
405+
Span<const std::byte> aad) override;
396406
};
397407

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