#include <stdint.h>
#include <stddef.h>
/* CPU-provided cryptographic randomness only. There is deliberately no
timestamp, address, PRNG or serial-input fallback. CPUID and carry must both
confirm support/success before any returned word is used. */
static uint32_t features(void)
{
uint32_t a,b,c,d,maximum;
__asm__ volatile("cpuid" : "=a"(maximum),"=b"(b),"=c"(c),"=d"(d) : "a"(0),"c"(0));
if(maximum < 1) return 0;
__asm__ volatile("cpuid" : "=a"(a),"=b"(b),"=c"(c),"=d"(d) : "a"(1),"c"(0));
uint32_t result = (c & (1U<<30)) ? 1 : 0;
if(maximum >= 7) {
__asm__ volatile("cpuid" : "=a"(a),"=b"(b),"=c"(c),"=d"(d) : "a"(7),"c"(0));
if(b & (1U<<18)) result |= 2;
}
return result;
}
uint32_t xfe_runtime_random_capabilities(void) { return features(); }
static int next_word(uint32_t source,uint64_t* output)
{
for(unsigned retry=0;retry<128;retry++) {
uint64_t value; unsigned char success;
if(source & 2) __asm__ volatile("rdseed %0; setc %1" : "=r"(value),"=qm"(success) :: "cc");
else __asm__ volatile("rdrand %0; setc %1" : "=r"(value),"=qm"(success) :: "cc");
if(success) { *output=value; return 1; }
__asm__ volatile("pause");
}
/* RDRAND is a separately advertised hardware CSPRNG, not a software
replacement for unavailable entropy. Its own carry check still applies. */
if((source & 3)==3) return next_word(1,output);
return 0;
}
int xfe_runtime_random_fill(uint8_t* destination,uint32_t length)
{
if(length > 1048576 || (length && !destination)) return 0;
if(!length) return 1;
uint32_t source=features(); if(!source) return 0;
uint64_t previous=0; int have_previous=0;
for(uint32_t offset=0;offset<length;) {
uint64_t word;
if(!next_word(source,&word) || (have_previous && word==previous)) {
volatile uint8_t* clear=destination;
for(uint32_t i=0;i<length;i++) clear[i]=0;
return 0;
}
previous=word; have_previous=1;
for(unsigned i=0;i<8 && offset<length;i++,offset++) destination[offset]=(uint8_t)(word>>(i*8));
word=0;
}
return 1;
}
/* .NET 10 System.Native contract: zero on success, -1 on failure. This is
required by Bouncy Castle's static SecureRandom initialization as well as
explicitly supplied TLS platform entropy. */
int32_t SystemNative_GetCryptographicallySecureRandomBytes(uint8_t* destination,int32_t length)
{
if(length<0) return -1;
return xfe_runtime_random_fill(destination,(uint32_t)length) ? 0 : -1;
}
#include <stdint.h>
#include <stddef.h>
/* CPU-provided cryptographic randomness only. There is deliberately no
timestamp, address, PRNG or serial-input fallback. CPUID and carry must both
confirm support/success before any returned word is used. */
static uint32_t features(void)
{
uint32_t a,b,c,d,maximum;
__asm__ volatile("cpuid" : "=a"(maximum),"=b"(b),"=c"(c),"=d"(d) : "a"(0),"c"(0));
if(maximum < 1) return 0;
__asm__ volatile("cpuid" : "=a"(a),"=b"(b),"=c"(c),"=d"(d) : "a"(1),"c"(0));
uint32_t result = (c & (1U<<30)) ? 1 : 0;
if(maximum >= 7) {
__asm__ volatile("cpuid" : "=a"(a),"=b"(b),"=c"(c),"=d"(d) : "a"(7),"c"(0));
if(b & (1U<<18)) result |= 2;
}
return result;
}
uint32_t xfe_runtime_random_capabilities(void) { return features(); }
static int next_word(uint32_t source,uint64_t* output)
{
for(unsigned retry=0;retry<128;retry++) {
uint64_t value; unsigned char success;
if(source & 2) __asm__ volatile("rdseed %0; setc %1" : "=r"(value),"=qm"(success) :: "cc");
else __asm__ volatile("rdrand %0; setc %1" : "=r"(value),"=qm"(success) :: "cc");
if(success) { *output=value; return 1; }
__asm__ volatile("pause");
}
/* RDRAND is a separately advertised hardware CSPRNG, not a software
replacement for unavailable entropy. Its own carry check still applies. */
if((source & 3)==3) return next_word(1,output);
return 0;
}
int xfe_runtime_random_fill(uint8_t* destination,uint32_t length)
{
if(length > 1048576 || (length && !destination)) return 0;
if(!length) return 1;
uint32_t source=features(); if(!source) return 0;
uint64_t previous=0; int have_previous=0;
for(uint32_t offset=0;offset<length;) {
uint64_t word;
if(!next_word(source,&word) || (have_previous && word==previous)) {
volatile uint8_t* clear=destination;
for(uint32_t i=0;i<length;i++) clear[i]=0;
return 0;
}
previous=word; have_previous=1;
for(unsigned i=0;i<8 && offset<length;i++,offset++) destination[offset]=(uint8_t)(word>>(i*8));
word=0;
}
return 1;
}
/* .NET 10 System.Native contract: zero on success, -1 on failure. This is
required by Bouncy Castle's static SecureRandom initialization as well as
explicitly supplied TLS platform entropy. */
int32_t SystemNative_GetCryptographicallySecureRandomBytes(uint8_t* destination,int32_t length)
{
if(length<0) return -1;
return xfe_runtime_random_fill(destination,(uint32_t)length) ? 0 : -1;
}