@@ -38,9 +38,12 @@ compile_error!("Rustls currently does not support alloc-less environments");
38
38
#[ cfg( feature = "alloc" ) ]
39
39
extern crate alloc;
40
40
41
+ use core:: { cell:: OnceCell , fmt:: Debug } ;
42
+
41
43
#[ cfg( feature = "alloc" ) ]
42
- use alloc:: sync:: Arc ;
44
+ use alloc:: { boxed :: Box , sync:: Arc } ;
43
45
46
+ use rand_core:: { CryptoRng , RngCore } ;
44
47
use rustls:: crypto:: {
45
48
CipherSuiteCommon , CryptoProvider , GetRandomFailed , KeyProvider , SecureRandom ,
46
49
} ;
@@ -49,7 +52,7 @@ use rustls::{CipherSuite, SupportedCipherSuite, Tls13CipherSuite};
49
52
#[ cfg( feature = "tls12" ) ]
50
53
use rustls:: SignatureScheme ;
51
54
52
- #[ derive( Debug ) ]
55
+ #[ derive( Debug , Clone ) ]
53
56
pub struct Provider ;
54
57
55
58
pub fn provider ( ) -> CryptoProvider {
@@ -62,15 +65,76 @@ pub fn provider() -> CryptoProvider {
62
65
}
63
66
}
64
67
68
+ // TODO: switch to ThinBox once it is available
69
+ #[ cfg( feature = "alloc" ) ]
70
+ static mut RNG : OnceCell < Box < dyn RngCore + Send + Sync > > = OnceCell :: new ( ) ;
71
+
72
+ #[ cfg( feature = "alloc" ) ]
73
+ fn get_rng_danger ( ) -> & ' static mut ( dyn RngCore + Send + Sync ) {
74
+ #[ cfg( feature = "getrandom" ) ]
75
+ #[ allow( static_mut_refs) ]
76
+ // SAFETY: we only init the randomness source if the once cell was not initialized
77
+ unsafe {
78
+ // TODO: Add unlikely(...) later when it is stabilized for faster speculative branch
79
+ if RNG . get ( ) . is_none ( ) {
80
+ // This would either set the randomness source or panic, in other word, infallible
81
+ init_randomness_source ( Box :: new ( rand_core:: OsRng ) ) ;
82
+ }
83
+ }
84
+
85
+ // SAFETY: If randomness source is not already set, the whole program panics due to the unwrap
86
+ // UNSAFETY: If you have a memory corruption (whether stack or heap or not), this could
87
+ #[ allow( static_mut_refs) ]
88
+ unsafe {
89
+ RNG . get_mut ( ) . expect ( "RNG was not set" ) . as_mut ( )
90
+ }
91
+ }
92
+
93
+ // Initialize an RNG source, and panic if it was already set, which would only happen if two threads set the data at the same time.
94
+ // This ensures the user would have to decide on the RNG source at the very beginning, likely the first function call in main and find way to provide entropy themselves
95
+ // TIP: Use Box::from_raw to prevent having to do real heap allocation if you can assume your program to be single-threaded and your put RNG state as a global variable
96
+ #[ cfg( feature = "alloc" ) ]
97
+ pub fn init_randomness_source ( rng : Box < dyn RngCore + Send + Sync > ) {
98
+ // SAFETY: If randomness source is already set, the whole program panics
99
+ #[ allow( static_mut_refs) ]
100
+ unsafe {
101
+ if RNG . set ( rng) . is_err ( ) {
102
+ panic ! ( "RNG was set twice" )
103
+ }
104
+ }
105
+ }
106
+
107
+ #[ cfg( feature = "alloc" ) ]
65
108
impl SecureRandom for Provider {
66
109
fn fill ( & self , bytes : & mut [ u8 ] ) -> Result < ( ) , GetRandomFailed > {
67
- use rand_core:: RngCore ;
68
- rand_core:: OsRng
110
+ get_rng_danger ( )
69
111
. try_fill_bytes ( bytes)
70
112
. map_err ( |_| GetRandomFailed )
71
113
}
72
114
}
73
115
116
+ #[ cfg( feature = "alloc" ) ]
117
+ impl RngCore for Provider {
118
+ fn next_u32 ( & mut self ) -> u32 {
119
+ get_rng_danger ( ) . next_u32 ( )
120
+ }
121
+
122
+ fn next_u64 ( & mut self ) -> u64 {
123
+ get_rng_danger ( ) . next_u64 ( )
124
+ }
125
+
126
+ fn fill_bytes ( & mut self , dest : & mut [ u8 ] ) {
127
+ get_rng_danger ( ) . fill_bytes ( dest)
128
+ }
129
+
130
+ fn try_fill_bytes ( & mut self , dest : & mut [ u8 ] ) -> Result < ( ) , rand_core:: Error > {
131
+ get_rng_danger ( ) . try_fill_bytes ( dest)
132
+ }
133
+ }
134
+
135
+ #[ cfg( feature = "alloc" ) ]
136
+ impl CryptoRng for Provider { }
137
+
74
138
impl KeyProvider for Provider {
75
139
fn load_private_key (
76
140
& self ,
@@ -81,15 +145,15 @@ impl KeyProvider for Provider {
81
145
}
82
146
83
147
#[ cfg( feature = "tls12" ) ]
84
- const TLS12_ECDSA_SCHEMES : [ SignatureScheme ; 4 ] = [
148
+ pub const TLS12_ECDSA_SCHEMES : [ SignatureScheme ; 4 ] = [
85
149
SignatureScheme :: ECDSA_NISTP256_SHA256 ,
86
150
SignatureScheme :: ECDSA_NISTP384_SHA384 ,
87
151
SignatureScheme :: ECDSA_NISTP521_SHA512 ,
88
152
SignatureScheme :: ED25519 ,
89
153
] ;
90
154
91
155
#[ cfg( feature = "tls12" ) ]
92
- const TLS12_RSA_SCHEMES : [ SignatureScheme ; 6 ] = [
156
+ pub const TLS12_RSA_SCHEMES : [ SignatureScheme ; 6 ] = [
93
157
SignatureScheme :: RSA_PKCS1_SHA256 ,
94
158
SignatureScheme :: RSA_PKCS1_SHA384 ,
95
159
SignatureScheme :: RSA_PKCS1_SHA512 ,
@@ -190,21 +254,21 @@ pub const TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: SupportedCipherSuite =
190
254
} ) ;
191
255
192
256
#[ cfg( feature = "tls12" ) ]
193
- const TLS_ECDHE_RSA_SUITES : & [ SupportedCipherSuite ] = & [
257
+ pub const TLS_ECDHE_RSA_SUITES : & [ SupportedCipherSuite ] = & [
194
258
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ,
195
259
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ,
196
260
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 ,
197
261
] ;
198
262
199
263
#[ cfg( feature = "tls12" ) ]
200
- const TLS12_SUITES : & [ SupportedCipherSuite ] = misc:: const_concat_slices!(
264
+ pub const TLS12_SUITES : & [ SupportedCipherSuite ] = misc:: const_concat_slices!(
201
265
SupportedCipherSuite ,
202
266
TLS_ECDHE_ECDSA_SUITES ,
203
267
TLS_ECDHE_RSA_SUITES
204
268
) ;
205
269
206
270
#[ cfg( not( feature = "tls12" ) ) ]
207
- const TLS12_SUITES : & [ SupportedCipherSuite ] = & [ ] ;
271
+ pub const TLS12_SUITES : & [ SupportedCipherSuite ] = & [ ] ;
208
272
209
273
pub const TLS13_AES_128_GCM_SHA256 : SupportedCipherSuite =
210
274
SupportedCipherSuite :: Tls13 ( & Tls13CipherSuite {
@@ -230,7 +294,7 @@ pub const TLS13_AES_256_GCM_SHA384: SupportedCipherSuite =
230
294
quic : None ,
231
295
} ) ;
232
296
233
- const TLS13_AES_SUITES : & [ SupportedCipherSuite ] =
297
+ pub const TLS13_AES_SUITES : & [ SupportedCipherSuite ] =
234
298
& [ TLS13_AES_128_GCM_SHA256 , TLS13_AES_256_GCM_SHA384 ] ;
235
299
236
300
pub const TLS13_CHACHA20_POLY1305_SHA256 : SupportedCipherSuite =
@@ -245,13 +309,13 @@ pub const TLS13_CHACHA20_POLY1305_SHA256: SupportedCipherSuite =
245
309
quic : None ,
246
310
} ) ;
247
311
248
- const TLS13_SUITES : & [ SupportedCipherSuite ] = misc:: const_concat_slices!(
312
+ pub const TLS13_SUITES : & [ SupportedCipherSuite ] = misc:: const_concat_slices!(
249
313
SupportedCipherSuite ,
250
314
TLS13_AES_SUITES ,
251
315
& [ TLS13_CHACHA20_POLY1305_SHA256 ]
252
316
) ;
253
317
254
- static ALL_CIPHER_SUITES : & [ SupportedCipherSuite ] = misc:: const_concat_slices!(
318
+ pub static ALL_CIPHER_SUITES : & [ SupportedCipherSuite ] = misc:: const_concat_slices!(
255
319
SupportedCipherSuite ,
256
320
if cfg!( feature = "tls12" ) {
257
321
TLS12_SUITES
0 commit comments