@@ -31,7 +31,11 @@ const KEY_ROTATION_INDEX: u32 = 1000;
31
31
/// For decryption, it is recommended to call `decrypt_message_stream` for automatic buffering.
32
32
pub struct Conduit {
33
33
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 ,
35
39
36
40
}
37
41
@@ -41,7 +45,7 @@ pub(super) struct Encryptor {
41
45
sending_nonce : u32 ,
42
46
}
43
47
44
- pub ( super ) struct Decryptor {
48
+ pub struct Decryptor {
45
49
receiving_key : SymmetricKey ,
46
50
receiving_chaining_key : SymmetricKey ,
47
51
receiving_nonce : u32 ,
@@ -72,7 +76,7 @@ impl Conduit {
72
76
receiving_key,
73
77
receiving_chaining_key : chaining_key,
74
78
receiving_nonce : 0 ,
75
- read_buffer : None ,
79
+ read_buffer : Some ( vec ! [ ] ) ,
76
80
pending_message_length : None ,
77
81
decrypted_payloads : VecDeque :: new ( ) ,
78
82
}
@@ -88,15 +92,6 @@ impl Conduit {
88
92
self . decryptor . read ( data)
89
93
}
90
94
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
-
100
95
fn increment_nonce ( nonce : & mut u32 , chaining_key : & mut SymmetricKey , key : & mut SymmetricKey ) {
101
96
* nonce += 1 ;
102
97
if * nonce == KEY_ROTATION_INDEX {
@@ -138,53 +133,48 @@ impl Encryptor {
138
133
}
139
134
140
135
impl Decryptor {
141
- pub ( super ) fn read ( & mut self , data : & [ u8 ] ) -> Result < ( ) , String > {
142
- let mut input_data = Some ( data) ;
143
136
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 ;
144
151
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;
147
155
self . decrypted_payloads . push_back ( result) ;
148
156
} ,
149
- Ok ( None ) => {
157
+ Ok ( ( None , 0 ) ) => {
158
+ self . read_buffer = Some ( buffer[ read_offset..] . to_vec ( ) ) ;
150
159
break ;
151
160
}
152
161
Err ( e) => {
153
162
return Err ( e) ;
154
163
}
164
+ Ok ( ( None , _) ) => { panic ! ( "Invalid return from decrypt_next()" ) }
155
165
}
156
- input_data = None ;
157
166
}
158
167
159
168
Ok ( ( ) )
160
169
}
161
170
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 {
178
175
panic ! ( "Attempted to decrypt message longer than 65535 + 16 bytes!" ) ;
179
176
}
180
177
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 > {
188
178
let message_length = if let Some ( length) = self . pending_message_length {
189
179
// we have already decrypted the header
190
180
length
@@ -272,10 +262,47 @@ mod tests {
272
262
let encrypted_message = connected_peer. encrypt ( & message) ;
273
263
assert_eq ! ( encrypted_message. len( ) , 2 + 16 + 16 ) ;
274
264
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 ( ) ;
276
267
assert_eq ! ( decrypted_message, Vec :: <u8 >:: new( ) ) ;
277
268
}
278
269
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
+
279
306
#[ test]
280
307
fn test_nonce_chaining ( ) {
281
308
let ( mut connected_peer, _remote_peer) = setup_peers ( ) ;
@@ -325,13 +352,16 @@ mod tests {
325
352
let mut current_encrypted_message = encrypted_messages. remove ( 0 ) ;
326
353
let next_encrypted_message = encrypted_messages. remove ( 0 ) ;
327
354
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 ( ) ;
329
358
assert_eq ! ( decrypted_message, message) ;
330
359
}
331
360
332
361
for _ in 0 ..501 {
333
362
// 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 ( ) ;
335
365
assert_eq ! ( decrypted_message, message) ;
336
366
}
337
367
}
@@ -376,7 +406,7 @@ mod tests {
376
406
fn max_message_len_encryption ( ) {
377
407
let ( mut connected_peer, _) = setup_peers ( ) ;
378
408
let msg = [ 4u8 ; LN_MAX_MSG_LEN + 1 ] ;
379
- connected_peer. encrypt ( & msg) ;
409
+ let _should_panic = connected_peer. encrypt ( & msg) ;
380
410
}
381
411
382
412
#[ test]
@@ -386,6 +416,6 @@ mod tests {
386
416
387
417
// MSG should not exceed LN_MAX_MSG_LEN + 16
388
418
let msg = [ 4u8 ; LN_MAX_MSG_LEN + 17 ] ;
389
- connected_peer. decrypt_single_message ( Some ( & msg) ) . unwrap ( ) ;
419
+ connected_peer. read ( & msg) . unwrap ( ) ;
390
420
}
391
421
}
0 commit comments