diff options
author | Jack Lloyd <[email protected]> | 2019-08-27 20:04:51 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2019-08-27 20:04:51 -0400 |
commit | ff416dcc98f2952792419410b6afff4c87abd489 (patch) | |
tree | 29fe6ebf915639c3754dcbd41b94b4a52158008c | |
parent | b4543c801cde2874b982bbaccba471bd14c27810 (diff) | |
parent | a9c3413bcd155a6a70a8b8c64a073f5db19cd86c (diff) |
Merge GH #2026 Add support for POWER9 hardware RNG
-rw-r--r-- | src/build-data/arch/ppc64.txt | 1 | ||||
-rw-r--r-- | src/build-data/buildh.in | 2 | ||||
-rw-r--r-- | src/build-data/cc/gcc.txt | 1 | ||||
-rw-r--r-- | src/lib/entropy/entropy_srcs.cpp | 11 | ||||
-rw-r--r-- | src/lib/entropy/p9_darn/info.txt | 11 | ||||
-rw-r--r-- | src/lib/entropy/p9_darn/p9_darn.cpp | 65 | ||||
-rw-r--r-- | src/lib/entropy/p9_darn/p9_darn.h | 23 | ||||
-rw-r--r-- | src/lib/utils/cpuid/cpuid.cpp | 1 | ||||
-rw-r--r-- | src/lib/utils/cpuid/cpuid.h | 7 | ||||
-rw-r--r-- | src/lib/utils/cpuid/cpuid_ppc.cpp | 3 |
10 files changed, 124 insertions, 1 deletions
diff --git a/src/build-data/arch/ppc64.txt b/src/build-data/arch/ppc64.txt index 23d3bb2a1..470bee2db 100644 --- a/src/build-data/arch/ppc64.txt +++ b/src/build-data/arch/ppc64.txt @@ -13,4 +13,5 @@ ppc64el <isa_extensions> altivec ppccrypto +power9 </isa_extensions> diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index caa160eb0..425d06498 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -181,7 +181,7 @@ * broken system RNG. */ #define BOTAN_ENTROPY_DEFAULT_SOURCES \ - { "rdseed", "rdrand", "getentropy", "dev_random", \ + { "rdseed", "rdrand", "p9_darn", "getentropy", "dev_random", \ "system_rng", "proc_walk", "system_stats" } /* Multiplier on a block cipher's native parallelism */ diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt index f495af4e6..cc3ce99e1 100644 --- a/src/build-data/cc/gcc.txt +++ b/src/build-data/cc/gcc.txt @@ -63,6 +63,7 @@ sha -> "-msha" altivec -> "-maltivec" ppccrypto -> "-mcrypto" +power9 -> "-mcpu=power9" arm64:armv8crypto -> "" arm64:armv8sm3 -> "-march=armv8.2-a+sm4" diff --git a/src/lib/entropy/entropy_srcs.cpp b/src/lib/entropy/entropy_srcs.cpp index 85e0b6dc5..ba60ed62d 100644 --- a/src/lib/entropy/entropy_srcs.cpp +++ b/src/lib/entropy/entropy_srcs.cpp @@ -20,6 +20,10 @@ #include <botan/internal/rdseed.h> #endif +#if defined(BOTAN_HAS_ENTROPY_SRC_DARN) + #include <botan/internal/p9_darn.h> +#endif + #if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) #include <botan/internal/dev_random.h> #endif @@ -83,6 +87,13 @@ std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name) } #endif +#if defined(BOTAN_HAS_ENTROPY_SRC_DARN) + if(name == "p9_darn") + { + return std::unique_ptr<Entropy_Source>(new POWER9_DARN); + } +#endif + #if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY) if(name == "getentropy") { diff --git a/src/lib/entropy/p9_darn/info.txt b/src/lib/entropy/p9_darn/info.txt new file mode 100644 index 000000000..47d99aa3d --- /dev/null +++ b/src/lib/entropy/p9_darn/info.txt @@ -0,0 +1,11 @@ +<defines> +ENTROPY_SRC_DARN -> 20180610 +</defines> + +<header:internal> +p9_darn.h +</header:internal> + +<arch> +ppc64 +</arch> diff --git a/src/lib/entropy/p9_darn/p9_darn.cpp b/src/lib/entropy/p9_darn/p9_darn.cpp new file mode 100644 index 000000000..8731b94e1 --- /dev/null +++ b/src/lib/entropy/p9_darn/p9_darn.cpp @@ -0,0 +1,65 @@ +/* +* (C) 2019 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/internal/p9_darn.h> +#include <botan/cpuid.h> + +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; + seed.reserve(DARN_BYTES / 8); + + for(size_t p = 0; p != DARN_BYTES / 8; ++p) + { + if(!read_darn(seed)) + break; + } + + 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; + } + +} diff --git a/src/lib/entropy/p9_darn/p9_darn.h b/src/lib/entropy/p9_darn/p9_darn.h new file mode 100644 index 000000000..9d8c508a1 --- /dev/null +++ b/src/lib/entropy/p9_darn/p9_darn.h @@ -0,0 +1,23 @@ +/* +* (C) 2019 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ENTROPY_SRC_DARN_H_ +#define BOTAN_ENTROPY_SRC_DARN_H_ + +#include <botan/entropy_src.h> + +namespace Botan { + +class POWER9_DARN final : public Entropy_Source + { + public: + std::string name() const override { return "p9_darn"; } + size_t poll(RandomNumberGenerator& rng) override; + }; + +} + +#endif diff --git a/src/lib/utils/cpuid/cpuid.cpp b/src/lib/utils/cpuid/cpuid.cpp index e890af061..18ccff419 100644 --- a/src/lib/utils/cpuid/cpuid.cpp +++ b/src/lib/utils/cpuid/cpuid.cpp @@ -63,6 +63,7 @@ std::string CPUID::to_string() #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) CPUID_PRINT(altivec); CPUID_PRINT(ppc_crypto); + CPUID_PRINT(darn_rng); #endif #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) diff --git a/src/lib/utils/cpuid/cpuid.h b/src/lib/utils/cpuid/cpuid.h index d278a8fcc..256c6cc57 100644 --- a/src/lib/utils/cpuid/cpuid.h +++ b/src/lib/utils/cpuid/cpuid.h @@ -107,6 +107,7 @@ class BOTAN_PUBLIC_API(2,1) CPUID final #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) CPUID_ALTIVEC_BIT = (1ULL << 0), CPUID_PPC_CRYPTO_BIT = (1ULL << 1), + CPUID_DARN_BIT = (1ULL << 2), #endif #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) @@ -138,6 +139,12 @@ class BOTAN_PUBLIC_API(2,1) CPUID final static bool has_ppc_crypto() { return has_cpuid_bit(CPUID_PPC_CRYPTO_BIT); } + /** + * Check if the processor supports POWER9 DARN RNG + */ + static bool has_darn_rng() + { return has_cpuid_bit(CPUID_DARN_BIT); } + #endif #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) diff --git a/src/lib/utils/cpuid/cpuid_ppc.cpp b/src/lib/utils/cpuid/cpuid_ppc.cpp index 08a04cafd..ff528d88e 100644 --- a/src/lib/utils/cpuid/cpuid_ppc.cpp +++ b/src/lib/utils/cpuid/cpuid_ppc.cpp @@ -58,6 +58,7 @@ uint64_t CPUID::CPUID_Data::detect_cpu_features(size_t* cache_line_size) enum PPC_hwcap_bit { ALTIVEC_bit = (1 << 28), CRYPTO_bit = (1 << 25), + DARN_bit = (1 << 21), ARCH_hwcap_altivec = 16, // AT_HWCAP ARCH_hwcap_crypto = 26, // AT_HWCAP2 @@ -72,6 +73,8 @@ uint64_t CPUID::CPUID_Data::detect_cpu_features(size_t* cache_line_size) const unsigned long hwcap_crypto = OS::get_auxval(PPC_hwcap_bit::ARCH_hwcap_crypto); if(hwcap_crypto & PPC_hwcap_bit::CRYPTO_bit) detected_features |= CPUID::CPUID_PPC_CRYPTO_BIT; + if(hwcap_crypto & PPC_hwcap_bit::DARN_bit) + detected_features |= CPUID::CPUID_DARN_BIT; return detected_features; |