• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 21768358452

06 Feb 2026 10:35PM UTC coverage: 90.064% (-0.003%) from 90.067%
21768358452

Pull #5289

github

web-flow
Merge f589db195 into 8ea0ca252
Pull Request #5289: Further misc header reductions, forward declarations, etc

102238 of 113517 relevant lines covered (90.06%)

11357432.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.29
/src/lib/rng/esdm_rng/esdm_rng.cpp
1
/*
2
* ESDM RNG
3
* (C) 2024, Markus Theil <theil.markus@gmail.com>
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/esdm_rng.h>
9

10
#include <botan/exceptn.h>
11
#include <esdm/esdm_rpc_client.h>
12
#include <mutex>
13

14
namespace Botan {
15

16
namespace {
17
/**
18
* This helper makes sure that the ESDM service is initialized and
19
* finalized as needed in a threadsafe fashion. Finalization happens
20
* as soon as all instances of ESDM_RNG are destructed. This may
21
* happen multiple times in the lifetime of the process.
22
*/
23
class ESDM_Context {
24
   public:
25
      [[nodiscard]] static std::shared_ptr<void> instance() {
4✔
26
         static ESDM_Context g_instance;
4✔
27
         return g_instance.acquire();
4✔
28
      }
29

30
   private:
31
      ESDM_Context() = default;
32

33
      [[nodiscard]] std::shared_ptr<void> acquire() {
4✔
34
         std::scoped_lock lk(m_mutex);
4✔
35
         if(m_refs++ == 0) {
4✔
36
            if(esdm_rpcc_init_unpriv_service(nullptr) != 0) {
3✔
37
               throw Botan::System_Error("unable to initialize ESDM unprivileged service");
×
38
            }
39
         }
40
         return std::shared_ptr<void>{nullptr, [this](void*) { this->release(); }};
8✔
41
      }
4✔
42

43
      void release() {
4✔
44
         std::scoped_lock lk(m_mutex);
4✔
45
         if(m_refs-- == 1) {
4✔
46
            esdm_rpcc_fini_unpriv_service();
3✔
47
         }
48
      }
4✔
49

50
   private:
51
      std::mutex m_mutex;
52
      size_t m_refs = 0;
53
};
54
}  // namespace
55

56
ESDM_RNG::ESDM_RNG(bool prediction_resistance) :
4✔
57
      m_prediction_resistance(prediction_resistance), m_ctx(ESDM_Context::instance()) {}
4✔
58

59
void ESDM_RNG::fill_bytes_with_input(std::span<uint8_t> out, std::span<const uint8_t> in) {
6✔
60
   /*
61
   * This variable is implicitly set by the "esdm_invoke" macro that comes
62
   * with the ESDM library. "esdm_invoke" implements a retry mechanism for
63
   * the underlying RPC mechanism of ESDM.
64
   */
65
   ssize_t ret = 0;
6✔
66

67
   if(!in.empty()) {
6✔
68
      ret = 0;
×
69

70
      /*
71
      * take additional input, but do not account entropy for it,
72
      * as this information is not included in the API
73
      */
74
      esdm_invoke(esdm_rpcc_write_data(in.data(), in.size()));
×
75
      /*
76
      * ret was set by esdm_invoke, as mentioned above
77
      */
78
      if(ret != 0) {
×
79
         throw Botan::System_Error("Writing additional input to ESDM failed");
×
80
      }
81
   }
82

83
   if(!out.empty()) {
6✔
84
      ret = 0;
6✔
85

86
      if(m_prediction_resistance) {
6✔
87
         esdm_invoke(esdm_rpcc_get_random_bytes_pr(out.data(), out.size()));
3✔
88
      } else {
89
         esdm_invoke(esdm_rpcc_get_random_bytes_full(out.data(), out.size()));
3✔
90
      }
91
      /*
92
      * ret was set by esdm_invoke, as mentioned above
93
      */
94
      if(ret != static_cast<ssize_t>(out.size())) {
6✔
95
         throw Botan::System_Error("Fetching random bytes from ESDM failed");
×
96
      }
97
   }
98
}
6✔
99

100
RandomNumberGenerator& esdm_rng() {
×
101
   static ESDM_RNG g_esdm_rng;
×
102
   return g_esdm_rng;
×
103
}
104

105
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc