# HG changeset patch # User Claus Gittinger # Date 1525907362 -7200 # Node ID 35e1ebb8020ef6942d0727edc2ce9ade97f2d123 # Parent fbe9af9a6158aef9f7188fe3616ca8710686219b *** empty log message *** diff -r fbe9af9a6158 -r 35e1ebb8020e RandomRDRand.st --- a/RandomRDRand.st Wed May 09 19:42:29 2018 +0200 +++ b/RandomRDRand.st Thu May 10 01:09:22 2018 +0200 @@ -2,7 +2,7 @@ " COPYRIGHT (c) 2014 Claus Gittinger - All Rights Reserved + All Rights Reserved This software is furnished under a license and may be used only in accordance with the terms of that license and with the @@ -27,7 +27,7 @@ copyright " COPYRIGHT (c) 2014 Claus Gittinger - All Rights Reserved + All Rights Reserved This software is furnished under a license and may be used only in accordance with the terms of that license and with the @@ -43,29 +43,29 @@ This generator uses the rdgen random generator which is built into modern intel chips. Before using, you should check via the isSupported query. - Warning: - there have been discussions about the security of the intel rdgen instruction - and whether there are NSA backdoors built into it. - Linus Torwalds refuses to use it for /dev/urandom in the linux kernel, for that very reason. - Be sure you know what you are doing, if you use this generator for sensitive cryptographic stuff. - We recommend using one of the libcrypt-based generators and use this only to get additional - entropy for the seed. + Warning: + there have been discussions about the security of the intel rdgen instruction + and whether there are NSA backdoors built into it. + Linus Torwalds refuses to use it for /dev/urandom in the linux kernel, for that very reason. + Be sure you know what you are doing, if you use this generator for sensitive cryptographic stuff. + We recommend using one of the libcrypt-based generators and use this only to get additional + entropy for the seed. NO WARRANTY RandomRDGen new nextInteger [see also:] - RandomGenerator - the default; uses the machine's /dev/random if available - Random - fast, but generates less quality random numbers - RandomTT800 - another random generator - RandomParkMiller - another random generator - RandomMT19937 - another random generator - RandomKISS - another random generator - exept:libcrypt - a library containing more stuff based on hashes and cyphers + RandomGenerator - the default; uses the machine's /dev/random if available + Random - fast, but generates less quality random numbers + RandomTT800 - another random generator + RandomParkMiller - another random generator + RandomMT19937 - another random generator + RandomKISS - another random generator + exept:libcrypt - a library containing more stuff based on hashes and cyphers [author:] - Claus Gittinger. + Claus Gittinger. " ! ! @@ -93,8 +93,8 @@ "true if this architecture supports hardware random numbers" ^ OperatingSystem getCPUType = 'x86_64' - and:[ (OperatingSystem getSystemInfo at:#extendedInstructions ifAbsent:#()) - includes:#aes ] + and:[ (OperatingSystem getSystemInfo at:#extendedInstructions ifAbsent:#()) + includes:#aes ] " self isSupported @@ -123,34 +123,51 @@ Notice, it may raise an illegal instruction exception on some cpu chips, even though the cpuid instruction says that it is available" + |cfStillSet| + %{ unsigned INT r = 0; int cf; + int count = 50; do { #ifdef USE_DRAND64 - cf = _rdrand64_step(&r); + cf = _rdrand64_step(&r); #else # ifdef USE_DRAND32 - cf = _rdrand32_step(&r); + cf = _rdrand32_step(&r); # else # if defined(__x86__) && defined(__GNUC__) && (__GNUC__ >= 2) - // Encoding of rdrand %eax - asm(".byte 0x0F, 0xC7, 0xF0; adcl $0,%1" - : "=a" (r), "=r" (cf) - : "0" (r), "1" (cf) - : "cc"); + // Encoding of rdrand %eax + asm(".byte 0x0F, 0xC7, 0xF0; adcl $0,%1" + : "=a" (r), "=r" (cf) + : "0" (r), "1" (cf) + : "cc"); # else - goto unsupported; +# if defined(__x86_64__) && defined(__GNUC__) && (__GNUC__ >= 2) + // Encoding of rdrand %rax + asm(".byte 0x48, 0x0F, 0xC7, 0xF0; adcl $0,%1" + : "=a" (r), "=r" (cf) + : "0" (r), "1" (cf) + : "cc"); + +# else + goto unsupported; +# endif # endif # endif #endif - } while (cf != 0); - RETURN (__MKUINT(r)); - + } while ((cf != 0) && (--count > 0)); + if (cf == 0) { + RETURN (__MKUINT(r)); + } + cfStillSet = true; unsupported: ; %}. + cfStillSet ifTrue:[ + self primitiveFailed:'carry flag not clear after 50 tries' + ]. self primitiveFailed:'unsupported on this architecture' " @@ -167,4 +184,3 @@ version_CVS ^ '$Header$' ! ! -