@@ -3,6 +3,8 @@ use super::*;
3
3
use std:: mem:: MaybeUninit ;
4
4
5
5
use libc:: c_int;
6
+ use libc:: c_uint;
7
+ use libc:: c_void;
6
8
7
9
// NOTE: This structure is copied from <openssl/aead.h> in order to be able to
8
10
// statically allocate it. While it is not often modified upstream, it needs to
@@ -15,6 +17,13 @@ struct EVP_AEAD_CTX {
15
17
tag_len : u8 ,
16
18
}
17
19
20
+ #[ derive( Clone ) ]
21
+ #[ repr( C ) ]
22
+ pub ( crate ) struct AES_KEY {
23
+ rd_key : [ u32 ; 4 * ( 14 + 1 ) ] ,
24
+ rounds : c_int ,
25
+ }
26
+
18
27
impl Algorithm {
19
28
fn get_evp_aead ( self ) -> * const EVP_AEAD {
20
29
match self {
@@ -126,29 +135,87 @@ impl Seal {
126
135
}
127
136
}
128
137
129
- fn make_aead_ctx ( alg : Algorithm , key : & [ u8 ] ) -> Result < EVP_AEAD_CTX > {
130
- let mut ctx = MaybeUninit :: uninit ( ) ;
138
+ #[ derive( Clone ) ]
139
+ pub ( crate ) enum HeaderProtectionKey {
140
+ Aes ( AES_KEY ) ,
131
141
132
- let ctx = unsafe {
133
- let aead = alg . get_evp_aead ( ) ;
142
+ ChaCha ( Vec < u8 > ) ,
143
+ }
134
144
135
- let rc = EVP_AEAD_CTX_init (
136
- ctx. as_mut_ptr ( ) ,
137
- aead,
138
- key. as_ptr ( ) ,
139
- alg. key_len ( ) ,
140
- alg. tag_len ( ) ,
141
- std:: ptr:: null_mut ( ) ,
142
- ) ;
145
+ impl HeaderProtectionKey {
146
+ pub fn new ( alg : Algorithm , hp_key : Vec < u8 > ) -> Result < Self > {
147
+ match alg {
148
+ Algorithm :: AES128_GCM => unsafe {
149
+ let mut aes_key = MaybeUninit :: < AES_KEY > :: uninit ( ) ;
143
150
144
- if rc != 1 {
145
- return Err ( Error :: CryptoFail ) ;
151
+ let rc = AES_set_encrypt_key (
152
+ ( & hp_key) . as_ptr ( ) ,
153
+ 128 ,
154
+ aes_key. as_mut_ptr ( ) ,
155
+ ) ;
156
+
157
+ if rc != 0 {
158
+ return Err ( Error :: CryptoFail ) ;
159
+ }
160
+
161
+ let aes_key = aes_key. assume_init ( ) ;
162
+ Ok ( Self :: Aes ( aes_key) )
163
+ } ,
164
+
165
+ Algorithm :: AES256_GCM => unsafe {
166
+ let mut aes_key = MaybeUninit :: < AES_KEY > :: uninit ( ) ;
167
+
168
+ let rc = AES_set_encrypt_key (
169
+ ( & hp_key) . as_ptr ( ) ,
170
+ 256 ,
171
+ aes_key. as_mut_ptr ( ) ,
172
+ ) ;
173
+
174
+ if rc != 0 {
175
+ return Err ( Error :: CryptoFail ) ;
176
+ }
177
+
178
+ let aes_key = aes_key. assume_init ( ) ;
179
+ Ok ( Self :: Aes ( aes_key) )
180
+ } ,
181
+
182
+ Algorithm :: ChaCha20_Poly1305 => Ok ( Self :: ChaCha ( hp_key) ) ,
146
183
}
184
+ }
147
185
148
- ctx . assume_init ( )
149
- } ;
186
+ pub fn new_mask ( & self , sample : & [ u8 ] ) -> Result < [ u8 ; 5 ] > {
187
+ let mut new_mask = [ 0_u8 ; 5 ] ;
150
188
151
- Ok ( ctx)
189
+ match self {
190
+ Self :: Aes ( aes_key) => unsafe {
191
+ AES_ecb_encrypt (
192
+ sample. as_ptr ( ) ,
193
+ ( & mut new_mask) . as_mut_ptr ( ) ,
194
+ aes_key as _ ,
195
+ 1 ,
196
+ ) ;
197
+ } ,
198
+
199
+ Self :: ChaCha ( key) => unsafe {
200
+ const PLAINTEXT : & [ u8 ; 5 ] = b"\x00 \x00 \x00 \x00 \x00 " ;
201
+
202
+ let counter = u32:: from_le_bytes ( [
203
+ sample[ 0 ] , sample[ 1 ] , sample[ 2 ] , sample[ 3 ] ,
204
+ ] ) ;
205
+
206
+ CRYPTO_chacha_20 (
207
+ ( & mut new_mask) . as_mut_ptr ( ) ,
208
+ PLAINTEXT . as_ptr ( ) ,
209
+ PLAINTEXT . len ( ) ,
210
+ ( & key) . as_ptr ( ) ,
211
+ ( & sample[ std:: mem:: size_of :: < u32 > ( ) ..] ) . as_ptr ( ) ,
212
+ counter,
213
+ ) ;
214
+ } ,
215
+ }
216
+
217
+ Ok ( new_mask)
218
+ }
152
219
}
153
220
154
221
pub ( crate ) struct PacketKey {
@@ -180,6 +247,31 @@ impl PacketKey {
180
247
}
181
248
}
182
249
250
+ fn make_aead_ctx ( alg : Algorithm , key : & [ u8 ] ) -> Result < EVP_AEAD_CTX > {
251
+ let mut ctx = MaybeUninit :: uninit ( ) ;
252
+
253
+ let ctx = unsafe {
254
+ let aead = alg. get_evp_aead ( ) ;
255
+
256
+ let rc = EVP_AEAD_CTX_init (
257
+ ctx. as_mut_ptr ( ) ,
258
+ aead,
259
+ key. as_ptr ( ) ,
260
+ alg. key_len ( ) ,
261
+ alg. tag_len ( ) ,
262
+ std:: ptr:: null_mut ( ) ,
263
+ ) ;
264
+
265
+ if rc != 1 {
266
+ return Err ( Error :: CryptoFail ) ;
267
+ }
268
+
269
+ ctx. assume_init ( )
270
+ } ;
271
+
272
+ Ok ( ctx)
273
+ }
274
+
183
275
pub ( crate ) fn hkdf_extract (
184
276
alg : Algorithm , out : & mut [ u8 ] , secret : & [ u8 ] , salt : & [ u8 ] ,
185
277
) -> Result < ( ) > {
@@ -262,4 +354,19 @@ extern {
262
354
nonce_len : usize , inp : * const u8 , in_len : usize , extra_in : * const u8 ,
263
355
extra_in_len : usize , ad : * const u8 , ad_len : usize ,
264
356
) -> c_int ;
357
+
358
+ // AES
359
+ fn AES_set_encrypt_key (
360
+ key : * const u8 , bits : c_uint , aeskey : * mut AES_KEY ,
361
+ ) -> c_int ;
362
+
363
+ fn AES_ecb_encrypt (
364
+ inp : * const u8 , out : * mut u8 , key : * const AES_KEY , enc : c_int ,
365
+ ) -> c_void ;
366
+
367
+ // ChaCha20
368
+ fn CRYPTO_chacha_20 (
369
+ out : * mut u8 , inp : * const u8 , in_len : usize , key : * const u8 ,
370
+ nonce : * const u8 , counter : u32 ,
371
+ ) -> c_void ;
265
372
}
0 commit comments