@@ -41,6 +41,8 @@ use core::ops::Deref;
4141#[ allow( unused_imports) ]
4242use crate :: prelude:: * ;
4343
44+ const DEFAULT_MIN_FAILURE_PACKET_LEN : usize = 256 ;
45+
4446pub ( crate ) struct OnionKeys {
4547 #[ cfg( test) ]
4648 pub ( crate ) shared_secret : SharedSecret ,
@@ -889,15 +891,16 @@ fn process_chacha(key: &[u8; 32], packet: &mut [u8]) {
889891}
890892
891893fn build_unencrypted_failure_packet (
892- shared_secret : & [ u8 ] , failure_type : u16 , failure_data : & [ u8 ] ,
894+ shared_secret : & [ u8 ] , failure_type : u16 , failure_data : & [ u8 ] , min_packet_len : usize ,
893895) -> OnionErrorPacket {
894896 assert_eq ! ( shared_secret. len( ) , 32 ) ;
895- assert ! ( failure_data. len( ) <= 256 - 2 ) ;
897+ assert ! ( failure_data. len( ) <= 64531 ) ;
896898
897899 // Failure len is 2 bytes type plus the data.
898900 let failure_len = 2 + failure_data. len ( ) ;
899901
900- let pad_len = 256 - failure_len;
902+ // The remaining length is the padding.
903+ let pad_len = min_packet_len. saturating_sub ( failure_len) ;
901904
902905 // Total len is a 32 bytes HMAC, 2 bytes failure len, failure, 2 bytes pad len and pad.
903906 let total_len = 32 + 2 + failure_len + 2 + pad_len;
@@ -929,8 +932,12 @@ fn build_unencrypted_failure_packet(
929932pub ( super ) fn build_failure_packet (
930933 shared_secret : & [ u8 ] , failure_type : u16 , failure_data : & [ u8 ] ,
931934) -> OnionErrorPacket {
932- let mut onion_error_packet =
933- build_unencrypted_failure_packet ( shared_secret, failure_type, failure_data) ;
935+ let mut onion_error_packet = build_unencrypted_failure_packet (
936+ shared_secret,
937+ failure_type,
938+ failure_data,
939+ DEFAULT_MIN_FAILURE_PACKET_LEN ,
940+ ) ;
934941
935942 crypt_failure_packet ( shared_secret, & mut onion_error_packet) ;
936943
@@ -2170,7 +2177,8 @@ mod tests {
21702177
21712178 use crate :: io;
21722179 use crate :: ln:: channelmanager:: PaymentId ;
2173- use crate :: ln:: msgs;
2180+ use crate :: ln:: msgs:: { self , UpdateFailHTLC } ;
2181+ use crate :: ln:: types:: ChannelId ;
21742182 use crate :: routing:: router:: { Path , PaymentParameters , Route , RouteHop } ;
21752183 use crate :: types:: features:: { ChannelFeatures , NodeFeatures } ;
21762184 use crate :: types:: payment:: PaymentHash ;
@@ -2504,6 +2512,7 @@ mod tests {
25042512 onion_keys[ 4 ] . shared_secret . as_ref ( ) ,
25052513 0x2002 ,
25062514 & [ 0 ; 0 ] ,
2515+ DEFAULT_MIN_FAILURE_PACKET_LEN ,
25072516 ) ;
25082517 let hex = "4c2fc8bc08510334b6833ad9c3e79cd1b52ae59dfe5c2a4b23ead50f09f7ee0b0002200200fe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ;
25092518 assert_eq ! ( onion_error. data, <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
@@ -2673,6 +2682,7 @@ mod tests {
26732682 outer_onion_keys[ 0 ] . shared_secret . as_ref ( ) ,
26742683 error_code,
26752684 & [ 0 ; 0 ] ,
2685+ DEFAULT_MIN_FAILURE_PACKET_LEN ,
26762686 ) ;
26772687
26782688 crypt_failure_packet (
@@ -2692,6 +2702,7 @@ mod tests {
26922702 outer_onion_keys[ 1 ] . shared_secret . as_ref ( ) ,
26932703 error_code,
26942704 & [ 0 ; 0 ] ,
2705+ DEFAULT_MIN_FAILURE_PACKET_LEN ,
26952706 ) ;
26962707
26972708 crypt_failure_packet (
@@ -2720,6 +2731,7 @@ mod tests {
27202731 trampoline_onion_keys[ 0 ] . shared_secret . as_ref ( ) ,
27212732 error_code,
27222733 & [ 0 ; 0 ] ,
2734+ DEFAULT_MIN_FAILURE_PACKET_LEN ,
27232735 ) ;
27242736
27252737 crypt_failure_packet (
@@ -2753,6 +2765,7 @@ mod tests {
27532765 trampoline_onion_keys[ 1 ] . shared_secret . as_ref ( ) ,
27542766 error_code,
27552767 & [ 0 ; 0 ] ,
2768+ DEFAULT_MIN_FAILURE_PACKET_LEN ,
27562769 ) ;
27572770
27582771 crypt_failure_packet (
@@ -2906,4 +2919,45 @@ mod tests {
29062919 let recipient_onion = RecipientOnionFields :: spontaneous_empty ( ) ;
29072920 set_max_path_length ( & mut route_params, & recipient_onion, None , None , 42 ) . unwrap ( ) ;
29082921 }
2922+
2923+ #[ test]
2924+ fn test_failure_packet_max_size ( ) {
2925+ // Create a failure message of the maximum size of 65535 bytes. It is composed of:
2926+ // - 32 bytes channel id
2927+ // - 8 bytes htlc id
2928+ // - 2 bytes reason length
2929+ // - 32 bytes of hmac
2930+ // - 2 bytes of failure type
2931+ // - 2 bytes of failure length
2932+ // - 64531 bytes of failure data
2933+ // - 2 bytes of pad len (0)
2934+ // - 1 byte attribution data tlv type
2935+ // - 3 bytes attribution data tlv length
2936+ // - 80 bytes of attribution data hold times
2937+ // - 840 bytes of attribution data hmacs
2938+ let failure_data = vec ! [ 0 ; 64531 ] ;
2939+
2940+ let shared_secret = [ 0 ; 32 ] ;
2941+ let onion_error = super :: build_unencrypted_failure_packet (
2942+ & shared_secret,
2943+ 0x2002 ,
2944+ & failure_data,
2945+ DEFAULT_MIN_FAILURE_PACKET_LEN ,
2946+ ) ;
2947+
2948+ let msg = UpdateFailHTLC {
2949+ channel_id : ChannelId ( [ 0 ; 32 ] ) ,
2950+ htlc_id : 0 ,
2951+ reason : onion_error. data ,
2952+ attribution_data : Some ( AttributionData {
2953+ hold_times : [ 0 ; MAX_HOPS * HOLD_TIME_LEN ] ,
2954+ hmacs : [ 0 ; HMAC_LEN * HMAC_COUNT ] ,
2955+ } ) ,
2956+ } ;
2957+
2958+ let mut buffer = Vec :: new ( ) ;
2959+ msg. write ( & mut buffer) . unwrap ( ) ;
2960+
2961+ assert_eq ! ( buffer. len( ) , 65535 ) ;
2962+ }
29092963}
0 commit comments