Botan  2.11.0
Crypto and TLS for C++11
sodium_utils.cpp
Go to the documentation of this file.
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 #include <botan/chacha.h>
9 #include <botan/mem_ops.h>
10 #include <botan/system_rng.h>
11 #include <botan/internal/os_utils.h>
12 #include <botan/internal/ct_utils.h>
13 #include <botan/loadstor.h>
14 
15 namespace Botan {
16 
17 void Sodium::randombytes_buf(void* buf, size_t len)
18  {
19  system_rng().randomize(static_cast<uint8_t*>(buf), len);
20  }
21 
22 uint32_t Sodium::randombytes_uniform(uint32_t upper_bound)
23  {
24  if(upper_bound <= 1)
25  return 0;
26 
27  // Not completely uniform
28  uint64_t x;
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])
34  {
35  const unsigned char nonce[12] = {
36  'L', 'i', 'b', 's', 'o', 'd', 'i', 'u', 'm', 'D', 'R', 'G'
37  };
38 
39  ChaCha chacha(20);
40  chacha.set_key(seed, randombytes_SEEDBYTES);
41  chacha.set_iv(nonce, sizeof(nonce));
42  chacha.write_keystream(static_cast<uint8_t*>(buf), size);
43  }
44 
45 int Sodium::crypto_verify_16(const uint8_t* x, const uint8_t* y)
46  {
47  return same_mem(x, y, 16);
48  }
49 
50 int Sodium::crypto_verify_32(const uint8_t* x, const uint8_t* y)
51  {
52  return same_mem(x, y, 32);
53  }
54 
55 int Sodium::crypto_verify_64(const uint8_t* x, const uint8_t* y)
56  {
57  return same_mem(x, y, 64);
58  }
59 
60 void Sodium::sodium_memzero(void* ptr, size_t len)
61  {
62  secure_scrub_memory(ptr, len);
63  }
64 
65 int Sodium::sodium_memcmp(const void* x, const void* y, size_t len)
66  {
67  const bool same = constant_time_compare(static_cast<const uint8_t*>(x), static_cast<const uint8_t*>(y), len);
68  return same ? 0 : -1;
69  }
70 
71 int Sodium::sodium_compare(const uint8_t x[], const uint8_t y[], size_t len)
72  {
73  const uint8_t LT = static_cast<uint8_t>(-1);
74  const uint8_t EQ = 0;
75  const uint8_t GT = 1;
76 
77  uint8_t result = EQ; // until found otherwise
78 
79  for(size_t i = 0; i != len; ++i)
80  {
81  const auto is_eq = CT::Mask<uint8_t>::is_equal(x[i], y[i]);
82  const auto is_lt = CT::Mask<uint8_t>::is_lt(x[i], y[i]);
83  result = is_eq.select(result, is_lt.select(LT, GT));
84  }
85 
86  return static_cast<int8_t>(result);
87  }
88 
89 int Sodium::sodium_is_zero(const uint8_t b[], size_t len)
90  {
91  uint8_t sum = 0;
92  for(size_t i = 0; i != len; ++i)
93  sum |= b[i];
94  return static_cast<int>(CT::Mask<uint8_t>::expand(sum).if_not_set_return(1));
95  }
96 
97 void Sodium::sodium_increment(uint8_t b[], size_t len)
98  {
99  uint8_t carry = 1;
100  for(size_t i = 0; i != len; ++i)
101  {
102  b[i] += carry;
103  carry &= (b[i] == 0);
104  }
105  }
106 
107 void Sodium::sodium_add(uint8_t a[], const uint8_t b[], size_t len)
108  {
109  uint8_t carry = 0;
110  for(size_t i = 0; i != len; ++i)
111  {
112  a[i] += b[i] + carry;
113  carry = (a[i] < b[i]);
114  }
115  }
116 
117 void* Sodium::sodium_malloc(size_t size)
118  {
119  const uint64_t len = size;
120 
121  if(size + sizeof(len) < size)
122  return nullptr;
123 
124  uint8_t* p = static_cast<uint8_t*>(std::calloc(size + sizeof(len), 1));
125  store_le(len, p);
126  return p + 8;
127  }
128 
129 void Sodium::sodium_free(void* ptr)
130  {
131  if(ptr == nullptr)
132  return;
133 
134  uint8_t* p = static_cast<uint8_t*>(ptr) - 8;
135  const uint64_t len = load_le<uint64_t>(p, 0);
136  secure_scrub_memory(ptr, static_cast<size_t>(len));
137  std::free(p);
138  }
139 
140 void* Sodium::sodium_allocarray(size_t count, size_t size)
141  {
142  const size_t bytes = count * size;
143  if(bytes < count || bytes < size)
144  return nullptr;
145  return sodium_malloc(bytes);
146  }
147 
149  {
151  return 0;
152  }
153 
155  {
157  return 0;
158  }
159 
160 }
RandomNumberGenerator & system_rng()
Definition: system_rng.cpp:279
void sodium_memzero(void *ptr, size_t len)
void sodium_increment(uint8_t n[], size_t nlen)
void * sodium_allocarray(size_t count, size_t size)
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:186
void * sodium_malloc(size_t size)
void carry(int64_t &h0, int64_t &h1)
void sodium_add(uint8_t a[], const uint8_t b[], size_t len)
virtual void randomize(uint8_t output[], size_t length)=0
int crypto_verify_16(const uint8_t x[16], const uint8_t y[16])
int sodium_mprotect_readwrite(void *ptr)
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.h:81
void randombytes_buf_deterministic(void *buf, size_t size, const uint8_t seed[32])
void page_prohibit_access(void *page)
Definition: os_utils.cpp:488
int sodium_mprotect_noaccess(void *ptr)
void sodium_free(void *ptr)
int sodium_memcmp(const void *x, const void *y, size_t len)
void randombytes_buf(void *buf, size_t size)
static Mask< T > expand(T v)
Definition: ct_utils.h:123
int sodium_compare(const uint8_t x[], const uint8_t y[], size_t len)
int crypto_verify_64(const uint8_t x[64], const uint8_t y[64])
uint64_t load_le< uint64_t >(const uint8_t in[], size_t off)
Definition: loadstor.h:235
Definition: alg_id.cpp:13
void secure_scrub_memory(void *ptr, size_t n)
Definition: os_utils.cpp:61
int sodium_is_zero(const uint8_t nonce[], size_t nlen)
void page_allow_access(void *page)
Definition: os_utils.cpp:476
uint32_t randombytes_uniform(uint32_t upper_bound)
int crypto_verify_32(const uint8_t x[32], const uint8_t y[32])
static Mask< T > is_equal(T x, T y)
Definition: ct_utils.h:149
static Mask< T > is_lt(T x, T y)
Definition: ct_utils.h:157
void store_le(uint16_t in, uint8_t out[2])
Definition: loadstor.h:452