Skip to content

Commit 2efad78

Browse files
Aditya Sharmaadi2011
Aditya Sharma
authored andcommitted
Add method to derive Peer Storage encryption key
Add get_peer_storage_key method to derive a 32-byte encryption key for securing Peer Storage. This method utilizes HKDF with the node's secret key as input and a fixed info string to generate the encryption key. - Add 'get_peer_storage_key' to NodeSigner. - Implement 'get_peer_storage_key' for KeysManager & PhantomKeysManager.
1 parent eaeed77 commit 2efad78

File tree

7 files changed

+79
-9
lines changed

7 files changed

+79
-9
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ impl TestChainMonitor {
203203
logger.clone(),
204204
feeest,
205205
Arc::clone(&persister),
206+
keys.get_peer_storage_key(),
206207
)),
207208
logger,
208209
keys,
@@ -336,6 +337,10 @@ impl NodeSigner for KeyProvider {
336337
unreachable!()
337338
}
338339

340+
fn get_peer_storage_key(&self) -> [u8; 32] {
341+
[0; 32]
342+
}
343+
339344
fn sign_bolt12_invoice(
340345
&self, _invoice: &UnsignedBolt12Invoice,
341346
) -> Result<schnorr::Signature, ()> {

fuzz/src/full_stack.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,10 @@ impl NodeSigner for KeyProvider {
420420
let secp_ctx = Secp256k1::signing_only();
421421
Ok(secp_ctx.sign_ecdsa(&msg_hash, &self.node_secret))
422422
}
423+
424+
fn get_peer_storage_key(&self) -> [u8; 32] {
425+
[0; 32]
426+
}
423427
}
424428

425429
impl SignerProvider for KeyProvider {
@@ -621,20 +625,23 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
621625
];
622626

623627
let broadcast = Arc::new(TestBroadcaster { txn_broadcasted: Mutex::new(Vec::new()) });
628+
629+
let keys_manager = Arc::new(KeyProvider {
630+
node_secret: our_network_key.clone(),
631+
inbound_payment_key: ExpandedKey::new(inbound_payment_key),
632+
counter: AtomicU64::new(0),
633+
signer_state: RefCell::new(new_hash_map()),
634+
});
635+
624636
let monitor = Arc::new(chainmonitor::ChainMonitor::new(
625637
None,
626638
broadcast.clone(),
627639
Arc::clone(&logger),
628640
fee_est.clone(),
629641
Arc::new(TestPersister { update_ret: Mutex::new(ChannelMonitorUpdateStatus::Completed) }),
642+
keys_manager.get_peer_storage_key(),
630643
));
631644

632-
let keys_manager = Arc::new(KeyProvider {
633-
node_secret: our_network_key.clone(),
634-
inbound_payment_key: ExpandedKey::new(inbound_payment_key),
635-
counter: AtomicU64::new(0),
636-
signer_state: RefCell::new(new_hash_map()),
637-
});
638645
let network = Network::Bitcoin;
639646
let best_block_timestamp = genesis_block(network).header.time;
640647
let params = ChainParameters { network, best_block: BestBlock::from_network(network) };

fuzz/src/onion_message.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ impl NodeSigner for KeyProvider {
246246
) -> Result<bitcoin::secp256k1::ecdsa::Signature, ()> {
247247
unreachable!()
248248
}
249+
250+
fn get_peer_storage_key(&self) -> [u8; 32] {
251+
unreachable!()
252+
}
249253
}
250254

