@@ -1709,18 +1709,19 @@ fn decode_next_hop<T, R: ReadableArgs<T>, N: NextPacketBytes>(
17091709
17101710
17111711const PAYLOAD_LEN : usize = 4 ;
1712+ const FULL_PAYLOAD_LEN : usize = PAYLOAD_LEN + 1 ;
17121713const MAX_HOPS : usize = 20 ;
17131714const HMAC_LEN : usize = 4 ;
1715+ const HMAC_COUNT : usize = MAX_HOPS * ( MAX_HOPS + 1 ) / 2 ;
17141716
17151717// Adds the current node's hmacs for all possible positions to this packet.
17161718fn add_hmacs ( shared_secret : & [ u8 ] , packet : & mut [ u8 ] ) {
1717- let full_payload_len = PAYLOAD_LEN + 1 ; // Including the marker byte.
17181719 let packet_len = packet. len ( ) ;
1719- let hmac_count = MAX_HOPS * ( MAX_HOPS + 1 ) / 2 ;
17201720
1721- let message = & packet[ ..packet_len - MAX_HOPS * full_payload_len-hmac_count* HMAC_LEN ] ;
1722- let payloads = & packet[ packet_len - MAX_HOPS * full_payload_len-hmac_count* HMAC_LEN ..packet_len-hmac_count* HMAC_LEN ] ;
1723- let hmacs = & packet[ packet_len - hmac_count* HMAC_LEN ..] ;
1721+ let message = & packet[ ..packet_len - MAX_HOPS * FULL_PAYLOAD_LEN - HMAC_COUNT * HMAC_LEN ] ;
1722+ let payloads = & packet[ packet_len - MAX_HOPS * FULL_PAYLOAD_LEN - HMAC_COUNT * HMAC_LEN
1723+ ..packet_len - HMAC_COUNT * HMAC_LEN ] ;
1724+ let hmacs = & packet[ packet_len - HMAC_COUNT * HMAC_LEN ..] ;
17241725
17251726 let mut new_hmacs = vec ! [ 0u8 ; MAX_HOPS * HMAC_LEN ] ;
17261727 let um = gen_um_from_shared_secret ( & shared_secret) ;
@@ -1730,7 +1731,7 @@ fn add_hmacs(shared_secret: &[u8], packet: &mut [u8]) {
17301731 let mut hmac_engine = HmacEngine :: < Sha256 > :: new ( & um) ;
17311732
17321733 hmac_engine. input ( & message) ;
1733- hmac_engine. input ( & payloads[ ..( position + 1 ) * full_payload_len ] ) ;
1734+ hmac_engine. input ( & payloads[ ..( position + 1 ) * FULL_PAYLOAD_LEN ] ) ;
17341735 write_downstream_hmacs ( position, MAX_HOPS , hmacs, & mut hmac_engine) ;
17351736
17361737 let full_hmac = Hmac :: from_engine ( hmac_engine) . to_byte_array ( ) ;
@@ -1739,7 +1740,7 @@ fn add_hmacs(shared_secret: &[u8], packet: &mut [u8]) {
17391740 new_hmacs[ i * HMAC_LEN ..( i + 1 ) * HMAC_LEN ] . copy_from_slice ( hmac) ;
17401741 }
17411742
1742- let processed_hmacs = & mut packet[ packet_len - hmac_count * HMAC_LEN ..] ;
1743+ let processed_hmacs = & mut packet[ packet_len - HMAC_COUNT * HMAC_LEN ..] ;
17431744 processed_hmacs[ ..new_hmacs. len ( ) ] . copy_from_slice ( & new_hmacs) ;
17441745}
17451746
@@ -1759,6 +1760,62 @@ pub fn write_downstream_hmacs(
17591760 }
17601761}
17611762
1763+
1764+ fn process_failure_packet ( packet : & [ u8 ] , shared_secret : & [ u8 ] , payload : & [ u8 ; 4 ] ) -> Vec < u8 > {
1765+ println ! ( "Failure packet: {}" , log_bytes!( & packet) ) ;
1766+
1767+ // Create new packet.
1768+ let mut processed_packet = vec ! [ 0 ; packet. len( ) ] ;
1769+
1770+ // Copy message.
1771+ let message = & packet[ ..packet. len ( ) - MAX_HOPS * FULL_PAYLOAD_LEN - HMAC_COUNT * HMAC_LEN ] ;
1772+ processed_packet[ ..packet. len ( ) - MAX_HOPS * FULL_PAYLOAD_LEN - HMAC_COUNT * HMAC_LEN ] . copy_from_slice ( message) ;
1773+
1774+ println ! ( "Message: {}" , log_bytes!( & message) ) ;
1775+
1776+ // Shift payloads right.
1777+ {
1778+ let payloads = & packet[ packet. len ( ) - MAX_HOPS * FULL_PAYLOAD_LEN - HMAC_COUNT * HMAC_LEN ..packet. len ( ) -HMAC_COUNT * HMAC_LEN ] ;
1779+ let processed_payloads = & mut processed_packet[ packet. len ( ) - MAX_HOPS * FULL_PAYLOAD_LEN - HMAC_COUNT * HMAC_LEN ..packet. len ( ) -HMAC_COUNT * HMAC_LEN ] ;
1780+ processed_payloads[ FULL_PAYLOAD_LEN ..] . copy_from_slice ( & payloads[ ..payloads. len ( ) -FULL_PAYLOAD_LEN ] ) ;
1781+
1782+ // Add this node's payload.
1783+ processed_payloads[ 1 ..1 +PAYLOAD_LEN ] . copy_from_slice ( payload) ;
1784+ }
1785+
1786+ // Shift hmacs right.
1787+ {
1788+ let hmacs = & packet[ packet. len ( ) - HMAC_COUNT * HMAC_LEN ..] ;
1789+ let processed_hmacs = & mut processed_packet[ packet. len ( ) - HMAC_COUNT * HMAC_LEN ..] ;
1790+
1791+ let mut src_idx = HMAC_COUNT - 2 ;
1792+ let mut dest_idx = HMAC_COUNT - 1 ;
1793+ let mut copy_len = 1 ;
1794+
1795+ for i in 0 ..MAX_HOPS - 1 {
1796+ processed_hmacs[ dest_idx * HMAC_LEN ..( dest_idx + copy_len) * HMAC_LEN ] .
1797+ copy_from_slice ( & hmacs[ src_idx * HMAC_LEN ..( src_idx + copy_len) * HMAC_LEN ] ) ;
1798+
1799+ // Break at last iteration to prevent underflow when updating indices.
1800+ if i == MAX_HOPS - 2 {
1801+ break ;
1802+ }
1803+
1804+ copy_len += 1 ;
1805+ src_idx -= copy_len + 1 ;
1806+ dest_idx -= copy_len;
1807+ }
1808+ }
1809+
1810+ // Add this node's hmacs.
1811+ add_hmacs ( & shared_secret, & mut processed_packet) ;
1812+
1813+ println ! ( "Failure packet post-hmac: {}" , log_bytes!( & processed_packet) ) ;
1814+
1815+ processed_packet
1816+ }
1817+
1818+
17621819#[ cfg( test) ]
17631820mod tests {
17641821 use core:: array;
@@ -2138,6 +2195,11 @@ use crate::io;
21382195 let encrypted_packet = super :: encrypt_failure_packet ( onion_keys[ 4 ] . shared_secret . as_ref ( ) , packet_slice) ;
21392196 assert_eq ! ( encrypted_packet. data. to_lower_hex_string( ) , EXPECTED_MESSAGES [ 0 ] ) ;
21402197
2198+ let payload = [ 0 , 0 , 0 , 2 ] ;
2199+ let encrypted_packet = process_failure_packet ( & encrypted_packet. data , onion_keys[ 3 ] . shared_secret . as_ref ( ) , & payload) ;
2200+ let encrypted_packet = super :: encrypt_failure_packet ( onion_keys[ 3 ] . shared_secret . as_ref ( ) , & encrypted_packet) ;
2201+
2202+ assert_eq ! ( encrypted_packet. data. to_lower_hex_string( ) , EXPECTED_MESSAGES [ 1 ] ) ;
21412203
21422204 // let onion_packet_1 = super::encrypt_failure_packet(
21432205 // onion_keys[4].shared_secret.as_ref(),
0 commit comments