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

randombit / botan / 24032704228

06 Apr 2026 12:58PM UTC coverage: 89.451% (-0.003%) from 89.454%
24032704228

Pull #5521

github

web-flow
Merge 17f437d7f into 417709dd7
Pull Request #5521: Rollup of small fixes

105882 of 118369 relevant lines covered (89.45%)

11473459.55 hits per line

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

66.23
/src/lib/compat/sodium/sodium_utils.cpp
1
/*
2
* (C) 2019 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include <botan/sodium.h>
8

9
#include <botan/mem_ops.h>
10
#include <botan/system_rng.h>
11
#include <botan/internal/chacha.h>
12
#include <botan/internal/ct_utils.h>
13
#include <botan/internal/loadstor.h>
14
#include <cstdlib>
15

16
namespace Botan {
17

18
void Sodium::randombytes_buf(void* buf, size_t len) {
×
19
   system_rng().randomize(static_cast<uint8_t*>(buf), len);
×
20
}
×
21

22
uint32_t Sodium::randombytes_uniform(uint32_t upper_bound) {
×
23
   if(upper_bound <= 1) {
×
24
      return 0;
25
   }
26

27
   // Not completely uniform
28
   uint64_t x = 0;
×
29
   randombytes_buf(&x, sizeof(x));
×
30
   return x % upper_bound;
×
31
}
32

33
void Sodium::randombytes_buf_deterministic(void* buf, size_t size, const uint8_t seed[randombytes_SEEDBYTES]) {
1✔
34
   const unsigned char nonce[12] = {'L', 'i', 'b', 's', 'o', 'd', 'i', 'u', 'm', 'D', 'R', 'G'};
1✔
35

36
   ChaCha chacha(20);
1✔
37
   chacha.set_key(seed, randombytes_SEEDBYTES);
1✔
38
   chacha.set_iv(nonce, sizeof(nonce));
1✔
39
   chacha.write_keystream(static_cast<uint8_t*>(buf), size);
1✔
40
}
1✔
41

42
int Sodium::crypto_verify_16(const uint8_t x[16], const uint8_t y[16]) {
×
43
   return static_cast<int>(CT::is_equal(x, y, 16).select(1, 0)) - 1;
×
44
}
45

46
int Sodium::crypto_verify_32(const uint8_t x[32], const uint8_t y[32]) {
×
47
   return static_cast<int>(CT::is_equal(x, y, 32).select(1, 0)) - 1;
×
48
}
49

50
int Sodium::crypto_verify_64(const uint8_t x[64], const uint8_t y[64]) {
×
51
   return static_cast<int>(CT::is_equal(x, y, 64).select(1, 0)) - 1;
×
52
}
53

54
void Sodium::sodium_memzero(void* ptr, size_t len) {
×
55
   secure_scrub_memory(ptr, len);
×
56
}
×
57

58
int Sodium::sodium_memcmp(const void* x, const void* y, size_t len) {
11✔
59
   const auto same = CT::is_equal(static_cast<const uint8_t*>(x), static_cast<const uint8_t*>(y), len);
11✔
60
   // Return 0 if same or -1 if differing
61
   return static_cast<int>(same.select(1, 0)) - 1;
11✔
62
}
63

64
int Sodium::sodium_compare(const uint8_t x[], const uint8_t y[], size_t len) {
3✔
65
   const uint8_t LT = static_cast<uint8_t>(-1);
3✔
66
   const uint8_t EQ = 0;
3✔
67
   const uint8_t GT = 1;
3✔
68

69
   uint8_t result = EQ;  // until found otherwise
3✔
70

71
   for(size_t i = 0; i != len; ++i) {
18✔
72
      const auto is_eq = CT::Mask<uint8_t>::is_equal(x[i], y[i]);
15✔
73
      const auto is_lt = CT::Mask<uint8_t>::is_lt(x[i], y[i]);
15✔
74
      result = is_eq.select(result, is_lt.select(LT, GT));
15✔
75
   }
76

77
   return static_cast<int8_t>(result);
3✔
78
}
79

80
int Sodium::sodium_is_zero(const uint8_t b[], size_t len) {
3✔
81
   uint8_t sum = 0;
3✔
82
   for(size_t i = 0; i != len; ++i) {
13✔
83
      sum |= b[i];
10✔
84
   }
85
   return static_cast<int>(CT::Mask<uint8_t>::expand(sum).if_not_set_return(1));
3✔
86
}
87

88
void Sodium::sodium_increment(uint8_t b[], size_t len) {
3✔
89
   uint8_t carry = 1;
3✔
90
   for(size_t i = 0; i != len; ++i) {
18✔
91
      b[i] += carry;
15✔
92
      carry &= CT::Mask<uint8_t>::is_zero(b[i]).if_set_return(1);
15✔
93
   }
94
}
3✔
95

96
void Sodium::sodium_add(uint8_t a[], const uint8_t b[], size_t len) {
4✔
97
   uint16_t carry = 0;
4✔
98
   for(size_t i = 0; i != len; ++i) {
24✔
99
      carry += static_cast<uint16_t>(a[i]) + b[i];
20✔
100
      a[i] = static_cast<uint8_t>(carry);
20✔
101
      carry >>= 8;
20✔
102
   }
103
}
4✔
104

105
void* Sodium::sodium_malloc(size_t size) {
1✔
106
   const uint64_t len = size;
1✔
107

108
   if(size + sizeof(len) < size) {
1✔
109
      return nullptr;
110
   }
111

112
   // NOLINTNEXTLINE(*-no-malloc,*-owning-memory,*-const-correctness)
113
   uint8_t* p = static_cast<uint8_t*>(std::calloc(size + sizeof(len), 1));
1✔
114
   store_le(len, p);
1✔
115
   return p + 8;
1✔
116
}
117

118
void Sodium::sodium_free(void* ptr) {
2✔
119
   if(ptr == nullptr) {
2✔
120
      return;
2✔
121
   }
122

123
   uint8_t* p = static_cast<uint8_t*>(ptr) - 8;
1✔
124
   const uint64_t len = load_le<uint64_t>(p, 0);
1✔
125
   secure_scrub_memory(ptr, static_cast<size_t>(len));
1✔
126
   // NOLINTNEXTLINE(*-no-malloc,*-owning-memory)
127
   std::free(p);
1✔
128
}
129

130
void* Sodium::sodium_allocarray(size_t count, size_t size) {
×
131
   if(count > 0 && size > SIZE_MAX / count) {
×
132
      return nullptr;
133
   }
134
   return sodium_malloc(count * size);
×
135
}
136

137
int Sodium::sodium_mprotect_noaccess(void* ptr) {
×
138
   BOTAN_UNUSED(ptr);
×
139
   return -1;
×
140
}
141

142
int Sodium::sodium_mprotect_readwrite(void* ptr) {
×
143
   BOTAN_UNUSED(ptr);
×
144
   return -1;
×
145
}
146

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