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

randombit / botan / 6187597626

14 Sep 2023 03:21PM UTC coverage: 91.686% (-0.03%) from 91.716%
6187597626

push

github

web-flow
Merge pull request #3698 from randombit/rsa_bigint_todo

kem follow-up, now we do have BigInt::encode_1363 working with std::s…

79072 of 86242 relevant lines covered (91.69%)

8667597.55 hits per line

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

22.73
/src/lib/entropy/rdseed/rdseed.cpp
1
/*
2
* Entropy Source Using Intel's rdseed instruction
3
* (C) 2015 Daniel Neus
4
* (C) 2015,2019 Jack Lloyd
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8

9
#include <botan/internal/rdseed.h>
10

11
#include <botan/internal/cpuid.h>
12

13
#include <immintrin.h>
14

15
namespace Botan {
16

17
namespace {
18

19
BOTAN_FUNC_ISA("rdseed") bool read_rdseed(secure_vector<uint32_t>& seed) {
×
20
   /*
21
   * RDSEED is not guaranteed to generate an output within any specific number
22
   * of attempts. However in testing on a Skylake system, with all hyperthreads
23
   * occupied in tight RDSEED loops, RDSEED will still usually succeed in under
24
   * 150 attempts. The maximum ever seen was 230 attempts until success. When
25
   * idle, RDSEED usually succeeds in 1 or 2 attempts.
26
   *
27
   * We set an upper bound of 1024 attempts, because it is possible that due
28
   * to firmware issue RDSEED is simply broken and never succeeds. We do not
29
   * want to loop forever in that case. If we exceed that limit, then we assume
30
   * the hardware is actually just broken, and stop the poll.
31
   */
32
   const size_t RDSEED_RETRIES = 1024;
×
33

34
   for(size_t i = 0; i != RDSEED_RETRIES; ++i) {
×
35
      uint32_t r = 0;
×
36
      int cf = 0;
×
37

38
#if defined(BOTAN_USE_GCC_INLINE_ASM)
39
      asm("rdseed %0; adcl $0,%1" : "=r"(r), "=r"(cf) : "0"(r), "1"(cf) : "cc");
×
40
#else
41
      cf = _rdseed32_step(&r);
42
#endif
43

44
      if(1 == cf) {
×
45
         seed.push_back(r);
×
46
         return true;
×
47
      }
48

49
      // Intel suggests pausing if RDSEED fails.
50
      _mm_pause();
×
51
   }
52

53
   return false;  // failed to produce an output after many attempts
54
}
55

56
}  // namespace
57

58
size_t Intel_Rdseed::poll(RandomNumberGenerator& rng) {
4✔
59
   const size_t RDSEED_BYTES = 1024;
4✔
60
   static_assert(RDSEED_BYTES % 4 == 0, "Bad RDSEED configuration");
4✔
61

62
   if(CPUID::has_rdseed()) {
4✔
63
      secure_vector<uint32_t> seed;
×
64
      seed.reserve(RDSEED_BYTES / 4);
×
65

66
      for(size_t p = 0; p != RDSEED_BYTES / 4; ++p) {
×
67
         /*
68
         If at any point we exceed our retry count, we stop the entire seed
69
         gathering process. This situation will only occur in situations of
70
         extremely high RDSEED utilization. If RDSEED is currently so highly
71
         contended, then the rest of the poll is likely to also face contention and
72
         it is better to quit now rather than (presumably) face very high retry
73
         times for the rest of the poll.
74
         */
75
         if(!read_rdseed(seed)) {
×
76
            break;
77
         }
78
      }
79

80
      if(!seed.empty()) {
×
81
         rng.add_entropy(reinterpret_cast<const uint8_t*>(seed.data()), seed.size() * sizeof(uint32_t));
×
82
      }
83
   }
×
84

85
   // RDSEED is used but not trusted
86
   return 0;
4✔
87
}
88

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

© 2025 Coveralls, Inc