7
7
// You may not use this file except in accordance with one or both of these
8
8
// licenses.
9
9
10
+ use super :: msgs:: OnionErrorPacket ;
10
11
use crate :: blinded_path:: BlindedHop ;
11
12
use crate :: crypto:: chacha20:: ChaCha20 ;
12
13
use crate :: crypto:: streams:: ChaChaReader ;
@@ -869,23 +870,20 @@ fn construct_onion_packet_with_init_noise<HD: Writeable, P: Packet>(
869
870
Ok ( P :: new ( onion_keys. first ( ) . unwrap ( ) . ephemeral_pubkey , packet_data, hmac_res) )
870
871
}
871
872
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 ) {
877
875
let ammag = gen_ammag_from_shared_secret ( & shared_secret) ;
876
+ process_chacha ( & ammag, & mut packet. data ) ;
877
+ }
878
878
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) ;
884
882
}
885
883
886
884
pub ( super ) fn build_failure_packet (
887
885
shared_secret : & [ u8 ] , failure_type : u16 , failure_data : & [ u8 ] ,
888
- ) -> msgs :: DecodedOnionErrorPacket {
886
+ ) -> OnionErrorPacket {
889
887
assert_eq ! ( shared_secret. len( ) , 32 ) ;
890
888
assert ! ( failure_data. len( ) <= 256 - 2 ) ;
891
889
@@ -909,15 +907,17 @@ pub(super) fn build_failure_packet(
909
907
hmac. input ( & packet. encode ( ) [ 32 ..] ) ;
910
908
packet. hmac = Hmac :: from_engine ( hmac) . to_byte_array ( ) ;
911
909
912
- packet
910
+ OnionErrorPacket { data : packet. encode ( ) }
913
911
}
914
912
915
913
#[ cfg( test) ]
916
914
pub ( super ) fn build_first_hop_failure_packet (
917
915
shared_secret : & [ u8 ] , failure_type : u16 , failure_data : & [ u8 ] ,
918
916
) -> 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
921
921
}
922
922
923
923
pub ( crate ) struct DecodedOnionFailure {
@@ -931,18 +931,12 @@ pub(crate) struct DecodedOnionFailure {
931
931
pub ( crate ) onion_error_data : Option < Vec < u8 > > ,
932
932
}
933
933
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
-
941
934
/// Process failure we got back from upstream on a payment we sent (implying htlc_source is an
942
935
/// OutboundRoute).
943
936
#[ inline]
944
937
pub ( 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 ,
946
940
) -> DecodedOnionFailure
947
941
where
948
942
L :: Target : Logger ,
@@ -975,7 +969,11 @@ where
975
969
const UPDATE : u16 = 0x1000 ;
976
970
977
971
// 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| {
979
977
if res. is_some ( ) {
980
978
return ;
981
979
}
@@ -1017,9 +1015,9 @@ where
1017
1015
{
1018
1016
// Actually parse the onion error data in tests so we can check that blinded hops fail
1019
1017
// back correctly.
1020
- decrypt_onion_error_packet ( & mut encrypted_packet, shared_secret ) ;
1018
+ crypt_failure_packet ( shared_secret . as_ref ( ) , & mut encrypted_packet) ;
1021
1019
let err_packet = msgs:: DecodedOnionErrorPacket :: read ( & mut Cursor :: new (
1022
- & encrypted_packet,
1020
+ & encrypted_packet. data ,
1023
1021
) )
1024
1022
. unwrap ( ) ;
1025
1023
error_code_ret = Some ( u16:: from_be_bytes (
@@ -1042,18 +1040,18 @@ where
1042
1040
let amt_to_forward = htlc_msat - route_hop. fee_msat ;
1043
1041
htlc_msat = amt_to_forward;
1044
1042
1045
- decrypt_onion_error_packet ( & mut encrypted_packet, shared_secret ) ;
1043
+ crypt_failure_packet ( shared_secret . as_ref ( ) , & mut encrypted_packet) ;
1046
1044
1047
1045
let um = gen_um_from_shared_secret ( shared_secret. as_ref ( ) ) ;
1048
1046
let mut hmac = HmacEngine :: < Sha256 > :: new ( & um) ;
1049
- hmac. input ( & encrypted_packet[ 32 ..] ) ;
1047
+ hmac. input ( & encrypted_packet. data [ 32 ..] ) ;
1050
1048
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 ] ) {
1052
1050
return ;
1053
1051
}
1054
1052
1055
1053
let err_packet =
1056
- match msgs:: DecodedOnionErrorPacket :: read ( & mut Cursor :: new ( & encrypted_packet) ) {
1054
+ match msgs:: DecodedOnionErrorPacket :: read ( & mut Cursor :: new ( & encrypted_packet. data ) ) {
1057
1055
Ok ( p) => p,
1058
1056
Err ( _) => {
1059
1057
log_warn ! ( logger, "Unreadable failure from {}" , route_hop. pubkey) ;
@@ -1366,27 +1364,30 @@ impl HTLCFailReason {
1366
1364
match self . 0 {
1367
1365
HTLCFailReasonRepr :: Reason { ref failure_code, ref data } => {
1368
1366
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
1378
1374
} else {
1379
- let packet = build_failure_packet (
1375
+ let mut packet = build_failure_packet (
1380
1376
incoming_packet_shared_secret,
1381
1377
* failure_code,
1382
1378
& 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
1386
1383
}
1387
1384
} ,
1388
1385
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
1390
1391
} ,
1391
1392
}
1392
1393
}
@@ -1399,7 +1400,7 @@ impl HTLCFailReason {
1399
1400
{
1400
1401
match self . 0 {
1401
1402
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 ( ) )
1403
1404
} ,
1404
1405
#[ allow( unused) ]
1405
1406
HTLCFailReasonRepr :: Reason { ref failure_code, ref data, .. } => {
@@ -2287,45 +2288,30 @@ mod tests {
2287
2288
// Returning Errors test vectors from BOLT 4
2288
2289
2289
2290
let onion_keys = build_test_onion_keys ( ) ;
2290
- let onion_error =
2291
+ let mut onion_error =
2291
2292
super :: build_failure_packet ( onion_keys[ 4 ] . shared_secret . as_ref ( ) , 0x2002 , & [ 0 ; 0 ] ) ;
2292
2293
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( ) ) ;
2294
2295
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) ;
2299
2297
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( ) ) ;
2301
2299
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) ;
2306
2301
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( ) ) ;
2308
2303
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) ;
2313
2305
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( ) ) ;
2315
2307
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) ;
2320
2309
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( ) ) ;
2322
2311
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) ;
2327
2313
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( ) ) ;
2329
2315
2330
2316
let logger: Arc < TestLogger > = Arc :: new ( TestLogger :: new ( ) ) ;
2331
2317
let ctx_full = Secp256k1 :: new ( ) ;
@@ -2339,7 +2325,7 @@ mod tests {
2339
2325
2340
2326
// Assert that the original failure can be retrieved and that all hmacs check out.
2341
2327
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 ) ;
2343
2329
2344
2330
assert_eq ! ( decrypted_failure. onion_error_code, Some ( 0x2002 ) ) ;
2345
2331
}
@@ -2348,10 +2334,11 @@ mod tests {
2348
2334
fn test_non_attributable_failure_packet_onion ( ) {
2349
2335
// Create a failure packet with bogus data.
2350
2336
let packet = vec ! [ 1u8 ; 292 ] ;
2337
+ let onion_error_packet = OnionErrorPacket { data : packet } ;
2351
2338
2352
2339
// In the current protocol, it is unfortunately not possible to identify the failure source.
2353
2340
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 ) ;
2355
2342
assert_eq ! ( decrypted_failure. short_channel_id, None ) ;
2356
2343
2357
2344
logger. assert_log_contains (
@@ -2376,11 +2363,12 @@ mod tests {
2376
2363
let hmac = Hmac :: from_engine ( hmac) . to_byte_array ( ) ;
2377
2364
packet[ ..32 ] . copy_from_slice ( & hmac) ;
2378
2365
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) ;
2380
2368
2381
2369
// For the unreadable failure, it is still expected that the failing channel can be identified.
2382
2370
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 ) ;
2384
2372
assert_eq ! ( decrypted_failure. short_channel_id, Some ( 0 ) ) ;
2385
2373
2386
2374
logger. assert_log_contains ( "lightning::ln::onion_utils" , "Unreadable failure" , 1 ) ;
@@ -2401,10 +2389,11 @@ mod tests {
2401
2389
hmac. input ( & packet. encode ( ) [ 32 ..] ) ;
2402
2390
packet. hmac = Hmac :: from_engine ( hmac) . to_byte_array ( ) ;
2403
2391
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) ;
2405
2394
2406
2395
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 ) ;
2408
2397
assert_eq ! ( decrypted_failure. short_channel_id, Some ( 0 ) ) ;
2409
2398
2410
2399
logger. assert_log_contains (
@@ -2414,7 +2403,9 @@ mod tests {
2414
2403
) ;
2415
2404
}
2416
2405
2417
- fn test_failure_attribution ( logger : & TestLogger , packet : & [ u8 ] ) -> DecodedOnionFailure {
2406
+ fn test_failure_attribution (
2407
+ logger : & TestLogger , packet : OnionErrorPacket ,
2408
+ ) -> DecodedOnionFailure {
2418
2409
let ctx_full = Secp256k1 :: new ( ) ;
2419
2410
let path = build_test_path ( ) ;
2420
2411
let htlc_source = HTLCSource :: OutboundRoute {
@@ -2424,8 +2415,7 @@ mod tests {
2424
2415
payment_id : PaymentId ( [ 1 ; 32 ] ) ,
2425
2416
} ;
2426
2417
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) ;
2429
2419
2430
2420
decrypted_failure
2431
2421
}
0 commit comments