@@ -22,7 +22,9 @@ use crate::types::features::{ChannelFeatures, NodeFeatures};
2222use crate :: types:: payment:: { PaymentHash , PaymentPreimage } ;
2323use crate :: util:: errors:: { self , APIError } ;
2424use crate :: util:: logger:: Logger ;
25- use crate :: util:: ser:: { LengthCalculatingWriter , Readable , ReadableArgs , Writeable , Writer } ;
25+ use crate :: util:: ser:: {
26+ LengthCalculatingWriter , Readable , ReadableArgs , VecWriter , Writeable , Writer ,
27+ } ;
2628
2729use bitcoin:: hashes:: cmp:: fixed_time_eq;
2830use bitcoin:: hashes:: hmac:: { Hmac , HmacEngine } ;
@@ -892,27 +894,36 @@ fn build_unencrypted_failure_packet(
892894 assert_eq ! ( shared_secret. len( ) , 32 ) ;
893895 assert ! ( failure_data. len( ) <= 256 - 2 ) ;
894896
895- let um = gen_um_from_shared_secret ( & shared_secret) ;
897+ // Failure len is 2 bytes type plus the data.
898+ let failure_len = 2 + failure_data. len ( ) ;
896899
897- let failuremsg = {
898- let mut res = Vec :: with_capacity ( 2 + failure_data. len ( ) ) ;
899- res. push ( ( ( failure_type >> 8 ) & 0xff ) as u8 ) ;
900- res. push ( ( ( failure_type >> 0 ) & 0xff ) as u8 ) ;
901- res. extend_from_slice ( & failure_data[ ..] ) ;
902- res
903- } ;
904- let pad = {
905- let mut res = Vec :: with_capacity ( 256 - 2 - failure_data. len ( ) ) ;
906- res. resize ( 256 - 2 - failure_data. len ( ) , 0 ) ;
907- res
908- } ;
909- let mut packet = msgs:: DecodedOnionErrorPacket { hmac : [ 0 ; 32 ] , failuremsg, pad } ;
900+ let pad_len = 256 - failure_len;
901+
902+ // Total len is a 32 bytes HMAC, 2 bytes failure len, failure, 2 bytes pad len and pad.
903+ let total_len = 32 + 2 + failure_len + 2 + pad_len;
910904
905+ let mut writer = VecWriter ( Vec :: with_capacity ( total_len) ) ;
906+
907+ // Reserve space for the HMAC.
908+ writer. 0 . extend_from_slice ( & [ 0 ; 32 ] ) ;
909+
910+ // Write failure len, type and data.
911+ ( failure_len as u16 ) . write ( & mut writer) . unwrap ( ) ;
912+ failure_type. write ( & mut writer) . unwrap ( ) ;
913+ writer. 0 . extend_from_slice ( & failure_data[ ..] ) ;
914+
915+ // Write pad len and resize to match padding.
916+ ( pad_len as u16 ) . write ( & mut writer) . unwrap ( ) ;
917+ writer. 0 . resize ( total_len, 0 ) ;
918+
919+ // Calculate and store HMAC.
920+ let um = gen_um_from_shared_secret ( & shared_secret) ;
911921 let mut hmac = HmacEngine :: < Sha256 > :: new ( & um) ;
912- hmac. input ( & packet. encode ( ) [ 32 ..] ) ;
913- packet. hmac = Hmac :: from_engine ( hmac) . to_byte_array ( ) ;
922+ hmac. input ( & writer. 0 [ 32 ..] ) ;
923+ let hmac = Hmac :: from_engine ( hmac) . to_byte_array ( ) ;
924+ writer. 0 [ ..32 ] . copy_from_slice ( & hmac) ;
914925
915- OnionErrorPacket { data : packet . encode ( ) , attribution_data : None }
926+ OnionErrorPacket { data : writer . 0 , attribution_data : None }
916927}
917928
918929pub ( super ) fn build_failure_packet (
0 commit comments