77// You may not use this file except in accordance with one or both of these
88// licenses.
99
10+ use super :: msgs:: OnionErrorPacket ;
1011use crate :: blinded_path:: BlindedHop ;
1112use crate :: crypto:: chacha20:: ChaCha20 ;
1213use crate :: crypto:: streams:: ChaChaReader ;
@@ -869,23 +870,20 @@ fn construct_onion_packet_with_init_noise<HD: Writeable, P: Packet>(
869870 Ok ( P :: new ( onion_keys. first ( ) . unwrap ( ) . ephemeral_pubkey , packet_data, hmac_res) )
870871}
871872
872- /// Encrypts a failure packet. raw_packet can either be a
873- /// msgs::DecodedOnionErrorPacket.encode() result or a msgs::OnionErrorPacket.data element.
874- pub ( super ) fn encrypt_failure_packet (
875- shared_secret : & [ u8 ] , raw_packet : & [ u8 ] ,
876- ) -> msgs:: OnionErrorPacket {
873+ /// Encrypts/decrypts a failure packet.
874+ pub ( super ) fn crypt_failure_packet ( shared_secret : & [ u8 ] , packet : & mut OnionErrorPacket ) {
877875 let ammag = gen_ammag_from_shared_secret ( & shared_secret) ;
876+ process_chacha ( & ammag, & mut packet. data ) ;
877+ }
878878
879- let mut packet_crypted = Vec :: with_capacity ( raw_packet. len ( ) ) ;
880- packet_crypted. resize ( raw_packet. len ( ) , 0 ) ;
881- let mut chacha = ChaCha20 :: new ( & ammag, & [ 0u8 ; 8 ] ) ;
882- chacha. process ( & raw_packet, & mut packet_crypted[ ..] ) ;
883- msgs:: OnionErrorPacket { data : packet_crypted }
879+ pub ( super ) fn process_chacha ( key : & [ u8 ; 32 ] , packet : & mut [ u8 ] ) {
880+ let mut chacha = ChaCha20 :: new ( key, & [ 0u8 ; 8 ] ) ;
881+ chacha. process_in_place ( packet) ;
884882}
885883
886884pub ( super ) fn build_failure_packet (
887885 shared_secret : & [ u8 ] , failure_type : u16 , failure_data : & [ u8 ] ,
888- ) -> msgs :: DecodedOnionErrorPacket {
886+ ) -> OnionErrorPacket {
889887 assert_eq ! ( shared_secret. len( ) , 32 ) ;
890888 assert ! ( failure_data. len( ) <= 256 - 2 ) ;
891889
@@ -909,15 +907,17 @@ pub(super) fn build_failure_packet(
909907 hmac. input ( & packet. encode ( ) [ 32 ..] ) ;
910908 packet. hmac = Hmac :: from_engine ( hmac) . to_byte_array ( ) ;
911909
912- packet
910+ OnionErrorPacket { data : packet. encode ( ) }
913911}
914912
915913#[ cfg( test) ]
916914pub ( super ) fn build_first_hop_failure_packet (
917915 shared_secret : & [ u8 ] , failure_type : u16 , failure_data : & [ u8 ] ,
918916) -> msgs:: OnionErrorPacket {
919- let failure_packet = build_failure_packet ( shared_secret, failure_type, failure_data) ;
920- encrypt_failure_packet ( shared_secret, & failure_packet. encode ( ) [ ..] )
917+ let mut failure_packet = build_failure_packet ( shared_secret, failure_type, failure_data) ;
918+ crypt_failure_packet ( shared_secret, & mut failure_packet) ;
919+
920+ failure_packet
921921}
922922
923923pub ( crate ) struct DecodedOnionFailure {
@@ -931,18 +931,12 @@ pub(crate) struct DecodedOnionFailure {
931931 pub ( crate ) onion_error_data : Option < Vec < u8 > > ,
932932}
933933
934- /// Decrypt the error packet in-place.
935- fn decrypt_onion_error_packet ( packet : & mut Vec < u8 > , shared_secret : SharedSecret ) {
936- let ammag = gen_ammag_from_shared_secret ( shared_secret. as_ref ( ) ) ;
937- let mut chacha = ChaCha20 :: new ( & ammag, & [ 0u8 ; 8 ] ) ;
938- chacha. process_in_place ( packet) ;
939- }
940-
941934/// Process failure we got back from upstream on a payment we sent (implying htlc_source is an
942935/// OutboundRoute).
943936#[ inline]
944937pub ( super ) fn process_onion_failure < T : secp256k1:: Signing , L : Deref > (
945- secp_ctx : & Secp256k1 < T > , logger : & L , htlc_source : & HTLCSource , mut encrypted_packet : Vec < u8 > ,
938+ secp_ctx : & Secp256k1 < T > , logger : & L , htlc_source : & HTLCSource ,
939+ mut encrypted_packet : OnionErrorPacket ,
946940) -> DecodedOnionFailure
947941where
948942 L :: Target : Logger ,
@@ -975,7 +969,11 @@ where
975969 const UPDATE : u16 = 0x1000 ;
976970
977971 // Handle packed channel/node updates for passing back for the route handler
978- let callback = |shared_secret, _, _, route_hop_opt : Option < & RouteHop > , route_hop_idx| {
972+ let callback = |shared_secret : SharedSecret ,
973+ _,
974+ _,
975+ route_hop_opt : Option < & RouteHop > ,
976+ route_hop_idx| {
979977 if res. is_some ( ) {
980978 return ;
981979 }
@@ -1017,9 +1015,9 @@ where
10171015 {
10181016 // Actually parse the onion error data in tests so we can check that blinded hops fail
10191017 // back correctly.
1020- decrypt_onion_error_packet ( & mut encrypted_packet, shared_secret ) ;
1018+ crypt_failure_packet ( shared_secret . as_ref ( ) , & mut encrypted_packet) ;
10211019 let err_packet = msgs:: DecodedOnionErrorPacket :: read ( & mut Cursor :: new (
1022- & encrypted_packet,
1020+ & encrypted_packet. data ,
10231021 ) )
10241022 . unwrap ( ) ;
10251023 error_code_ret = Some ( u16:: from_be_bytes (
@@ -1042,18 +1040,18 @@ where
10421040 let amt_to_forward = htlc_msat - route_hop. fee_msat ;
10431041 htlc_msat = amt_to_forward;
10441042
1045- decrypt_onion_error_packet ( & mut encrypted_packet, shared_secret ) ;
1043+ crypt_failure_packet ( shared_secret . as_ref ( ) , & mut encrypted_packet) ;
10461044
10471045 let um = gen_um_from_shared_secret ( shared_secret. as_ref ( ) ) ;
10481046 let mut hmac = HmacEngine :: < Sha256 > :: new ( & um) ;
1049- hmac. input ( & encrypted_packet[ 32 ..] ) ;
1047+ hmac. input ( & encrypted_packet. data [ 32 ..] ) ;
10501048
1051- if !fixed_time_eq ( & Hmac :: from_engine ( hmac) . to_byte_array ( ) , & encrypted_packet[ ..32 ] ) {
1049+ if !fixed_time_eq ( & Hmac :: from_engine ( hmac) . to_byte_array ( ) , & encrypted_packet. data [ ..32 ] ) {
10521050 return ;
10531051 }
10541052
10551053 let err_packet =
1056- match msgs:: DecodedOnionErrorPacket :: read ( & mut Cursor :: new ( & encrypted_packet) ) {
1054+ match msgs:: DecodedOnionErrorPacket :: read ( & mut Cursor :: new ( & encrypted_packet. data ) ) {
10571055 Ok ( p) => p,
10581056 Err ( _) => {
10591057 log_warn ! ( logger, "Unreadable failure from {}" , route_hop. pubkey) ;
@@ -1366,27 +1364,30 @@ impl HTLCFailReason {
13661364 match self . 0 {
13671365 HTLCFailReasonRepr :: Reason { ref failure_code, ref data } => {
13681366 if let Some ( secondary_shared_secret) = secondary_shared_secret {
1369- let inner_packet =
1370- build_failure_packet ( secondary_shared_secret, * failure_code, & data[ ..] )
1371- . encode ( ) ;
1372- let encrypted_inner_packet =
1373- encrypt_failure_packet ( secondary_shared_secret, & inner_packet) ;
1374- encrypt_failure_packet (
1375- incoming_packet_shared_secret,
1376- & encrypted_inner_packet. data [ ..] ,
1377- )
1367+ let mut packet =
1368+ build_failure_packet ( secondary_shared_secret, * failure_code, & data[ ..] ) ;
1369+
1370+ crypt_failure_packet ( secondary_shared_secret, & mut packet) ;
1371+ crypt_failure_packet ( incoming_packet_shared_secret, & mut packet) ;
1372+
1373+ packet
13781374 } else {
1379- let packet = build_failure_packet (
1375+ let mut packet = build_failure_packet (
13801376 incoming_packet_shared_secret,
13811377 * failure_code,
13821378 & data[ ..] ,
1383- )
1384- . encode ( ) ;
1385- encrypt_failure_packet ( incoming_packet_shared_secret, & packet)
1379+ ) ;
1380+ crypt_failure_packet ( incoming_packet_shared_secret, & mut packet) ;
1381+
1382+ packet
13861383 }
13871384 } ,
13881385 HTLCFailReasonRepr :: LightningError { ref err } => {
1389- encrypt_failure_packet ( incoming_packet_shared_secret, & err. data )
1386+ let mut err = err. clone ( ) ;
1387+
1388+ crypt_failure_packet ( incoming_packet_shared_secret, & mut err) ;
1389+
1390+ err
13901391 } ,
13911392 }
13921393 }
@@ -1399,7 +1400,7 @@ impl HTLCFailReason {
13991400 {
14001401 match self . 0 {
14011402 HTLCFailReasonRepr :: LightningError { ref err } => {
1402- process_onion_failure ( secp_ctx, logger, & htlc_source, err. data . clone ( ) )
1403+ process_onion_failure ( secp_ctx, logger, & htlc_source, err. clone ( ) )
14031404 } ,
14041405 #[ allow( unused) ]
14051406 HTLCFailReasonRepr :: Reason { ref failure_code, ref data, .. } => {
@@ -2287,45 +2288,30 @@ mod tests {
22872288 // Returning Errors test vectors from BOLT 4
22882289
22892290 let onion_keys = build_test_onion_keys ( ) ;
2290- let onion_error =
2291+ let mut onion_error =
22912292 super :: build_failure_packet ( onion_keys[ 4 ] . shared_secret . as_ref ( ) , 0x2002 , & [ 0 ; 0 ] ) ;
22922293 let hex = "4c2fc8bc08510334b6833ad9c3e79cd1b52ae59dfe5c2a4b23ead50f09f7ee0b0002200200fe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ;
2293- assert_eq ! ( onion_error. encode ( ) , <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
2294+ assert_eq ! ( onion_error. data , <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
22942295
2295- let onion_packet_1 = super :: encrypt_failure_packet (
2296- onion_keys[ 4 ] . shared_secret . as_ref ( ) ,
2297- & onion_error. encode ( ) [ ..] ,
2298- ) ;
2296+ super :: crypt_failure_packet ( onion_keys[ 4 ] . shared_secret . as_ref ( ) , & mut onion_error) ;
22992297 let hex = "a5e6bd0c74cb347f10cce367f949098f2457d14c046fd8a22cb96efb30b0fdcda8cb9168b50f2fd45edd73c1b0c8b33002df376801ff58aaa94000bf8a86f92620f343baef38a580102395ae3abf9128d1047a0736ff9b83d456740ebbb4aeb3aa9737f18fb4afb4aa074fb26c4d702f42968888550a3bded8c05247e045b866baef0499f079fdaeef6538f31d44deafffdfd3afa2fb4ca9082b8f1c465371a9894dd8c243fb4847e004f5256b3e90e2edde4c9fb3082ddfe4d1e734cacd96ef0706bf63c9984e22dc98851bcccd1c3494351feb458c9c6af41c0044bea3c47552b1d992ae542b17a2d0bba1a096c78d169034ecb55b6e3a7263c26017f033031228833c1daefc0dedb8cf7c3e37c9c37ebfe42f3225c326e8bcfd338804c145b16e34e4" ;
2300- assert_eq ! ( onion_packet_1 . data, <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
2298+ assert_eq ! ( onion_error . data, <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
23012299
2302- let onion_packet_2 = super :: encrypt_failure_packet (
2303- onion_keys[ 3 ] . shared_secret . as_ref ( ) ,
2304- & onion_packet_1. data [ ..] ,
2305- ) ;
2300+ super :: crypt_failure_packet ( onion_keys[ 3 ] . shared_secret . as_ref ( ) , & mut onion_error) ;
23062301 let hex = "c49a1ce81680f78f5f2000cda36268de34a3f0a0662f55b4e837c83a8773c22aa081bab1616a0011585323930fa5b9fae0c85770a2279ff59ec427ad1bbff9001c0cd1497004bd2a0f68b50704cf6d6a4bf3c8b6a0833399a24b3456961ba00736785112594f65b6b2d44d9f5ea4e49b5e1ec2af978cbe31c67114440ac51a62081df0ed46d4a3df295da0b0fe25c0115019f03f15ec86fabb4c852f83449e812f141a9395b3f70b766ebbd4ec2fae2b6955bd8f32684c15abfe8fd3a6261e52650e8807a92158d9f1463261a925e4bfba44bd20b166d532f0017185c3a6ac7957adefe45559e3072c8dc35abeba835a8cb01a71a15c736911126f27d46a36168ca5ef7dccd4e2886212602b181463e0dd30185c96348f9743a02aca8ec27c0b90dca270" ;
2307- assert_eq ! ( onion_packet_2 . data, <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
2302+ assert_eq ! ( onion_error . data, <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
23082303
2309- let onion_packet_3 = super :: encrypt_failure_packet (
2310- onion_keys[ 2 ] . shared_secret . as_ref ( ) ,
2311- & onion_packet_2. data [ ..] ,
2312- ) ;
2304+ super :: crypt_failure_packet ( onion_keys[ 2 ] . shared_secret . as_ref ( ) , & mut onion_error) ;
23132305 let hex = "a5d3e8634cfe78b2307d87c6d90be6fe7855b4f2cc9b1dfb19e92e4b79103f61ff9ac25f412ddfb7466e74f81b3e545563cdd8f5524dae873de61d7bdfccd496af2584930d2b566b4f8d3881f8c043df92224f38cf094cfc09d92655989531524593ec6d6caec1863bdfaa79229b5020acc034cd6deeea1021c50586947b9b8e6faa83b81fbfa6133c0af5d6b07c017f7158fa94f0d206baf12dda6b68f785b773b360fd0497e16cc402d779c8d48d0fa6315536ef0660f3f4e1865f5b38ea49c7da4fd959de4e83ff3ab686f059a45c65ba2af4a6a79166aa0f496bf04d06987b6d2ea205bdb0d347718b9aeff5b61dfff344993a275b79717cd815b6ad4c0beb568c4ac9c36ff1c315ec1119a1993c4b61e6eaa0375e0aaf738ac691abd3263bf937e3" ;
2314- assert_eq ! ( onion_packet_3 . data, <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
2306+ assert_eq ! ( onion_error . data, <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
23152307
2316- let onion_packet_4 = super :: encrypt_failure_packet (
2317- onion_keys[ 1 ] . shared_secret . as_ref ( ) ,
2318- & onion_packet_3. data [ ..] ,
2319- ) ;
2308+ super :: crypt_failure_packet ( onion_keys[ 1 ] . shared_secret . as_ref ( ) , & mut onion_error) ;
23202309 let hex = "aac3200c4968f56b21f53e5e374e3a2383ad2b1b6501bbcc45abc31e59b26881b7dfadbb56ec8dae8857add94e6702fb4c3a4de22e2e669e1ed926b04447fc73034bb730f4932acd62727b75348a648a1128744657ca6a4e713b9b646c3ca66cac02cdab44dd3439890ef3aaf61708714f7375349b8da541b2548d452d84de7084bb95b3ac2345201d624d31f4d52078aa0fa05a88b4e20202bd2b86ac5b52919ea305a8949de95e935eed0319cf3cf19ebea61d76ba92532497fcdc9411d06bcd4275094d0a4a3c5d3a945e43305a5a9256e333e1f64dbca5fcd4e03a39b9012d197506e06f29339dfee3331995b21615337ae060233d39befea925cc262873e0530408e6990f1cbd233a150ef7b004ff6166c70c68d9f8c853c1abca640b8660db2921" ;
2321- assert_eq ! ( onion_packet_4 . data, <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
2310+ assert_eq ! ( onion_error . data, <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
23222311
2323- let onion_packet_5 = super :: encrypt_failure_packet (
2324- onion_keys[ 0 ] . shared_secret . as_ref ( ) ,
2325- & onion_packet_4. data [ ..] ,
2326- ) ;
2312+ super :: crypt_failure_packet ( onion_keys[ 0 ] . shared_secret . as_ref ( ) , & mut onion_error) ;
23272313 let hex = "9c5add3963fc7f6ed7f148623c84134b5647e1306419dbe2174e523fa9e2fbed3a06a19f899145610741c83ad40b7712aefaddec8c6baf7325d92ea4ca4d1df8bce517f7e54554608bf2bd8071a4f52a7a2f7ffbb1413edad81eeea5785aa9d990f2865dc23b4bc3c301a94eec4eabebca66be5cf638f693ec256aec514620cc28ee4a94bd9565bc4d4962b9d3641d4278fb319ed2b84de5b665f307a2db0f7fbb757366067d88c50f7e829138fde4f78d39b5b5802f1b92a8a820865af5cc79f9f30bc3f461c66af95d13e5e1f0381c184572a91dee1c849048a647a1158cf884064deddbf1b0b88dfe2f791428d0ba0f6fb2f04e14081f69165ae66d9297c118f0907705c9c4954a199bae0bb96fad763d690e7daa6cfda59ba7f2c8d11448b604d12d" ;
2328- assert_eq ! ( onion_packet_5 . data, <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
2314+ assert_eq ! ( onion_error . data, <Vec <u8 >>:: from_hex( hex) . unwrap( ) ) ;
23292315
23302316 let logger: Arc < TestLogger > = Arc :: new ( TestLogger :: new ( ) ) ;
23312317 let ctx_full = Secp256k1 :: new ( ) ;
@@ -2339,7 +2325,7 @@ mod tests {
23392325
23402326 // Assert that the original failure can be retrieved and that all hmacs check out.
23412327 let decrypted_failure =
2342- process_onion_failure ( & ctx_full, & logger, & htlc_source, onion_packet_5 . data ) ;
2328+ process_onion_failure ( & ctx_full, & logger, & htlc_source, onion_error ) ;
23432329
23442330 assert_eq ! ( decrypted_failure. onion_error_code, Some ( 0x2002 ) ) ;
23452331 }
@@ -2348,10 +2334,11 @@ mod tests {
23482334 fn test_non_attributable_failure_packet_onion ( ) {
23492335 // Create a failure packet with bogus data.
23502336 let packet = vec ! [ 1u8 ; 292 ] ;
2337+ let onion_error_packet = OnionErrorPacket { data : packet } ;
23512338
23522339 // In the current protocol, it is unfortunately not possible to identify the failure source.
23532340 let logger: TestLogger = TestLogger :: new ( ) ;
2354- let decrypted_failure = test_failure_attribution ( & logger, & packet ) ;
2341+ let decrypted_failure = test_failure_attribution ( & logger, onion_error_packet ) ;
23552342 assert_eq ! ( decrypted_failure. short_channel_id, None ) ;
23562343
23572344 logger. assert_log_contains (
@@ -2376,11 +2363,12 @@ mod tests {
23762363 let hmac = Hmac :: from_engine ( hmac) . to_byte_array ( ) ;
23772364 packet[ ..32 ] . copy_from_slice ( & hmac) ;
23782365
2379- let packet = encrypt_failure_packet ( shared_secret, & packet) ;
2366+ let mut onion_error_packet = OnionErrorPacket { data : packet. to_vec ( ) } ;
2367+ crypt_failure_packet ( shared_secret, & mut onion_error_packet) ;
23802368
23812369 // For the unreadable failure, it is still expected that the failing channel can be identified.
23822370 let logger: TestLogger = TestLogger :: new ( ) ;
2383- let decrypted_failure = test_failure_attribution ( & logger, & packet . data ) ;
2371+ let decrypted_failure = test_failure_attribution ( & logger, onion_error_packet ) ;
23842372 assert_eq ! ( decrypted_failure. short_channel_id, Some ( 0 ) ) ;
23852373
23862374 logger. assert_log_contains ( "lightning::ln::onion_utils" , "Unreadable failure" , 1 ) ;
@@ -2401,10 +2389,11 @@ mod tests {
24012389 hmac. input ( & packet. encode ( ) [ 32 ..] ) ;
24022390 packet. hmac = Hmac :: from_engine ( hmac) . to_byte_array ( ) ;
24032391
2404- let packet = encrypt_failure_packet ( shared_secret, & packet. encode ( ) [ ..] ) ;
2392+ let mut onion_error_packet = OnionErrorPacket { data : packet. encode ( ) } ;
2393+ crypt_failure_packet ( shared_secret, & mut onion_error_packet) ;
24052394
24062395 let logger = TestLogger :: new ( ) ;
2407- let decrypted_failure = test_failure_attribution ( & logger, & packet . data ) ;
2396+ let decrypted_failure = test_failure_attribution ( & logger, onion_error_packet ) ;
24082397 assert_eq ! ( decrypted_failure. short_channel_id, Some ( 0 ) ) ;
24092398
24102399 logger. assert_log_contains (
@@ -2414,7 +2403,9 @@ mod tests {
24142403 ) ;
24152404 }
24162405
2417- fn test_failure_attribution ( logger : & TestLogger , packet : & [ u8 ] ) -> DecodedOnionFailure {
2406+ fn test_failure_attribution (
2407+ logger : & TestLogger , packet : OnionErrorPacket ,
2408+ ) -> DecodedOnionFailure {
24182409 let ctx_full = Secp256k1 :: new ( ) ;
24192410 let path = build_test_path ( ) ;
24202411 let htlc_source = HTLCSource :: OutboundRoute {
@@ -2424,8 +2415,7 @@ mod tests {
24242415 payment_id : PaymentId ( [ 1 ; 32 ] ) ,
24252416 } ;
24262417
2427- let decrypted_failure =
2428- process_onion_failure ( & ctx_full, & logger, & htlc_source, packet. into ( ) ) ;
2418+ let decrypted_failure = process_onion_failure ( & ctx_full, & logger, & htlc_source, packet) ;
24292419
24302420 decrypted_failure
24312421 }
0 commit comments