@@ -880,10 +880,7 @@ fn crypt_failure_packet(shared_secret: &[u8], packet: &mut OnionErrorPacket) {
880
880
chacha. process_in_place ( & mut packet. data ) ;
881
881
882
882
if let Some ( ref mut attribution_data) = packet. attribution_data {
883
- let ammagext = gen_ammagext_from_shared_secret ( & shared_secret) ;
884
- let mut chacha = ChaCha20 :: new ( & ammagext, & [ 0u8 ; 8 ] ) ;
885
- chacha. process_in_place ( & mut attribution_data. hold_times ) ;
886
- chacha. process_in_place ( & mut attribution_data. hmacs ) ;
883
+ attribution_data. crypt ( shared_secret) ;
887
884
}
888
885
}
889
886
@@ -945,10 +942,7 @@ fn update_attribution_data(
945
942
let attribution_data =
946
943
onion_error_packet. attribution_data . get_or_insert ( AttributionData :: new ( ) ) ;
947
944
948
- let hold_time_bytes: [ u8 ; 4 ] = hold_time. to_be_bytes ( ) ;
949
- attribution_data. hold_times [ ..HOLD_TIME_LEN ] . copy_from_slice ( & hold_time_bytes) ;
950
-
951
- attribution_data. add_hmacs ( shared_secret, & onion_error_packet. data ) ;
945
+ attribution_data. update ( & onion_error_packet. data , shared_secret, hold_time) ;
952
946
}
953
947
954
948
pub ( super ) fn build_failure_packet (
@@ -1214,34 +1208,37 @@ where
1214
1208
// nearby failure, the verified HMACs will include some zero padding data. Failures beyond the last
1215
1209
// attributable hop will not be attributable.
1216
1210
let position = attributable_hop_count - route_hop_idx - 1 ;
1217
- let hold_time = attribution_data. verify (
1211
+ let res = attribution_data. verify (
1218
1212
& encrypted_packet. data ,
1219
1213
shared_secret. as_ref ( ) ,
1220
1214
position,
1221
1215
) ;
1222
- if let Some ( hold_time) = hold_time {
1223
- hop_hold_times. push ( hold_time) ;
1224
-
1225
- log_debug ! (
1226
- logger,
1227
- "Htlc hold time at pos {}: {} ms" ,
1228
- route_hop_idx,
1229
- ( hold_time as u128 ) * HOLD_TIME_UNIT_MILLIS
1230
- ) ;
1216
+ match res {
1217
+ Ok ( hold_time) => {
1218
+ hop_hold_times. push ( hold_time) ;
1219
+
1220
+ log_debug ! (
1221
+ logger,
1222
+ "Htlc hold time at pos {}: {} ms" ,
1223
+ route_hop_idx,
1224
+ ( hold_time as u128 ) * HOLD_TIME_UNIT_MILLIS
1225
+ ) ;
1231
1226
1232
- // Shift attribution data to prepare for processing the next hop.
1233
- attribution_data. shift_left ( ) ;
1234
- } else {
1235
- // Store the failing hop, but continue processing the failure for the remaining hops. During the
1236
- // upgrade period, it may happen that nodes along the way drop attribution data. If the legacy
1237
- // failure is still valid, it should be processed normally.
1238
- attribution_failed_channel = route_hop. short_channel_id ( ) ;
1239
-
1240
- log_debug ! (
1241
- logger,
1242
- "Invalid HMAC in attribution data for node at pos {}" ,
1243
- route_hop_idx
1244
- ) ;
1227
+ // Shift attribution data to prepare for processing the next hop.
1228
+ attribution_data. shift_left ( ) ;
1229
+ } ,
1230
+ Err ( ( ) ) => {
1231
+ // Store the failing hop, but continue processing the failure for the remaining hops. During the
1232
+ // upgrade period, it may happen that nodes along the way drop attribution data. If the legacy
1233
+ // failure is still valid, it should be processed normally.
1234
+ attribution_failed_channel = route_hop. short_channel_id ( ) ;
1235
+
1236
+ log_debug ! (
1237
+ logger,
1238
+ "Invalid failure HMAC in attribution data for node at pos {}" ,
1239
+ route_hop_idx
1240
+ ) ;
1241
+ } ,
1245
1242
}
1246
1243
}
1247
1244
} else {
@@ -2657,6 +2654,14 @@ impl_writeable!(AttributionData, {
2657
2654
} ) ;
2658
2655
2659
2656
impl AttributionData {
2657
+ /// Encrypts or decrypts the attribution data using the provided shared secret.
2658
+ pub ( crate ) fn crypt ( & mut self , shared_secret : & [ u8 ] ) {
2659
+ let ammagext = gen_ammagext_from_shared_secret ( & shared_secret) ;
2660
+ let mut chacha = ChaCha20 :: new ( & ammagext, & [ 0u8 ; 8 ] ) ;
2661
+ chacha. process_in_place ( & mut self . hold_times ) ;
2662
+ chacha. process_in_place ( & mut self . hmacs ) ;
2663
+ }
2664
+
2660
2665
/// Adds the current node's HMACs for all possible positions to this packet.
2661
2666
pub ( crate ) fn add_hmacs ( & mut self , shared_secret : & [ u8 ] , message : & [ u8 ] ) {
2662
2667
let um: [ u8 ; 32 ] = gen_um_from_shared_secret ( & shared_secret) ;
@@ -2705,8 +2710,8 @@ impl AttributionData {
2705
2710
}
2706
2711
2707
2712
/// Verifies the attribution data of a failure packet for the given position in the path. If the HMAC checks out, the
2708
- /// reported hold time is returned. If the HMAC does not match, None is returned.
2709
- fn verify ( & self , message : & Vec < u8 > , shared_secret : & [ u8 ] , position : usize ) -> Option < u32 > {
2713
+ /// reported hold time is returned. If the HMAC does not match, an error is returned.
2714
+ fn verify ( & self , message : & [ u8 ] , shared_secret : & [ u8 ] , position : usize ) -> Result < u32 , ( ) > {
2710
2715
// Calculate the expected HMAC.
2711
2716
let um = gen_um_from_shared_secret ( shared_secret) ;
2712
2717
let mut hmac = HmacEngine :: < Sha256 > :: new ( & um) ;
@@ -2719,13 +2724,13 @@ impl AttributionData {
2719
2724
let hmac_idx = MAX_HOPS - position - 1 ;
2720
2725
let actual_hmac = self . get_hmac ( hmac_idx) ;
2721
2726
if !fixed_time_eq ( expected_hmac, actual_hmac) {
2722
- return None ;
2727
+ return Err ( ( ) ) ;
2723
2728
}
2724
2729
2725
2730
// The HMAC checks out and the hold time can be extracted and returned;
2726
2731
let hold_time: u32 = u32:: from_be_bytes ( self . get_hold_time_bytes ( 0 ) . try_into ( ) . unwrap ( ) ) ;
2727
2732
2728
- Some ( hold_time)
2733
+ Ok ( hold_time)
2729
2734
}
2730
2735
2731
2736
/// Shifts hold times and HMACs to the left, taking into account HMAC pruning. This is the inverse operation of what
@@ -2791,6 +2796,12 @@ impl AttributionData {
2791
2796
fn get_hold_time_bytes ( & self , idx : usize ) -> & [ u8 ] {
2792
2797
& self . hold_times [ idx * HOLD_TIME_LEN ..( idx + 1 ) * HOLD_TIME_LEN ]
2793
2798
}
2799
+
2800
+ fn update ( & mut self , message : & [ u8 ] , shared_secret : & [ u8 ] , hold_time : u32 ) {
2801
+ let hold_time_bytes: [ u8 ; 4 ] = hold_time. to_be_bytes ( ) ;
2802
+ self . hold_times [ ..HOLD_TIME_LEN ] . copy_from_slice ( & hold_time_bytes) ;
2803
+ self . add_hmacs ( shared_secret, message) ;
2804
+ }
2794
2805
}
2795
2806
2796
2807
/// Updates the attribution data for an intermediate node.
0 commit comments