@@ -3,241 +3,14 @@ use std::os::unix::prelude::RawFd;
33use ktls_sys:: bindings as ktls;
44use rustls:: internal:: msgs:: enums:: AlertLevel ;
55use rustls:: internal:: msgs:: message:: Message ;
6- use rustls:: { AlertDescription , ConnectionTrafficSecrets , SupportedCipherSuite } ;
6+ use rustls:: AlertDescription ;
77
88pub ( crate ) const TLS_1_2_VERSION_NUMBER : u16 = ( ( ( ktls:: TLS_1_2_VERSION_MAJOR & 0xFF ) as u16 ) << 8 )
99 | ( ( ktls:: TLS_1_2_VERSION_MINOR & 0xFF ) as u16 ) ;
1010
1111pub ( crate ) const TLS_1_3_VERSION_NUMBER : u16 = ( ( ( ktls:: TLS_1_3_VERSION_MAJOR & 0xFF ) as u16 ) << 8 )
1212 | ( ( ktls:: TLS_1_3_VERSION_MINOR & 0xFF ) as u16 ) ;
1313
14- /// `setsockopt` level constant: TCP
15- const SOL_TCP : libc:: c_int = 6 ;
16-
17- /// `setsockopt` SOL_TCP name constant: "upper level protocol"
18- const TCP_ULP : libc:: c_int = 31 ;
19-
20- /// `setsockopt` level constant: TLS
21- const SOL_TLS : libc:: c_int = 282 ;
22-
23- /// `setsockopt` SOL_TLS level constant: transmit (write)
24- const TLS_TX : libc:: c_int = 1 ;
25-
26- /// `setsockopt` SOL_TLS level constant: receive (read)
27- const TLX_RX : libc:: c_int = 2 ;
28-
29- pub fn setup_ulp ( fd : RawFd ) -> std:: io:: Result < ( ) > {
30- unsafe {
31- if libc:: setsockopt (
32- fd,
33- SOL_TCP ,
34- TCP_ULP ,
35- "tls" . as_ptr ( ) as * const libc:: c_void ,
36- 3 ,
37- ) < 0
38- {
39- return Err ( std:: io:: Error :: last_os_error ( ) ) ;
40- }
41- }
42-
43- Ok ( ( ) )
44- }
45-
46- #[ derive( Clone , Copy , Debug ) ]
47- pub enum Direction {
48- // Transmit
49- Tx ,
50- // Receive
51- Rx ,
52- }
53-
54- impl From < Direction > for libc:: c_int {
55- fn from ( val : Direction ) -> Self {
56- match val {
57- Direction :: Tx => TLS_TX ,
58- Direction :: Rx => TLX_RX ,
59- }
60- }
61- }
62-
63- #[ allow( dead_code) ]
64- pub enum CryptoInfo {
65- AesGcm128 ( ktls:: tls12_crypto_info_aes_gcm_128 ) ,
66- AesGcm256 ( ktls:: tls12_crypto_info_aes_gcm_256 ) ,
67- AesCcm128 ( ktls:: tls12_crypto_info_aes_ccm_128 ) ,
68- Chacha20Poly1305 ( ktls:: tls12_crypto_info_chacha20_poly1305 ) ,
69- Sm4Gcm ( ktls:: tls12_crypto_info_sm4_gcm ) ,
70- Sm4Ccm ( ktls:: tls12_crypto_info_sm4_ccm ) ,
71- }
72-
73- impl CryptoInfo {
74- /// Return the system struct as a pointer.
75- pub fn as_ptr ( & self ) -> * const libc:: c_void {
76- match self {
77- CryptoInfo :: AesGcm128 ( info) => info as * const _ as * const libc:: c_void ,
78- CryptoInfo :: AesGcm256 ( info) => info as * const _ as * const libc:: c_void ,
79- CryptoInfo :: AesCcm128 ( info) => info as * const _ as * const libc:: c_void ,
80- CryptoInfo :: Chacha20Poly1305 ( info) => info as * const _ as * const libc:: c_void ,
81- CryptoInfo :: Sm4Gcm ( info) => info as * const _ as * const libc:: c_void ,
82- CryptoInfo :: Sm4Ccm ( info) => info as * const _ as * const libc:: c_void ,
83- }
84- }
85-
86- /// Return the system struct size.
87- pub fn size ( & self ) -> usize {
88- match self {
89- CryptoInfo :: AesGcm128 ( _) => std:: mem:: size_of :: < ktls:: tls12_crypto_info_aes_gcm_128 > ( ) ,
90- CryptoInfo :: AesGcm256 ( _) => std:: mem:: size_of :: < ktls:: tls12_crypto_info_aes_gcm_256 > ( ) ,
91- CryptoInfo :: AesCcm128 ( _) => std:: mem:: size_of :: < ktls:: tls12_crypto_info_aes_ccm_128 > ( ) ,
92- CryptoInfo :: Chacha20Poly1305 ( _) => {
93- std:: mem:: size_of :: < ktls:: tls12_crypto_info_chacha20_poly1305 > ( )
94- }
95- CryptoInfo :: Sm4Gcm ( _) => std:: mem:: size_of :: < ktls:: tls12_crypto_info_sm4_gcm > ( ) ,
96- CryptoInfo :: Sm4Ccm ( _) => std:: mem:: size_of :: < ktls:: tls12_crypto_info_sm4_ccm > ( ) ,
97- }
98- }
99- }
100-
101- #[ derive( thiserror:: Error , Debug ) ]
102- pub enum KtlsCompatibilityError {
103- #[ error( "cipher suite not supported with kTLS: {0:?}" ) ]
104- UnsupportedCipherSuite ( SupportedCipherSuite ) ,
105-
106- #[ error( "wrong size key" ) ]
107- WrongSizeKey ,
108-
109- #[ error( "wrong size iv" ) ]
110- WrongSizeIv ,
111- }
112-
113- impl CryptoInfo {
114- /// Try to convert rustls cipher suite and secrets into a `CryptoInfo`.
115- pub fn from_rustls (
116- cipher_suite : SupportedCipherSuite ,
117- ( seq, secrets) : ( u64 , ConnectionTrafficSecrets ) ,
118- ) -> Result < CryptoInfo , KtlsCompatibilityError > {
119- let version = match cipher_suite {
120- SupportedCipherSuite :: Tls12 ( ..) => TLS_1_2_VERSION_NUMBER ,
121- SupportedCipherSuite :: Tls13 ( ..) => TLS_1_3_VERSION_NUMBER ,
122- } ;
123-
124- Ok ( match secrets {
125- ConnectionTrafficSecrets :: Aes128Gcm { key, iv } => {
126- // see https://github.com/rustls/rustls/issues/1833, between
127- // rustls 0.21 and 0.22, the extract_keys codepath was changed,
128- // so, for TLS 1.2, both GCM-128 and GCM-256 return the
129- // Aes128Gcm variant.
130-
131- match key. as_ref ( ) . len ( ) {
132- 16 => CryptoInfo :: AesGcm128 ( ktls:: tls12_crypto_info_aes_gcm_128 {
133- info : ktls:: tls_crypto_info {
134- version,
135- cipher_type : ktls:: TLS_CIPHER_AES_GCM_128 as _ ,
136- } ,
137- iv : iv
138- . as_ref ( )
139- . get ( 4 ..)
140- . expect ( "AES-GCM-128 iv is 8 bytes" )
141- . try_into ( )
142- . expect ( "AES-GCM-128 iv is 8 bytes" ) ,
143- key : key
144- . as_ref ( )
145- . try_into ( )
146- . expect ( "AES-GCM-128 key is 16 bytes" ) ,
147- salt : iv
148- . as_ref ( )
149- . get ( ..4 )
150- . expect ( "AES-GCM-128 salt is 4 bytes" )
151- . try_into ( )
152- . expect ( "AES-GCM-128 salt is 4 bytes" ) ,
153- rec_seq : seq. to_be_bytes ( ) ,
154- } ) ,
155- 32 => CryptoInfo :: AesGcm256 ( ktls:: tls12_crypto_info_aes_gcm_256 {
156- info : ktls:: tls_crypto_info {
157- version,
158- cipher_type : ktls:: TLS_CIPHER_AES_GCM_256 as _ ,
159- } ,
160- iv : iv
161- . as_ref ( )
162- . get ( 4 ..)
163- . expect ( "AES-GCM-256 iv is 8 bytes" )
164- . try_into ( )
165- . expect ( "AES-GCM-256 iv is 8 bytes" ) ,
166- key : key
167- . as_ref ( )
168- . try_into ( )
169- . expect ( "AES-GCM-256 key is 32 bytes" ) ,
170- salt : iv
171- . as_ref ( )
172- . get ( ..4 )
173- . expect ( "AES-GCM-256 salt is 4 bytes" )
174- . try_into ( )
175- . expect ( "AES-GCM-256 salt is 4 bytes" ) ,
176- rec_seq : seq. to_be_bytes ( ) ,
177- } ) ,
178- _ => unreachable ! ( "GCM key length is not 16 or 32" ) ,
179- }
180- }
181- ConnectionTrafficSecrets :: Aes256Gcm { key, iv } => {
182- CryptoInfo :: AesGcm256 ( ktls:: tls12_crypto_info_aes_gcm_256 {
183- info : ktls:: tls_crypto_info {
184- version,
185- cipher_type : ktls:: TLS_CIPHER_AES_GCM_256 as _ ,
186- } ,
187- iv : iv
188- . as_ref ( )
189- . get ( 4 ..)
190- . expect ( "AES-GCM-256 iv is 8 bytes" )
191- . try_into ( )
192- . expect ( "AES-GCM-256 iv is 8 bytes" ) ,
193- key : key
194- . as_ref ( )
195- . try_into ( )
196- . expect ( "AES-GCM-256 key is 32 bytes" ) ,
197- salt : iv
198- . as_ref ( )
199- . get ( ..4 )
200- . expect ( "AES-GCM-256 salt is 4 bytes" )
201- . try_into ( )
202- . expect ( "AES-GCM-256 salt is 4 bytes" ) ,
203- rec_seq : seq. to_be_bytes ( ) ,
204- } )
205- }
206- ConnectionTrafficSecrets :: Chacha20Poly1305 { key, iv } => {
207- CryptoInfo :: Chacha20Poly1305 ( ktls:: tls12_crypto_info_chacha20_poly1305 {
208- info : ktls:: tls_crypto_info {
209- version,
210- cipher_type : ktls:: TLS_CIPHER_CHACHA20_POLY1305 as _ ,
211- } ,
212- iv : iv
213- . as_ref ( )
214- . try_into ( )
215- . expect ( "Chacha20-Poly1305 iv is 12 bytes" ) ,
216- key : key
217- . as_ref ( )
218- . try_into ( )
219- . expect ( "Chacha20-Poly1305 key is 32 bytes" ) ,
220- salt : ktls:: __IncompleteArrayField:: new ( ) ,
221- rec_seq : seq. to_be_bytes ( ) ,
222- } )
223- }
224- _ => {
225- return Err ( KtlsCompatibilityError :: UnsupportedCipherSuite ( cipher_suite) ) ;
226- }
227- } )
228- }
229- }
230-
231- pub fn setup_tls_info ( fd : RawFd , dir : Direction , info : CryptoInfo ) -> Result < ( ) , crate :: Error > {
232- let ret = unsafe { libc:: setsockopt ( fd, SOL_TLS , dir. into ( ) , info. as_ptr ( ) , info. size ( ) as _ ) } ;
233- if ret < 0 {
234- return Err ( crate :: Error :: TlsCryptoInfoError (
235- std:: io:: Error :: last_os_error ( ) ,
236- ) ) ;
237- }
238- Ok ( ( ) )
239- }
240-
24114const TLS_SET_RECORD_TYPE : libc:: c_int = 1 ;
24215const ALERT : u8 = 0x15 ;
24316
0 commit comments