Skip to content

Commit ad37155

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 c2ee142 commit ad37155

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
@@ -2193,6 +2193,9 @@ where
21932193

21942194
inbound_payment_key: inbound_payment::ExpandedKey,
21952195

2196+
/// The key used to encrypt our peer storage that would be sent to our peers.
2197+
our_peerstorage_encryption_key: [u8;32],
2198+
21962199
/// LDK puts the [fake scids] that it generates into namespaces, to identify the type of an
21972200
/// incoming payment. To make it harder for a third-party to identify the type of a payment,
21982201
/// we encrypt the namespace identifier using these bytes.
@@ -3060,6 +3063,7 @@ where
30603063
secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
30613064
let inbound_pmt_key_material = node_signer.get_inbound_payment_key_material();
30623065
let expanded_inbound_key = inbound_payment::ExpandedKey::new(&inbound_pmt_key_material);
3066+
let our_peerstorage_encryption_key = node_signer.get_peer_storage_key();
30633067
ChannelManager {
30643068
default_configuration: config.clone(),
30653069
chain_hash: ChainHash::using_genesis_block(params.network),
@@ -3084,6 +3088,8 @@ where
30843088
secp_ctx,
30853089

30863090
inbound_payment_key: expanded_inbound_key,
3091+
our_peerstorage_encryption_key,
3092+
30873093
fake_scid_rand_bytes: entropy_source.get_secure_random_bytes(),
30883094

30893095
probing_cookie_secret: entropy_source.get_secure_random_bytes(),
@@ -3120,6 +3126,13 @@ where
31203126
&self.default_configuration
31213127
}
31223128

3129+
/// Returns the encrypted [`OurPeerStorage`] which can be distributed among our peers.
3130+
/// We use a key derived from our seed to encrypt this.
3131+
pub fn get_encrypted_our_peer_storage(&self) -> Vec<u8> {
3132+
let our_peer_storage = self.our_peer_storage.read().unwrap();
3133+
our_peer_storage.encrypt_our_peer_storage(self.our_peerstorage_encryption_key)
3134+
}
3135+
31233136
fn create_and_insert_outbound_scid_alias(&self) -> u64 {
31243137
let height = self.best_block.read().unwrap().height;
31253138
let mut outbound_scid_alias = 0;
@@ -8328,6 +8341,30 @@ where
83288341
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))
83298342
}
83308343
};
8344+
8345+
{
8346+
let per_peer_state = self.per_peer_state.read().unwrap();
8347+
let mut peer_state_lock = per_peer_state.get(counterparty_node_id)
8348+
.ok_or_else(|| {
8349+
debug_assert!(false);
8350+
MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
8351+
}).map(|mtx| mtx.lock().unwrap())?;
8352+
let peer_state = &mut *peer_state_lock;
8353+
let our_peer_storage = self.get_encrypted_our_peer_storage();
8354+
8355+
for context in peer_state.channel_by_id.iter().map(|(_, phase)| phase.context()) {
8356+
// Update latest PeerStorage for the peer.
8357+
peer_state.pending_msg_events.push(
8358+
events::MessageSendEvent::SendPeerStorageMessage {
8359+
node_id: context.get_counterparty_node_id(),
8360+
msg: msgs::PeerStorageMessage {
8361+
data: our_peer_storage.clone()
8362+
},
8363+
}
8364+
);
8365+
}
8366+
}
8367+
83318368
self.fail_holding_cell_htlcs(htlcs_to_fail, msg.channel_id, counterparty_node_id);
83328369
Ok(())
83338370
}
@@ -10599,6 +10636,7 @@ where
1059910636
if let Some(peer_state_mutex) = per_peer_state.get(counterparty_node_id) {
1060010637
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
1060110638
let peer_state = &mut *peer_state_lock;
10639+
let num_channels = peer_state.total_channel_count();
1060210640
let pending_msg_events = &mut peer_state.pending_msg_events;
1060310641

1060410642
if let Some(peer_storage) = self.peer_storage.lock().unwrap().get(counterparty_node_id) {
@@ -10610,6 +10648,15 @@ where
1061010648
});
1061110649
}
1061210650

10651+
if peer_state.latest_features.supports_provide_peer_storage() && num_channels > 0 {
10652+
let our_peer_storage = self.get_encrypted_our_peer_storage();
10653+
pending_msg_events.push(events::MessageSendEvent::SendPeerStorageMessage {
10654+
node_id: counterparty_node_id.clone(),
10655+
msg: msgs::PeerStorageMessage {
10656+
data: our_peer_storage
10657+
},
10658+
});
10659+
}
1061310660

1061410661
for (_, phase) in peer_state.channel_by_id.iter_mut() {
1061510662
match phase {
@@ -12588,6 +12635,7 @@ where
1258812635

1258912636
let inbound_pmt_key_material = args.node_signer.get_inbound_payment_key_material();
1259012637
let expanded_inbound_key = inbound_payment::ExpandedKey::new(&inbound_pmt_key_material);
12638+
let our_peerstorage_encryption_key = args.node_signer.get_peer_storage_key();
1259112639

1259212640
let mut claimable_payments = hash_map_with_capacity(claimable_htlcs_list.len());
1259312641
if let Some(purposes) = claimable_htlc_purposes {
@@ -12810,6 +12858,7 @@ where
1281012858
best_block: RwLock::new(BestBlock::new(best_block_hash, best_block_height)),
1281112859

1281212860
inbound_payment_key: expanded_inbound_key,
12861+
our_peerstorage_encryption_key,
1281312862
pending_inbound_payments: Mutex::new(pending_inbound_payments),
1281412863
pending_outbound_payments: pending_outbounds,
1281512864
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`]
@@ -2172,6 +2201,14 @@ impl NodeSigner for KeysManager {
21722201
self.inbound_payment_key.clone()
21732202
}
21742203

2204+
fn get_peer_storage_key(&self) -> [u8; 32] {
2205+
let (t1, _) = hkdf_extract_expand_twice(
2206+
b"Peer Storage Encryption Key",
2207+
&self.get_node_secret_key().secret_bytes(),
2208+
);
2209+
t1
2210+
}
2211+
21752212
fn sign_invoice(
21762213
&self, invoice: &RawBolt11Invoice, recipient: Recipient,
21772214
) -> Result<RecoverableSignature, ()> {
@@ -2347,6 +2384,14 @@ impl NodeSigner for PhantomKeysManager {
23472384
self.inbound_payment_key.clone()
23482385
}
23492386

2387+
fn get_peer_storage_key(&self) -> [u8; 32] {
2388+
let (t1, _) = hkdf_extract_expand_twice(
2389+
b"Peer Storage Encryption Key",
2390+
&self.get_node_secret_key().secret_bytes(),
2391+
);
2392+
t1
2393+
}
2394+
23502395
fn sign_invoice(
23512396
&self, invoice: &RawBolt11Invoice, recipient: Recipient,
23522397
) -> Result<RecoverableSignature, ()> {

0 commit comments

Comments
 (0)