Skip to content

Commit df9c632

Browse files
Aditya SharmaAditya Sharma
authored andcommitted
lightning: Add a key inside NodeSigner which would be used to encrypt or decrpt the peerstorage and send PeerStorage on every RAA and upon reconnection.
1 parent cc26ace commit df9c632

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2332,6 +2332,9 @@ where
23322332

23332333
inbound_payment_key: inbound_payment::ExpandedKey,
23342334

2335+
/// The key used to encrypt our peer storage that would be sent to our peers.
2336+
our_peerstorage_encryption_key: [u8;32],
2337+
23352338
/// LDK puts the [fake scids] that it generates into namespaces, to identify the type of an
23362339
/// incoming payment. To make it harder for a third-party to identify the type of a payment,
23372340
/// we encrypt the namespace identifier using these bytes.
@@ -3212,6 +3215,7 @@ where
32123215
secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
32133216
let inbound_pmt_key_material = node_signer.get_inbound_payment_key_material();
32143217
let expanded_inbound_key = inbound_payment::ExpandedKey::new(&inbound_pmt_key_material);
3218+
let our_peerstorage_encryption_key = node_signer.get_peer_storage_key();
32153219
ChannelManager {
32163220
default_configuration: config.clone(),
32173221
chain_hash: ChainHash::using_genesis_block(params.network),
@@ -3237,6 +3241,8 @@ where
32373241
secp_ctx,
32383242

32393243
inbound_payment_key: expanded_inbound_key,
3244+
our_peerstorage_encryption_key,
3245+
32403246
fake_scid_rand_bytes: entropy_source.get_secure_random_bytes(),
32413247

32423248
probing_cookie_secret: entropy_source.get_secure_random_bytes(),
@@ -3274,6 +3280,13 @@ where
32743280
&self.default_configuration
32753281
}
32763282

3283+
/// Returns the encrypted [`OurPeerStorage`] which can be distributed among our peers.
3284+
/// We use a key derived from our seed to encrypt this.
3285+
pub fn get_encrypted_our_peer_storage(&self) -> Vec<u8> {
3286+
let our_peer_storage = self.our_peer_storage.read().unwrap();
3287+
our_peer_storage.encrypt_our_peer_storage(self.our_peerstorage_encryption_key)
3288+
}
3289+
32773290
fn create_and_insert_outbound_scid_alias(&self) -> u64 {
32783291
let height = self.best_block.read().unwrap().height;
32793292
let mut outbound_scid_alias = 0;
@@ -8597,6 +8610,30 @@ where
85978610
hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
85988611
}
85998612
};
8613+
8614+
{
8615+
let per_peer_state = self.per_peer_state.read().unwrap();
8616+
let mut peer_state_lock = per_peer_state.get(counterparty_node_id)
8617+
.ok_or_else(|| {
8618+
debug_assert!(false);
8619+
MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
8620+
}).map(|mtx| mtx.lock().unwrap())?;
8621+
let peer_state = &mut *peer_state_lock;
8622+
let our_peer_storage = self.get_encrypted_our_peer_storage();
8623+
8624+
for context in peer_state.channel_by_id.iter().map(|(_, phase)| phase.context()) {
8625+
// Update latest PeerStorage for the peer.
8626+
peer_state.pending_msg_events.push(
8627+
events::MessageSendEvent::SendPeerStorageMessage {
8628+
node_id: context.get_counterparty_node_id(),
8629+
msg: msgs::PeerStorageMessage {
8630+
data: our_peer_storage.clone()
8631+
},
8632+
}
8633+
);
8634+
}
8635+
}
8636+
86008637
self.fail_holding_cell_htlcs(htlcs_to_fail, msg.channel_id, counterparty_node_id);
86018638
Ok(())
86028639
}
@@ -10898,6 +10935,7 @@ where
1089810935
if let Some(peer_state_mutex) = per_peer_state.get(&counterparty_node_id) {
1089910936
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
1090010937
let peer_state = &mut *peer_state_lock;
10938+
let num_channels = peer_state.total_channel_count();
1090110939
let pending_msg_events = &mut peer_state.pending_msg_events;
1090210940

1090310941
if !peer_state.peer_storage.is_empty() {
@@ -10909,6 +10947,15 @@ where
1090910947
});
1091010948
}
1091110949

