@@ -31,7 +31,11 @@ const KEY_ROTATION_INDEX: u32 = 1000;
3131/// For decryption, it is recommended to call `decrypt_message_stream` for automatic buffering.
3232pub struct Conduit {
3333 pub ( super ) encryptor : Encryptor ,
34- pub ( super ) decryptor : Decryptor
34+
35+ #[ cfg( feature = "fuzztarget" ) ]
36+ pub decryptor : Decryptor ,
37+ #[ cfg( not( feature = "fuzztarget" ) ) ]
38+ pub ( super ) decryptor : Decryptor ,
3539
3640}
3741
@@ -41,7 +45,7 @@ pub(super) struct Encryptor {
4145 sending_nonce : u32 ,
4246}
4347
44- pub ( super ) struct Decryptor {
48+ pub struct Decryptor {
4549 receiving_key : SymmetricKey ,
4650 receiving_chaining_key : SymmetricKey ,
4751 receiving_nonce : u32 ,
@@ -72,7 +76,7 @@ impl Conduit {
7276 receiving_key,
7377 receiving_chaining_key : chaining_key,
7478 receiving_nonce : 0 ,
75- read_buffer : None ,
79+ read_buffer : Some ( vec ! [ ] ) ,
7680 pending_message_length : None ,
7781 decrypted_payloads : VecDeque :: new ( ) ,
7882 }
@@ -88,15 +92,6 @@ impl Conduit {
8892 self . decryptor . read ( data)
8993 }
9094
91- /// Decrypt a single message. If data containing more than one message has been received,
92- /// only the first message will be returned, and the rest stored in the internal buffer.
93- /// If a message pending in the buffer still hasn't been decrypted, that message will be
94- /// returned in lieu of anything new, even if new data is provided.
95- #[ cfg( any( test, feature = "fuzztarget" ) ) ]
96- pub fn decrypt_single_message ( & mut self , new_data : Option < & [ u8 ] > ) -> Result < Option < Vec < u8 > > , String > {
97- Ok ( self . decryptor . decrypt_single_message ( new_data) ?)
98- }
99-
10095 fn increment_nonce ( nonce : & mut u32 , chaining_key : & mut SymmetricKey , key : & mut SymmetricKey ) {
10196 * nonce += 1 ;
10297 if * nonce == KEY_ROTATION_INDEX {
@@ -138,53 +133,48 @@ impl Encryptor {
138133}
139134
140135impl Decryptor {
141- pub ( super ) fn read ( & mut self , data : & [ u8 ] ) -> Result < ( ) , String > {
142- let mut input_data = Some ( data) ;
143136
137+ // Read in new encrypted data and process it. This attempts to decrypt the input data and any
138+ // existing data in the internal read buffer and can return an error if there is an error raised
139+ // from the decryption code.
140+ pub fn read ( & mut self , data : & [ u8 ] ) -> Result < ( ) , String > {
141+ let mut read_buffer = self . read_buffer . take ( ) . unwrap ( ) ;
142+
143+ let buffer = if read_buffer. is_empty ( ) {
144+ data
145+ } else {
146+ read_buffer. extend_from_slice ( data) ;
147+ read_buffer. as_slice ( )
148+ } ;
149+
150+ let mut read_offset = 0 ;
144151 loop {
145- match self . decrypt_single_message ( input_data) {
146- Ok ( Some ( result) ) => {
152+ match self . decrypt_next ( & buffer[ read_offset..] ) {
153+ Ok ( ( Some ( result) , bytes_read) ) => {
154+ read_offset += bytes_read;
147155 self . decrypted_payloads . push_back ( result) ;
148156 } ,
149- Ok ( None ) => {
157+ Ok ( ( None , 0 ) ) => {
158+ self . read_buffer = Some ( buffer[ read_offset..] . to_vec ( ) ) ;
150159 break ;
151160 }
152161 Err ( e) => {
153162 return Err ( e) ;
154163 }
164+ Ok ( ( None , _) ) => { panic ! ( "Invalid return from decrypt_next()" ) }
155165 }
156- input_data = None ;
157166 }
158167
159168 Ok ( ( ) )
160169 }
161170
162- /// Decrypt a single message. If data containing more than one message has been received,
163- /// only the first message will be returned, and the rest stored in the internal buffer.
164- /// If a message pending in the buffer still hasn't been decrypted, that message will be
165- /// returned in lieu of anything new, even if new data is provided.
166- pub fn decrypt_single_message ( & mut self , new_data : Option < & [ u8 ] > ) -> Result < Option < Vec < u8 > > , String > {
167- let mut read_buffer = if let Some ( buffer) = self . read_buffer . take ( ) {
168- buffer
169- } else {
170- Vec :: new ( )
171- } ;
172-
173- if let Some ( data) = new_data {
174- read_buffer. extend_from_slice ( data) ;
175- }
176-
177- if read_buffer. len ( ) > LN_MAX_MSG_LEN + 16 {
171+ // Decrypt the next payload from the slice returning the number of bytes consumed during the
172+ // operation. This will always be (None, 0) if no payload could be decrypted.
173+ fn decrypt_next ( & mut self , buffer : & [ u8 ] ) -> Result < ( Option < Vec < u8 > > , usize ) , String > {
174+ if buffer. len ( ) > LN_MAX_MSG_LEN + 16 {
178175 panic ! ( "Attempted to decrypt message longer than 65535 + 16 bytes!" ) ;
179176 }
180177
181- let ( current_message, offset) = self . decrypt ( & read_buffer[ ..] ) ?;
182- read_buffer. drain ( ..offset) ; // drain the read buffer
183- self . read_buffer = Some ( read_buffer) ; // assign the new value to the built-in buffer
184- Ok ( current_message)
185- }
186-
187- fn decrypt ( & mut self , buffer : & [ u8 ] ) -> Result < ( Option < Vec < u8 > > , usize ) , String > {
188178 let message_length = if let Some ( length) = self . pending_message_length {
189179 // we have already decrypted the header
190180 length
@@ -272,10 +262,47 @@ mod tests {
272262 let encrypted_message = connected_peer. encrypt ( & message) ;
273263 assert_eq ! ( encrypted_message. len( ) , 2 + 16 + 16 ) ;
274264
275- let decrypted_message = remote_peer. decrypt_single_message ( Some ( & encrypted_message) ) . unwrap ( ) . unwrap ( ) ;
265+ remote_peer. decryptor . read ( & encrypted_message[ ..] ) . unwrap ( ) ;
266+ let decrypted_message = remote_peer. decryptor . next ( ) . unwrap ( ) ;
276267 assert_eq ! ( decrypted_message, Vec :: <u8 >:: new( ) ) ;
277268 }
278269
270+ // Test that descrypting from a slice that is the partial data followed by another decrypt call
271+ // with the remaining data works. This exercises the slow-path for decryption and ensures the
272+ // data is written to the read_buffer properly.
273+ #[ test]
274+ fn test_decrypt_from_slice_two_calls_no_header_then_rest ( ) {
275+ let ( mut connected_peer, mut remote_peer) = setup_peers ( ) ;
276+
277+ let message: Vec < u8 > = vec ! [ 1 ] ;
278+ let encrypted_message = connected_peer. encrypt ( & message) ;
279+
280+ remote_peer. decryptor . read ( & encrypted_message[ ..1 ] ) . unwrap ( ) ;
281+ assert ! ( remote_peer. decryptor. next( ) . is_none( ) ) ;
282+
283+ remote_peer. decryptor . read ( & encrypted_message[ 1 ..] ) . unwrap ( ) ;
284+ let decrypted_message = remote_peer. decryptor . next ( ) . unwrap ( ) ;
285+
286+ assert_eq ! ( decrypted_message, vec![ 1 ] ) ;
287+ }
288+
289+ // Include the header in the first slice
290+ #[ test]
291+ fn test_decrypt_from_slice_two_calls_header_then_rest ( ) {
292+ let ( mut connected_peer, mut remote_peer) = setup_peers ( ) ;
293+
294+ let message: Vec < u8 > = vec ! [ 1 ] ;
295+ let encrypted_message = connected_peer. encrypt ( & message) ;
296+
297+ remote_peer. decryptor . read ( & encrypted_message[ ..20 ] ) . unwrap ( ) ;
298+ assert ! ( remote_peer. decryptor. next( ) . is_none( ) ) ;
299+
300+ remote_peer. decryptor . read ( & encrypted_message[ 20 ..] ) . unwrap ( ) ;
301+ let decrypted_message = remote_peer. decryptor . next ( ) . unwrap ( ) ;
302+
303+ assert_eq ! ( decrypted_message, vec![ 1 ] ) ;
304+ }
305+
279306 #[ test]
280307 fn test_nonce_chaining ( ) {
281308 let ( mut connected_peer, _remote_peer) = setup_peers ( ) ;
@@ -325,13 +352,16 @@ mod tests {
325352 let mut current_encrypted_message = encrypted_messages. remove ( 0 ) ;
326353 let next_encrypted_message = encrypted_messages. remove ( 0 ) ;
327354 current_encrypted_message. extend_from_slice ( & next_encrypted_message) ;
328- let decrypted_message = remote_peer. decrypt_single_message ( Some ( & current_encrypted_message) ) . unwrap ( ) . unwrap ( ) ;
355+ remote_peer. read ( & current_encrypted_message[ ..] ) . unwrap ( ) ;
356+
357+ let decrypted_message = remote_peer. decryptor . next ( ) . unwrap ( ) ;
329358 assert_eq ! ( decrypted_message, message) ;
330359 }
331360
332361 for _ in 0 ..501 {
333362 // decrypt messages directly from buffer without adding to it
334- let decrypted_message = remote_peer. decrypt_single_message ( None ) . unwrap ( ) . unwrap ( ) ;
363+ remote_peer. read ( & [ ] ) . unwrap ( ) ;
364+ let decrypted_message = remote_peer. decryptor . next ( ) . unwrap ( ) ;
335365 assert_eq ! ( decrypted_message, message) ;
336366 }
337367 }
@@ -376,7 +406,7 @@ mod tests {
376406 fn max_message_len_encryption ( ) {
377407 let ( mut connected_peer, _) = setup_peers ( ) ;
378408 let msg = [ 4u8 ; LN_MAX_MSG_LEN + 1 ] ;
379- connected_peer. encrypt ( & msg) ;
409+ let _should_panic = connected_peer. encrypt ( & msg) ;
380410 }
381411
382412 #[ test]
@@ -386,6 +416,6 @@ mod tests {
386416
387417 // MSG should not exceed LN_MAX_MSG_LEN + 16
388418 let msg = [ 4u8 ; LN_MAX_MSG_LEN + 17 ] ;
389- connected_peer. decrypt_single_message ( Some ( & msg) ) . unwrap ( ) ;
419+ connected_peer. read ( & msg) . unwrap ( ) ;
390420 }
391421}
0 commit comments