From 100d4c361b304997e9be96915269a8ff594324f0 Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Mon, 18 Apr 2022 11:57:32 -0400 Subject: [PATCH] Receiving/forwarding onion messages -- internal api changes This commit covers the internal refactors needed for receiving and forwarding onion messages, and docs updates. Note that we support receiving custom TLVs, just not sending them. --- lightning/src/ln/channelmanager.rs | 14 +-------- lightning/src/ln/onion_message.rs | 12 ++++++++ lightning/src/ln/onion_utils.rs | 37 +++++++++++++++++++++-- lightning/src/util/chacha20poly1305rfc.rs | 4 +++ 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 7323930f330..599650c3afd 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -2097,21 +2097,9 @@ impl ChannelMana }, onion_utils::Hop::Forward { next_hop_data, next_hop_hmac, new_packet_bytes } => { let mut new_pubkey = msg.onion_routing_packet.public_key.unwrap(); - - let blinding_factor = { - let mut sha = Sha256::engine(); - sha.input(&new_pubkey.serialize()[..]); - sha.input(&shared_secret); - Sha256::from_engine(sha).into_inner() - }; - - let public_key = if let Err(e) = new_pubkey.mul_assign(&self.secp_ctx, &blinding_factor[..]) { - Err(e) - } else { Ok(new_pubkey) }; - let outgoing_packet = msgs::OnionPacket { version: 0, - public_key, + public_key: onion_utils::next_hop_packet_pubkey(&new_pubkey, &shared_secret), hop_data: new_packet_bytes, hmac: next_hop_hmac.clone(), }; diff --git a/lightning/src/ln/onion_message.rs b/lightning/src/ln/onion_message.rs index 2dc2f7e6bb8..c9c584bdaa4 100644 --- a/lightning/src/ln/onion_message.rs +++ b/lightning/src/ln/onion_message.rs @@ -19,6 +19,15 @@ impl Writeable for Payload { } } +/// Reads of `Payload`s are parameterized by the `rho` of a `SharedSecret`, which is used to decrypt +/// the onion message payload's `encrypted_data` field. +impl ReadableArgs for Payload { + fn read(mut r: &mut R, encrypted_data_ss: SharedSecret) -> Result { + // calls: + // * ChaCha20Poly1305RFC::decrypt_in_place + } +} + // Coming soon: // enum Message { // InvoiceRequest(InvoiceRequest), @@ -154,6 +163,9 @@ impl OnionMessager impl OnionMessageHandler for OnionMessager { fn handle_onion_message(&self, peer_node_id: &PublicKey, msg: &msgs::OnionMessage) { + // calls: + // * onion_utils::decode_next_message_hop + // * onion_utils::next_hop_packet_pubkey } } diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 9e08d924f00..515337f8bcb 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -73,6 +73,8 @@ pub(super) fn gen_ammag_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] { Hmac::from_engine(hmac).into_inner() } +pub(super) fn next_hop_packet_pubkey(packet_pubkey: &PublicKey, packet_shared_secret: &SharedSecret) -> Result {} + // can only fail if an intermediary hop has an invalid public key or session_priv is invalid #[inline] pub(super) fn construct_onion_keys_callback (secp_ctx: &Secp256k1, path: &Vec, session_priv: &SecretKey, mut callback: FType) -> Result<(), secp256k1::Error> { @@ -515,8 +517,33 @@ pub(super) fn process_onion_failure(secp_ctx: & } else { unreachable!(); } } -/// Data decrypted from the onion payload. -pub(crate) enum Hop { +/// Used in the decoding of inbound payments' and onion messages' routing packets. This enum allows +/// us to use `decode_next_hop` to return the payloads and next hop packet bytes of both payments +/// and onion messages. +enum Payload { + /// This payload was for an incoming payment. + Payment(PaymentPayload), + /// This payload was for an incoming onion message. + Message(MessagePayload), +} + +/// Data decrypted from the onion message's onion payload. +pub(crate) enum MessagePayload { + /// This onion payload was for us, not for forwarding to a next-hop. + Receive(onion_message::Payload), + /// This onion payload needs to be forwarded to a next-hop. + Forward { + /// Onion payload data used in forwarding the onion message. + next_hop_data: onion_message::Payload, + /// HMAC of the next hop's onion packet. + next_hop_hmac: [u8; 32], + /// Bytes of the onion packet we're forwarding. + new_packet_bytes: [u8; 20*65], + }, +} + +/// Data decrypted from the payment's onion payload. +pub(crate) enum PaymentPayload { /// This onion payload was for us, not for forwarding to a next-hop. Contains information for /// verifying the incoming payment. Receive(msgs::OnionHopData), @@ -545,7 +572,11 @@ pub(crate) enum OnionDecodeErr { }, } -pub(crate) fn decode_next_hop(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: PaymentHash) -> Result { +pub(crate) fn decode_next_payment_hop(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: PaymentHash) -> Result {} + +pub(crate) fn decode_next_message_hop(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], encrypted_tlvs_ss: SharedSecret) -> Result {} + + fn decode_next_hop(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: Option, encrypted_tlvs_ss: Option) -> Result<(Payload, Option<([u8; 32], [u8; 20*65])>), OnionDecodeErr> { let (rho, mu) = gen_rho_mu_from_shared_secret(&shared_secret); let mut hmac = HmacEngine::::new(&mu); hmac.input(hop_data); diff --git a/lightning/src/util/chacha20poly1305rfc.rs b/lightning/src/util/chacha20poly1305rfc.rs index 683941417d6..8ae383be97f 100644 --- a/lightning/src/util/chacha20poly1305rfc.rs +++ b/lightning/src/util/chacha20poly1305rfc.rs @@ -96,6 +96,10 @@ mod real_chachapoly { false } } + + pub fn decrypt_in_place(&mut self, input_output: &mut [u8], tag: &[u8]) -> bool {} + + fn decrypt_inner(&mut self, input: &mut [u8], output: Option<&mut [u8]>, tag: &[u8]) -> bool {} } } #[cfg(not(fuzzing))]