@@ -89,6 +89,14 @@ pub(super) fn gen_ammag_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] {
8989 Hmac :: from_engine ( hmac) . to_byte_array ( )
9090}
9191
92+ #[ inline]
93+ pub ( super ) fn gen_ammagext_from_shared_secret ( shared_secret : & [ u8 ] ) -> [ u8 ; 32 ] {
94+ assert_eq ! ( shared_secret. len( ) , 32 ) ;
95+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & [ 0x61 , 0x6d , 0x6d , 0x61 , 0x67 , 0x65 , 0x78 , 0x74 ] ) ; // ammagext
96+ hmac. input ( & shared_secret) ;
97+ Hmac :: from_engine ( hmac) . to_byte_array ( )
98+ }
99+
92100#[ cfg( test) ]
93101#[ inline]
94102pub ( super ) fn gen_pad_from_shared_secret ( shared_secret : & [ u8 ] ) -> [ u8 ; 32 ] {
@@ -875,16 +883,20 @@ fn construct_onion_packet_with_init_noise<HD: Writeable, P: Packet>(
875883/// Encrypts a failure packet. raw_packet can either be a
876884/// msgs::DecodedOnionErrorPacket.encode() result or a msgs::OnionErrorPacket.data element.
877885pub ( super ) fn encrypt_failure_packet (
878- shared_secret : & [ u8 ] , packet : & OnionErrorPacket
879- ) -> msgs:: OnionErrorPacket {
880- let raw_packet = & packet. data ;
886+ shared_secret : & [ u8 ] , packet : & mut OnionErrorPacket
887+ ) {
881888 let ammag = gen_ammag_from_shared_secret ( & shared_secret) ;
889+ process_chacha ( & ammag, & mut packet. data ) ;
890+
891+ if let Some ( ref mut attribution_data) = packet. attribution_data {
892+ let ammagext = gen_ammagext_from_shared_secret ( & shared_secret) ;
893+ process_chacha ( & ammagext, attribution_data) ;
894+ }
895+ }
882896
883- let mut packet_crypted = Vec :: with_capacity ( raw_packet. len ( ) ) ;
884- packet_crypted. resize ( raw_packet. len ( ) , 0 ) ;
885- let mut chacha = ChaCha20 :: new ( & ammag, & [ 0u8 ; 8 ] ) ;
886- chacha. process ( & raw_packet, & mut packet_crypted[ ..] ) ;
887- msgs:: OnionErrorPacket { data : packet_crypted, attribution_data : packet. attribution_data } // TODO: Encrypt attribution_data
897+ pub ( super ) fn process_chacha ( key : & [ u8 ; 32 ] , packet : & mut [ u8 ] ) {
898+ let mut chacha = ChaCha20 :: new ( key, & [ 0u8 ; 8 ] ) ;
899+ chacha. process_in_place ( packet) ;
888900}
889901
890902pub ( super ) fn build_failure_packet (
@@ -938,8 +950,10 @@ pub(super) fn build_first_hop_failure_packet(
938950 shared_secret : & [ u8 ] , failure_type : u16 , failure_data : & [ u8 ] ,
939951) -> msgs:: OnionErrorPacket {
940952 let payload = [ 0 ; 4 ] ;
941- let failure_packet = build_failure_packet ( shared_secret, failure_type, failure_data, & payload) ;
942- encrypt_failure_packet ( shared_secret, & failure_packet)
953+ let mut failure_packet = build_failure_packet ( shared_secret, failure_type, failure_data, & payload) ;
954+ encrypt_failure_packet ( shared_secret, & mut failure_packet) ;
955+
956+ failure_packet
943957}
944958
945959pub ( crate ) struct DecodedOnionFailure {
@@ -956,12 +970,12 @@ pub(crate) struct DecodedOnionFailure {
956970/// Note that we always decrypt `packet` in-place here even if the deserialization into
957971/// [`msgs::DecodedOnionErrorPacket`] ultimately fails.
958972fn decrypt_onion_error_packet (
959- packet : & mut Vec < u8 > , shared_secret : SharedSecret ,
973+ packet : & mut OnionErrorPacket , shared_secret : SharedSecret ,
960974) -> Result < msgs:: DecodedOnionErrorPacket , msgs:: DecodeError > {
961- let ammag = gen_ammag_from_shared_secret ( shared_secret . as_ref ( ) ) ;
962- let mut chacha = ChaCha20 :: new ( & ammag , & [ 0u8 ; 8 ] ) ;
963- chacha . process_in_place ( packet ) ;
964- msgs:: DecodedOnionErrorPacket :: read ( & mut Cursor :: new ( packet) )
975+ // Decrypt the packet.
976+ encrypt_failure_packet ( shared_secret . as_ref ( ) , packet ) ;
977+
978+ msgs:: DecodedOnionErrorPacket :: read ( & mut Cursor :: new ( & packet. data ) )
965979}
966980
967981/// Process failure we got back from upstream on a payment we sent (implying htlc_source is an
@@ -1048,7 +1062,7 @@ where
10481062 // Actually parse the onion error data in tests so we can check that blinded hops fail
10491063 // back correctly.
10501064 let err_packet =
1051- decrypt_onion_error_packet ( & mut encrypted_packet. data , shared_secret)
1065+ decrypt_onion_error_packet ( & mut encrypted_packet, shared_secret)
10521066 . unwrap ( ) ;
10531067 error_code_ret = Some ( u16:: from_be_bytes (
10541068 err_packet. failuremsg . get ( 0 ..2 ) . unwrap ( ) . try_into ( ) . unwrap ( ) ,
@@ -1070,7 +1084,7 @@ where
10701084 let amt_to_forward = htlc_msat - route_hop. fee_msat ;
10711085 htlc_msat = amt_to_forward;
10721086
1073- let decrypt_result = decrypt_onion_error_packet ( & mut encrypted_packet. data , shared_secret) ;
1087+ let decrypt_result = decrypt_onion_error_packet ( & mut encrypted_packet, shared_secret) ;
10741088
10751089 let um = gen_um_from_shared_secret ( shared_secret. as_ref ( ) ) ;
10761090
@@ -1452,26 +1466,32 @@ impl HTLCFailReason {
14521466 HTLCFailReasonRepr :: Reason { ref failure_code, ref data } => {
14531467 let payload = [ 1 ; 4 ] ;
14541468 if let Some ( phantom_ss) = phantom_shared_secret {
1455- let phantom_packet =
1469+ let mut phantom_packet =
14561470 build_failure_packet ( phantom_ss, * failure_code, & data[ ..] , & payload) ;
1457- let encrypted_phantom_packet =
1458- encrypt_failure_packet ( phantom_ss, & phantom_packet) ;
1471+ encrypt_failure_packet ( phantom_ss, & mut phantom_packet) ;
14591472 encrypt_failure_packet (
14601473 incoming_packet_shared_secret,
1461- & encrypted_phantom_packet
1462- )
1474+ & mut phantom_packet
1475+ ) ;
1476+
1477+ phantom_packet
14631478 } else {
1464- let packet = build_failure_packet (
1479+ let mut packet = build_failure_packet (
14651480 incoming_packet_shared_secret,
14661481 * failure_code,
14671482 & data[ ..] ,
14681483 & payload
14691484 ) ;
1470- encrypt_failure_packet ( incoming_packet_shared_secret, & packet)
1485+ encrypt_failure_packet ( incoming_packet_shared_secret, & mut packet) ;
1486+
1487+ packet
14711488 }
14721489 } ,
14731490 HTLCFailReasonRepr :: LightningError { ref err } => {
1474- encrypt_failure_packet ( incoming_packet_shared_secret, & err)
1491+ let mut err = err. clone ( ) ;
1492+ encrypt_failure_packet ( incoming_packet_shared_secret, & mut err) ;
1493+
1494+ err
14751495 } ,
14761496 }
14771497 }
@@ -2341,11 +2361,8 @@ use crate::util::test_utils::TestLogger;
23412361 for mutated_index in 0 ..1060 +920 {
23422362 let decrypted_failure = test_attributable_failure_packet_onion_with_mutation ( mutating_node, mutated_index) ;
23432363
2344- // if let Some(chan_id) = decrypted_failure.short_channel_id {
2345- // println!("Testing mutation {} on node {}: chan failure at {}", mutated_index, mutating_node, chan_id);
2346- // }
2347-
2348- assert ! ( decrypted_failure. onion_error_code == Some ( 16399 ) || decrypted_failure. short_channel_id. is_some( ) ) ;
2364+ assert ! ( decrypted_failure. onion_error_code == Some ( 16399 ) ||
2365+ decrypted_failure. short_channel_id == Some ( 4 -mutating_node as u64 ) ) ;
23492366 }
23502367 }
23512368 }
@@ -2383,12 +2400,12 @@ use crate::util::test_utils::TestLogger;
23832400 let payload = [ 0 , 0 , 0 , 1 ] ;
23842401
23852402 let onion_keys = build_test_onion_keys ( ) ;
2386- let onion_error =
2403+ let mut onion_error =
23872404 super :: build_failure_packet ( onion_keys[ 4 ] . shared_secret . as_ref ( ) , 0x400f , & failure_data, & payload) ;
23882405
23892406 let logger: Arc < TestLogger > = Arc :: new ( TestLogger :: new ( ) ) ;
23902407
2391- let mut encrypted_packet = super :: encrypt_failure_packet ( onion_keys[ 4 ] . shared_secret . as_ref ( ) , & onion_error) ;
2408+ super :: encrypt_failure_packet ( onion_keys[ 4 ] . shared_secret . as_ref ( ) , & mut onion_error) ;
23922409 // assert_eq!(encrypted_packet.data.to_lower_hex_string(), EXPECTED_MESSAGES[0]);
23932410
23942411 let mutate_packet = |packet : & mut OnionErrorPacket , mutated_index| {
@@ -2401,19 +2418,19 @@ use crate::util::test_utils::TestLogger;
24012418 } ;
24022419
24032420 if mutating_node == 0 {
2404- mutate_packet ( & mut encrypted_packet , mutated_index) ;
2421+ mutate_packet ( & mut onion_error , mutated_index) ;
24052422 }
24062423
24072424 for idx in 1 ..5 {
24082425
24092426 let shared_secret = onion_keys[ 4 - idx] . shared_secret . as_ref ( ) ;
24102427
24112428 let payload = [ 0 , 0 , 0 , ( idx + 1 ) as u8 ] ;
2412- process_failure_packet ( & mut encrypted_packet , shared_secret, & payload) ;
2413- encrypted_packet = super :: encrypt_failure_packet ( shared_secret, & encrypted_packet ) ;
2429+ process_failure_packet ( & mut onion_error , shared_secret, & payload) ;
2430+ super :: encrypt_failure_packet ( shared_secret, & mut onion_error ) ;
24142431
24152432 if mutating_node == idx {
2416- mutate_packet ( & mut encrypted_packet , mutated_index) ;
2433+ mutate_packet ( & mut onion_error , mutated_index) ;
24172434 }
24182435
24192436 // assert_eq!(encrypted_packet.data.to_lower_hex_string(), EXPECTED_MESSAGES[idx]);
@@ -2432,7 +2449,7 @@ use crate::util::test_utils::TestLogger;
24322449
24332450
24342451 // Assert that the original failure can be retrieved and that all hmacs check out.
2435- let decrypted_failure = process_onion_failure ( & ctx_full, & logger, & htlc_source, encrypted_packet ) ;
2452+ let decrypted_failure = process_onion_failure ( & ctx_full, & logger, & htlc_source, onion_error ) ;
24362453
24372454 decrypted_failure
24382455
0 commit comments