@@ -237,15 +237,7 @@ mod inbound_payment {
237
237
pub ( super ) fn verify < L : Deref > ( payment_hash : PaymentHash , payment_data : msgs:: FinalOnionHopData , highest_seen_timestamp : u64 , keys : & ExpandedKey , logger : & L ) -> Result < Option < PaymentPreimage > , ( ) >
238
238
where L :: Target : Logger
239
239
{
240
- let mut iv_bytes = [ 0 ; IV_LEN ] ;
241
- let ( iv_slice, encrypted_metadata_bytes) = payment_data. payment_secret . 0 . split_at ( IV_LEN ) ;
242
- iv_bytes. copy_from_slice ( iv_slice) ;
243
-
244
- let chacha_block = ChaCha20 :: get_single_block ( & keys. metadata_key , & iv_bytes) ;
245
- let mut metadata_bytes: [ u8 ; METADATA_LEN ] = [ 0 ; METADATA_LEN ] ;
246
- for i in 0 ..METADATA_LEN {
247
- metadata_bytes[ i] = chacha_block[ i] ^ encrypted_metadata_bytes[ i] ;
248
- }
240
+ let ( iv_bytes, metadata_bytes) = decrypt_metadata ( payment_data. payment_secret , keys) ;
249
241
250
242
let payment_type_res = Method :: from_bits ( ( metadata_bytes[ 0 ] & 0b1110_0000 ) >> METHOD_TYPE_OFFSET ) ;
251
243
let mut amt_msat_bytes = [ 0 ; AMT_MSAT_LEN ] ;
@@ -269,15 +261,13 @@ mod inbound_payment {
269
261
}
270
262
} ,
271
263
Ok ( Method :: LdkPaymentHash ) => {
272
- let mut hmac = HmacEngine :: < Sha256 > :: new ( & keys. ldk_pmt_hash_key ) ;
273
- hmac. input ( & iv_bytes) ;
274
- hmac. input ( & metadata_bytes) ;
275
- let decoded_payment_preimage = Hmac :: from_engine ( hmac) . into_inner ( ) ;
276
- if !fixed_time_eq ( & payment_hash. 0 , & Sha256 :: hash ( & decoded_payment_preimage) . into_inner ( ) ) {
277
- log_trace ! ( logger, "Failing HTLC with payment_hash {}: payment preimage {} did not match" , log_bytes!( payment_hash. 0 ) , log_bytes!( decoded_payment_preimage) ) ;
278
- return Err ( ( ) )
264
+ match derive_ldk_payment_preimage ( payment_hash, & iv_bytes, & metadata_bytes, keys) {
265
+ Ok ( preimage) => payment_preimage = Some ( preimage) ,
266
+ Err ( bad_preimage_bytes) => {
267
+ log_trace ! ( logger, "Failing HTLC with payment_hash {} due to mismatching preimage {}" , log_bytes!( payment_hash. 0 ) , log_bytes!( bad_preimage_bytes) ) ;
268
+ return Err ( ( ) )
269
+ }
279
270
}
280
- payment_preimage = Some ( PaymentPreimage ( decoded_payment_preimage) ) ;
281
271
} ,
282
272
Err ( unknown_bits) => {
283
273
log_trace ! ( logger, "Failing HTLC with payment hash {} due to unknown payment type {}" , log_bytes!( payment_hash. 0 ) , unknown_bits) ;
@@ -298,6 +288,33 @@ mod inbound_payment {
298
288
Ok ( payment_preimage)
299
289
}
300
290
291
+ fn decrypt_metadata ( payment_secret : PaymentSecret , keys : & ExpandedKey ) -> ( [ u8 ; IV_LEN ] , [ u8 ; METADATA_LEN ] ) {
292
+ let mut iv_bytes = [ 0 ; IV_LEN ] ;
293
+ let ( iv_slice, encrypted_metadata_bytes) = payment_secret. 0 . split_at ( IV_LEN ) ;
294
+ iv_bytes. copy_from_slice ( iv_slice) ;
295
+
296
+ let chacha_block = ChaCha20 :: get_single_block ( & keys. metadata_key , & iv_bytes) ;
297
+ let mut metadata_bytes: [ u8 ; METADATA_LEN ] = [ 0 ; METADATA_LEN ] ;
298
+ for i in 0 ..METADATA_LEN {
299
+ metadata_bytes[ i] = chacha_block[ i] ^ encrypted_metadata_bytes[ i] ;
300
+ }
301
+
302
+ ( iv_bytes, metadata_bytes)
303
+ }
304
+
305
+ // Errors if the payment preimage doesn't match `payment_hash`. Returns the bad preimage bytes in
306
+ // this case.
307
+ fn derive_ldk_payment_preimage ( payment_hash : PaymentHash , iv_bytes : & [ u8 ; IV_LEN ] , metadata_bytes : & [ u8 ; METADATA_LEN ] , keys : & ExpandedKey ) -> Result < PaymentPreimage , [ u8 ; 32 ] > {
308
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & keys. ldk_pmt_hash_key ) ;
309
+ hmac. input ( iv_bytes) ;
310
+ hmac. input ( metadata_bytes) ;
311
+ let decoded_payment_preimage = Hmac :: from_engine ( hmac) . into_inner ( ) ;
312
+ if !fixed_time_eq ( & payment_hash. 0 , & Sha256 :: hash ( & decoded_payment_preimage) . into_inner ( ) ) {
313
+ return Err ( decoded_payment_preimage) ;
314
+ }
315
+ return Ok ( PaymentPreimage ( decoded_payment_preimage) )
316
+ }
317
+
301
318
fn hkdf_extract_expand ( salt : & [ u8 ] , ikm : & KeyMaterial ) -> ExpandedKey {
302
319
let mut hmac = HmacEngine :: < Sha256 > :: new ( salt) ;
303
320
hmac. input ( & ikm. 0 ) ;
0 commit comments