X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fchacha20poly1305rfc.rs;h=d5792e0ac2b35f28bc8a90d43217d1874cd0e3ce;hb=bedc2c64fcfe5fa5f85ded630e9ed2eb3c3651eb;hp=1dbd91e65e0488168f59d439cdd4565f8d56803f;hpb=8c6cb9953a3b00ce3da25fbdfd8ada0ec48fc63f;p=rust-lightning diff --git a/lightning/src/util/chacha20poly1305rfc.rs b/lightning/src/util/chacha20poly1305rfc.rs index 1dbd91e6..d5792e0a 100644 --- a/lightning/src/util/chacha20poly1305rfc.rs +++ b/lightning/src/util/chacha20poly1305rfc.rs @@ -10,14 +10,14 @@ // This is a port of Andrew Moons poly1305-donna // https://github.com/floodyberry/poly1305-donna -use ln::msgs::DecodeError; -use util::ser::{FixedLengthReader, LengthRead, LengthReadableArgs, Readable, Writeable, Writer}; -use io::{self, Read, Write}; +use crate::ln::msgs::DecodeError; +use crate::util::ser::{FixedLengthReader, LengthRead, LengthReadableArgs, Readable, Writeable, Writer}; +use crate::io::{self, Read, Write}; #[cfg(not(fuzzing))] mod real_chachapoly { - use util::chacha20::ChaCha20; - use util::poly1305::Poly1305; + use crate::util::chacha20::ChaCha20; + use crate::util::poly1305::Poly1305; use bitcoin::hashes::cmp::fixed_time_eq; #[derive(Clone, Copy)] @@ -74,6 +74,11 @@ mod real_chachapoly { self.mac.raw_result(out_tag); } + pub fn encrypt_full_message_in_place(&mut self, input_output: &mut [u8], out_tag: &mut [u8]) { + self.encrypt_in_place(input_output); + self.finish_and_get_tag(out_tag); + } + // Encrypt `input_output` in-place. To finish and calculate the tag, use `finish_and_get_tag` // below. pub(super) fn encrypt_in_place(&mut self, input_output: &mut [u8]) { @@ -117,10 +122,15 @@ mod real_chachapoly { } } - // Decrypt in place, without checking the tag. Use `finish_and_check_tag` to check it - // later when decryption finishes. - // - // Should never be `pub` because the public API should always enforce tag checking. + pub fn check_decrypt_in_place(&mut self, input_output: &mut [u8], tag: &[u8]) -> Result<(), ()> { + self.decrypt_in_place(input_output); + if self.finish_and_check_tag(tag) { Ok(()) } else { Err(()) } + } + + /// Decrypt in place, without checking the tag. Use `finish_and_check_tag` to check it + /// later when decryption finishes. + /// + /// Should never be `pub` because the public API should always enforce tag checking. pub(super) fn decrypt_in_place(&mut self, input_output: &mut [u8]) { debug_assert!(self.finished == false); self.mac.input(input_output); @@ -128,8 +138,8 @@ mod real_chachapoly { self.cipher.process_in_place(input_output); } - // If we were previously decrypting with `decrypt_in_place`, this method must be used to finish - // decrypting and check the tag. Returns whether or not the tag is valid. + /// If we were previously decrypting with `just_decrypt_in_place`, this method must be used + /// to check the tag. Returns whether or not the tag is valid. pub(super) fn finish_and_check_tag(&mut self, tag: &[u8]) -> bool { debug_assert!(self.finished == false); self.finished = true; @@ -223,7 +233,6 @@ impl<'a, T: Writeable> Writeable for ChaChaPolyWriteAdapter<'a, T> { /// Enables the use of the serialization macros for objects that need to be simultaneously decrypted and /// deserialized. This allows us to avoid an intermediate Vec allocation. pub(crate) struct ChaChaPolyReadAdapter { - #[allow(unused)] // This will be used soon for onion messages pub readable: R, } @@ -284,6 +293,11 @@ mod fuzzy_chachapoly { self.finished = true; } + pub fn encrypt_full_message_in_place(&mut self, input_output: &mut [u8], out_tag: &mut [u8]) { + self.encrypt_in_place(input_output); + self.finish_and_get_tag(out_tag); + } + pub(super) fn encrypt_in_place(&mut self, _input_output: &mut [u8]) { assert!(self.finished == false); } @@ -304,6 +318,11 @@ mod fuzzy_chachapoly { true } + pub fn check_decrypt_in_place(&mut self, input_output: &mut [u8], tag: &[u8]) -> Result<(), ()> { + self.decrypt_in_place(input_output); + if self.finish_and_check_tag(tag) { Ok(()) } else { Err(()) } + } + pub(super) fn decrypt_in_place(&mut self, _input: &mut [u8]) { assert!(self.finished == false); } @@ -320,21 +339,21 @@ pub use self::fuzzy_chachapoly::ChaCha20Poly1305RFC; #[cfg(test)] mod tests { - use ln::msgs::DecodeError; + use crate::ln::msgs::DecodeError; use super::{ChaChaPolyReadAdapter, ChaChaPolyWriteAdapter}; - use util::ser::{self, FixedLengthReader, LengthReadableArgs, Writeable}; + use crate::util::ser::{self, FixedLengthReader, LengthReadableArgs, Writeable}; // Used for for testing various lengths of serialization. - #[derive(Debug, PartialEq)] + #[derive(Debug, PartialEq, Eq)] struct TestWriteable { field1: Vec, field2: Vec, field3: Vec, } impl_writeable_tlv_based!(TestWriteable, { - (1, field1, vec_type), - (2, field2, vec_type), - (3, field3, vec_type), + (1, field1, required_vec), + (2, field2, required_vec), + (3, field3, required_vec), }); #[test] @@ -402,7 +421,7 @@ mod tests { #[test] fn chacha_stream_adapters_ser_macros() { // Test that our stream adapters work as expected with the TLV macros. - // This also serves to test the `option: $trait` variant of the `decode_tlv` ser macro. + // This also serves to test the `option: $trait` variant of the `_decode_tlv` ser macro. do_chacha_stream_adapters_ser_macros().unwrap() } }