diff options
Diffstat (limited to 'src/lib/entropy')
-rw-r--r-- | src/lib/entropy/p9_darn/info.txt | 8 | ||||
-rw-r--r-- | src/lib/entropy/p9_darn/p9_darn.cpp | 47 |
2 files changed, 42 insertions, 13 deletions
diff --git a/src/lib/entropy/p9_darn/info.txt b/src/lib/entropy/p9_darn/info.txt index 30f76603b..47d99aa3d 100644 --- a/src/lib/entropy/p9_darn/info.txt +++ b/src/lib/entropy/p9_darn/info.txt @@ -6,14 +6,6 @@ ENTROPY_SRC_DARN -> 20180610 p9_darn.h </header:internal> -<cc> -gcc:7.0 -</cc> - -<isa> -power9 -</isa> - <arch> ppc64 </arch> diff --git a/src/lib/entropy/p9_darn/p9_darn.cpp b/src/lib/entropy/p9_darn/p9_darn.cpp index aa88b8301..8731b94e1 100644 --- a/src/lib/entropy/p9_darn/p9_darn.cpp +++ b/src/lib/entropy/p9_darn/p9_darn.cpp @@ -9,19 +9,56 @@ namespace Botan { +namespace { + +bool read_darn(secure_vector<uint64_t>& seed) + { + const size_t DARN_RETRIES = 512; + + for(size_t i = 0; i != DARN_RETRIES; ++i) + { + uint64_t r = 0; + + // DARN 0: 32-bit conditioned, 1: 64-bit condition, 2: 64-bit raw (ala RDSEED) + asm volatile("darn %0, 2" : "=r" (r)); + + // DARN indicates error by 0xFF..FF, ie is biased (!?!?) + if((~r) != 0) + { + seed.push_back(r); + return true; + } + } + + return false; // failed to produce an output after many attempts + } + +} + size_t POWER9_DARN::poll(RandomNumberGenerator& rng) { + const size_t DARN_BYTES = 1024; + static_assert(DARN_BYTES % 8 == 0, "Bad DARN configuration"); + if(CPUID::has_darn_rng()) { - secure_vector<uint64_t> seed(64); + secure_vector<uint64_t> seed; + seed.reserve(DARN_BYTES / 8); - for(size_t i = 0; i != seed.size(); ++i) - seed[i] = __builtin_darn_raw(); + for(size_t p = 0; p != DARN_BYTES / 8; ++p) + { + if(!read_darn(seed)) + break; + } - rng.add_entropy(reinterpret_cast<const uint8_t*>(seed.data()), - seed.size() * sizeof(uint64_t)); + if(seed.size() > 0) + { + rng.add_entropy(reinterpret_cast<const uint8_t*>(seed.data()), + seed.size() * sizeof(uint32_t)); + } } + // DARN is used but not trusted return 0; } |