Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/random/ivy.c
Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
static u_int random_ivy_read(void *, u_int); | static u_int random_ivy_read(void *, u_int); | ||||
static struct random_source random_ivy = { | static struct random_source random_ivy = { | ||||
.rs_ident = "Intel Secure Key RNG", | .rs_ident = "Intel Secure Key RNG", | ||||
.rs_source = RANDOM_PURE_RDRAND, | .rs_source = RANDOM_PURE_RDRAND, | ||||
.rs_read = random_ivy_read | .rs_read = random_ivy_read | ||||
}; | }; | ||||
static int | static bool | ||||
x86_rdrand_store(u_long *buf) | x86_rdrand_store(u_long *buf) | ||||
{ | { | ||||
u_long rndval; | u_long rndval; | ||||
int retry; | int retry; | ||||
retry = RETRY_COUNT; | retry = RETRY_COUNT; | ||||
__asm __volatile( | __asm __volatile( | ||||
"1:\n\t" | "1:\n\t" | ||||
"rdrand %1\n\t" /* read randomness into rndval */ | "rdrand %1\n\t" /* read randomness into rndval */ | ||||
"jc 2f\n\t" /* CF is set on success, exit retry loop */ | "jc 2f\n\t" /* CF is set on success, exit retry loop */ | ||||
"dec %0\n\t" /* otherwise, retry-- */ | "dec %0\n\t" /* otherwise, retry-- */ | ||||
"jne 1b\n\t" /* and loop if retries are not exhausted */ | "jne 1b\n\t" /* and loop if retries are not exhausted */ | ||||
"2:" | "2:" | ||||
: "+r" (retry), "=r" (rndval) : : "cc"); | : "+r" (retry), "=r" (rndval) : : "cc"); | ||||
*buf = rndval; | *buf = rndval; | ||||
return (retry); | return (retry != 0); | ||||
} | } | ||||
static int | static bool | ||||
x86_rdseed_store(u_long *buf) | x86_rdseed_store(u_long *buf) | ||||
{ | { | ||||
u_long rndval; | u_long rndval; | ||||
int retry; | int retry; | ||||
retry = RETRY_COUNT; | retry = RETRY_COUNT; | ||||
__asm __volatile( | __asm __volatile( | ||||
"1:\n\t" | "1:\n\t" | ||||
"rdseed %1\n\t" /* read randomness into rndval */ | "rdseed %1\n\t" /* read randomness into rndval */ | ||||
"jc 2f\n\t" /* CF is set on success, exit retry loop */ | "jc 2f\n\t" /* CF is set on success, exit retry loop */ | ||||
"dec %0\n\t" /* otherwise, retry-- */ | "dec %0\n\t" /* otherwise, retry-- */ | ||||
"jne 1b\n\t" /* and loop if retries are not exhausted */ | "jne 1b\n\t" /* and loop if retries are not exhausted */ | ||||
"2:" | "2:" | ||||
: "+r" (retry), "=r" (rndval) : : "cc"); | : "+r" (retry), "=r" (rndval) : : "cc"); | ||||
*buf = rndval; | *buf = rndval; | ||||
return (retry); | return (retry != 0); | ||||
} | } | ||||
static int | static bool | ||||
x86_unimpl_store(u_long *buf __unused) | x86_unimpl_store(u_long *buf __unused) | ||||
{ | { | ||||
panic("%s called", __func__); | panic("%s called", __func__); | ||||
} | } | ||||
DEFINE_IFUNC(static, int, x86_rng_store, (u_long *buf)) | DEFINE_IFUNC(static, bool, x86_rng_store, (u_long *buf)) | ||||
{ | { | ||||
has_rdrand = (cpu_feature2 & CPUID2_RDRAND); | has_rdrand = (cpu_feature2 & CPUID2_RDRAND); | ||||
has_rdseed = (cpu_stdext_feature & CPUID_STDEXT_RDSEED); | has_rdseed = (cpu_stdext_feature & CPUID_STDEXT_RDSEED); | ||||
if (has_rdseed) | if (has_rdseed) | ||||
return (x86_rdseed_store); | return (x86_rdseed_store); | ||||
else if (has_rdrand) | else if (has_rdrand) | ||||
return (x86_rdrand_store); | return (x86_rdrand_store); | ||||
else | else | ||||
return (x86_unimpl_store); | return (x86_unimpl_store); | ||||
} | } | ||||
/* It is required that buf length is a multiple of sizeof(u_long). */ | /* It is required that buf length is a multiple of sizeof(u_long). */ | ||||
static u_int | static u_int | ||||
random_ivy_read(void *buf, u_int c) | random_ivy_read(void *buf, u_int c) | ||||
{ | { | ||||
u_long *b, rndval; | u_long *b, rndval; | ||||
u_int count; | u_int count; | ||||
KASSERT(c % sizeof(*b) == 0, ("partial read %d", c)); | KASSERT(c % sizeof(*b) == 0, ("partial read %d", c)); | ||||
b = buf; | b = buf; | ||||
for (count = c; count > 0; count -= sizeof(*b)) { | for (count = c; count > 0; count -= sizeof(*b)) { | ||||
if (x86_rng_store(&rndval) == 0) | if (!x86_rng_store(&rndval)) | ||||
break; | break; | ||||
*b++ = rndval; | *b++ = rndval; | ||||
} | } | ||||
return (c - count); | return (c - count); | ||||
} | } | ||||
static int | static int | ||||
rdrand_modevent(module_t mod, int type, void *unused) | rdrand_modevent(module_t mod, int type, void *unused) | ||||
Show All 37 Lines |