@@ -22,7 +22,11 @@ const KEY_ROTATION_INDEX: u32 = 1000;
22
22
/// For decryption, it is recommended to call `decrypt_message_stream` for automatic buffering.
23
23
pub struct Conduit {
24
24
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 ,
26
30
27
31
}
28
32
@@ -32,7 +36,7 @@ pub(super) struct Encryptor {
32
36
sending_nonce : u32 ,
33
37
}
34
38
35
- pub ( super ) struct Decryptor {
39
+ pub struct Decryptor {
36
40
receiving_key : SymmetricKey ,
37
41
receiving_chaining_key : SymmetricKey ,
38
42
receiving_nonce : u32 ,
@@ -63,7 +67,7 @@ impl Conduit {
63
67
receiving_key,
64
68
receiving_chaining_key : chaining_key,
65
69
receiving_nonce : 0 ,
66
- read_buffer : None ,
70
+ read_buffer : Some ( vec ! [ ] ) ,
67
71
pending_message_length : None ,
68
72
decrypted_payloads : VecDeque :: new ( ) ,
69
73
}
@@ -79,15 +83,6 @@ impl Conduit {
79
83
self . decryptor . read ( data)
80
84
}
81
85
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
-
91
86
fn increment_nonce ( nonce : & mut u32 , chaining_key : & mut SymmetricKey , key : & mut SymmetricKey ) {
92
87
* nonce += 1 ;
93
88
if * nonce == KEY_ROTATION_INDEX {
@@ -129,53 +124,48 @@ impl Encryptor {
129
124
}
130
125
131
126
impl Decryptor {
132
- pub ( super ) fn read ( & mut self , data : & [ u8 ] ) -> Result < ( ) , String > {
133
- let mut input_data = Some ( data) ;
134
127
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 ;
135
142
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;
138
146
self . decrypted_payloads . push_back ( result) ;
139
147
} ,
140
- Ok ( None ) => {
148
+ Ok ( ( None , 0 ) ) => {
149
+ self . read_buffer = Some ( buffer[ read_offset..] . to_vec ( ) ) ;
141
150
break ;
142
151
}
143
152
Err ( e) => {
144
153
return Err ( e) ;
145
154
}
155
+ Ok ( ( None , _) ) => { panic ! ( "Invalid return from decrypt_next()" ) }
146
156
}
147
- input_data = None ;
148
157
}
149
158
150
159
Ok ( ( ) )
151
160
}
152
161
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 {
169
166
panic ! ( "Attempted to decrypt message longer than 65535 + 16 bytes!" ) ;
170
167
}
171
168
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 > {
179
169
let message_length = if let Some ( length) = self . pending_message_length {
180
170
// we have already decrypted the header
181
171
length
@@ -263,10 +253,47 @@ mod tests {
263
253
let encrypted_message = connected_peer. encrypt ( & message) ;
264
254
assert_eq ! ( encrypted_message. len( ) , 2 + 16 + 16 ) ;
265
255
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 ( ) ;
267
258
assert_eq ! ( decrypted_message, Vec :: <u8 >:: new( ) ) ;
268
259
}
269
260
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
+
270
297
#[ test]
271
298
fn test_nonce_chaining ( ) {
272
299
let ( mut connected_peer, _remote_peer) = setup_peers ( ) ;
@@ -316,13 +343,16 @@ mod tests {
316
343
let mut current_encrypted_message = encrypted_messages. remove ( 0 ) ;
317
344
let next_encrypted_message = encrypted_messages. remove ( 0 ) ;
318
345
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 ( ) ;
320
349
assert_eq ! ( decrypted_message, message) ;
321
350
}
322
351
323
352
for _ in 0 ..501 {
324
353
// 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 ( ) ;
326
356
assert_eq ! ( decrypted_message, message) ;
327
357
}
328
358
}
@@ -367,7 +397,7 @@ mod tests {
367
397
fn max_message_len_encryption ( ) {
368
398
let ( mut connected_peer, _) = setup_peers ( ) ;
369
399
let msg = [ 4u8 ; LN_MAX_MSG_LEN + 1 ] ;
370
- connected_peer. encrypt ( & msg) ;
400
+ let _should_panic = connected_peer. encrypt ( & msg) ;
371
401
}
372
402
373
403
#[ test]
@@ -377,6 +407,6 @@ mod tests {
377
407
378
408
// MSG should not exceed LN_MAX_MSG_LEN + 16
379
409
let msg = [ 4u8 ; LN_MAX_MSG_LEN + 17 ] ;
380
- connected_peer. decrypt_single_message ( Some ( & msg) ) . unwrap ( ) ;
410
+ connected_peer. read ( & msg) . unwrap ( ) ;
381
411
}
382
412
}
0 commit comments