@@ -15,35 +15,120 @@ const KEY_ROTATION_INDEX: u32 = 1000;
15
15
/// Automatically handles key rotation.
16
16
/// For decryption, it is recommended to call `decrypt_message_stream` for automatic buffering.
17
17
pub struct Conduit {
18
- pub ( crate ) sending_key : SymmetricKey ,
19
- pub ( crate ) receiving_key : SymmetricKey ,
18
+ pub ( super ) encryptor : Encryptor ,
19
+ pub ( super ) decryptor : Decryptor
20
20
21
- pub ( crate ) sending_chaining_key : SymmetricKey ,
22
- pub ( crate ) receiving_chaining_key : SymmetricKey ,
21
+ }
22
+
23
+ pub ( super ) struct Encryptor {
24
+ sending_key : SymmetricKey ,
25
+ sending_chaining_key : SymmetricKey ,
26
+ sending_nonce : u32 ,
27
+ }
23
28
24
- pub ( crate ) receiving_nonce : u32 ,
25
- pub ( crate ) sending_nonce : u32 ,
29
+ pub ( super ) struct Decryptor {
30
+ receiving_key : SymmetricKey ,
31
+ receiving_chaining_key : SymmetricKey ,
32
+ receiving_nonce : u32 ,
26
33
27
- pub ( super ) read_buffer : Option < Vec < u8 > > ,
34
+ pending_message_length : Option < usize > ,
35
+ read_buffer : Option < Vec < u8 > > ,
36
+ }
37
+
38
+ impl Iterator for Decryptor {
39
+ type Item = Vec < u8 > ;
40
+
41
+ fn next ( & mut self ) -> Option < Self :: Item > {
42
+ self . decrypt_single_message ( None )
43
+ }
28
44
}
29
45
30
46
impl Conduit {
47
+ /// Instantiate a new Conduit with specified sending and receiving keys
48
+ pub fn new ( sending_key : SymmetricKey , sending_chaining_key : SymmetricKey , receiving_key : SymmetricKey , receiving_chaining_key : SymmetricKey ) -> Self {
49
+ Conduit {
50
+ encryptor : Encryptor {
51
+ sending_key,
52
+ sending_chaining_key,
53
+ sending_nonce : 0
54
+ } ,
55
+ decryptor : Decryptor {
56
+ receiving_key,
57
+ receiving_chaining_key,
58
+ receiving_nonce : 0 ,
59
+ read_buffer : None ,
60
+ pending_message_length : None
61
+ }
62
+ }
63
+ }
64
+
31
65
/// Encrypt data to be sent to peer
32
66
pub fn encrypt ( & mut self , buffer : & [ u8 ] ) -> Vec < u8 > {
67
+ self . encryptor . encrypt ( buffer)
68
+ }
69
+
70
+ pub ( super ) fn read ( & mut self , data : & [ u8 ] ) {
71
+ self . decryptor . read ( data)
72
+ }
73
+
74
+ /// Decrypt a single message. If data containing more than one message has been received,
75
+ /// only the first message will be returned, and the rest stored in the internal buffer.
76
+ /// If a message pending in the buffer still hasn't been decrypted, that message will be
77
+ /// returned in lieu of anything new, even if new data is provided.
78
+ pub fn decrypt_single_message ( & mut self , new_data : Option < & [ u8 ] > ) -> Option < Vec < u8 > > {
79
+ self . decryptor . decrypt_single_message ( new_data)
80
+ }
81
+
82
+ /// Decrypt a message from the beginning of the provided buffer. Returns the consumed number of bytes.
83
+ fn decrypt ( & mut self , buffer : & [ u8 ] ) -> ( Option < Vec < u8 > > , usize ) {
84
+ self . decryptor . decrypt ( buffer)
85
+ }
86
+
87
+ fn increment_sending_nonce ( & mut self ) {
88
+ self . encryptor . increment_nonce ( )
89
+ }
90
+
91
+ fn increment_receiving_nonce ( & mut self ) {
92
+ self . decryptor . increment_nonce ( )
93
+ }
94
+
95
+ fn increment_nonce ( nonce : & mut u32 , chaining_key : & mut SymmetricKey , key : & mut SymmetricKey ) {
96
+ * nonce += 1 ;
97
+ if * nonce == KEY_ROTATION_INDEX {
98
+ Self :: rotate_key ( chaining_key, key) ;
99
+ * nonce = 0 ;
100
+ }
101
+ }
102
+
103
+ fn rotate_key ( chaining_key : & mut SymmetricKey , key : & mut SymmetricKey ) {
104
+ let ( new_chaining_key, new_key) = hkdf:: derive ( chaining_key, key) ;
105
+ chaining_key. copy_from_slice ( & new_chaining_key) ;
106
+ key. copy_from_slice ( & new_key) ;
107
+ }
108
+ }
109
+
110
+ impl Encryptor {
111
+ pub ( super ) fn encrypt ( & mut self , buffer : & [ u8 ] ) -> Vec < u8 > {
33
112
let length = buffer. len ( ) as u16 ;
34
113
let length_bytes = byte_utils:: be16_to_array ( length) ;
35
114
36
115
let mut ciphertext = vec ! [ 0u8 ; TAGGED_MESSAGE_LENGTH_HEADER_SIZE + length as usize + chacha:: TAG_SIZE ] ;
37
116
38
117
ciphertext[ 0 ..TAGGED_MESSAGE_LENGTH_HEADER_SIZE ] . copy_from_slice ( & chacha:: encrypt ( & self . sending_key , self . sending_nonce as u64 , & [ 0 ; 0 ] , & length_bytes) ) ;
39
- self . increment_sending_nonce ( ) ;
118
+ self . increment_nonce ( ) ;
40
119
41
120
ciphertext[ TAGGED_MESSAGE_LENGTH_HEADER_SIZE ..] . copy_from_slice ( & chacha:: encrypt ( & self . sending_key , self . sending_nonce as u64 , & [ 0 ; 0 ] , buffer) ) ;
42
- self . increment_sending_nonce ( ) ;
121
+ self . increment_nonce ( ) ;
43
122
44
123
ciphertext
45
124
}
46
125
126
+ fn increment_nonce ( & mut self ) {
127
+ Conduit :: increment_nonce ( & mut self . sending_nonce , & mut self . sending_chaining_key , & mut self . sending_key ) ;
128
+ }
129
+ }
130
+
131
+ impl Decryptor {
47
132
pub ( super ) fn read ( & mut self , data : & [ u8 ] ) {
48
133
let read_buffer = self . read_buffer . get_or_insert ( Vec :: new ( ) ) ;
49
134
read_buffer. extend_from_slice ( data) ;
@@ -70,61 +155,53 @@ impl Conduit {
70
155
current_message
71
156
}
72
157
73
- /// Decrypt a message from the beginning of the provided buffer. Returns the consumed number of bytes.
74
158
fn decrypt ( & mut self , buffer : & [ u8 ] ) -> ( Option < Vec < u8 > > , usize ) {
75
- if buffer. len ( ) < TAGGED_MESSAGE_LENGTH_HEADER_SIZE {
76
- // A message must be at least 18 bytes (2 for encrypted length, 16 for the tag)
77
- return ( None , 0 ) ;
78
- }
159
+ let message_length = if let Some ( length) = self . pending_message_length {
160
+ // we have already decrypted the header
161
+ length
162
+ } else {
163
+ if buffer. len ( ) < TAGGED_MESSAGE_LENGTH_HEADER_SIZE {
164
+ // A message must be at least 18 bytes (2 for encrypted length, 16 for the tag)
165
+ return ( None , 0 ) ;
166
+ }
167
+
168
+ let encrypted_length = & buffer[ 0 ..TAGGED_MESSAGE_LENGTH_HEADER_SIZE ] ;
169
+ let mut length_bytes = [ 0u8 ; MESSAGE_LENGTH_HEADER_SIZE ] ;
170
+ length_bytes. copy_from_slice ( & chacha:: decrypt ( & self . receiving_key , self . receiving_nonce as u64 , & [ 0 ; 0 ] , encrypted_length) . unwrap ( ) ) ;
79
171
80
- let encrypted_length = & buffer [ 0 .. TAGGED_MESSAGE_LENGTH_HEADER_SIZE ] ;
81
- let mut length_bytes = [ 0u8 ; MESSAGE_LENGTH_HEADER_SIZE ] ;
82
- length_bytes . copy_from_slice ( & chacha :: decrypt ( & self . receiving_key , self . receiving_nonce as u64 , & [ 0 ; 0 ] , encrypted_length ) . unwrap ( ) ) ;
83
- // message_length is the length of the encrypted message excluding its trailing 16-byte tag
84
- let message_length = byte_utils :: slice_to_be16 ( & length_bytes ) as usize ;
172
+ self . increment_nonce ( ) ;
173
+
174
+ // the message length
175
+ byte_utils :: slice_to_be16 ( & length_bytes ) as usize
176
+ } ;
85
177
86
178
let message_end_index = TAGGED_MESSAGE_LENGTH_HEADER_SIZE + message_length + chacha:: TAG_SIZE ;
179
+
87
180
if buffer. len ( ) < message_end_index {
181
+ self . pending_message_length = Some ( message_length) ;
88
182
return ( None , 0 ) ;
89
183
}
90
184
91
- let encrypted_message = & buffer [ TAGGED_MESSAGE_LENGTH_HEADER_SIZE ..message_end_index ] ;
185
+ self . pending_message_length = None ;
92
186
93
- self . increment_receiving_nonce ( ) ;
187
+ let encrypted_message = & buffer [ TAGGED_MESSAGE_LENGTH_HEADER_SIZE ..message_end_index ] ;
94
188
95
189
let message = chacha:: decrypt ( & self . receiving_key , self . receiving_nonce as u64 , & [ 0 ; 0 ] , encrypted_message) . unwrap ( ) ;
96
190
97
- self . increment_receiving_nonce ( ) ;
191
+ self . increment_nonce ( ) ;
98
192
99
193
( Some ( message) , message_end_index)
100
194
}
101
195
102
- fn increment_sending_nonce ( & mut self ) {
103
- Self :: increment_nonce ( & mut self . sending_nonce , & mut self . sending_chaining_key , & mut self . sending_key ) ;
104
- }
105
-
106
- fn increment_receiving_nonce ( & mut self ) {
107
- Self :: increment_nonce ( & mut self . receiving_nonce , & mut self . receiving_chaining_key , & mut self . receiving_key ) ;
108
- }
109
-
110
- fn increment_nonce ( nonce : & mut u32 , chaining_key : & mut SymmetricKey , key : & mut SymmetricKey ) {
111
- * nonce += 1 ;
112
- if * nonce == KEY_ROTATION_INDEX {
113
- Self :: rotate_key ( chaining_key, key) ;
114
- * nonce = 0 ;
115
- }
116
- }
117
-
118
- fn rotate_key ( chaining_key : & mut SymmetricKey , key : & mut SymmetricKey ) {
119
- let ( new_chaining_key, new_key) = hkdf:: derive ( chaining_key, key) ;
120
- chaining_key. copy_from_slice ( & new_chaining_key) ;
121
- key. copy_from_slice ( & new_key) ;
196
+ fn increment_nonce ( & mut self ) {
197
+ Conduit :: increment_nonce ( & mut self . receiving_nonce , & mut self . receiving_chaining_key , & mut self . receiving_key ) ;
122
198
}
123
199
}
124
200
125
201
#[ cfg( test) ]
126
202
mod tests {
127
203
use hex;
204
+
128
205
use ln:: peers:: conduit:: Conduit ;
129
206
130
207
fn setup_peers ( ) -> ( Conduit , Conduit ) {
@@ -140,25 +217,8 @@ mod tests {
140
217
let mut receiving_key = [ 0u8 ; 32 ] ;
141
218
receiving_key. copy_from_slice ( & receiving_key_vec) ;
142
219
143
- let connected_peer = Conduit {
144
- sending_key,
145
- receiving_key,
146
- sending_chaining_key : chaining_key,
147
- receiving_chaining_key : chaining_key,
148
- sending_nonce : 0 ,
149
- receiving_nonce : 0 ,
150
- read_buffer : None ,
151
- } ;
152
-
153
- let remote_peer = Conduit {
154
- sending_key : receiving_key,
155
- receiving_key : sending_key,
156
- sending_chaining_key : chaining_key,
157
- receiving_chaining_key : chaining_key,
158
- sending_nonce : 0 ,
159
- receiving_nonce : 0 ,
160
- read_buffer : None ,
161
- } ;
220
+ let connected_peer = Conduit :: new ( sending_key, chaining_key, receiving_key, chaining_key) ;
221
+ let remote_peer = Conduit :: new ( receiving_key, chaining_key, sending_key, chaining_key) ;
162
222
163
223
( connected_peer, remote_peer)
164
224
}
0 commit comments