From 7e59e1e3927f3baf586bc393bdd519449eaed08b Mon Sep 17 00:00:00 2001 From: Yuntai Kyong Date: Mon, 26 Nov 2018 20:10:01 +0900 Subject: [PATCH 1/1] Add a method to get session secret for onion packet to KeysInterface --- fuzz/fuzz_targets/full_stack_target.rs | 8 +++++++- src/chain/keysinterface.rs | 22 ++++++++++++++++++++++ src/ln/channel.rs | 1 + src/ln/channelmanager.rs | 6 +----- src/util/mod.rs | 2 +- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/fuzz/fuzz_targets/full_stack_target.rs b/fuzz/fuzz_targets/full_stack_target.rs index 3b277906b..354625604 100644 --- a/fuzz/fuzz_targets/full_stack_target.rs +++ b/fuzz/fuzz_targets/full_stack_target.rs @@ -21,7 +21,7 @@ use lightning::ln::channelmanager::{ChannelManager, PaymentFailReason}; use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor}; use lightning::ln::router::Router; use lightning::util::events::{EventsProvider,Event}; -use lightning::util::reset_rng_state; +use lightning::util::{reset_rng_state, fill_bytes}; use lightning::util::logger::Logger; use lightning::util::sha2::Sha256; use lightning::util::config::UserConfig; @@ -265,6 +265,12 @@ impl KeysInterface for KeyProvider { } } } + + fn get_session_key(&self) -> SecretKey { + let mut session_key = [0; 32]; + fill_bytes(&mut session_key); + SecretKey::from_slice(&Secp256k1::without_caps(), &session_key).unwrap() + } } #[inline] diff --git a/src/chain/keysinterface.rs b/src/chain/keysinterface.rs index 8e71625df..4e35e6764 100644 --- a/src/chain/keysinterface.rs +++ b/src/chain/keysinterface.rs @@ -79,6 +79,8 @@ pub trait KeysInterface: Send + Sync { /// Get a new set of ChannelKeys for per-channel secrets. These MUST be unique even if you /// restarted with some stale data! fn get_channel_keys(&self, inbound: bool) -> ChannelKeys; + /// Get a secret for construting an onion packet + fn get_session_key(&self) -> SecretKey; } /// Set of lightning keys needed to operate a channel as described in BOLT 3 @@ -158,6 +160,8 @@ pub struct KeysManager { shutdown_pubkey: PublicKey, channel_master_key: ExtendedPrivKey, channel_child_index: AtomicUsize, + session_master_key: ExtendedPrivKey, + session_child_index: AtomicUsize, logger: Arc, } @@ -184,6 +188,7 @@ impl KeysManager { Err(_) => panic!("Your RNG is busted"), }; let channel_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(3)).expect("Your RNG is busted"); + let session_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(4)).expect("Your RNG is busted"); KeysManager { secp_ctx, node_secret, @@ -191,6 +196,8 @@ impl KeysManager { shutdown_pubkey, channel_master_key, channel_child_index: AtomicUsize::new(0), + session_master_key, + session_child_index: AtomicUsize::new(0), logger, } @@ -235,4 +242,19 @@ impl KeysInterface for KeysManager { sha.result(&mut seed); ChannelKeys::new_from_seed(&seed) } + + fn get_session_key(&self) -> SecretKey { + let mut sha = Sha256::new(); + let mut res = [0u8; 32]; + + let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards"); + sha.input(&byte_utils::be32_to_array(now.subsec_nanos())); + sha.input(&byte_utils::be64_to_array(now.as_secs())); + + let child_ix = self.session_child_index.fetch_add(1, Ordering::AcqRel); + let child_privkey = self.session_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32)).expect("Your RNG is busted"); + sha.input(&child_privkey.secret_key[..]); + sha.result(&mut res); + SecretKey::from_slice(&self.secp_ctx, &res).expect("Your RNG is busted") + } } diff --git a/src/ln/channel.rs b/src/ln/channel.rs index e0fdcaf90..4fcebe25d 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -3902,6 +3902,7 @@ mod tests { } fn get_channel_keys(&self, _inbound: bool) -> ChannelKeys { self.chan_keys.clone() } + fn get_session_key(&self) -> SecretKey { panic!(); } } #[test] diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index 6933198c6..ac4fa819f 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -1199,11 +1199,7 @@ impl ChannelManager { } } - let session_priv = SecretKey::from_slice(&self.secp_ctx, &{ - let mut session_key = [0; 32]; - rng::fill_bytes(&mut session_key); - session_key - }).expect("RNG is bad!"); + let session_priv = self.keys_manager.get_session_key(); let cur_height = self.latest_block_height.load(Ordering::Acquire) as u32 + 1; diff --git a/src/util/mod.rs b/src/util/mod.rs index 842fbea60..3df1529e0 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -25,7 +25,7 @@ pub mod sha2; pub(crate) mod sha2; #[cfg(feature = "fuzztarget")] -pub use self::rng::reset_rng_state; +pub use self::rng::{reset_rng_state, fill_bytes}; #[cfg(test)] pub(crate) mod test_utils; -- 2.39.5