Skip to content

Commit 169c7f5

Browse files
committed
Revert "Raise minimum supported Apple OS versions (rust-random#388)"
This reverts commit 5fe3c8e.
1 parent f68a940 commit 169c7f5

File tree

6 files changed

+64
-30
lines changed

6 files changed

+64
-30
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [master]
8+
### Changed
9+
10+
- Reverted "Raise minimum supported Apple OS versions to macOS 10.12 and iOS 10 [#388]"
11+
712
## [0.2.12] - 2024-01-09
813
### Fixed
914
- Custom backend for targets without atomics [#385]

src/apple-other.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
1-
//! Implementation for iOS, tvOS, and watchOS where `getentropy` is unavailable.
1+
// Copyright 2018 Developers of the Rand project.
2+
//
3+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6+
// option. This file may not be copied, modified, or distributed
7+
// except according to those terms.
8+
9+
//! Implementation for iOS
210
use crate::Error;
3-
use core::{ffi::c_void, mem::MaybeUninit};
11+
use core::{ffi::c_void, mem::MaybeUninit, ptr::null};
412

5-
// libsystem contains the libc of Darwin, and every binary ends up linked against it either way. This
6-
// makes it a more lightweight choice compared to `Security.framework`.
13+
#[link(name = "Security", kind = "framework")]
714
extern "C" {
8-
// This RNG uses a thread-local CSPRNG to provide data, which is seeded by the operating system's root CSPRNG.
9-
// Its the best option after `getentropy` on modern Darwin-based platforms that also avoids the
10-
// high startup costs and linking of Security.framework.
11-
//
12-
// While its just an implementation detail, `Security.framework` just calls into this anyway.
13-
fn CCRandomGenerateBytes(bytes: *mut c_void, size: usize) -> i32;
15+
fn SecRandomCopyBytes(rnd: *const c_void, count: usize, bytes: *mut u8) -> i32;
1416
}
1517

1618
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
17-
let ret = unsafe { CCRandomGenerateBytes(dest.as_mut_ptr() as *mut c_void, dest.len()) };
18-
// kCCSuccess (from CommonCryptoError.h) is always zero.
19+
// Apple's documentation guarantees kSecRandomDefault is a synonym for NULL.
20+
let ret = unsafe { SecRandomCopyBytes(null(), dest.len(), dest.as_mut_ptr() as *mut u8) };
21+
// errSecSuccess (from SecBase.h) is always zero.
1922
if ret != 0 {
2023
Err(Error::IOS_SEC_RANDOM)
2124
} else {

src/error.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ impl Error {
3030
pub const ERRNO_NOT_POSITIVE: Error = internal_error(1);
3131
/// Encountered an unexpected situation which should not happen in practice.
3232
pub const UNEXPECTED: Error = internal_error(2);
33-
/// Call to [`CCRandomGenerateBytes`](https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonRandom.h.auto.html) failed
34-
/// on iOS, tvOS, or waatchOS.
35-
// TODO: Update this constant name in the next breaking release.
33+
/// Call to iOS [`SecRandomCopyBytes`](https://developer.apple.com/documentation/security/1399291-secrandomcopybytes) failed.
3634
pub const IOS_SEC_RANDOM: Error = internal_error(3);
3735
/// Call to Windows [`RtlGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom) failed.
3836
pub const WINDOWS_RTL_GEN_RANDOM: Error = internal_error(4);

src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
//! | ----------------- | ------------------ | --------------
77
//! | Linux, Android | `*‑linux‑*` | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random`
88
//! | Windows | `*‑windows‑*` | [`BCryptGenRandom`]
9-
//! | macOS | `*‑apple‑darwin` | [`getentropy`][3]
10-
//! | iOS, tvOS, watchOS | `*‑apple‑ios`, `*-apple-tvos`, `*-apple-watchos` | [`CCRandomGenerateBytes`]
9+
//! | macOS | `*‑apple‑darwin` | [`getentropy`][3] if available, otherwise [`/dev/urandom`][4] (identical to `/dev/random`)
10+
//! | iOS, tvOS, watchOS | `*‑apple‑ios`, `*-apple-tvos`, `*-apple-watchos` | [`SecRandomCopyBytes`]
1111
//! | FreeBSD | `*‑freebsd` | [`getrandom`][5] if available, otherwise [`kern.arandom`][6]
1212
//! | OpenBSD | `*‑openbsd` | [`getentropy`][7]
1313
//! | NetBSD | `*‑netbsd` | [`getrandom`][16] if available, otherwise [`kern.arandom`][8]
@@ -171,7 +171,7 @@
171171
//! [`BCryptGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
172172
//! [`Crypto.getRandomValues`]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
173173
//! [`RDRAND`]: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
174-
//! [`CCRandomGenerateBytes`]: https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonRandom.h.auto.html
174+
//! [`SecRandomCopyBytes`]: https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc
175175
//! [`cprng_draw`]: https://fuchsia.dev/fuchsia-src/zircon/syscalls/cprng_draw
176176
//! [`crypto.randomFillSync`]: https://nodejs.org/api/crypto.html#cryptorandomfillsyncbuffer-offset-size
177177
//! [`esp_fill_random`]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html#_CPPv415esp_fill_randomPv6size_t
@@ -242,6 +242,7 @@ cfg_if! {
242242
#[path = "apple-other.rs"] mod imp;
243243
} else if #[cfg(target_os = "macos")] {
244244
mod util_libc;
245+
mod use_file;
245246
#[path = "macos.rs"] mod imp;
246247
} else if #[cfg(target_os = "openbsd")] {
247248
mod util_libc;

src/macos.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,36 @@
1+
// Copyright 2019 Developers of the Rand project.
2+
//
3+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6+
// option. This file may not be copied, modified, or distributed
7+
// except according to those terms.
8+
19
//! Implementation for macOS
2-
use crate::{util_libc::last_os_error, Error};
3-
use core::mem::MaybeUninit;
10+
use crate::{
11+
use_file,
12+
util_libc::{last_os_error, Weak},
13+
Error,
14+
};
15+
use core::mem::{self, MaybeUninit};
416

5-
extern "C" {
6-
// Supported as of macOS 10.12+.
7-
fn getentropy(buf: *mut u8, size: libc::size_t) -> libc::c_int;
8-
}
17+
type GetEntropyFn = unsafe extern "C" fn(*mut u8, libc::size_t) -> libc::c_int;
918

1019
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
11-
for chunk in dest.chunks_mut(256) {
12-
let ret = unsafe { getentropy(chunk.as_mut_ptr() as *mut u8, chunk.len()) };
13-
if ret != 0 {
14-
return Err(last_os_error());
20+
// getentropy(2) was added in 10.12, Rust supports 10.7+
21+
static GETENTROPY: Weak = unsafe { Weak::new("getentropy\0") };
22+
if let Some(fptr) = GETENTROPY.ptr() {
23+
let func: GetEntropyFn = unsafe { mem::transmute(fptr) };
24+
for chunk in dest.chunks_mut(256) {
25+
let ret = unsafe { func(chunk.as_mut_ptr() as *mut u8, chunk.len()) };
26+
if ret != 0 {
27+
return Err(last_os_error());
28+
}
1529
}
30+
Ok(())
31+
} else {
32+
// We fallback to reading from /dev/random instead of SecRandomCopyBytes
33+
// to avoid high startup costs and linking the Security framework.
34+
use_file::getrandom_inner(dest)
1635
}
17-
Ok(())
1836
}

src/use_file.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
// Copyright 2018 Developers of the Rand project.
2+
//
3+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6+
// option. This file may not be copied, modified, or distributed
7+
// except according to those terms.
8+
19
//! Implementations that just need to read from a file
210
use crate::{
311
util_libc::{open_readonly, sys_fill_exact},
@@ -12,7 +20,7 @@ use core::{
1220
// We prefer using /dev/urandom and only use /dev/random if the OS
1321
// documentation indicates that /dev/urandom is insecure.
1422
// On Solaris/Illumos, see src/solaris_illumos.rs
15-
// On Dragonfly, Haiku, and QNX Neutrino the devices are identical.
23+
// On Dragonfly, Haiku, macOS, and QNX Neutrino the devices are identical.
1624
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
1725
const FILE_PATH: &str = "/dev/random\0";
1826
#[cfg(any(
@@ -22,6 +30,7 @@ const FILE_PATH: &str = "/dev/random\0";
2230
target_os = "redox",
2331
target_os = "dragonfly",
2432
target_os = "haiku",
33+
target_os = "macos",
2534
target_os = "nto",
2635
))]
2736
const FILE_PATH: &str = "/dev/urandom\0";

0 commit comments

Comments
 (0)