-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
aarch64-dit: initial crate #1102
Conversation
Adds a crate with wrappers for the Data-Independent Timing (DIT) feature of AArch64 CPUs.
CARGO_INCREMENTAL: 0 | ||
RUSTFLAGS: "-Dwarnings" | ||
|
||
jobs: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW I tried to see if it would work under cross
in Linux, but unfortunately not:
---- tests::get stdout ----
thread 'tests::get' panicked at aarch64-dit/src/lib.rs:46:13:
DIT is not available on this CPU
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Looks like this will need a higher MSRV:
Edit: looks like it was stabilized in 1.61 |
aarch64-dit/src/lib.rs
Outdated
/// Enable DIT for the current thread. | ||
#[target_feature(enable = "dit")] | ||
pub unsafe fn set_dit_enabled() { | ||
asm!("msr DIT, #1"); | ||
} | ||
|
||
/// Restore DIT state depending on the enabled bit. | ||
#[target_feature(enable = "dit")] | ||
pub unsafe fn restore_dit(enabled: bool) { | ||
if !enabled { | ||
// Disable DIT | ||
asm!("msr DIT, #0"); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These could be combined into a single function like:
/// Enable DIT for the current thread. | |
#[target_feature(enable = "dit")] | |
pub unsafe fn set_dit_enabled() { | |
asm!("msr DIT, #1"); | |
} | |
/// Restore DIT state depending on the enabled bit. | |
#[target_feature(enable = "dit")] | |
pub unsafe fn restore_dit(enabled: bool) { | |
if !enabled { | |
// Disable DIT | |
asm!("msr DIT, #0"); | |
} | |
} | |
/// Enable DIT for the current thread. | |
#[target_feature(enable = "dit")] | |
pub unsafe fn set_dit_enabled(enabled: bool) { | |
if enabled { | |
asm!("msr DIT, #1"); | |
} else { | |
asm!("msr DIT, #0"); | |
} | |
} |
...however the current version does avoid duplicated msr
calls in the event DIT is already enabled.
At some point we might consider having an ISA-independent crate for this sort of instruction pattern, provided we can actually build a portable abstraction over it: https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/best-practices/data-operand-independent-timing-isa-guidance.html |
Adds a crate with wrappers for the Data-Independent Timing (DIT) feature of AArch64 CPUs.
The implementation is largely a translation of Apple's guide of how to write wrappers for enabling/disabling DIT: https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Enable-DIT-for-constant-time-cryptographic-operations
It would be nice to wrap that all up into an RAII guard which can first use
cpufeatures
to check forFEAT_DIT
and, if available, enable it for the current thread, while also first querying the processor status register and restoring the previous state onDrop
, which is necessary for proper nested usage of DIT.But for now, this just wraps the barebones functionality in an
unsafe
API.