@@ -643,6 +643,8 @@ pub struct ChannelManager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref,
643
643
our_network_key : SecretKey ,
644
644
our_network_pubkey : PublicKey ,
645
645
646
+ inbound_payment_key : SecretKey ,
647
+
646
648
/// Used to track the last value sent in a node_announcement "timestamp" field. We ensure this
647
649
/// value increases strictly since we don't assume access to a time source.
648
650
last_node_announcement_serial : AtomicUsize ,
@@ -1343,6 +1345,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1343
1345
our_network_pubkey : PublicKey :: from_secret_key ( & secp_ctx, & keys_manager. get_node_secret ( ) ) ,
1344
1346
secp_ctx,
1345
1347
1348
+ inbound_payment_key : keys_manager. get_inbound_payment_secret ( ) ,
1349
+
1346
1350
last_node_announcement_serial : AtomicUsize :: new ( 0 ) ,
1347
1351
highest_seen_timestamp : AtomicUsize :: new ( 0 ) ,
1348
1352
@@ -2594,7 +2598,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2594
2598
// `create_inbound_payment_for_hash` for details on our checks.
2595
2599
fn verify_inbound_payment_data ( & self , payment_hash : PaymentHash , payment_data : msgs:: FinalOnionHopData ) -> Result < Option < PaymentPreimage > , ( ) > {
2596
2600
let ( iv_bytes, encrypted_metadata_bytes) = payment_data. payment_secret . 0 . split_at ( 16 ) ;
2597
- let mut chacha = ChaCha20 :: new ( & self . our_network_key [ ..] , & iv_bytes[ ..12 ] ) ;
2601
+ let mut chacha = ChaCha20 :: new ( & self . inbound_payment_key [ ..] , & iv_bytes[ ..12 ] ) ;
2598
2602
let mut chacha_bytes = [ 0 ; 16 ] ;
2599
2603
chacha. process_in_place ( & mut chacha_bytes) ;
2600
2604
@@ -2610,9 +2614,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2610
2614
}
2611
2615
2612
2616
let is_user_payment_hash = metadata_bytes[ 0 ] & 1 << 7 != 0 ;
2617
+ let ( user_pmt_hash_key, ldk_pmt_hash_key) = hkdf_extract_expand ( & vec ! [ 0 ] , & self . inbound_payment_key [ ..] ) ;
2613
2618
let mut payment_preimage = None ;
2614
2619
if is_user_payment_hash {
2615
- let mut hmac = HmacEngine :: < Sha256 > :: new ( & self . our_network_key [ .. ] ) ;
2620
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & user_pmt_hash_key ) ;
2616
2621
hmac. input ( & metadata_bytes[ ..] ) ;
2617
2622
hmac. input ( & payment_hash. 0 [ ..] ) ;
2618
2623
if iv_bytes != Hmac :: from_engine ( hmac) . into_inner ( ) . split_at_mut ( 16 ) . 0 {
@@ -2634,7 +2639,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2634
2639
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) ;
2635
2640
return Err ( ( ) )
2636
2641
}
2637
- let mut hmac = HmacEngine :: < Sha256 > :: new ( & self . our_network_key [ .. ] ) ;
2642
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & ldk_pmt_hash_key ) ;
2638
2643
hmac. input ( & iv_bytes) ;
2639
2644
hmac. input ( & metadata_bytes) ;
2640
2645
let decoded_payment_preimage = Hmac :: from_engine ( hmac) . into_inner ( ) ;
@@ -4616,7 +4621,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4616
4621
// METADATA = payment amount (8 bytes) || expiry (8 bytes)
4617
4622
// IV = 16 random bytes
4618
4623
// payment_preimage = HMAC(ldk_pmt_hash_key, IV || METADATA)
4619
- // payment_secret = IV || CHACHA(self.inbound_payments_key , IV) xor METADATA
4624
+ // payment_secret = IV || CHACHA(self.inbound_payment_key , IV) xor METADATA
4620
4625
//
4621
4626
// Then on payment receipt, we verify in `verify_inbound_payment_data` that the payment preimage
4622
4627
// and payment secret match what was constructed in `create_inbound_payment`.
@@ -4641,7 +4646,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4641
4646
let rand_bytes = self . keys_manager . get_secure_random_bytes ( ) ;
4642
4647
let iv_bytes = & rand_bytes[ ..16 ] ;
4643
4648
4644
- let mut hmac = HmacEngine :: < Sha256 > :: new ( & self . our_network_key [ ..] ) ;
4649
+ let ( _, ldk_pmt_hash_key) = hkdf_extract_expand ( & vec ! [ 0 ] , & self . inbound_payment_key [ ..] ) ;
4650
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & ldk_pmt_hash_key) ;
4645
4651
hmac. input ( iv_bytes) ;
4646
4652
hmac. input ( & metadata_bytes) ;
4647
4653
let payment_preimage_bytes = Hmac :: from_engine ( hmac) . into_inner ( ) ;
@@ -4651,7 +4657,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4651
4657
let ( iv_slice, encrypted_metadata_slice) = payment_secret_bytes. split_at_mut ( 16 ) ;
4652
4658
iv_slice. copy_from_slice ( iv_bytes) ;
4653
4659
4654
- let mut chacha = ChaCha20 :: new ( & self . our_network_key [ ..] , & iv_bytes[ ..12 ] ) ;
4660
+ let mut chacha = ChaCha20 :: new ( & self . inbound_payment_key [ ..] , & iv_bytes[ ..12 ] ) ;
4655
4661
let mut chacha_bytes = [ 0 ; 16 ] ;
4656
4662
chacha. process_in_place ( & mut chacha_bytes) ;
4657
4663
@@ -4702,7 +4708,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4702
4708
//
4703
4709
// METADATA = top bit set for user-generated payment hash || payment amount (8 bytes) || expiry (8 bytes)
4704
4710
// IV = HMAC(user_pmt_hash_key, METADATA || payment_hash)[0..16]
4705
- // payment_secret = IV || CHACHA(self.inbound_payments_key , IV) xor METADATA
4711
+ // payment_secret = IV || CHACHA(self.inbound_payment_key , IV) xor METADATA
4706
4712
//
4707
4713
// Then on payment receipt, we verify in `verify_inbound_payment_data` that the payment preimage
4708
4714
// and payment secret match what was constructed in `create_inbound_payment`.
@@ -4729,7 +4735,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4729
4735
expiry_slice. copy_from_slice ( & expiry_bytes) ;
4730
4736
}
4731
4737
4732
- let mut hmac = HmacEngine :: < Sha256 > :: new ( & self . our_network_key [ ..] ) ;
4738
+ let ( user_pmt_hash_key, _) = hkdf_extract_expand ( & vec ! [ 0 ] , & self . inbound_payment_key [ ..] ) ;
4739
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & user_pmt_hash_key) ;
4733
4740
hmac. input ( & metadata_bytes) ;
4734
4741
hmac. input ( & payment_hash. 0 ) ;
4735
4742
let hmac_bytes = Hmac :: from_engine ( hmac) . into_inner ( ) ;
@@ -4740,7 +4747,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4740
4747
let ( iv_slice, encrypted_metadata_slice) = payment_secret_bytes. split_at_mut ( 16 ) ;
4741
4748
iv_slice. copy_from_slice ( iv_bytes) ;
4742
4749
4743
- let mut chacha = ChaCha20 :: new ( & self . our_network_key [ ..] , & iv_bytes[ ..12 ] ) ;
4750
+ let mut chacha = ChaCha20 :: new ( & self . inbound_payment_key [ ..] , & iv_bytes[ ..12 ] ) ;
4744
4751
let mut chacha_bytes = [ 0 ; 16 ] ;
4745
4752
chacha. process_in_place ( & mut chacha_bytes) ;
4746
4753
@@ -5820,6 +5827,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable f
5820
5827
}
5821
5828
write_tlv_fields ! ( writer, {
5822
5829
( 1 , pending_outbound_payments_no_retry, required) ,
5830
+ ( 2 , self . inbound_payment_key, required) ,
5823
5831
( 3 , pending_outbound_payments, required) ,
5824
5832
} ) ;
5825
5833
@@ -6115,10 +6123,15 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
6115
6123
// pending_outbound_payments_no_retry is for compatibility with 0.0.101 clients.
6116
6124
let mut pending_outbound_payments_no_retry: Option < HashMap < PaymentId , HashSet < [ u8 ; 32 ] > > > = None ;
6117
6125
let mut pending_outbound_payments = None ;
6126
+ let mut inbound_payment_key = None ;
6118
6127
read_tlv_fields ! ( reader, {
6119
6128
( 1 , pending_outbound_payments_no_retry, option) ,
6129
+ ( 2 , inbound_payment_key, option) ,
6120
6130
( 3 , pending_outbound_payments, option) ,
6121
6131
} ) ;
6132
+ if inbound_payment_key. is_none ( ) {
6133
+ inbound_payment_key = Some ( args. keys_manager . get_inbound_payment_secret ( ) ) ;
6134
+ }
6122
6135
if pending_outbound_payments. is_none ( ) && pending_outbound_payments_no_retry. is_none ( ) {
6123
6136
pending_outbound_payments = Some ( pending_outbound_payments_compat) ;
6124
6137
} else if pending_outbound_payments. is_none ( ) {
@@ -6196,6 +6209,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
6196
6209
claimable_htlcs,
6197
6210
pending_msg_events : Vec :: new ( ) ,
6198
6211
} ) ,
6212
+ inbound_payment_key : inbound_payment_key. unwrap ( ) ,
6199
6213
pending_inbound_payments : Mutex :: new ( pending_inbound_payments) ,
6200
6214
pending_outbound_payments : Mutex :: new ( pending_outbound_payments. unwrap ( ) ) ,
6201
6215
@@ -6229,6 +6243,19 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
6229
6243
}
6230
6244
}
6231
6245
6246
+ fn hkdf_extract_expand ( salt : & [ u8 ] , ikm : & [ u8 ] ) -> ( [ u8 ; 32 ] , [ u8 ; 32 ] ) {
6247
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( salt) ;
6248
+ hmac. input ( ikm) ;
6249
+ let prk = Hmac :: from_engine ( hmac) . into_inner ( ) ;
6250
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & prk[ ..] ) ;
6251
+ hmac. input ( & [ 1 ; 1 ] ) ;
6252
+ let t1 = Hmac :: from_engine ( hmac) . into_inner ( ) ;
6253
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & prk[ ..] ) ;
6254
+ hmac. input ( & t1) ;
6255
+ hmac. input ( & [ 2 ; 1 ] ) ;
6256
+ ( t1, Hmac :: from_engine ( hmac) . into_inner ( ) )
6257
+ }
6258
+
6232
6259
#[ cfg( test) ]
6233
6260
mod tests {
6234
6261
use bitcoin:: hashes:: Hash ;
0 commit comments