@@ -1002,8 +1002,7 @@ void V2Transport::StartSendingHandshake() noexcept
1002
1002
m_send_buffer.resize (EllSwiftPubKey::size () + m_send_garbage.size ());
1003
1003
std::copy (std::begin (m_cipher.GetOurPubKey ()), std::end (m_cipher.GetOurPubKey ()), MakeWritableByteSpan (m_send_buffer).begin ());
1004
1004
std::copy (m_send_garbage.begin (), m_send_garbage.end (), m_send_buffer.begin () + EllSwiftPubKey::size ());
1005
- // We cannot wipe m_send_garbage as it will still be used to construct the garbage
1006
- // authentication packet.
1005
+ // We cannot wipe m_send_garbage as it will still be used as AAD later in the handshake.
1007
1006
}
1008
1007
1009
1008
V2Transport::V2Transport (NodeId nodeid, bool initiating, int type_in, int version_in, const CKey& key, Span<const std::byte> ent32, std::vector<uint8_t > garbage) noexcept :
@@ -1037,9 +1036,6 @@ void V2Transport::SetReceiveState(RecvState recv_state) noexcept
1037
1036
Assume (recv_state == RecvState::GARB_GARBTERM);
1038
1037
break ;
1039
1038
case RecvState::GARB_GARBTERM:
1040
- Assume (recv_state == RecvState::GARBAUTH);
1041
- break ;
1042
- case RecvState::GARBAUTH:
1043
1039
Assume (recv_state == RecvState::VERSION);
1044
1040
break ;
1045
1041
case RecvState::VERSION:
@@ -1171,24 +1167,15 @@ bool V2Transport::ProcessReceivedKeyBytes() noexcept
1171
1167
m_cipher.GetSendGarbageTerminator ().end (),
1172
1168
MakeWritableByteSpan (m_send_buffer).last (BIP324Cipher::GARBAGE_TERMINATOR_LEN).begin ());
1173
1169
1174
- // Construct garbage authentication packet in the send buffer (using the garbage data which
1175
- // is still there).
1176
- m_send_buffer.resize (m_send_buffer.size () + BIP324Cipher::EXPANSION);
1177
- m_cipher.Encrypt (
1178
- /* contents=*/ {},
1179
- /* aad=*/ MakeByteSpan (m_send_garbage),
1180
- /* ignore=*/ false ,
1181
- /* output=*/ MakeWritableByteSpan (m_send_buffer).last (BIP324Cipher::EXPANSION));
1182
- // We no longer need the garbage.
1183
- ClearShrink (m_send_garbage);
1184
-
1185
- // Construct version packet in the send buffer.
1170
+ // Construct version packet in the send buffer, with the sent garbage data as AAD.
1186
1171
m_send_buffer.resize (m_send_buffer.size () + BIP324Cipher::EXPANSION + VERSION_CONTENTS.size ());
1187
1172
m_cipher.Encrypt (
1188
1173
/* contents=*/ VERSION_CONTENTS,
1189
- /* aad=*/ {} ,
1174
+ /* aad=*/ MakeByteSpan (m_send_garbage) ,
1190
1175
/* ignore=*/ false ,
1191
1176
/* output=*/ MakeWritableByteSpan (m_send_buffer).last (BIP324Cipher::EXPANSION + VERSION_CONTENTS.size ()));
1177
+ // We no longer need the garbage.
1178
+ ClearShrink (m_send_garbage);
1192
1179
} else {
1193
1180
// We still have to receive more key bytes.
1194
1181
}
@@ -1202,11 +1189,11 @@ bool V2Transport::ProcessReceivedGarbageBytes() noexcept
1202
1189
Assume (m_recv_buffer.size () <= MAX_GARBAGE_LEN + BIP324Cipher::GARBAGE_TERMINATOR_LEN);
1203
1190
if (m_recv_buffer.size () >= BIP324Cipher::GARBAGE_TERMINATOR_LEN) {
1204
1191
if (MakeByteSpan (m_recv_buffer).last (BIP324Cipher::GARBAGE_TERMINATOR_LEN) == m_cipher.GetReceiveGarbageTerminator ()) {
1205
- // Garbage terminator received. Switch to receiving garbage authentication packet .
1206
- m_recv_garbage = std::move (m_recv_buffer);
1207
- m_recv_garbage .resize (m_recv_garbage .size () - BIP324Cipher::GARBAGE_TERMINATOR_LEN);
1192
+ // Garbage terminator received. Store garbage to authenticate it as AAD later .
1193
+ m_recv_aad = std::move (m_recv_buffer);
1194
+ m_recv_aad .resize (m_recv_aad .size () - BIP324Cipher::GARBAGE_TERMINATOR_LEN);
1208
1195
m_recv_buffer.clear ();
1209
- SetReceiveState (RecvState::GARBAUTH );
1196
+ SetReceiveState (RecvState::VERSION );
1210
1197
} else if (m_recv_buffer.size () == MAX_GARBAGE_LEN + BIP324Cipher::GARBAGE_TERMINATOR_LEN) {
1211
1198
// We've reached the maximum length for garbage + garbage terminator, and the
1212
1199
// terminator still does not match. Abort.
@@ -1225,8 +1212,7 @@ bool V2Transport::ProcessReceivedGarbageBytes() noexcept
1225
1212
bool V2Transport::ProcessReceivedPacketBytes () noexcept
1226
1213
{
1227
1214
AssertLockHeld (m_recv_mutex);
1228
- Assume (m_recv_state == RecvState::GARBAUTH || m_recv_state == RecvState::VERSION ||
1229
- m_recv_state == RecvState::APP);
1215
+ Assume (m_recv_state == RecvState::VERSION || m_recv_state == RecvState::APP);
1230
1216
1231
1217
// The maximum permitted contents length for a packet, consisting of:
1232
1218
// - 0x00 byte: indicating long message type encoding
@@ -1249,45 +1235,37 @@ bool V2Transport::ProcessReceivedPacketBytes() noexcept
1249
1235
// as GetMaxBytesToProcess only allows up to LENGTH_LEN into the buffer before that point.
1250
1236
m_recv_decode_buffer.resize (m_recv_len);
1251
1237
bool ignore{false };
1252
- Span<const std::byte> aad;
1253
- if (m_recv_state == RecvState::GARBAUTH) aad = MakeByteSpan (m_recv_garbage);
1254
1238
bool ret = m_cipher.Decrypt (
1255
1239
/* input=*/ MakeByteSpan (m_recv_buffer).subspan (BIP324Cipher::LENGTH_LEN),
1256
- /* aad=*/ aad ,
1240
+ /* aad=*/ MakeByteSpan (m_recv_aad) ,
1257
1241
/* ignore=*/ ignore,
1258
1242
/* contents=*/ MakeWritableByteSpan (m_recv_decode_buffer));
1259
1243
if (!ret) {
1260
1244
LogPrint (BCLog::NET, " V2 transport error: packet decryption failure (%u bytes), peer=%d\n " , m_recv_len, m_nodeid);
1261
1245
return false ;
1262
1246
}
1247
+ // We have decrypted a valid packet with the AAD we expected, so clear the expected AAD.
1248
+ ClearShrink (m_recv_aad);
1263
1249
// Feed the last 4 bytes of the Poly1305 authentication tag (and its timing) into our RNG.
1264
1250
RandAddEvent (ReadLE32 (m_recv_buffer.data () + m_recv_buffer.size () - 4 ));
1265
1251
1266
- // At this point we have a valid packet decrypted into m_recv_decode_buffer. Depending on
1267
- // the current state, decide what to do with it.
1268
- switch (m_recv_state) {
1269
- case RecvState::GARBAUTH:
1270
- // Ignore flag does not matter for garbage authentication. Any valid packet functions
1271
- // as authentication. Receive and process the version packet next.
1272
- SetReceiveState (RecvState::VERSION);
1273
- ClearShrink (m_recv_garbage);
1274
- break ;
1275
- case RecvState::VERSION:
1276
- if (!ignore) {
1252
+ // At this point we have a valid packet decrypted into m_recv_decode_buffer. If it's not a
1253
+ // decoy, which we simply ignore, use the current state to decide what to do with it.
1254
+ if (!ignore) {
1255
+ switch (m_recv_state) {
1256
+ case RecvState::VERSION:
1277
1257
// Version message received; transition to application phase. The contents is
1278
1258
// ignored, but can be used for future extensions.
1279
1259
SetReceiveState (RecvState::APP);
1280
- }
1281
- break ;
1282
- case RecvState::APP:
1283
- if (!ignore) {
1260
+ break ;
1261
+ case RecvState::APP:
1284
1262
// Application message decrypted correctly. It can be extracted using GetMessage().
1285
1263
SetReceiveState (RecvState::APP_READY);
1264
+ break ;
1265
+ default :
1266
+ // Any other state is invalid (this function should not have been called).
1267
+ Assume (false );
1286
1268
}
1287
- break ;
1288
- default :
1289
- // Any other state is invalid (this function should not have been called).
1290
- Assume (false );
1291
1269
}
1292
1270
// Wipe the receive buffer where the next packet will be received into.
1293
1271
ClearShrink (m_recv_buffer);
@@ -1323,7 +1301,6 @@ size_t V2Transport::GetMaxBytesToProcess() noexcept
1323
1301
case RecvState::GARB_GARBTERM:
1324
1302
// Process garbage bytes one by one (because terminator may appear anywhere).
1325
1303
return 1 ;
1326
- case RecvState::GARBAUTH:
1327
1304
case RecvState::VERSION:
1328
1305
case RecvState::APP:
1329
1306
// These three states all involve decoding a packet. Process the length descriptor first,
@@ -1377,7 +1354,6 @@ bool V2Transport::ReceivedBytes(Span<const uint8_t>& msg_bytes) noexcept
1377
1354
// bytes).
1378
1355
m_recv_buffer.reserve (MAX_GARBAGE_LEN + BIP324Cipher::GARBAGE_TERMINATOR_LEN);
1379
1356
break ;
1380
- case RecvState::GARBAUTH:
1381
1357
case RecvState::VERSION:
1382
1358
case RecvState::APP: {
1383
1359
// During states where a packet is being received, as much as is expected but never
@@ -1421,7 +1397,6 @@ bool V2Transport::ReceivedBytes(Span<const uint8_t>& msg_bytes) noexcept
1421
1397
if (!ProcessReceivedGarbageBytes ()) return false ;
1422
1398
break ;
1423
1399
1424
- case RecvState::GARBAUTH:
1425
1400
case RecvState::VERSION:
1426
1401
case RecvState::APP:
1427
1402
if (!ProcessReceivedPacketBytes ()) return false ;
0 commit comments