@@ -640,6 +640,8 @@ pub struct ChannelManager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref,
640
640
our_network_key : SecretKey ,
641
641
our_network_pubkey : PublicKey ,
642
642
643
+ inbound_payments_key : SecretKey ,
644
+
643
645
/// Used to track the last value sent in a node_announcement "timestamp" field. We ensure this
644
646
/// value increases strictly since we don't assume access to a time source.
645
647
last_node_announcement_serial : AtomicUsize ,
@@ -1340,6 +1342,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1340
1342
our_network_pubkey : PublicKey :: from_secret_key ( & secp_ctx, & keys_manager. get_node_secret ( ) ) ,
1341
1343
secp_ctx,
1342
1344
1345
+ inbound_payments_key : SecretKey :: from_slice ( & keys_manager. get_secure_random_bytes ( ) ) . expect ( "broken RNG" ) ,
1346
+
1343
1347
last_node_announcement_serial : AtomicUsize :: new ( 0 ) ,
1344
1348
highest_seen_timestamp : AtomicUsize :: new ( 0 ) ,
1345
1349
@@ -2590,7 +2594,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2590
2594
// Check that an inbound payment's `payment_data` field is sane.
2591
2595
fn verify_inbound_payment_data ( & self , payment_hash : PaymentHash , payment_data : msgs:: FinalOnionHopData ) -> Result < Option < PaymentPreimage > , ( ) > {
2592
2596
let ( iv_bytes, encrypted_metadata_bytes) = payment_data. payment_secret . 0 . split_at ( 16 ) ;
2593
- let mut chacha = ChaCha20 :: new ( & self . our_network_key [ ..] , & iv_bytes[ ..12 ] ) ;
2597
+ let mut chacha = ChaCha20 :: new ( & self . inbound_payments_key [ ..] , & iv_bytes[ ..12 ] ) ;
2594
2598
let mut chacha_bytes = [ 0 ; 16 ] ;
2595
2599
chacha. process_in_place ( & mut chacha_bytes) ;
2596
2600
@@ -2606,9 +2610,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2606
2610
}
2607
2611
2608
2612
let is_user_payment_hash = metadata_bytes[ 0 ] & 1 << 7 != 0 ;
2613
+ let ( user_pmt_hash_key, ldk_pmt_hash_key) = hkdf_extract_expand ( & vec ! [ 0 ] , & self . inbound_payments_key [ ..] ) ;
2609
2614
let mut payment_preimage = None ;
2610
2615
if is_user_payment_hash {
2611
- let mut hmac = HmacEngine :: < Sha256 > :: new ( & self . our_network_key [ .. ] ) ;
2616
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & user_pmt_hash_key ) ;
2612
2617
hmac. input ( & metadata_bytes[ ..] ) ;
2613
2618
hmac. input ( & payment_hash. 0 [ ..] ) ;
2614
2619
if iv_bytes != Hmac :: from_engine ( hmac) . into_inner ( ) . split_at_mut ( 16 ) . 0 {
@@ -2630,7 +2635,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2630
2635
log_trace ! ( self . logger, "Failing HTLC with payment_hash {} due to total_msat {} being less than the minimum amount of {} msat" , log_bytes!( payment_hash. 0 ) , payment_data. total_msat, min_amt_msat) ;
2631
2636
return Err ( ( ) )
2632
2637
}
2633
- let mut hmac = HmacEngine :: < Sha256 > :: new ( & self . our_network_key [ .. ] ) ;
2638
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & ldk_pmt_hash_key ) ;
2634
2639
hmac. input ( & iv_bytes) ;
2635
2640
hmac. input ( & metadata_bytes) ;
2636
2641
let decoded_payment_preimage = Hmac :: from_engine ( hmac) . into_inner ( ) ;
@@ -4626,7 +4631,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4626
4631
let rand_bytes = self . keys_manager . get_secure_random_bytes ( ) ;
4627
4632
let iv_bytes = & rand_bytes[ ..16 ] ;
4628
4633
4629
- let mut hmac = HmacEngine :: < Sha256 > :: new ( & self . our_network_key [ ..] ) ;
4634
+ let ( _, ldk_pmt_hash_key) = hkdf_extract_expand ( & vec ! [ 0 ] , & self . inbound_payments_key [ ..] ) ;
4635
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & ldk_pmt_hash_key) ;
4630
4636
hmac. input ( iv_bytes) ;
4631
4637
hmac. input ( & metadata_bytes) ;
4632
4638
let payment_preimage_bytes = Hmac :: from_engine ( hmac) . into_inner ( ) ;
@@ -4636,7 +4642,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4636
4642
let ( iv_slice, encrypted_metadata_slice) = payment_secret_bytes. split_at_mut ( 16 ) ;
4637
4643
iv_slice. copy_from_slice ( iv_bytes) ;
4638
4644
4639
- let mut chacha = ChaCha20 :: new ( & self . our_network_key [ ..] , & iv_bytes[ ..12 ] ) ;
4645
+ let mut chacha = ChaCha20 :: new ( & self . inbound_payments_key [ ..] , & iv_bytes[ ..12 ] ) ;
4640
4646
let mut chacha_bytes = [ 0 ; 16 ] ;
4641
4647
chacha. process_in_place ( & mut chacha_bytes) ;
4642
4648
@@ -4705,7 +4711,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4705
4711
expiry_slice. copy_from_slice ( & expiry_bytes) ;
4706
4712
}
4707
4713
4708
- let mut hmac = HmacEngine :: < Sha256 > :: new ( & self . our_network_key [ ..] ) ;
4714
+ let ( user_pmt_hash_key, _) = hkdf_extract_expand ( & vec ! [ 0 ] , & self . inbound_payments_key [ ..] ) ;
4715
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & user_pmt_hash_key) ;
4709
4716
hmac. input ( & metadata_bytes) ;
4710
4717
hmac. input ( & payment_hash. 0 ) ;
4711
4718
let hmac_bytes = Hmac :: from_engine ( hmac) . into_inner ( ) ;
@@ -4716,7 +4723,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4716
4723
let ( iv_slice, encrypted_metadata_slice) = payment_secret_bytes. split_at_mut ( 16 ) ;
4717
4724
iv_slice. copy_from_slice ( iv_bytes) ;
4718
4725
4719
- let mut chacha = ChaCha20 :: new ( & self . our_network_key [ ..] , & iv_bytes[ ..12 ] ) ;
4726
+ let mut chacha = ChaCha20 :: new ( & self . inbound_payments_key [ ..] , & iv_bytes[ ..12 ] ) ;
4720
4727
let mut chacha_bytes = [ 0 ; 16 ] ;
4721
4728
chacha. process_in_place ( & mut chacha_bytes) ;
4722
4729
@@ -5796,6 +5803,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable f
5796
5803
}
5797
5804
write_tlv_fields ! ( writer, {
5798
5805
( 1 , pending_outbound_payments_no_retry, required) ,
5806
+ ( 2 , self . inbound_payments_key, required) ,
5799
5807
( 3 , pending_outbound_payments, required) ,
5800
5808
} ) ;
5801
5809
@@ -6089,10 +6097,15 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
6089
6097
// pending_outbound_payments_no_retry is for compatibility with 0.0.101 clients.
6090
6098
let mut pending_outbound_payments_no_retry: Option < HashMap < PaymentId , HashSet < [ u8 ; 32 ] > > > = None ;
6091
6099
let mut pending_outbound_payments = None ;
6100
+ let mut inbound_payments_key = None ;
6092
6101
read_tlv_fields ! ( reader, {
6093
6102
( 1 , pending_outbound_payments_no_retry, option) ,
6103
+ ( 2 , inbound_payments_key, option) ,
6094
6104
( 3 , pending_outbound_payments, option) ,
6095
6105
} ) ;
6106
+ if inbound_payments_key. is_none ( ) {
6107
+ inbound_payments_key = Some ( SecretKey :: from_slice ( & args. keys_manager . get_secure_random_bytes ( ) ) . expect ( "broken RNG" ) ) ;
6108
+ }
6096
6109
if pending_outbound_payments. is_none ( ) && pending_outbound_payments_no_retry. is_none ( ) {
6097
6110
pending_outbound_payments = Some ( pending_outbound_payments_compat) ;
6098
6111
} else if pending_outbound_payments. is_none ( ) {
@@ -6170,6 +6183,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
6170
6183
claimable_htlcs,
6171
6184
pending_msg_events : Vec :: new ( ) ,
6172
6185
} ) ,
6186
+ inbound_payments_key : inbound_payments_key. unwrap ( ) ,
6173
6187
pending_inbound_payments : Mutex :: new ( pending_inbound_payments) ,
6174
6188
pending_outbound_payments : Mutex :: new ( pending_outbound_payments. unwrap ( ) ) ,
6175
6189
@@ -6203,6 +6217,19 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
6203
6217
}
6204
6218
}
6205
6219
6220
+ fn hkdf_extract_expand ( salt : & [ u8 ] , ikm : & [ u8 ] ) -> ( [ u8 ; 32 ] , [ u8 ; 32 ] ) {
6221
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( salt) ;
6222
+ hmac. input ( ikm) ;
6223
+ let prk = Hmac :: from_engine ( hmac) . into_inner ( ) ;
6224
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & prk[ ..] ) ;
6225
+ hmac. input ( & [ 1 ; 1 ] ) ;
6226
+ let t1 = Hmac :: from_engine ( hmac) . into_inner ( ) ;
6227
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & prk[ ..] ) ;
6228
+ hmac. input ( & t1) ;
6229
+ hmac. input ( & [ 2 ; 1 ] ) ;
6230
+ ( t1, Hmac :: from_engine ( hmac) . into_inner ( ) )
6231
+ }
6232
+
6206
6233
#[ cfg( test) ]
6207
6234
mod tests {
6208
6235
use bitcoin:: hashes:: Hash ;
0 commit comments