Skip to content

Instantly share code, notes, and snippets.

@randomoracle
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save randomoracle/7ea224739e5b98fa392e to your computer and use it in GitHub Desktop.
Save randomoracle/7ea224739e5b98fa392e to your computer and use it in GitHub Desktop.
Check for and use RDRAND instruction on Intel/AMD CPUs
// Compile and run via:
// g++ -o randcheck randcheck.c && ./randcheck
#include <stdlib.h>
#include <stdio.h>
typedef unsigned long long quadword;
quadword check_cpu_features(int leaf_ID) {
quadword cpu_features = 0;
asm("xorq %%rcx, %%rcx;"
"xorq %%rdx, %%rdx;"
"mov %1, %%eax;"
"cpuid;"
// Combine EDX:ECX together, with EDX making up upper 32-bits
"shlq $32, %%rdx;"
"orq %%rcx, %%rdx;"
"movq %%rdx, %0;"
: "=r" (cpu_features)
: "r" (leaf_ID)
: "%rax", "%rcx", "%rdx"
);
return cpu_features;
}
void sample_rng(int amount) {
printf("Actually trying RDRAND instruction now...\n");
for (int total = 0; total < amount; total += 8) {
quadword value;
asm("rdrand %%rax;"
"movq %%rax, %0;"
: "=r" (value)
:
: "%rax"
);
printf("%016llx\n", value);
}
}
int check_for_bit(quadword value, int index) {
return ((1LL << index) & value) != 0;
}
int main(int argc, char **argv) {
quadword features = check_cpu_features(1);
printf("Advertised CPU features: %016llx\n", features);
int on_hypervisor = check_for_bit(features,31);
printf("Running on hypervisor: %s\n", on_hypervisor ? "YES" : "NO");
int has_rdrand = check_for_bit(features, 30);
if (has_rdrand) {
printf("CPUID advertises support for RNG.\n");
sample_rng(64);
} else {
printf("This processor does not have a hardware RNG.\n");
}
return !has_rdrand;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment