@@ -1709,18 +1709,19 @@ fn decode_next_hop<T, R: ReadableArgs<T>, N: NextPacketBytes>(
1709
1709
1710
1710
1711
1711
const PAYLOAD_LEN : usize = 4 ;
1712
+ const FULL_PAYLOAD_LEN : usize = PAYLOAD_LEN + 1 ;
1712
1713
const MAX_HOPS : usize = 20 ;
1713
1714
const HMAC_LEN : usize = 4 ;
1715
+ const HMAC_COUNT : usize = MAX_HOPS * ( MAX_HOPS + 1 ) / 2 ;
1714
1716
1715
1717
// Adds the current node's hmacs for all possible positions to this packet.
1716
1718
fn add_hmacs ( shared_secret : & [ u8 ] , packet : & mut [ u8 ] ) {
1717
- let full_payload_len = PAYLOAD_LEN + 1 ; // Including the marker byte.
1718
1719
let packet_len = packet. len ( ) ;
1719
- let hmac_count = MAX_HOPS * ( MAX_HOPS + 1 ) / 2 ;
1720
1720
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 ..] ;
1724
1725
1725
1726
let mut new_hmacs = vec ! [ 0u8 ; MAX_HOPS * HMAC_LEN ] ;
1726
1727
let um = gen_um_from_shared_secret ( & shared_secret) ;
@@ -1730,7 +1731,7 @@ fn add_hmacs(shared_secret: &[u8], packet: &mut [u8]) {
1730
1731
let mut hmac_engine = HmacEngine :: < Sha256 > :: new ( & um) ;
1731
1732
1732
1733
hmac_engine. input ( & message) ;
1733
- hmac_engine. input ( & payloads[ ..( position + 1 ) * full_payload_len ] ) ;
1734
+ hmac_engine. input ( & payloads[ ..( position + 1 ) * FULL_PAYLOAD_LEN ] ) ;
1734
1735
write_downstream_hmacs ( position, MAX_HOPS , hmacs, & mut hmac_engine) ;
1735
1736
1736
1737
let full_hmac = Hmac :: from_engine ( hmac_engine) . to_byte_array ( ) ;
@@ -1739,7 +1740,7 @@ fn add_hmacs(shared_secret: &[u8], packet: &mut [u8]) {
1739
1740
new_hmacs[ i * HMAC_LEN ..( i + 1 ) * HMAC_LEN ] . copy_from_slice ( hmac) ;
1740
1741
}
1741
1742
1742
- let processed_hmacs = & mut packet[ packet_len - hmac_count * HMAC_LEN ..] ;
1743
+ let processed_hmacs = & mut packet[ packet_len - HMAC_COUNT * HMAC_LEN ..] ;
1743
1744
processed_hmacs[ ..new_hmacs. len ( ) ] . copy_from_slice ( & new_hmacs) ;
1744
1745
}
1745
1746
@@ -1759,6 +1760,62 @@ pub fn write_downstream_hmacs(
1759
1760
}
1760
1761
}
1761
1762
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
+
1762
1819
#[ cfg( test) ]
1763
1820
mod tests {
1764
1821
use core:: array;
@@ -2138,6 +2195,11 @@ use crate::io;
2138
2195
let encrypted_packet = super :: encrypt_failure_packet ( onion_keys[ 4 ] . shared_secret . as_ref ( ) , packet_slice) ;
2139
2196
assert_eq ! ( encrypted_packet. data. to_lower_hex_string( ) , EXPECTED_MESSAGES [ 0 ] ) ;
2140
2197
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 ] ) ;
2141
2203
2142
2204
// let onion_packet_1 = super::encrypt_failure_packet(
2143
2205
// onion_keys[4].shared_secret.as_ref(),
0 commit comments