diff options
author | lloyd <[email protected]> | 2012-05-25 22:52:00 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-05-25 22:52:00 +0000 |
commit | 12090a7148d9ee73572cc1a7268fc489504a8173 (patch) | |
tree | 51e50ce0852c56231e9e6dc13f168b10edd45d01 /src/entropy/rdrand/rdrand.cpp | |
parent | 9594979caf775dc4062850044715b804d1fda60c (diff) | |
parent | 65cc04445f8d40497f02a14bd8cb97081790e54b (diff) |
propagate from branch 'net.randombit.botan.x509-path-validation' (head 63b5a20eab129ca13287fda33d2d02eec329708f)
to branch 'net.randombit.botan' (head 8b8150f09c55184f028f2929c4e7f7cd0d46d96e)
Diffstat (limited to 'src/entropy/rdrand/rdrand.cpp')
-rw-r--r-- | src/entropy/rdrand/rdrand.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/entropy/rdrand/rdrand.cpp b/src/entropy/rdrand/rdrand.cpp new file mode 100644 index 000000000..51b2bd5f6 --- /dev/null +++ b/src/entropy/rdrand/rdrand.cpp @@ -0,0 +1,60 @@ +/* +* Entropy Source Using Intel's rdrand instruction +* (C) 2012 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/internal/rdrand.h> +#include <botan/cpuid.h> + +#if !defined(BOTAN_USE_GCC_INLINE_ASM) + #include <immintrin.h> +#endif + +namespace Botan { + +/* +* Get the timestamp +*/ +void Intel_Rdrand::poll(Entropy_Accumulator& accum) + { + if(!CPUID::has_rdrand()) + return; + + /* + * Put an upper bound on the total entropy we're willing to claim + * for any one polling of rdrand to prevent it from swamping our + * poll. Internally, the rdrand system is a DRGB that reseeds at a + * somewhat unpredictable rate (the current conditions are + * documented, but that might not be true for different + * implementations, eg on Haswell or a future AMD chip, so I don't + * want to assume). This limit ensures we're going to poll at least + * one other source so we have some diversity in our inputs. + */ + + const size_t POLL_UPPER_BOUND = 96; + const size_t RDRAND_POLLS = 32; + const double ENTROPY_PER_POLL = + static_cast<double>(POLL_UPPER_BOUND) / (RDRAND_POLLS * 4); + + for(size_t i = 0; i != RDRAND_POLLS; ++i) + { + unsigned int r; + +#if BOTAN_USE_GCC_INLINE_ASM + int cf = 0; + + // Encoding of rdrand %eax + asm(".byte 0x0F, 0xC7, 0xF0; adcl $0,%1" : + "=a" (r), "=r" (cf) : "0" (r), "1" (cf) : "cc"); +#else + int cf = _rdrand32_step(&r); +#endif + + if(cf == 1) + accum.add(r, ENTROPY_PER_POLL); + } + } + +} |