@@ -89,6 +89,14 @@ pub(super) fn gen_ammag_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] {
89
89
Hmac :: from_engine ( hmac) . to_byte_array ( )
90
90
}
91
91
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
+
92
100
#[ cfg( test) ]
93
101
#[ inline]
94
102
pub ( 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>(
875
883
/// Encrypts a failure packet. raw_packet can either be a
876
884
/// msgs::DecodedOnionErrorPacket.encode() result or a msgs::OnionErrorPacket.data element.
877
885
pub ( 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
+ ) {
881
888
let ammag = gen_ammag_from_shared_secret ( & shared_secret) ;
889
+ process_chacha ( & ammag, & mut packet. data ) ;
882
890
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
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
+ }
896
+
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) ;
888
900
}
889
901
890
902
pub ( super ) fn build_failure_packet (
@@ -938,8 +950,10 @@ pub(super) fn build_first_hop_failure_packet(
938
950
shared_secret : & [ u8 ] , failure_type : u16 , failure_data : & [ u8 ] ,
939
951
) -> msgs:: OnionErrorPacket {
940
952
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
943
957
}
944
958
945
959
pub ( crate ) struct DecodedOnionFailure {
@@ -956,12 +970,12 @@ pub(crate) struct DecodedOnionFailure {
956
970
/// Note that we always decrypt `packet` in-place here even if the deserialization into
957
971
/// [`msgs::DecodedOnionErrorPacket`] ultimately fails.
958
972
fn decrypt_onion_error_packet (
959
- packet : & mut Vec < u8 > , shared_secret : SharedSecret ,
973
+ packet : & mut OnionErrorPacket , shared_secret : SharedSecret ,
960
974
) -> 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 ) )
965
979
}
966
980
967
981
/// Process failure we got back from upstream on a payment we sent (implying htlc_source is an
@@ -1048,7 +1062,7 @@ where
1048
1062
// Actually parse the onion error data in tests so we can check that blinded hops fail
1049
1063
// back correctly.
1050
1064
let err_packet =
1051
- decrypt_onion_error_packet ( & mut encrypted_packet. data , shared_secret)
1065
+ decrypt_onion_error_packet ( & mut encrypted_packet, shared_secret)
1052
1066
. unwrap ( ) ;
1053
1067
error_code_ret = Some ( u16:: from_be_bytes (
1054
1068
err_packet. failuremsg . get ( 0 ..2 ) . unwrap ( ) . try_into ( ) . unwrap ( ) ,
@@ -1070,7 +1084,7 @@ where
1070
1084
let amt_to_forward = htlc_msat - route_hop. fee_msat ;
1071
1085
htlc_msat = amt_to_forward;
1072
1086
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) ;
1074
1088
1075
1089
let um = gen_um_from_shared_secret ( shared_secret. as_ref ( ) ) ;
1076
1090
@@ -1452,26 +1466,32 @@ impl HTLCFailReason {
1452
1466
HTLCFailReasonRepr :: Reason { ref failure_code, ref data } => {
1453
1467
let payload = [ 1 ; 4 ] ;
1454
1468
if let Some ( phantom_ss) = phantom_shared_secret {
1455
- let phantom_packet =
1469
+ let mut phantom_packet =
1456
1470
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) ;
1459
1472
encrypt_failure_packet (
1460
1473
incoming_packet_shared_secret,
1461
- & encrypted_phantom_packet
1462
- )
1474
+ & mut phantom_packet
1475
+ ) ;
1476
+
1477
+ phantom_packet
1463
1478
} else {
1464
- let packet = build_failure_packet (
1479
+ let mut packet = build_failure_packet (
1465
1480
incoming_packet_shared_secret,
1466
1481
* failure_code,
1467
1482
& data[ ..] ,
1468
1483
& payload
1469
1484
) ;
1470
- encrypt_failure_packet ( incoming_packet_shared_secret, & packet)
1485
+ encrypt_failure_packet ( incoming_packet_shared_secret, & mut packet) ;
1486
+
1487
+ packet
1471
1488
}
1472
1489
} ,
1473
1490
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
1475
1495
} ,
1476
1496
}
1477
1497
}
@@ -2341,12 +2361,9 @@ use crate::util::test_utils::TestLogger;
2341
2361
for mutated_index in 0 ..1060 +920 {
2342
2362
let decrypted_failure = test_attributable_failure_packet_onion_with_mutation ( mutating_node, mutated_index) ;
2343
2363
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( ) ) ;
2349
- }
2364
+ assert ! ( decrypted_failure. onion_error_code == Some ( 16399 ) ||
2365
+ decrypted_failure. short_channel_id == Some ( 4 -mutating_node as u64 ) ) ;
2366
+ }
2350
2367
}
2351
2368
}
2352
2369
@@ -2383,12 +2400,12 @@ use crate::util::test_utils::TestLogger;
2383
2400
let payload = [ 0 , 0 , 0 , 1 ] ;
2384
2401
2385
2402
let onion_keys = build_test_onion_keys ( ) ;
2386
- let onion_error =
2403
+ let mut onion_error =
2387
2404
super :: build_failure_packet ( onion_keys[ 4 ] . shared_secret . as_ref ( ) , 0x400f , & failure_data, & payload) ;
2388
2405
2389
2406
let logger: Arc < TestLogger > = Arc :: new ( TestLogger :: new ( ) ) ;
2390
2407
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) ;
2392
2409
// assert_eq!(encrypted_packet.data.to_lower_hex_string(), EXPECTED_MESSAGES[0]);
2393
2410
2394
2411
let mutate_packet = |packet : & mut OnionErrorPacket , mutated_index| {
@@ -2401,19 +2418,19 @@ use crate::util::test_utils::TestLogger;
2401
2418
} ;
2402
2419
2403
2420
if mutating_node == 0 {
2404
- mutate_packet ( & mut encrypted_packet , mutated_index) ;
2421
+ mutate_packet ( & mut onion_error , mutated_index) ;
2405
2422
}
2406
2423
2407
2424
for idx in 1 ..5 {
2408
2425
2409
2426
let shared_secret = onion_keys[ 4 - idx] . shared_secret . as_ref ( ) ;
2410
2427
2411
2428
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 ) ;
2414
2431
2415
2432
if mutating_node == idx {
2416
- mutate_packet ( & mut encrypted_packet , mutated_index) ;
2433
+ mutate_packet ( & mut onion_error , mutated_index) ;
2417
2434
}
2418
2435
2419
2436
// assert_eq!(encrypted_packet.data.to_lower_hex_string(), EXPECTED_MESSAGES[idx]);
@@ -2432,7 +2449,7 @@ use crate::util::test_utils::TestLogger;
2432
2449
2433
2450
2434
2451
// 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 ) ;
2436
2453
2437
2454
decrypted_failure
2438
2455
0 commit comments