@@ -41,6 +41,8 @@ use core::ops::Deref;
41
41
#[ allow( unused_imports) ]
42
42
use crate :: prelude:: * ;
43
43
44
+ const DEFAULT_MIN_FAILURE_PACKET_LEN : usize = 256 ;
45
+
44
46
pub ( crate ) struct OnionKeys {
45
47
#[ cfg( test) ]
46
48
pub ( crate ) shared_secret : SharedSecret ,
@@ -889,15 +891,16 @@ fn process_chacha(key: &[u8; 32], packet: &mut [u8]) {
889
891
}
890
892
891
893
fn 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 ,
893
895
) -> OnionErrorPacket {
894
896
assert_eq ! ( shared_secret. len( ) , 32 ) ;
895
- assert ! ( failure_data. len( ) <= 256 - 2 ) ;
897
+ assert ! ( failure_data. len( ) <= 64531 ) ;
896
898
897
899
// Failure len is 2 bytes type plus the data.
898
900
let failure_len = 2 + failure_data. len ( ) ;
899
901
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) ;
901
904
902
905
// Total len is a 32 bytes HMAC, 2 bytes failure len, failure, 2 bytes pad len and pad.
903
906
let total_len = 32 + 2 + failure_len + 2 + pad_len;
@@ -929,8 +932,12 @@ fn build_unencrypted_failure_packet(
929
932
pub ( super ) fn build_failure_packet (
930
933
shared_secret : & [ u8 ] , failure_type : u16 , failure_data : & [ u8 ] ,
931
934
) -> 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
+ ) ;
934
941
935
942
crypt_failure_packet ( shared_secret, & mut onion_error_packet) ;
936
943
@@ -2170,7 +2177,8 @@ mod tests {
2170
2177
2171
2178
use crate :: io;
2172
2179
use crate :: ln:: channelmanager:: PaymentId ;
2173
- use crate :: ln:: msgs;
2180
+ use crate :: ln:: msgs:: { self , UpdateFailHTLC } ;
2181
+ use crate :: ln:: types:: ChannelId ;
2174
2182
use crate :: routing:: router:: { Path , PaymentParameters , Route , RouteHop } ;
2175
2183
use crate :: types:: features:: { ChannelFeatures , NodeFeatures } ;
2176
2184
use crate :: types:: payment:: PaymentHash ;
@@ -2504,6 +2512,7 @@ mod tests {
2504
2512
onion_keys[ 4 ] . shared_secret . as_ref ( ) ,
2505
2513
0x2002 ,
2506
2514
& [ 0 ; 0 ] ,
2515
+ DEFAULT_MIN_FAILURE_PACKET_LEN ,
2507
2516
) ;
2508
2517
let hex = "4c2fc8bc08510334b6833ad9c3e79cd1b52ae59dfe5c2a4b23ead50f09f7ee0b0002200200fe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ;
2509
2518
assert_eq ! ( onion_error. data, <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
@@ -2673,6 +2682,7 @@ mod tests {
2673
2682
outer_onion_keys[ 0 ] . shared_secret . as_ref ( ) ,
2674
2683
error_code,
2675
2684
& [ 0 ; 0 ] ,
2685
+ DEFAULT_MIN_FAILURE_PACKET_LEN ,
2676
2686
) ;
2677
2687
2678
2688
crypt_failure_packet (
@@ -2692,6 +2702,7 @@ mod tests {
2692
2702
outer_onion_keys[ 1 ] . shared_secret . as_ref ( ) ,
2693
2703
error_code,
2694
2704
& [ 0 ; 0 ] ,
2705
+ DEFAULT_MIN_FAILURE_PACKET_LEN ,
2695
2706
) ;
2696
2707
2697
2708
crypt_failure_packet (
@@ -2720,6 +2731,7 @@ mod tests {
2720
2731
trampoline_onion_keys[ 0 ] . shared_secret . as_ref ( ) ,
2721
2732
error_code,
2722
2733
& [ 0 ; 0 ] ,
2734
+ DEFAULT_MIN_FAILURE_PACKET_LEN ,
2723
2735
) ;
2724
2736
2725
2737
crypt_failure_packet (
@@ -2753,6 +2765,7 @@ mod tests {
2753
2765
trampoline_onion_keys[ 1 ] . shared_secret . as_ref ( ) ,
2754
2766
error_code,
2755
2767
& [ 0 ; 0 ] ,
2768
+ DEFAULT_MIN_FAILURE_PACKET_LEN ,
2756
2769
) ;
2757
2770
2758
2771
crypt_failure_packet (
@@ -2906,4 +2919,45 @@ mod tests {
2906
2919
let recipient_onion = RecipientOnionFields :: spontaneous_empty ( ) ;
2907
2920
set_max_path_length ( & mut route_params, & recipient_onion, None , None , 42 ) . unwrap ( ) ;
2908
2921
}
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
+ }
2909
2963
}
0 commit comments