99
1010use crate :: prelude:: * ;
1111
12+ use crate :: io:: Write ;
1213use crate :: ln:: msgs;
1314use crate :: ln:: msgs:: LightningError ;
1415use crate :: ln:: wire;
@@ -26,7 +27,7 @@ use bitcoin::secp256k1::{PublicKey, SecretKey};
2627
2728use crate :: crypto:: chacha20poly1305rfc:: ChaCha20Poly1305RFC ;
2829use crate :: crypto:: utils:: hkdf_extract_expand_twice;
29- use crate :: util:: ser:: VecWriter ;
30+ use crate :: util:: ser:: { BigSize , VecWriter , Writeable } ;
3031
3132use core:: ops:: Deref ;
3233
@@ -555,23 +556,85 @@ impl PeerChannelEncryptor {
555556 }
556557 }
557558
559+ fn maybe_add_message_padding ( & self , buffer : & mut Vec < u8 > ) {
560+ // In the base case, a serialized UpdateAddHTLC message is 1450 bytes: 32 (channel_id) + 8
561+ // (htlc_id) + 8 (amount_msat) + 32 (payment_hash) + 4 (cltv_expiry) + 1366
562+ // (onion_routing_packet). When including the additional 2 (encrypted message length) + 16
563+ // (encrypted message length MAC) + 2 (type) bytes, this has us at 1470 bytes
564+ // pre-encryption. As the encryption step adds 16 more bytes for the MAC of the encrypted
565+ // message itself, resulting in 1486 bytes TCP payload.
566+ //
567+ // As this base case however doesn't take into account any potential optional fields that
568+ // might be set on UpdateAddHTLC (such as the `path_key` for route blinding or other TLVs),
569+ // we opt to add another 50 bytes of leeway to our padding threshold size.
570+ //
571+ // Note that anything above this threshold won't get padded and will stand out in monitored
572+ // network traffic.
573+ const PADDING_THRESHOLD_BYTES : usize = 1470 + 50 ;
574+
575+ let orig_buffer_len = buffer. len ( ) ;
576+ let padding_len =
577+ PADDING_THRESHOLD_BYTES . checked_sub ( orig_buffer_len) . map_or ( 0 , |expected_len| {
578+ // As the TLV's length BigSize grows as we add more padding bytes, we might end up with
579+ // slightly larger messages than expected. To that end, we here account for this and
580+ // reduce the number of padding bytes by any serialized length of the BigSize beyond 1.
581+ //
582+ // TODO: This method risks that by subtracting the overhead we fall again just below
583+ // the `BigSize` steps which could leak the original padding len (and hence the
584+ // original message size). We should look into making this even more exact.
585+ let big_size_overhead =
586+ BigSize ( expected_len as u64 ) . serialized_length ( ) . saturating_sub ( 1 ) ;
587+ expected_len. saturating_sub ( big_size_overhead)
588+ } ) ;
589+
590+ // We always add type and length headers so unpadded messages just at
591+ // PADDING_THRESHOLD_BYTES don't stand out.
592+ BigSize ( u64:: max_value ( ) )
593+ . write ( buffer)
594+ . expect ( "In-memory messages must never fail to serialize" ) ;
595+ BigSize ( padding_len as u64 )
596+ . write ( buffer)
597+ . expect ( "In-memory messages must never fail to serialize" ) ;
598+ let mut bytes_written: usize = 0 ;
599+ while bytes_written < padding_len {
600+ // Write padding in 32-byte chunks if possible.
601+ const PAD_BYTES_LEN : usize = 32 ;
602+ let pad_bytes = [ 42u8 ; PAD_BYTES_LEN ] ;
603+ let bytes_to_write = ( padding_len - bytes_written) . min ( PAD_BYTES_LEN ) ;
604+ buffer
605+ . write_all ( & pad_bytes[ ..bytes_to_write] )
606+ . expect ( "In-memory messages must never fail to serialize" ) ;
607+ bytes_written += bytes_to_write;
608+ }
609+
610+ #[ cfg( debug_assertions) ]
611+ if orig_buffer_len < PADDING_THRESHOLD_BYTES {
612+ debug_assert_eq ! ( buffer. len( ) , PADDING_THRESHOLD_BYTES + 9 + 1 ) ;
613+ }
614+ }
615+
558616 /// Encrypts the given pre-serialized message, returning the encrypted version.
559617 /// panics if msg.len() > 65535 or Noise handshake has not finished.
560- pub fn encrypt_buffer ( & mut self , mut msg : MessageBuf ) -> Vec < u8 > {
618+ pub fn encrypt_buffer ( & mut self , mut msg : MessageBuf , should_pad : bool ) -> Vec < u8 > {
619+ if should_pad {
620+ self . maybe_add_message_padding ( & mut msg. 0 ) ;
621+ }
561622 self . encrypt_message_with_header_0s ( & mut msg. 0 ) ;
562623 msg. 0
563624 }
564625
565626 /// Encrypts the given message, returning the encrypted version.
566627 /// panics if the length of `message`, once encoded, is greater than 65535 or if the Noise
567628 /// handshake has not finished.
568- pub fn encrypt_message < M : wire:: Type > ( & mut self , message : & M ) -> Vec < u8 > {
629+ pub fn encrypt_message < M : wire:: Type > ( & mut self , message : & M , should_pad : bool ) -> Vec < u8 > {
569630 // Allocate a buffer with 2KB, fitting most common messages. Reserve the first 16+2 bytes
570631 // for the 2-byte message type prefix and its MAC.
571632 let mut res = VecWriter ( Vec :: with_capacity ( MSG_BUF_ALLOC_SIZE ) ) ;
572633 res. 0 . resize ( 16 + 2 , 0 ) ;
573634 wire:: write ( message, & mut res) . expect ( "In-memory messages must never fail to serialize" ) ;
574-
635+ if should_pad {
636+ self . maybe_add_message_padding ( & mut res. 0 ) ;
637+ }
575638 self . encrypt_message_with_header_0s ( & mut res. 0 ) ;
576639 res. 0
577640 }
@@ -1015,7 +1078,7 @@ mod tests {
10151078
10161079 for i in 0 ..1005 {
10171080 let msg = [ 0x68 , 0x65 , 0x6c , 0x6c , 0x6f ] ;
1018- let mut res = outbound_peer. encrypt_buffer ( MessageBuf :: from_encoded ( & msg) ) ;
1081+ let mut res = outbound_peer. encrypt_buffer ( MessageBuf :: from_encoded ( & msg) , false ) ;
10191082 assert_eq ! ( res. len( ) , 5 + 2 * 16 + 2 ) ;
10201083
10211084 let len_header = res[ 0 ..2 + 16 ] . to_vec ( ) ;
@@ -1060,7 +1123,7 @@ mod tests {
10601123 fn max_message_len_encryption ( ) {
10611124 let mut outbound_peer = get_outbound_peer_for_initiator_test_vectors ( ) ;
10621125 let msg = [ 4u8 ; LN_MAX_MSG_LEN + 1 ] ;
1063- outbound_peer. encrypt_buffer ( MessageBuf :: from_encoded ( & msg) ) ;
1126+ outbound_peer. encrypt_buffer ( MessageBuf :: from_encoded ( & msg) , false ) ;
10641127 }
10651128
10661129 #[ test]
0 commit comments