@@ -40,7 +40,7 @@ use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitor
40
40
use chain:: transaction:: { OutPoint , TransactionData } ;
41
41
// Since this struct is returned in `list_channels` methods, expose it here in case users want to
42
42
// construct one themselves.
43
- use ln:: { PaymentHash , PaymentPreimage , PaymentSecret } ;
43
+ use ln:: { inbound_payment , PaymentHash , PaymentPreimage , PaymentSecret } ;
44
44
use ln:: channel:: { Channel , ChannelError , ChannelUpdateStatus , UpdateFulfillCommitFetch } ;
45
45
use ln:: features:: { ChannelTypeFeatures , InitFeatures , NodeFeatures } ;
46
46
use routing:: router:: { PaymentParameters , Route , RouteHop , RoutePath , RouteParameters } ;
@@ -71,276 +71,6 @@ use core::ops::Deref;
71
71
use std:: time:: Instant ;
72
72
use util:: crypto:: sign;
73
73
74
- mod inbound_payment {
75
- use alloc:: string:: ToString ;
76
- use bitcoin:: hashes:: { Hash , HashEngine } ;
77
- use bitcoin:: hashes:: cmp:: fixed_time_eq;
78
- use bitcoin:: hashes:: hmac:: { Hmac , HmacEngine } ;
79
- use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
80
- use chain:: keysinterface:: { KeyMaterial , KeysInterface , Sign } ;
81
- use ln:: { PaymentHash , PaymentPreimage , PaymentSecret } ;
82
- use ln:: channelmanager:: APIError ;
83
- use ln:: msgs;
84
- use ln:: msgs:: MAX_VALUE_MSAT ;
85
- use util:: chacha20:: ChaCha20 ;
86
- use util:: crypto:: hkdf_extract_expand_thrice;
87
- use util:: logger:: Logger ;
88
-
89
- use core:: convert:: TryInto ;
90
- use core:: ops:: Deref ;
91
-
92
- const IV_LEN : usize = 16 ;
93
- const METADATA_LEN : usize = 16 ;
94
- const METADATA_KEY_LEN : usize = 32 ;
95
- const AMT_MSAT_LEN : usize = 8 ;
96
- // Used to shift the payment type bits to take up the top 3 bits of the metadata bytes, or to
97
- // retrieve said payment type bits.
98
- const METHOD_TYPE_OFFSET : usize = 5 ;
99
-
100
- /// A set of keys that were HKDF-expanded from an initial call to
101
- /// [`KeysInterface::get_inbound_payment_key_material`].
102
- ///
103
- /// [`KeysInterface::get_inbound_payment_key_material`]: crate::chain::keysinterface::KeysInterface::get_inbound_payment_key_material
104
- pub ( super ) struct ExpandedKey {
105
- /// The key used to encrypt the bytes containing the payment metadata (i.e. the amount and
106
- /// expiry, included for payment verification on decryption).
107
- metadata_key : [ u8 ; 32 ] ,
108
- /// The key used to authenticate an LDK-provided payment hash and metadata as previously
109
- /// registered with LDK.
110
- ldk_pmt_hash_key : [ u8 ; 32 ] ,
111
- /// The key used to authenticate a user-provided payment hash and metadata as previously
112
- /// registered with LDK.
113
- user_pmt_hash_key : [ u8 ; 32 ] ,
114
- }
115
-
116
- impl ExpandedKey {
117
- pub ( super ) fn new ( key_material : & KeyMaterial ) -> ExpandedKey {
118
- let ( metadata_key, ldk_pmt_hash_key, user_pmt_hash_key) =
119
- hkdf_extract_expand_thrice ( b"LDK Inbound Payment Key Expansion" , & key_material. 0 ) ;
120
- Self {
121
- metadata_key,
122
- ldk_pmt_hash_key,
123
- user_pmt_hash_key,
124
- }
125
- }
126
- }
127
-
128
- enum Method {
129
- LdkPaymentHash = 0 ,
130
- UserPaymentHash = 1 ,
131
- }
132
-
133
- impl Method {
134
- fn from_bits ( bits : u8 ) -> Result < Method , u8 > {
135
- match bits {
136
- bits if bits == Method :: LdkPaymentHash as u8 => Ok ( Method :: LdkPaymentHash ) ,
137
- bits if bits == Method :: UserPaymentHash as u8 => Ok ( Method :: UserPaymentHash ) ,
138
- unknown => Err ( unknown) ,
139
- }
140
- }
141
- }
142
-
143
- pub ( super ) fn create < Signer : Sign , K : Deref > ( keys : & ExpandedKey , min_value_msat : Option < u64 > , invoice_expiry_delta_secs : u32 , keys_manager : & K , highest_seen_timestamp : u64 ) -> Result < ( PaymentHash , PaymentSecret ) , ( ) >
144
- where K :: Target : KeysInterface < Signer = Signer >
145
- {
146
- let metadata_bytes = construct_metadata_bytes ( min_value_msat, Method :: LdkPaymentHash , invoice_expiry_delta_secs, highest_seen_timestamp) ?;
147
-
148
- let mut iv_bytes = [ 0 as u8 ; IV_LEN ] ;
149
- let rand_bytes = keys_manager. get_secure_random_bytes ( ) ;
150
- iv_bytes. copy_from_slice ( & rand_bytes[ ..IV_LEN ] ) ;
151
-
152
- let mut hmac = HmacEngine :: < Sha256 > :: new ( & keys. ldk_pmt_hash_key ) ;
153
- hmac. input ( & iv_bytes) ;
154
- hmac. input ( & metadata_bytes) ;
155
- let payment_preimage_bytes = Hmac :: from_engine ( hmac) . into_inner ( ) ;
156
-
157
- let ldk_pmt_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage_bytes) . into_inner ( ) ) ;
158
- let payment_secret = construct_payment_secret ( & iv_bytes, & metadata_bytes, & keys. metadata_key ) ;
159
- Ok ( ( ldk_pmt_hash, payment_secret) )
160
- }
161
-
162
- pub ( super ) fn create_from_hash ( keys : & ExpandedKey , min_value_msat : Option < u64 > , payment_hash : PaymentHash , invoice_expiry_delta_secs : u32 , highest_seen_timestamp : u64 ) -> Result < PaymentSecret , ( ) > {
163
- let metadata_bytes = construct_metadata_bytes ( min_value_msat, Method :: UserPaymentHash , invoice_expiry_delta_secs, highest_seen_timestamp) ?;
164
-
165
- let mut hmac = HmacEngine :: < Sha256 > :: new ( & keys. user_pmt_hash_key ) ;
166
- hmac. input ( & metadata_bytes) ;
167
- hmac. input ( & payment_hash. 0 ) ;
168
- let hmac_bytes = Hmac :: from_engine ( hmac) . into_inner ( ) ;
169
-
170
- let mut iv_bytes = [ 0 as u8 ; IV_LEN ] ;
171
- iv_bytes. copy_from_slice ( & hmac_bytes[ ..IV_LEN ] ) ;
172
-
173
- Ok ( construct_payment_secret ( & iv_bytes, & metadata_bytes, & keys. metadata_key ) )
174
- }
175
-
176
- fn construct_metadata_bytes ( min_value_msat : Option < u64 > , payment_type : Method , invoice_expiry_delta_secs : u32 , highest_seen_timestamp : u64 ) -> Result < [ u8 ; METADATA_LEN ] , ( ) > {
177
- if min_value_msat. is_some ( ) && min_value_msat. unwrap ( ) > MAX_VALUE_MSAT {
178
- return Err ( ( ) ) ;
179
- }
180
-
181
- let mut min_amt_msat_bytes: [ u8 ; AMT_MSAT_LEN ] = match min_value_msat {
182
- Some ( amt) => amt. to_be_bytes ( ) ,
183
- None => [ 0 ; AMT_MSAT_LEN ] ,
184
- } ;
185
- min_amt_msat_bytes[ 0 ] |= ( payment_type as u8 ) << METHOD_TYPE_OFFSET ;
186
-
187
- // We assume that highest_seen_timestamp is pretty close to the current time - it's updated when
188
- // we receive a new block with the maximum time we've seen in a header. It should never be more
189
- // than two hours in the future. Thus, we add two hours here as a buffer to ensure we
190
- // absolutely never fail a payment too early.
191
- // Note that we assume that received blocks have reasonably up-to-date timestamps.
192
- let expiry_bytes = ( highest_seen_timestamp + invoice_expiry_delta_secs as u64 + 7200 ) . to_be_bytes ( ) ;
193
-
194
- let mut metadata_bytes: [ u8 ; METADATA_LEN ] = [ 0 ; METADATA_LEN ] ;
195
- metadata_bytes[ ..AMT_MSAT_LEN ] . copy_from_slice ( & min_amt_msat_bytes) ;
196
- metadata_bytes[ AMT_MSAT_LEN ..] . copy_from_slice ( & expiry_bytes) ;
197
-
198
- Ok ( metadata_bytes)
199
- }
200
-
201
- fn construct_payment_secret ( iv_bytes : & [ u8 ; IV_LEN ] , metadata_bytes : & [ u8 ; METADATA_LEN ] , metadata_key : & [ u8 ; METADATA_KEY_LEN ] ) -> PaymentSecret {
202
- let mut payment_secret_bytes: [ u8 ; 32 ] = [ 0 ; 32 ] ;
203
- let ( iv_slice, encrypted_metadata_slice) = payment_secret_bytes. split_at_mut ( IV_LEN ) ;
204
- iv_slice. copy_from_slice ( iv_bytes) ;
205
-
206
- let chacha_block = ChaCha20 :: get_single_block ( metadata_key, iv_bytes) ;
207
- for i in 0 ..METADATA_LEN {
208
- encrypted_metadata_slice[ i] = chacha_block[ i] ^ metadata_bytes[ i] ;
209
- }
210
- PaymentSecret ( payment_secret_bytes)
211
- }
212
-
213
- /// Check that an inbound payment's `payment_data` field is sane.
214
- ///
215
- /// LDK does not store any data for pending inbound payments. Instead, we construct our payment
216
- /// secret (and, if supplied by LDK, our payment preimage) to include encrypted metadata about the
217
- /// payment.
218
- ///
219
- /// The metadata is constructed as:
220
- /// payment method (3 bits) || payment amount (8 bytes - 3 bits) || expiry (8 bytes)
221
- /// and encrypted using a key derived from [`KeysInterface::get_inbound_payment_key_material`].
222
- ///
223
- /// Then on payment receipt, we verify in this method that the payment preimage and payment secret
224
- /// match what was constructed.
225
- ///
226
- /// [`create_inbound_payment`] and [`create_inbound_payment_for_hash`] are called by the user to
227
- /// construct the payment secret and/or payment hash that this method is verifying. If the former
228
- /// method is called, then the payment method bits mentioned above are represented internally as
229
- /// [`Method::LdkPaymentHash`]. If the latter, [`Method::UserPaymentHash`].
230
- ///
231
- /// For the former method, the payment preimage is constructed as an HMAC of payment metadata and
232
- /// random bytes. Because the payment secret is also encoded with these random bytes and metadata
233
- /// (with the metadata encrypted with a block cipher), we're able to authenticate the preimage on
234
- /// payment receipt.
235
- ///
236
- /// For the latter, the payment secret instead contains an HMAC of the user-provided payment hash
237
- /// and payment metadata (encrypted with a block cipher), allowing us to authenticate the payment
238
- /// hash and metadata on payment receipt.
239
- ///
240
- /// See [`ExpandedKey`] docs for more info on the individual keys used.
241
- ///
242
- /// [`KeysInterface::get_inbound_payment_key_material`]: crate::chain::keysinterface::KeysInterface::get_inbound_payment_key_material
243
- /// [`create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment
244
- /// [`create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
245
- pub ( super ) fn verify < L : Deref > ( payment_hash : PaymentHash , payment_data : msgs:: FinalOnionHopData , highest_seen_timestamp : u64 , keys : & ExpandedKey , logger : & L ) -> Result < Option < PaymentPreimage > , ( ) >
246
- where L :: Target : Logger
247
- {
248
- let ( iv_bytes, metadata_bytes) = decrypt_metadata ( payment_data. payment_secret , keys) ;
249
-
250
- let payment_type_res = Method :: from_bits ( ( metadata_bytes[ 0 ] & 0b1110_0000 ) >> METHOD_TYPE_OFFSET ) ;
251
- let mut amt_msat_bytes = [ 0 ; AMT_MSAT_LEN ] ;
252
- amt_msat_bytes. copy_from_slice ( & metadata_bytes[ ..AMT_MSAT_LEN ] ) ;
253
- // Zero out the bits reserved to indicate the payment type.
254
- amt_msat_bytes[ 0 ] &= 0b00011111 ;
255
- let min_amt_msat: u64 = u64:: from_be_bytes ( amt_msat_bytes. into ( ) ) ;
256
- let expiry = u64:: from_be_bytes ( metadata_bytes[ AMT_MSAT_LEN ..] . try_into ( ) . unwrap ( ) ) ;
257
-
258
- // Make sure to check to check the HMAC before doing the other checks below, to mitigate timing
259
- // attacks.
260
- let mut payment_preimage = None ;
261
- match payment_type_res {
262
- Ok ( Method :: UserPaymentHash ) => {
263
- let mut hmac = HmacEngine :: < Sha256 > :: new ( & keys. user_pmt_hash_key ) ;
264
- hmac. input ( & metadata_bytes[ ..] ) ;
265
- hmac. input ( & payment_hash. 0 ) ;
266
- if !fixed_time_eq ( & iv_bytes, & Hmac :: from_engine ( hmac) . into_inner ( ) . split_at_mut ( IV_LEN ) . 0 ) {
267
- log_trace ! ( logger, "Failing HTLC with user-generated payment_hash {}: unexpected payment_secret" , log_bytes!( payment_hash. 0 ) ) ;
268
- return Err ( ( ) )
269
- }
270
- } ,
271
- Ok ( Method :: LdkPaymentHash ) => {
272
- match derive_ldk_payment_preimage ( payment_hash, & iv_bytes, & metadata_bytes, keys) {
273
- Ok ( preimage) => payment_preimage = Some ( preimage) ,
274
- Err ( bad_preimage_bytes) => {
275
- log_trace ! ( logger, "Failing HTLC with payment_hash {} due to mismatching preimage {}" , log_bytes!( payment_hash. 0 ) , log_bytes!( bad_preimage_bytes) ) ;
276
- return Err ( ( ) )
277
- }
278
- }
279
- } ,
280
- Err ( unknown_bits) => {
281
- log_trace ! ( logger, "Failing HTLC with payment hash {} due to unknown payment type {}" , log_bytes!( payment_hash. 0 ) , unknown_bits) ;
282
- return Err ( ( ) ) ;
283
- }
284
- }
285
-
286
- if payment_data. total_msat < min_amt_msat {
287
- log_trace ! ( 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) ;
288
- return Err ( ( ) )
289
- }
290
-
291
- if expiry < highest_seen_timestamp {
292
- log_trace ! ( logger, "Failing HTLC with payment_hash {}: expired payment" , log_bytes!( payment_hash. 0 ) ) ;
293
- return Err ( ( ) )
294
- }
295
-
296
- Ok ( payment_preimage)
297
- }
298
-
299
- pub ( super ) fn get_payment_preimage ( payment_hash : PaymentHash , payment_secret : PaymentSecret , keys : & ExpandedKey ) -> Result < PaymentPreimage , APIError > {
300
- let ( iv_bytes, metadata_bytes) = decrypt_metadata ( payment_secret, keys) ;
301
-
302
- match Method :: from_bits ( ( metadata_bytes[ 0 ] & 0b1110_0000 ) >> METHOD_TYPE_OFFSET ) {
303
- Ok ( Method :: LdkPaymentHash ) => {
304
- derive_ldk_payment_preimage ( payment_hash, & iv_bytes, & metadata_bytes, keys)
305
- . map_err ( |bad_preimage_bytes| APIError :: APIMisuseError {
306
- err : format ! ( "Payment hash {} did not match decoded preimage {}" , log_bytes!( payment_hash. 0 ) , log_bytes!( bad_preimage_bytes) )
307
- } )
308
- } ,
309
- Ok ( Method :: UserPaymentHash ) => Err ( APIError :: APIMisuseError {
310
- err : "Expected payment type to be LdkPaymentHash, instead got UserPaymentHash" . to_string ( )
311
- } ) ,
312
- Err ( other) => Err ( APIError :: APIMisuseError { err : format ! ( "Unknown payment type: {}" , other) } ) ,
313
- }
314
- }
315
-
316
- fn decrypt_metadata ( payment_secret : PaymentSecret , keys : & ExpandedKey ) -> ( [ u8 ; IV_LEN ] , [ u8 ; METADATA_LEN ] ) {
317
- let mut iv_bytes = [ 0 ; IV_LEN ] ;
318
- let ( iv_slice, encrypted_metadata_bytes) = payment_secret. 0 . split_at ( IV_LEN ) ;
319
- iv_bytes. copy_from_slice ( iv_slice) ;
320
-
321
- let chacha_block = ChaCha20 :: get_single_block ( & keys. metadata_key , & iv_bytes) ;
322
- let mut metadata_bytes: [ u8 ; METADATA_LEN ] = [ 0 ; METADATA_LEN ] ;
323
- for i in 0 ..METADATA_LEN {
324
- metadata_bytes[ i] = chacha_block[ i] ^ encrypted_metadata_bytes[ i] ;
325
- }
326
-
327
- ( iv_bytes, metadata_bytes)
328
- }
329
-
330
- // Errors if the payment preimage doesn't match `payment_hash`. Returns the bad preimage bytes in
331
- // this case.
332
- fn derive_ldk_payment_preimage ( payment_hash : PaymentHash , iv_bytes : & [ u8 ; IV_LEN ] , metadata_bytes : & [ u8 ; METADATA_LEN ] , keys : & ExpandedKey ) -> Result < PaymentPreimage , [ u8 ; 32 ] > {
333
- let mut hmac = HmacEngine :: < Sha256 > :: new ( & keys. ldk_pmt_hash_key ) ;
334
- hmac. input ( iv_bytes) ;
335
- hmac. input ( metadata_bytes) ;
336
- let decoded_payment_preimage = Hmac :: from_engine ( hmac) . into_inner ( ) ;
337
- if !fixed_time_eq ( & payment_hash. 0 , & Sha256 :: hash ( & decoded_payment_preimage) . into_inner ( ) ) {
338
- return Err ( decoded_payment_preimage) ;
339
- }
340
- return Ok ( PaymentPreimage ( decoded_payment_preimage) )
341
- }
342
- }
343
-
344
74
// We hold various information about HTLC relay in the HTLC objects in Channel itself:
345
75
//
346
76
// Upon receipt of an HTLC from a peer, we'll give it a PendingHTLCStatus indicating if it should
@@ -7557,7 +7287,7 @@ mod tests {
7557
7287
match inbound_payment:: verify ( bad_payment_hash, payment_data. clone ( ) , nodes[ 0 ] . node . highest_seen_timestamp . load ( Ordering :: Acquire ) as u64 , & nodes[ 0 ] . node . inbound_payment_key , & nodes[ 0 ] . logger ) {
7558
7288
Ok ( _) => panic ! ( "Unexpected ok" ) ,
7559
7289
Err ( ( ) ) => {
7560
- nodes[ 0 ] . logger . assert_log_contains ( "lightning::ln::channelmanager:: inbound_payment" . to_string ( ) , "Failing HTLC with user-generated payment_hash" . to_string ( ) , 1 ) ;
7290
+ nodes[ 0 ] . logger . assert_log_contains ( "lightning::ln::inbound_payment" . to_string ( ) , "Failing HTLC with user-generated payment_hash" . to_string ( ) , 1 ) ;
7561
7291
}
7562
7292
}
7563
7293
0 commit comments