diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c old mode 100644 new mode 100755 index 24206b3b8..a93d9416c --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -22,7 +22,7 @@ #ifdef HAVE_CONFIG_H #include #endif - + #include /* on HPUX 11 you may need to install /dev/random see @@ -570,6 +570,83 @@ int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz, return 0; } +#elif defined(HAVE_INTEL_RDGEN) + +#ifndef _MSC_VER + #define cpuid(reg, leaf, sub)\ + __asm__ __volatile__ ("cpuid":\ + "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3]) :\ + "a" (leaf), "c"(sub)); + + #define XASM_LINK(f) asm(f) +#else + + #include + #define cpuid(a,b) __cpuid((int*)a,b) + + #define XASM_LINK(f) + +#endif /* _MSC_VER */ + +#define EAX 0 +#define EBX 1 +#define ECX 2 +#define EDX 3 + +#define CPUID_AVX1 0x1 +#define CPUID_AVX2 0x2 +#define CPUID_RDRAND 0x4 +#define CPUID_RDSEED 0x8 + +#define IS_INTEL_RDRAND (cpuid_flags&CPUID_RDRAND) +#define IS_INTEL_RDSEED (cpuid_flags&CPUID_RDSEED) + +static word32 cpuid_flags = 0 ; + +static word32 cpuid_flag(word32 leaf, word32 sub, word32 num, word32 bit) { + int got_intel_cpu=0; + unsigned int reg[5]; + + reg[4] = '\0' ; + cpuid(reg, 0, 0); + if(memcmp((char *)&(reg[EBX]), "Genu", 4) == 0 && + memcmp((char *)&(reg[EDX]), "ineI", 4) == 0 && + memcmp((char *)&(reg[ECX]), "ntel", 4) == 0) { + got_intel_cpu = 1; + } + if (got_intel_cpu) { + cpuid(reg, leaf, sub); + return((reg[num]>>bit)&0x1) ; + } + return 0 ; +} + +static int set_cpuid_flags(void) { + if(cpuid_flag(1, 0, ECX, 30)){ cpuid_flags |= CPUID_RDRAND ;} + if(cpuid_flag(7, 0, EBX, 18)){ cpuid_flags |= CPUID_RDSEED ;} + + if(cpuid_flags == 0)return 1 ; + else return 0 ; +} + +int wc_InitRng(RNG* rng) +{ + (void) rng ; + return set_cpuid_flags() ; +} + +int wc_RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) +{ + (void) rng ; + return wc_GenerateSeed(NULL, output, sz) ; +} + + +int wc_RNG_GenerateByte(RNG* rng, byte* b) +{ + (void) rng ; + return wc_GenerateSeed(NULL, b, 1) ; +} #else /* HAVE_HASHDRBG || NO_RC4 */ @@ -978,6 +1055,56 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) return 0; } +#elif defined(HAVE_INTEL_RDGEN) + +static inline int IntelRNrand32(unsigned int *rnd) +{ + int rdrand; + + __asm__ volatile("rdrand %0":"=r"(rdrand)); + if(rdrand){ + *rnd = rdrand ; + return 0 ; + } else + return 1; +} + + +static inline int IntelRNseed32(unsigned int *seed) +{ + int rdseed; + + __asm__ volatile("rdseed %0":"=r"(rdseed)); + if(rdseed){ + *seed = rdseed ; + return 0 ; + } else + return 1; +} + +int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) +{ + (void) os ; + int ret ; byte buff[4] ; + + for( ; sz/4 > 0; sz-=4, output+=4) { + if (IS_INTEL_RDSEED)ret = IntelRNseed32((word32 *)output) ; + else if(IS_INTEL_RDRAND)ret = IntelRNrand32((word32 *)output); + else return 1 ; + if(ret) + return 1 ; + } + if(sz == 0)return 0 ; + + if (IS_INTEL_RDSEED)ret = IntelRNseed32((word32 *)buff) ; + else if(IS_INTEL_RDRAND)ret = IntelRNrand32((word32 *)buff); + else return 1 ; + if(ret) + return 1 ; + XMEMCPY(output, buff, sz) ; + return 0; +} + #elif defined(CUSTOM_RAND_GENERATE) /* Implement your own random generation function