Last active
September 28, 2023 08:46
-
-
Save snarkyboojum/8b1f453bb77d84ab17efb36ed3c3bb82 to your computer and use it in GitHub Desktop.
Check for AES-NI support in Rust
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(asm)] | |
/* For Intel */ | |
// "Before an application attempts to use AESNI instructions or PCLMULQDQ, | |
// the application should follow the steps illustrated in Section 11.6.2, | |
// “Checking for SSE/SSE2 Support.” Next, use the additional step provided below: | |
// Check that the processor supports AESNI (if CPUID.01H:ECX.AESNI[bit 25] = 1); | |
// check that the processor supports PCLMULQDQ (if CPUID.01H:ECX.PCLMULQDQ[bit 1] = 1)." | |
/* For AMD */ | |
// we need to call the CPUID instruction to look for AES CPU support | |
// | |
// TODO: perform check for AMD vs Intel at least | |
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] | |
fn check_aes_hardware() -> bool { | |
// The CPUID instruction makes implicit use of the EAX, EBX, ECX, and EDX registers. | |
// Software loads a function code into EAX and, for some function codes, a | |
// sub-function code in ECX, executes the CPUID instruction, and then reads the | |
// associated processor-feature information in EAX, EBX, ECX, and EDX. | |
// N.B. CPUID is covered on p160 of Vol 3. of the AMD64 APM | |
// See, "CPUID Feature Flags Related to Instruction Support" (p558) and | |
// "Appendix E Obtaining Processor Information Via the CPUID Instruction" (p561) | |
// of Vol 3 of the AMD64 APM | |
// We need to check ECX[25] when using the "standard" CPUID Function '1h' | |
// e.g. CPUID Fn0000_0001_ECX and check for the 26th bit in ECX' | |
// We could do this with #cfg[target_features = "aes"], but let's do it in assembly language :D | |
let features: u32; | |
unsafe { | |
asm!("mov eax, 1 | |
cpuid" | |
: "={ecx}"(features) | |
: | |
: "eax" | |
: "intel" | |
); | |
} | |
// println!("CPU feature flags in EAX: {:b}", features); | |
let aes_support: u32 = (features >> 25) & 1; | |
aes_support == 1 | |
} | |
fn main() { | |
print!( | |
"Checking if CPU supports AES native instructions: {}", | |
check_aes_hardware() | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment