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

randombit / botan / 19596147897

22 Nov 2025 01:25PM UTC coverage: 90.629% (+0.002%) from 90.627%
19596147897

Pull #5168

github

web-flow
Merge 9ea34d5a5 into f8eb34002
Pull Request #5168: Add clang-format 17 formatting rules for attributes and inline assembly

100659 of 111067 relevant lines covered (90.63%)

12696690.87 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 <esdm/esdm_rpc_client.h>
11
#include <mutex>
12

13
namespace Botan {
14

15
namespace {
16
/**
17
* This helper makes sure that the ESDM service is initialized and
18
* finalized as needed in a threadsafe fashion. Finalization happens
19
* as soon as all instances of ESDM_RNG are destructed. This may
20
* happen multiple times in the lifetime of the process.
21
*/
22
class ESDM_Context {
23
   public:
24
      [[nodiscard]]
25
      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]]
34
      std::shared_ptr<void> acquire() {
4✔
35
         std::scoped_lock lk(m_mutex);
4✔
36
         if(m_refs++ == 0) {
4✔
37
            if(esdm_rpcc_init_unpriv_service(nullptr) != 0) {
3✔
38
               throw Botan::System_Error("unable to initialize ESDM unprivileged service");
×
39
            }
40
         }
41
         return std::shared_ptr<void>{nullptr, [this](void*) { this->release(); }};
8✔
42
      }
4✔
43

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

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

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

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

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

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

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

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

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

106
}  // 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