251255
impl SignerProvider for KeyProvider {

lightning/src/ln/blinded_payment_tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,6 +1550,7 @@ fn route_blinding_spec_test_vector() {
15501550
fn sign_invoice(
15511551
&self, _invoice: &RawBolt11Invoice, _recipient: Recipient,
15521552
) -> Result<RecoverableSignature, ()> { unreachable!() }
1553+
fn get_peer_storage_key(&self) -> [u8;32] { unreachable!() }
15531554
fn sign_bolt12_invoice(
15541555
&self, _invoice: &UnsignedBolt12Invoice,
15551556
) -> Result<schnorr::Signature, ()> { unreachable!() }

lightning/src/ln/channelmanager.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16314,7 +16314,7 @@ mod tests {
1631416314
pub mod bench {
1631516315
use crate::chain::Listen;
1631616316
use crate::chain::chainmonitor::{ChainMonitor, Persist};
16317-
use crate::sign::{KeysManager, InMemorySigner};
16317+
use crate::sign::{KeysManager, InMemorySigner, NodeSigner};
1631816318
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider};
1631916319
use crate::ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentId, RecipientOnionFields, Retry};
1632016320
use crate::ln::functional_test_utils::*;
@@ -16377,19 +16377,19 @@ pub mod bench {
1637716377
config.channel_config.max_dust_htlc_exposure = MaxDustHTLCExposure::FeeRateMultiplier(5_000_000 / 253);
1637816378
config.channel_handshake_config.minimum_depth = 1;
1637916379

16380-
let chain_monitor_a = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_a);
1638116380
let seed_a = [1u8; 32];
1638216381
let keys_manager_a = KeysManager::new(&seed_a, 42, 42);
16382+
let chain_monitor_a = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_a, keys_manager_a.get_peer_storage_key());
1638316383
let node_a = ChannelManager::new(&fee_estimator, &chain_monitor_a, &tx_broadcaster, &router, &message_router, &logger_a, &keys_manager_a, &keys_manager_a, &keys_manager_a, config.clone(), ChainParameters {
1638416384
network,
1638516385
best_block: BestBlock::from_network(network),
1638616386
}, genesis_block.header.time);
1638716387
let node_a_holder = ANodeHolder { node: &node_a };
1638816388

1638916389
let logger_b = test_utils::TestLogger::with_id("node a".to_owned());
16390-
let chain_monitor_b = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_b);
1639116390
let seed_b = [2u8; 32];
1639216391
let keys_manager_b = KeysManager::new(&seed_b, 42, 42);
16392+
let chain_monitor_b = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_b, keys_manager_b.get_peer_storage_key());
1639316393
let node_b = ChannelManager::new(&fee_estimator, &chain_monitor_b, &tx_broadcaster, &router, &message_router, &logger_b, &keys_manager_b, &keys_manager_b, &keys_manager_b, config.clone(), ChainParameters {
1639416394
network,
1639516395
best_block: BestBlock::from_network(network),

lightning/src/sign/mod.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,35 @@ pub trait NodeSigner {
856856
/// [phantom node payments]: PhantomKeysManager
857857
fn get_inbound_payment_key(&self) -> ExpandedKey;
858858

859+
/// Generates a 32-byte key used for peer storage encryption.
860+
///
861+
/// This function derives an encryption key for peer storage by using the HKDF
862+
/// (HMAC-based Key Derivation Function) with a specific label and the node
863+
/// secret key. The derived key is used for encrypting or decrypting peer storage
864+
/// data.
865+
///
866+
/// The process involves the following steps:
867+
/// 1. Retrieves the node secret key.
868+
/// 2. Uses the node secret key and the label `"Peer Storage Encryption Key"`
869+
/// to perform HKDF extraction and expansion.
870+
/// 3. Returns the first part of the derived key, which is a 32-byte array.
871+
///
872+
/// # Returns
873+
///
874+
/// Returns a 32-byte array that serves as the encryption key for peer storage.
875+
///
876+
/// # Panics
877+
///
878+
/// This function does not panic under normal circumstances, but failures in
879+
/// obtaining the node secret key or issues within the HKDF function may cause
880+
/// unexpected behavior.
881+
///
882+
/// # Notes
883+
///
884+
/// Ensure that the node secret key is securely managed, as it is crucial for
885+
/// the security of the derived encryption key.
886+
fn get_peer_storage_key(&self) -> [u8; 32];
887+
859888
/// Get node id based on the provided [`Recipient`].
860889
///
861890
/// This method must return the same value each time it is called with a given [`Recipient`]
@@ -2201,6 +2230,14 @@ impl NodeSigner for KeysManager {
22012230
self.inbound_payment_key.clone()
22022231
}
22032232

2233+
fn get_peer_storage_key(&self) -> [u8; 32] {
2234+
let (t1, _) = hkdf_extract_expand_twice(
2235+
b"Peer Storage Encryption Key",
2236+
&self.get_node_secret_key().secret_bytes(),
2237+
);
2238+
t1
2239+
}
2240+
22042241
fn sign_invoice(
22052242
&self, invoice: &RawBolt11Invoice, recipient: Recipient,
22062243
) -> Result<RecoverableSignature, ()> {
@@ -2370,6 +2407,14 @@ impl NodeSigner for PhantomKeysManager {
23702407
self.inbound_payment_key.clone()
23712408
}
23722409

2410+
fn get_peer_storage_key(&self) -> [u8; 32] {
2411+
let (t1, _) = hkdf_extract_expand_twice(
2412+
b"Peer Storage Encryption Key",
2413+
&self.get_node_secret_key().secret_bytes(),
2414+
);
2415+
t1
2416+
}
2417+
23732418
fn sign_invoice(
23742419
&self, invoice: &RawBolt11Invoice, recipient: Recipient,
23752420
) -> Result<RecoverableSignature, ()> {

lightning/src/util/test_utils.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,6 +1460,10 @@ impl NodeSigner for TestNodeSigner {
14601460
unreachable!()
14611461
}
14621462

1463+
fn get_peer_storage_key(&self) -> [u8; 32] {
1464+
unreachable!()
1465+
}
1466+
14631467
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
14641468
let node_secret = match recipient {
14651469
Recipient::Node => Ok(&self.node_secret),
@@ -1538,6 +1542,10 @@ impl NodeSigner for TestKeysInterface {
15381542
self.backing.sign_invoice(invoice, recipient)
15391543
}
15401544

1545+
fn get_peer_storage_key(&self) -> [u8; 32] {
1546+
self.backing.get_peer_storage_key()
1547+
}
1548+
15411549
fn sign_bolt12_invoice(
15421550
&self, invoice: &UnsignedBolt12Invoice,
15431551
) -> Result<schnorr::Signature, ()> {

0 commit comments

Comments
 (0)