10950+
if peer_state.latest_features.supports_provide_peer_storage() && num_channels > 0 {
10951+
let our_peer_storage = self.get_encrypted_our_peer_storage();
10952+
pending_msg_events.push(events::MessageSendEvent::SendPeerStorageMessage {
10953+
node_id: counterparty_node_id.clone(),
10954+
msg: msgs::PeerStorageMessage {
10955+
data: our_peer_storage
10956+
},
10957+
});
10958+
}
1091210959

1091310960
for (_, phase) in peer_state.channel_by_id.iter_mut() {
1091410961
match phase {
@@ -12952,6 +12999,7 @@ where
1295212999

1295313000
let inbound_pmt_key_material = args.node_signer.get_inbound_payment_key_material();
1295413001
let expanded_inbound_key = inbound_payment::ExpandedKey::new(&inbound_pmt_key_material);
13002+
let our_peerstorage_encryption_key = args.node_signer.get_peer_storage_key();
1295513003

1295613004
let mut claimable_payments = hash_map_with_capacity(claimable_htlcs_list.len());
1295713005
if let Some(purposes) = claimable_htlc_purposes {
@@ -13177,6 +13225,7 @@ where
1317713225
best_block: RwLock::new(BestBlock::new(best_block_hash, best_block_height)),
1317813226

1317913227
inbound_payment_key: expanded_inbound_key,
13228+
our_peerstorage_encryption_key,
1318013229
pending_inbound_payments: Mutex::new(pending_inbound_payments),
1318113230
pending_outbound_payments: pending_outbounds,
1318213231
pending_intercepted_htlcs: Mutex::new(pending_intercepted_htlcs.unwrap()),

lightning/src/sign/mod.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,35 @@ pub trait NodeSigner {
835835
/// [phantom node payments]: PhantomKeysManager
836836
fn get_inbound_payment_key_material(&self) -> KeyMaterial;
837837

838+
/// Generates a 32-byte key used for peer storage encryption.
839+
///
840+
/// This function derives an encryption key for peer storage by using the HKDF
841+
/// (HMAC-based Key Derivation Function) with a specific label and the node
842+
/// secret key. The derived key is used for encrypting or decrypting peer storage
843+
/// data.
844+
///
845+
/// The process involves the following steps:
846+
/// 1. Retrieves the node secret key.
847+
/// 2. Uses the node secret key and the label `"Peer Storage Encryption Key"`
848+
/// to perform HKDF extraction and expansion.
849+
/// 3. Returns the first part of the derived key, which is a 32-byte array.
850+
///
851+
/// # Returns
852+
///
853+
/// Returns a 32-byte array that serves as the encryption key for peer storage.
854+
///
855+
/// # Panics
856+
///
857+
/// This function does not panic under normal circumstances, but failures in
858+
/// obtaining the node secret key or issues within the HKDF function may cause
859+
/// unexpected behavior.
860+
///
861+
/// # Notes
862+
///
863+
/// Ensure that the node secret key is securely managed, as it is crucial for
864+
/// the security of the derived encryption key.
865+
fn get_peer_storage_key(&self) -> [u8; 32];
866+
838867
/// Get node id based on the provided [`Recipient`].
839868
///
840869
/// This method must return the same value each time it is called with a given [`Recipient`]
@@ -2174,6 +2203,14 @@ impl NodeSigner for KeysManager {
21742203
self.inbound_payment_key.clone()
21752204
}
21762205

2206+
fn get_peer_storage_key(&self) -> [u8; 32] {
2207+
let (t1, _) = hkdf_extract_expand_twice(
2208+
b"Peer Storage Encryption Key",
2209+
&self.get_node_secret_key().secret_bytes(),
2210+
);
2211+
t1
2212+
}
2213+
21772214
fn sign_invoice(
21782215
&self, invoice: &RawBolt11Invoice, recipient: Recipient,
21792216
) -> Result<RecoverableSignature, ()> {
@@ -2352,6 +2389,14 @@ impl NodeSigner for PhantomKeysManager {
23522389
self.inbound_payment_key.clone()
23532390
}
23542391

2392+
fn get_peer_storage_key(&self) -> [u8; 32] {
2393+
let (t1, _) = hkdf_extract_expand_twice(
2394+
b"Peer Storage Encryption Key",
2395+
&self.get_node_secret_key().secret_bytes(),
2396+
);
2397+
t1
2398+
}
2399+
23552400
fn sign_invoice(
23562401
&self, invoice: &RawBolt11Invoice, recipient: Recipient,
23572402
) -> Result<RecoverableSignature, ()> {

0 commit comments

Comments
 (0)