@@ -137,9 +137,11 @@ mod imp {
137
137
}
138
138
}
139
139
140
- #[ cfg( any ( target_os = "macos" , target_os = "ios" , target_os = "watchos" ) ) ]
140
+ #[ cfg( target_os = "macos" ) ]
141
141
mod imp {
142
- use crate :: io;
142
+ use crate :: fs:: File ;
143
+ use crate :: io:: Read ;
144
+ use crate :: sys:: os:: errno;
143
145
use crate :: sys:: weak:: weak;
144
146
use libc:: { c_int, c_void, size_t} ;
145
147
@@ -153,72 +155,22 @@ mod imp {
153
155
for s in v. chunks_mut ( 256 ) {
154
156
let ret = unsafe { f ( s. as_mut_ptr ( ) as * mut c_void , s. len ( ) ) } ;
155
157
if ret == -1 {
156
- panic ! ( "unexpected getentropy error: {}" , io :: Error :: last_os_error ( ) ) ;
158
+ panic ! ( "unexpected getentropy error: {}" , errno ( ) ) ;
157
159
}
158
160
}
159
161
true
160
162
} )
161
163
. unwrap_or ( false )
162
164
}
163
165
164
- #[ cfg( target_os = "macos" ) ]
165
- fn fallback_fill_bytes ( v : & mut [ u8 ] ) {
166
- use crate :: fs:: File ;
167
- use crate :: io:: Read ;
168
-
169
- let mut file = File :: open ( "/dev/urandom" ) . expect ( "failed to open /dev/urandom" ) ;
170
- file. read_exact ( v) . expect ( "failed to read /dev/urandom" )
171
- }
172
-
173
- // On iOS and MacOS `SecRandomCopyBytes` calls `CCRandomCopyBytes` with
174
- // `kCCRandomDefault`. `CCRandomCopyBytes` manages a CSPRNG which is seeded
175
- // from `/dev/random` and which runs on its own thread accessed via GCD.
176
- //
177
- // This is very heavyweight compared to the alternatives, but they may not be usable:
178
- // - `getentropy` was added in iOS 10, but we support a minimum of iOS 7
179
- // - `/dev/urandom` is not accessible inside the iOS app sandbox.
180
- //
181
- // Therefore `SecRandomCopyBytes` is only used on older iOS versions where no
182
- // better options are present.
183
- #[ cfg( target_os = "ios" ) ]
184
- fn fallback_fill_bytes ( v : & mut [ u8 ] ) {
185
- use crate :: ptr;
186
-
187
- enum SecRandom { }
188
-
189
- #[ allow( non_upper_case_globals) ]
190
- const kSecRandomDefault: * const SecRandom = ptr:: null ( ) ;
191
-
192
- extern "C" {
193
- fn SecRandomCopyBytes ( rnd : * const SecRandom , count : size_t , bytes : * mut u8 ) -> c_int ;
194
- }
195
-
196
- let ret = unsafe { SecRandomCopyBytes ( kSecRandomDefault, v. len ( ) , v. as_mut_ptr ( ) ) } ;
197
- if ret == -1 {
198
- panic ! ( "couldn't generate random bytes: {}" , io:: Error :: last_os_error( ) ) ;
199
- }
200
- }
201
-
202
- // All supported versions of watchOS (>= 5) have support for `getentropy`.
203
- #[ cfg( target_os = "watchos" ) ]
204
- #[ cold]
205
- fn fallback_fill_bytes ( _: & mut [ u8 ] ) {
206
- unreachable ! ( )
207
- }
208
-
209
166
pub fn fill_bytes ( v : & mut [ u8 ] ) {
210
167
if getentropy_fill_bytes ( v) {
211
168
return ;
212
169
}
213
170
214
- // Older macOS versions (< 10.12) don't support `getentropy`. Fallback to
215
- // reading from `/dev/urandom` on these systems.
216
- //
217
- // Older iOS versions (< 10) don't support it either. Fallback to
218
- // `SecRandomCopyBytes` on these systems. On watchOS, this is unreachable
219
- // because the minimum supported version is 5 while `getentropy` became accessible
220
- // in 3.
221
- fallback_fill_bytes ( v)
171
+ // for older macos which doesn't support getentropy
172
+ let mut file = File :: open ( "/dev/urandom" ) . expect ( "failed to open /dev/urandom" ) ;
173
+ file. read_exact ( v) . expect ( "failed to read /dev/urandom" )
222
174
}
223
175
}
224
176
@@ -237,6 +189,36 @@ mod imp {
237
189
}
238
190
}
239
191
192
+ // On iOS and MacOS `SecRandomCopyBytes` calls `CCRandomCopyBytes` with
193
+ // `kCCRandomDefault`. `CCRandomCopyBytes` manages a CSPRNG which is seeded
194
+ // from `/dev/random` and which runs on its own thread accessed via GCD.
195
+ // This seems needlessly heavyweight for the purposes of generating two u64s
196
+ // once per thread in `hashmap_random_keys`. Therefore `SecRandomCopyBytes` is
197
+ // only used on iOS where direct access to `/dev/urandom` is blocked by the
198
+ // sandbox.
199
+ #[ cfg( any( target_os = "ios" , target_os = "watchos" ) ) ]
200
+ mod imp {
201
+ use crate :: io;
202
+ use crate :: ptr;
203
+ use libc:: { c_int, size_t} ;
204
+
205
+ enum SecRandom { }
206
+
207
+ #[ allow( non_upper_case_globals) ]
208
+ const kSecRandomDefault: * const SecRandom = ptr:: null ( ) ;
209
+
210
+ extern "C" {
211
+ fn SecRandomCopyBytes ( rnd : * const SecRandom , count : size_t , bytes : * mut u8 ) -> c_int ;
212
+ }
213
+
214
+ pub fn fill_bytes ( v : & mut [ u8 ] ) {
215
+ let ret = unsafe { SecRandomCopyBytes ( kSecRandomDefault, v. len ( ) , v. as_mut_ptr ( ) ) } ;
216
+ if ret == -1 {
217
+ panic ! ( "couldn't generate random bytes: {}" , io:: Error :: last_os_error( ) ) ;
218
+ }
219
+ }
220
+ }
221
+
240
222
#[ cfg( any( target_os = "freebsd" , target_os = "netbsd" ) ) ]
241
223
mod imp {
242
224
use crate :: ptr;
0 commit comments