-
Notifications
You must be signed in to change notification settings - Fork 570
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Entropy Source and DRNG Manager (ESDM) RNG support
ESDM is a Linux-based user-space PRNG daemon, with configurable entropy sources. See: https://github.com/smuellerDD/esdm It currently gets used, when a high level of control over entropy sources is desirable, e.g. for VPN appliance solutions. In order to use this source, the ESDM server daemon has to be running and botan must be configured --with-esdm. ESDM currently works only on Linux. Signed-off-by: Markus Theil <[email protected]>
- Loading branch information
Showing
10 changed files
with
257 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/* | ||
* ESDM RNG | ||
* (C) 2024, Markus Theil <[email protected]> | ||
* | ||
* Botan is released under the Simplified BSD License (see license.txt) | ||
*/ | ||
|
||
#include "esdm_rng.h" | ||
#include <esdm/esdm_rpc_client.h> | ||
|
||
namespace Botan { | ||
|
||
ESDM_RNG::ESDM_RNG() : ESDM_RNG(false) {} | ||
|
||
ESDM_RNG::ESDM_RNG(bool prediction_resistance) : m_prediction_resistance(prediction_resistance) { | ||
std::lock_guard lg(m_init_lock); | ||
|
||
if(m_ref_cnt == 0) { | ||
if(esdm_rpcc_init_unpriv_service(nullptr) != 0) { | ||
throw Botan::System_Error("unable to initialize ESDM unprivileged service"); | ||
} | ||
} | ||
++m_ref_cnt; | ||
} | ||
|
||
ESDM_RNG::~ESDM_RNG() { | ||
std::lock_guard lg(m_init_lock); | ||
|
||
if(m_ref_cnt == 1) { | ||
esdm_rpcc_fini_unpriv_service(); | ||
} | ||
--m_ref_cnt; | ||
} | ||
|
||
std::string ESDM_RNG::name() const { | ||
if(m_prediction_resistance) { | ||
return "esdm-pr"; | ||
} else { | ||
return "esdm-full"; | ||
} | ||
} | ||
|
||
/* | ||
* as long as we use only the _full and _pr calls, just return true here | ||
*/ | ||
bool ESDM_RNG::is_seeded() const { | ||
return true; | ||
} | ||
|
||
bool ESDM_RNG::accepts_input() const { | ||
return true; | ||
} | ||
|
||
/* | ||
* the ESDM RNG does not hold any state outside ESDM, that should be cleared | ||
* here | ||
*/ | ||
void ESDM_RNG::clear() {} | ||
|
||
void ESDM_RNG::fill_bytes_with_input(std::span<uint8_t> out, std::span<const uint8_t> in) { | ||
if(in.size() > 0) { | ||
ssize_t ret = 0; | ||
// take additional input, but do not account entropy for it, | ||
// as this information is not included in the API | ||
esdm_invoke(esdm_rpcc_write_data(in.data(), in.size())); | ||
if(ret != 0) { | ||
throw Botan::System_Error("Writing additional input to ESDM failed"); | ||
} | ||
} | ||
if(out.size() > 0) { | ||
ssize_t ret = 0; | ||
if(m_prediction_resistance) | ||
esdm_invoke(esdm_rpcc_get_random_bytes_pr(out.data(), out.size())); | ||
else | ||
esdm_invoke(esdm_rpcc_get_random_bytes_full(out.data(), out.size())); | ||
if(ret != static_cast<ssize_t>(out.size())) { | ||
throw Botan::System_Error("Fetching random bytes from ESDM failed"); | ||
} | ||
} | ||
} | ||
|
||
RandomNumberGenerator& esdm_rng() { | ||
static ESDM_RNG g_esdm_rng; | ||
return g_esdm_rng; | ||
} | ||
|
||
}; // namespace Botan |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* ESDM RNG | ||
* (C) 2024, Markus Theil <[email protected]> | ||
* | ||
* Botan is released under the Simplified BSD License (see license.txt) | ||
*/ | ||
|
||
#ifndef ESDM_RNG_H | ||
#define ESDM_RNG_H | ||
|
||
#include <botan/rng.h> | ||
#include <mutex> | ||
|
||
namespace Botan { | ||
|
||
/** | ||
* Return a shared reference to a global PRNG instance provided by ESDM | ||
*/ | ||
BOTAN_PUBLIC_API(3, 6) RandomNumberGenerator& esdm_rng(); | ||
|
||
/** | ||
* Entropy Source and DRNG Manager (ESDM) is a Linux/Unix based | ||
* PRNG manager, which can be seeded from NTG.1/SP800-90B sources. | ||
* | ||
* See: | ||
* - Repository: https://github.com/smuellerDD/esdm | ||
* - Further Docs: https://www.chronox.de/esdm/index.html | ||
* | ||
* Different entropy sources can be configured in respect of beeing | ||
* active and how much entropy is accounted for each of them. | ||
* | ||
* ESDM tracks its seed and reseed status and blocks, when not fully seeded. | ||
* For this functionality, the esdm_rpcc_get_random_bytes_pr (prediction resistant) or | ||
* esdm_rpcc_get_random_bytes_full (fully seeded) calls have to be used. | ||
* | ||
* Configurable modes: | ||
* - fully seeded (-> fast): provide entropy from a DRBG/PRNG after beeing fully seeded, | ||
* block until this point is reached, reseed from after a time | ||
* and/or invocation limit, block again if reseeding is not possible | ||
* - prediction resistance (-> slow): reseed ESDM with fresh entropy after each invocation | ||
* | ||
* You typically want to use the fast fully seeded mode, which is the default. | ||
* | ||
* Instances of this class communicate over RPC with ESDM. The esdm_rpc_client | ||
* library, provided by ESDM, is leveraged for this. | ||
*/ | ||
class BOTAN_PUBLIC_API(3, 6) ESDM_RNG final : public Botan::RandomNumberGenerator { | ||
public: | ||
/** | ||
* Default constructor for ESDM, fully seeded mode | ||
*/ | ||
ESDM_RNG(); | ||
|
||
/** | ||
* Construct ESDM instance with configurable mode | ||
* | ||
* @param prediction_resistance: use prediction resistant mode if true, | ||
* fully seeded mode otherwise | ||
*/ | ||
explicit ESDM_RNG(bool prediction_resistance); | ||
|
||
virtual ~ESDM_RNG(); | ||
|
||
std::string name() const override; | ||
|
||
/** | ||
* ESDM blocks, if it is not seeded, | ||
* | ||
* @return true | ||
*/ | ||
bool is_seeded() const override; | ||
|
||
/** | ||
* ESDM can inject additional inputs | ||
* but we do not account entropy for it | ||
* | ||
* @return true | ||
*/ | ||
bool accepts_input() const override; | ||
|
||
void clear() override; | ||
|
||
protected: | ||
void fill_bytes_with_input(std::span<uint8_t> out, std::span<const uint8_t> in) override; | ||
|
||
private: | ||
/** | ||
* tracks if predicition resistant or fully seeded interface should be queried | ||
*/ | ||
const bool m_prediction_resistance; | ||
|
||
/** | ||
* ESDM rpc client locks concurrent accesses, but initialization should be | ||
* only done once | ||
*/ | ||
inline static std::mutex m_init_lock; | ||
|
||
/** | ||
* counts how many ESDM RNG instances are active in order to perform init and | ||
* fini on first/last one | ||
*/ | ||
inline static size_t m_ref_cnt = 0; | ||
}; | ||
|
||
}; // namespace Botan | ||
|
||
#endif /* ESDM_RNG_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<defines> | ||
ESDM_RNG -> 20240814 | ||
</defines> | ||
|
||
<module_info> | ||
name -> "ESDM RNG" | ||
brief -> "ESDM-based RNG" | ||
</module_info> | ||
|
||
<header:public> | ||
esdm_rng.h | ||
</header:public> | ||
|
||
<requires> | ||
esdm | ||
</requires> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<defines> | ||
ESDM -> 20240814 | ||
</defines> | ||
|
||
<module_info> | ||
name -> "ESDM" | ||
</module_info> | ||
|
||
load_on vendor | ||
|
||
<libs> | ||
linux -> esdm_rpc_client | ||
</libs> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters