Skip to content

Instantly share code, notes, and snippets.

@snarkyboojum
Last active September 28, 2023 08:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snarkyboojum/8b1f453bb77d84ab17efb36ed3c3bb82 to your computer and use it in GitHub Desktop.
Save snarkyboojum/8b1f453bb77d84ab17efb36ed3c3bb82 to your computer and use it in GitHub Desktop.
Check for AES-NI support in Rust
#![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