@@ -880,10 +880,7 @@ fn crypt_failure_packet(shared_secret: &[u8], packet: &mut OnionErrorPacket) {
880880 chacha. process_in_place ( & mut packet. data ) ;
881881
882882 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) ;
887884 }
888885}
889886
@@ -945,10 +942,7 @@ fn update_attribution_data(
945942 let attribution_data =
946943 onion_error_packet. attribution_data . get_or_insert ( AttributionData :: new ( ) ) ;
947944
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) ;
952946}
953947
954948pub ( super ) fn build_failure_packet (
@@ -1214,34 +1208,37 @@ where
12141208 // nearby failure, the verified HMACs will include some zero padding data. Failures beyond the last
12151209 // attributable hop will not be attributable.
12161210 let position = attributable_hop_count - route_hop_idx - 1 ;
1217- let hold_time = attribution_data. verify (
1211+ let res = attribution_data. verify (
12181212 & encrypted_packet. data ,
12191213 shared_secret. as_ref ( ) ,
12201214 position,
12211215 ) ;
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+ ) ;
12311226
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+ } ,
12451242 }
12461243 }
12471244 } else {
@@ -2657,6 +2654,14 @@ impl_writeable!(AttributionData, {
26572654} ) ;
26582655
26592656impl 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+
26602665 /// Adds the current node's HMACs for all possible positions to this packet.
26612666 pub ( crate ) fn add_hmacs ( & mut self , shared_secret : & [ u8 ] , message : & [ u8 ] ) {
26622667 let um: [ u8 ; 32 ] = gen_um_from_shared_secret ( & shared_secret) ;
@@ -2705,8 +2710,8 @@ impl AttributionData {
27052710 }
27062711
27072712 /// 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 , ( ) > {
27102715 // Calculate the expected HMAC.
27112716 let um = gen_um_from_shared_secret ( shared_secret) ;
27122717 let mut hmac = HmacEngine :: < Sha256 > :: new ( & um) ;
@@ -2719,13 +2724,13 @@ impl AttributionData {
27192724 let hmac_idx = MAX_HOPS - position - 1 ;
27202725 let actual_hmac = self . get_hmac ( hmac_idx) ;
27212726 if !fixed_time_eq ( expected_hmac, actual_hmac) {
2722- return None ;
2727+ return Err ( ( ) ) ;
27232728 }
27242729
27252730 // The HMAC checks out and the hold time can be extracted and returned;
27262731 let hold_time: u32 = u32:: from_be_bytes ( self . get_hold_time_bytes ( 0 ) . try_into ( ) . unwrap ( ) ) ;
27272732
2728- Some ( hold_time)
2733+ Ok ( hold_time)
27292734 }
27302735
27312736 /// 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 {
27912796 fn get_hold_time_bytes ( & self , idx : usize ) -> & [ u8 ] {
27922797 & self . hold_times [ idx * HOLD_TIME_LEN ..( idx + 1 ) * HOLD_TIME_LEN ]
27932798 }
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+ }
27942805}
27952806
27962807/// Updates the attribution data for an intermediate node.
0 commit comments