use crate::source::{EntropySource, Platform, Requirement, SourceCategory, SourceInfo};
static DUAL_CLOCK_DOMAIN_INFO: SourceInfo = SourceInfo {
name: "dual_clock_domain",
description: "24 MHz CNTVCT × 41 MHz Apple private timer beat-frequency entropy",
physics: "JIT-reads undocumented S3_1_c15_c0_6 (41 MHz Apple SoC timer) alongside \
CNTVCT_EL0 (24 MHz ARM generic timer). Phase difference between the two \
independent oscillators increments at the beat frequency \
|41−24| + thermal_noise MHz. XOR of lower 24 bits gives CV=704.2%. \
The 41 MHz timer domain is accessible only via JIT-generated MRS — it \
lives in the ARM64 implementation-defined CRn=c15 namespace and has no \
documented name. Manufacturing spread (±100 ppm) plus thermal noise in \
each oscillator's RC circuit makes the phase difference unpredictable \
on sub-microsecond timescales. No prior entropy library exploits this \
beat because the 41 MHz register requires JIT MRS to access.",
category: SourceCategory::Microarch,
platform: Platform::MacOS,
requirements: &[Requirement::AppleSilicon],
entropy_rate_estimate: 6.0,
composite: false,
is_fast: false,
};
pub struct DualClockDomainSource;
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
mod imp {
use super::*;
use crate::sources::helpers::{read_cntvct, xor_fold_u64};
#[allow(clippy::identity_op)]
const APPLE_41MHZ_MRS_X0: u32 = 0xD5380000u32
| (1u32 << 16) | (15u32 << 12) | (0u32 << 8) | (6u32 << 5);
const APPLE_41MHZ_B_MRS_X0: u32 = 0xD5380000u32
| (4u32 << 16) | (15u32 << 12) | (10u32 << 8) | (5u32 << 5);
const RET: u32 = 0xD65F03C0u32;
type FnPtr = unsafe extern "C" fn() -> u64;
struct JitTimer {
fn_ptr: FnPtr,
page: *mut libc::c_void,
}
unsafe impl Send for JitTimer {}
unsafe impl Sync for JitTimer {}
impl Drop for JitTimer {
fn drop(&mut self) {
unsafe {
libc::munmap(self.page, 4096);
}
}
}
unsafe fn build_timer(instr: u32) -> Option<JitTimer> {
let page = unsafe {
libc::mmap(
std::ptr::null_mut(),
4096,
libc::PROT_READ | libc::PROT_WRITE | libc::PROT_EXEC,
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS | 0x0800,
-1,
0,
)
};
if page == libc::MAP_FAILED {
return None;
}
unsafe {
libc::pthread_jit_write_protect_np(0);
let code = page as *mut u32;
code.write(instr);
code.add(1).write(RET);
libc::pthread_jit_write_protect_np(1);
core::arch::asm!("dc cvau, {p}", "ic ivau, {p}", p = in(reg) page, options(nostack));
core::arch::asm!("dsb ish", "isb", options(nostack));
}
let fn_ptr: FnPtr = unsafe { std::mem::transmute(page) };
Some(JitTimer { fn_ptr, page })
}
#[inline]
unsafe fn read_41mhz(timer: &JitTimer) -> u64 {
unsafe { (timer.fn_ptr)() }
}
impl EntropySource for DualClockDomainSource {
fn info(&self) -> &SourceInfo {
&DUAL_CLOCK_DOMAIN_INFO
}
fn is_available(&self) -> bool {
static DUAL_CLOCK_AVAILABLE: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
*DUAL_CLOCK_AVAILABLE.get_or_init(|| {
crate::sources::helpers::probe_jit_instruction_safe(APPLE_41MHZ_MRS_X0)
&& crate::sources::helpers::probe_jit_instruction_safe(APPLE_41MHZ_B_MRS_X0)
})
}
fn collect(&self, n_samples: usize) -> Vec<u8> {
unsafe {
let Some(timer_a) = build_timer(APPLE_41MHZ_MRS_X0) else {
return Vec::new();
};
let Some(timer_b) = build_timer(APPLE_41MHZ_B_MRS_X0) else {
return Vec::new();
};
for _ in 0..64 {
let _ = read_41mhz(&timer_a);
let _ = read_41mhz(&timer_b);
}
let raw_count = n_samples + 64;
let mut out = Vec::with_capacity(n_samples);
for _ in 0..raw_count {
let cntvct = read_cntvct();
let soc_a = read_41mhz(&timer_a);
let soc_b = read_41mhz(&timer_b);
let beat = cntvct ^ soc_a ^ soc_b;
out.push(xor_fold_u64(beat));
if out.len() >= n_samples {
break;
}
}
out.truncate(n_samples);
out
}
}
}
}
#[cfg(not(all(target_os = "macos", target_arch = "aarch64")))]
impl EntropySource for DualClockDomainSource {
fn info(&self) -> &SourceInfo {
&DUAL_CLOCK_DOMAIN_INFO
}
fn is_available(&self) -> bool {
false
}
fn collect(&self, _n_samples: usize) -> Vec<u8> {
Vec::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn info() {
let src = DualClockDomainSource;
assert_eq!(src.info().name, "dual_clock_domain");
assert!(matches!(src.info().category, SourceCategory::Microarch));
assert_eq!(src.info().platform, Platform::MacOS);
assert!(!src.info().composite);
assert!(src.info().entropy_rate_estimate > 1.0 && src.info().entropy_rate_estimate <= 8.0);
}
#[test]
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
fn is_available_on_apple_silicon() {
let src = DualClockDomainSource;
let _ = src.is_available();
}
#[test]
#[ignore] fn collects_high_variance_beats() {
let src = DualClockDomainSource;
if !src.is_available() {
return;
}
let data = src.collect(64);
assert!(!data.is_empty());
let unique: std::collections::HashSet<u8> = data.iter().copied().collect();
assert!(
unique.len() > 8,
"expected high-entropy beat distribution (got {} unique bytes)",
unique.len()
);
}
}