@@ -22,7 +22,11 @@ const KEY_ROTATION_INDEX: u32 = 1000;
2222/// For decryption, it is recommended to call `decrypt_message_stream` for automatic buffering.
2323pub struct Conduit {
2424 pub ( super ) encryptor : Encryptor ,
25- pub ( super ) decryptor : Decryptor
25+
26+ #[ cfg( feature = "fuzztarget" ) ]
27+ pub decryptor : Decryptor ,
28+ #[ cfg( not( feature = "fuzztarget" ) ) ]
29+ pub ( super ) decryptor : Decryptor ,
2630
2731}
2832
@@ -32,7 +36,7 @@ pub(super) struct Encryptor {
3236 sending_nonce : u32 ,
3337}
3438
35- pub ( super ) struct Decryptor {
39+ pub struct Decryptor {
3640 receiving_key : SymmetricKey ,
3741 receiving_chaining_key : SymmetricKey ,
3842 receiving_nonce : u32 ,
@@ -63,7 +67,7 @@ impl Conduit {
6367 receiving_key,
6468 receiving_chaining_key : chaining_key,
6569 receiving_nonce : 0 ,
66- read_buffer : None ,
70+ read_buffer : Some ( vec ! [ ] ) ,
6771 pending_message_length : None ,
6872 decrypted_payloads : VecDeque :: new ( ) ,
6973 }
@@ -79,15 +83,6 @@ impl Conduit {
7983 self . decryptor . read ( data)
8084 }
8185
82- /// Decrypt a single message. If data containing more than one message has been received,
83- /// only the first message will be returned, and the rest stored in the internal buffer.
84- /// If a message pending in the buffer still hasn't been decrypted, that message will be
85- /// returned in lieu of anything new, even if new data is provided.
86- #[ cfg( any( test, feature = "fuzztarget" ) ) ]
87- pub fn decrypt_single_message ( & mut self , new_data : Option < & [ u8 ] > ) -> Result < Option < Vec < u8 > > , String > {
88- Ok ( self . decryptor . decrypt_single_message ( new_data) ?)
89- }
90-
9186 fn increment_nonce ( nonce : & mut u32 , chaining_key : & mut SymmetricKey , key : & mut SymmetricKey ) {
9287 * nonce += 1 ;
9388 if * nonce == KEY_ROTATION_INDEX {
@@ -129,53 +124,48 @@ impl Encryptor {
129124}
130125
131126impl Decryptor {
132- pub ( super ) fn read ( & mut self , data : & [ u8 ] ) -> Result < ( ) , String > {
133- let mut input_data = Some ( data) ;
134127
128+ // Read in new encrypted data and process it. This attempts to decrypt the input data and any
129+ // existing data in the internal read buffer and can return an error if there is an error raised
130+ // from the decryption code.
131+ pub fn read ( & mut self , data : & [ u8 ] ) -> Result < ( ) , String > {
132+ let mut read_buffer = self . read_buffer . take ( ) . unwrap ( ) ;
133+
134+ let buffer = if read_buffer. is_empty ( ) {
135+ data
136+ } else {
137+ read_buffer. extend_from_slice ( data) ;
138+ read_buffer. as_slice ( )
139+ } ;
140+
141+ let mut read_offset = 0 ;
135142 loop {
136- match self . decrypt_single_message ( input_data) {
137- Ok ( Some ( result) ) => {
143+ match self . decrypt_next ( & buffer[ read_offset..] ) {
144+ Ok ( ( Some ( result) , bytes_read) ) => {
145+ read_offset += bytes_read;
138146 self . decrypted_payloads . push_back ( result) ;
139147 } ,
140- Ok ( None ) => {
148+ Ok ( ( None , 0 ) ) => {
149+ self . read_buffer = Some ( buffer[ read_offset..] . to_vec ( ) ) ;
141150 break ;
142151 }
143152 Err ( e) => {
144153 return Err ( e) ;
145154 }
155+ Ok ( ( None , _) ) => { panic ! ( "Invalid return from decrypt_next()" ) }
146156 }
147- input_data = None ;
148157 }
149158
150159 Ok ( ( ) )
151160 }
152161
153- /// Decrypt a single message. If data containing more than one message has been received,
154- /// only the first message will be returned, and the rest stored in the internal buffer.
155- /// If a message pending in the buffer still hasn't been decrypted, that message will be
156- /// returned in lieu of anything new, even if new data is provided.
157- pub fn decrypt_single_message ( & mut self , new_data : Option < & [ u8 ] > ) -> Result < Option < Vec < u8 > > , String > {
158- let mut read_buffer = if let Some ( buffer) = self . read_buffer . take ( ) {
159- buffer
160- } else {
161- Vec :: new ( )
162- } ;
163-
164- if let Some ( data) = new_data {
165- read_buffer. extend_from_slice ( data) ;
166- }
167-
168- if read_buffer. len ( ) > LN_MAX_MSG_LEN + 16 {
162+ // Decrypt the next payload from the slice returning the number of bytes consumed during the
163+ // operation. This will always be (None, 0) if no payload could be decrypted.
164+ fn decrypt_next ( & mut self , buffer : & [ u8 ] ) -> Result < ( Option < Vec < u8 > > , usize ) , String > {
165+ if buffer. len ( ) > LN_MAX_MSG_LEN + 16 {
169166 panic ! ( "Attempted to decrypt message longer than 65535 + 16 bytes!" ) ;
170167 }
171168
172- let ( current_message, offset) = self . decrypt ( & read_buffer[ ..] ) ?;
173- read_buffer. drain ( ..offset) ; // drain the read buffer
174- self . read_buffer = Some ( read_buffer) ; // assign the new value to the built-in buffer
175- Ok ( current_message)
176- }
177-
178- fn decrypt ( & mut self , buffer : & [ u8 ] ) -> Result < ( Option < Vec < u8 > > , usize ) , String > {
179169 let message_length = if let Some ( length) = self . pending_message_length {
180170 // we have already decrypted the header
181171 length
@@ -263,10 +253,47 @@ mod tests {
263253 let encrypted_message = connected_peer. encrypt ( & message) ;
264254 assert_eq ! ( encrypted_message. len( ) , 2 + 16 + 16 ) ;
265255
266- let decrypted_message = remote_peer. decrypt_single_message ( Some ( & encrypted_message) ) . unwrap ( ) . unwrap ( ) ;
256+ remote_peer. decryptor . read ( & encrypted_message[ ..] ) . unwrap ( ) ;
257+ let decrypted_message = remote_peer. decryptor . next ( ) . unwrap ( ) ;
267258 assert_eq ! ( decrypted_message, Vec :: <u8 >:: new( ) ) ;
268259 }
269260
261+ // Test that descrypting from a slice that is the partial data followed by another decrypt call
262+ // with the remaining data works. This exercises the slow-path for decryption and ensures the
263+ // data is written to the read_buffer properly.
264+ #[ test]
265+ fn test_decrypt_from_slice_two_calls_no_header_then_rest ( ) {
266+ let ( mut connected_peer, mut remote_peer) = setup_peers ( ) ;
267+
268+ let message: Vec < u8 > = vec ! [ 1 ] ;
269+ let encrypted_message = connected_peer. encrypt ( & message) ;
270+
271+ remote_peer. decryptor . read ( & encrypted_message[ ..1 ] ) . unwrap ( ) ;
272+ assert ! ( remote_peer. decryptor. next( ) . is_none( ) ) ;
273+
274+ remote_peer. decryptor . read ( & encrypted_message[ 1 ..] ) . unwrap ( ) ;
275+ let decrypted_message = remote_peer. decryptor . next ( ) . unwrap ( ) ;
276+
277+ assert_eq ! ( decrypted_message, vec![ 1 ] ) ;
278+ }
279+
280+ // Include the header in the first slice
281+ #[ test]
282+ fn test_decrypt_from_slice_two_calls_header_then_rest ( ) {
283+ let ( mut connected_peer, mut remote_peer) = setup_peers ( ) ;
284+
285+ let message: Vec < u8 > = vec ! [ 1 ] ;
286+ let encrypted_message = connected_peer. encrypt ( & message) ;
287+
288+ remote_peer. decryptor . read ( & encrypted_message[ ..20 ] ) . unwrap ( ) ;
289+ assert ! ( remote_peer. decryptor. next( ) . is_none( ) ) ;
290+
291+ remote_peer. decryptor . read ( & encrypted_message[ 20 ..] ) . unwrap ( ) ;
292+ let decrypted_message = remote_peer. decryptor . next ( ) . unwrap ( ) ;
293+
294+ assert_eq ! ( decrypted_message, vec![ 1 ] ) ;
295+ }
296+
270297 #[ test]
271298 fn test_nonce_chaining ( ) {
272299 let ( mut connected_peer, _remote_peer) = setup_peers ( ) ;
@@ -316,13 +343,16 @@ mod tests {
316343 let mut current_encrypted_message = encrypted_messages. remove ( 0 ) ;
317344 let next_encrypted_message = encrypted_messages. remove ( 0 ) ;
318345 current_encrypted_message. extend_from_slice ( & next_encrypted_message) ;
319- let decrypted_message = remote_peer. decrypt_single_message ( Some ( & current_encrypted_message) ) . unwrap ( ) . unwrap ( ) ;
346+ remote_peer. read ( & current_encrypted_message[ ..] ) . unwrap ( ) ;
347+
348+ let decrypted_message = remote_peer. decryptor . next ( ) . unwrap ( ) ;
320349 assert_eq ! ( decrypted_message, message) ;
321350 }
322351
323352 for _ in 0 ..501 {
324353 // decrypt messages directly from buffer without adding to it
325- let decrypted_message = remote_peer. decrypt_single_message ( None ) . unwrap ( ) . unwrap ( ) ;
354+ remote_peer. read ( & [ ] ) . unwrap ( ) ;
355+ let decrypted_message = remote_peer. decryptor . next ( ) . unwrap ( ) ;
326356 assert_eq ! ( decrypted_message, message) ;
327357 }
328358 }
@@ -367,7 +397,7 @@ mod tests {
367397 fn max_message_len_encryption ( ) {
368398 let ( mut connected_peer, _) = setup_peers ( ) ;
369399 let msg = [ 4u8 ; LN_MAX_MSG_LEN + 1 ] ;
370- connected_peer. encrypt ( & msg) ;
400+ let _should_panic = connected_peer. encrypt ( & msg) ;
371401 }
372402
373403 #[ test]
@@ -377,6 +407,6 @@ mod tests {
377407
378408 // MSG should not exceed LN_MAX_MSG_LEN + 16
379409 let msg = [ 4u8 ; LN_MAX_MSG_LEN + 17 ] ;
380- connected_peer. decrypt_single_message ( Some ( & msg) ) . unwrap ( ) ;
410+ connected_peer. read ( & msg) . unwrap ( ) ;
381411 }
382412}
0 commit comments