@@ -1805,18 +1805,19 @@ fn decode_next_hop<T, R: ReadableArgs<T>, N: NextPacketBytes>(
18051805
18061806
18071807const PAYLOAD_LEN : usize = 4 ;
1808+ const FULL_PAYLOAD_LEN : usize = PAYLOAD_LEN + 1 ;
18081809const MAX_HOPS : usize = 20 ;
18091810const HMAC_LEN : usize = 4 ;
1811+ const HMAC_COUNT : usize = MAX_HOPS * ( MAX_HOPS + 1 ) / 2 ;
18101812
18111813// Adds the current node's hmacs for all possible positions to this packet.
18121814fn add_hmacs ( shared_secret : & [ u8 ] , packet : & mut [ u8 ] ) {
1813- let full_payload_len = PAYLOAD_LEN + 1 ; // Including the marker byte.
18141815 let packet_len = packet. len ( ) ;
1815- let hmac_count = MAX_HOPS * ( MAX_HOPS + 1 ) / 2 ;
18161816
1817- let message = & packet[ ..packet_len - MAX_HOPS * full_payload_len-hmac_count* HMAC_LEN ] ;
1818- let payloads = & packet[ packet_len - MAX_HOPS * full_payload_len-hmac_count* HMAC_LEN ..packet_len-hmac_count* HMAC_LEN ] ;
1819- let hmacs = & packet[ packet_len - hmac_count* HMAC_LEN ..] ;
1817+ let message = & packet[ ..packet_len - MAX_HOPS * FULL_PAYLOAD_LEN - HMAC_COUNT * HMAC_LEN ] ;
1818+ let payloads = & packet[ packet_len - MAX_HOPS * FULL_PAYLOAD_LEN - HMAC_COUNT * HMAC_LEN
1819+ ..packet_len - HMAC_COUNT * HMAC_LEN ] ;
1820+ let hmacs = & packet[ packet_len - HMAC_COUNT * HMAC_LEN ..] ;
18201821
18211822 let mut new_hmacs = vec ! [ 0u8 ; MAX_HOPS * HMAC_LEN ] ;
18221823 let um = gen_um_from_shared_secret ( & shared_secret) ;
@@ -1826,7 +1827,7 @@ fn add_hmacs(shared_secret: &[u8], packet: &mut [u8]) {
18261827 let mut hmac_engine = HmacEngine :: < Sha256 > :: new ( & um) ;
18271828
18281829 hmac_engine. input ( & message) ;
1829- hmac_engine. input ( & payloads[ ..( position + 1 ) * full_payload_len ] ) ;
1830+ hmac_engine. input ( & payloads[ ..( position + 1 ) * FULL_PAYLOAD_LEN ] ) ;
18301831 write_downstream_hmacs ( position, MAX_HOPS , hmacs, & mut hmac_engine) ;
18311832
18321833 let full_hmac = Hmac :: from_engine ( hmac_engine) . to_byte_array ( ) ;
@@ -1835,7 +1836,7 @@ fn add_hmacs(shared_secret: &[u8], packet: &mut [u8]) {
18351836 new_hmacs[ i * HMAC_LEN ..( i + 1 ) * HMAC_LEN ] . copy_from_slice ( hmac) ;
18361837 }
18371838
1838- let processed_hmacs = & mut packet[ packet_len - hmac_count * HMAC_LEN ..] ;
1839+ let processed_hmacs = & mut packet[ packet_len - HMAC_COUNT * HMAC_LEN ..] ;
18391840 processed_hmacs[ ..new_hmacs. len ( ) ] . copy_from_slice ( & new_hmacs) ;
18401841}
18411842
@@ -1855,6 +1856,62 @@ pub fn write_downstream_hmacs(
18551856 }
18561857}
18571858
1859+
1860+ fn process_failure_packet ( packet : & [ u8 ] , shared_secret : & [ u8 ] , payload : & [ u8 ; 4 ] ) -> Vec < u8 > {
1861+ println ! ( "Failure packet: {}" , log_bytes!( & packet) ) ;
1862+
1863+ // Create new packet.
1864+ let mut processed_packet = vec ! [ 0 ; packet. len( ) ] ;
1865+
1866+ // Copy message.
1867+ let message = & packet[ ..packet. len ( ) - MAX_HOPS * FULL_PAYLOAD_LEN - HMAC_COUNT * HMAC_LEN ] ;
1868+ processed_packet[ ..packet. len ( ) - MAX_HOPS * FULL_PAYLOAD_LEN - HMAC_COUNT * HMAC_LEN ] . copy_from_slice ( message) ;
1869+
1870+ println ! ( "Message: {}" , log_bytes!( & message) ) ;
1871+
1872+ // Shift payloads right.
1873+ {
1874+ let payloads = & packet[ packet. len ( ) - MAX_HOPS * FULL_PAYLOAD_LEN - HMAC_COUNT * HMAC_LEN ..packet. len ( ) -HMAC_COUNT * HMAC_LEN ] ;
1875+ let processed_payloads = & mut processed_packet[ packet. len ( ) - MAX_HOPS * FULL_PAYLOAD_LEN - HMAC_COUNT * HMAC_LEN ..packet. len ( ) -HMAC_COUNT * HMAC_LEN ] ;
1876+ processed_payloads[ FULL_PAYLOAD_LEN ..] . copy_from_slice ( & payloads[ ..payloads. len ( ) -FULL_PAYLOAD_LEN ] ) ;
1877+
1878+ // Add this node's payload.
1879+ processed_payloads[ 1 ..1 +PAYLOAD_LEN ] . copy_from_slice ( payload) ;
1880+ }
1881+
1882+ // Shift hmacs right.
1883+ {
1884+ let hmacs = & packet[ packet. len ( ) - HMAC_COUNT * HMAC_LEN ..] ;
1885+ let processed_hmacs = & mut processed_packet[ packet. len ( ) - HMAC_COUNT * HMAC_LEN ..] ;
1886+
1887+ let mut src_idx = HMAC_COUNT - 2 ;
1888+ let mut dest_idx = HMAC_COUNT - 1 ;
1889+ let mut copy_len = 1 ;
1890+
1891+ for i in 0 ..MAX_HOPS - 1 {
1892+ processed_hmacs[ dest_idx * HMAC_LEN ..( dest_idx + copy_len) * HMAC_LEN ] .
1893+ copy_from_slice ( & hmacs[ src_idx * HMAC_LEN ..( src_idx + copy_len) * HMAC_LEN ] ) ;
1894+
1895+ // Break at last iteration to prevent underflow when updating indices.
1896+ if i == MAX_HOPS - 2 {
1897+ break ;
1898+ }
1899+
1900+ copy_len += 1 ;
1901+ src_idx -= copy_len + 1 ;
1902+ dest_idx -= copy_len;
1903+ }
1904+ }
1905+
1906+ // Add this node's hmacs.
1907+ add_hmacs ( & shared_secret, & mut processed_packet) ;
1908+
1909+ println ! ( "Failure packet post-hmac: {}" , log_bytes!( & processed_packet) ) ;
1910+
1911+ processed_packet
1912+ }
1913+
1914+
18581915#[ cfg( test) ]
18591916mod tests {
18601917 use core:: array;
@@ -2234,6 +2291,11 @@ use crate::io;
22342291 let encrypted_packet = super :: encrypt_failure_packet ( onion_keys[ 4 ] . shared_secret . as_ref ( ) , packet_slice) ;
22352292 assert_eq ! ( encrypted_packet. data. to_lower_hex_string( ) , EXPECTED_MESSAGES [ 0 ] ) ;
22362293
2294+ let payload = [ 0 , 0 , 0 , 2 ] ;
2295+ let encrypted_packet = process_failure_packet ( & encrypted_packet. data , onion_keys[ 3 ] . shared_secret . as_ref ( ) , & payload) ;
2296+ let encrypted_packet = super :: encrypt_failure_packet ( onion_keys[ 3 ] . shared_secret . as_ref ( ) , & encrypted_packet) ;
2297+
2298+ assert_eq ! ( encrypted_packet. data. to_lower_hex_string( ) , EXPECTED_MESSAGES [ 1 ] ) ;
22372299
22382300 // let onion_packet_1 = super::encrypt_failure_packet(
22392301 // onion_keys[4].shared_secret.as_ref(),
0 commit comments