Botan 3.7.1
Crypto and TLS for C&
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
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#if defined(BOTAN_HAS_OS_UTILS)
17 #include <botan/internal/os_utils.h>
18#endif
19
20namespace Botan {
21
22void Sodium::randombytes_buf(void* buf, size_t len) {
23 system_rng().randomize(static_cast<uint8_t*>(buf), len);
24}
25
26uint32_t Sodium::randombytes_uniform(uint32_t upper_bound) {
27 if(upper_bound <= 1) {
28 return 0;
29 }
30
31 // Not completely uniform
32 uint64_t x;
33 randombytes_buf(&x, sizeof(x));
34 return x % upper_bound;
35}
36
37void Sodium::randombytes_buf_deterministic(void* buf, size_t size, const uint8_t seed[randombytes_SEEDBYTES]) {
38 const unsigned char nonce[12] = {'L', 'i', 'b', 's', 'o', 'd', 'i', 'u', 'm', 'D', 'R', 'G'};
39
40 ChaCha chacha(20);
41 chacha.set_key(seed, randombytes_SEEDBYTES);
42 chacha.set_iv(nonce, sizeof(nonce));
43 chacha.write_keystream(static_cast<uint8_t*>(buf), size);
44}
45
46int Sodium::crypto_verify_16(const uint8_t x[16], const uint8_t y[16]) {
47 return static_cast<int>(CT::is_equal(x, y, 16).select(1, 0));
48}
49
50int Sodium::crypto_verify_32(const uint8_t x[32], const uint8_t y[32]) {
51 return static_cast<int>(CT::is_equal(x, y, 32).select(1, 0));
52}
53
54int Sodium::crypto_verify_64(const uint8_t x[64], const uint8_t y[64]) {
55 return static_cast<int>(CT::is_equal(x, y, 64).select(1, 0));
56}
57
58void Sodium::sodium_memzero(void* ptr, size_t len) {
59 secure_scrub_memory(ptr, len);
60}
61
62int Sodium::sodium_memcmp(const void* x, const void* y, size_t len) {
63 const auto same = CT::is_equal(static_cast<const uint8_t*>(x), static_cast<const uint8_t*>(y), len);
64 // Return 0 if same or -1 if differing
65 return static_cast<int>(same.select(1, 0)) - 1;
66}
67
68int Sodium::sodium_compare(const uint8_t x[], const uint8_t y[], size_t len) {
69 const uint8_t LT = static_cast<uint8_t>(-1);
70 const uint8_t EQ = 0;
71 const uint8_t GT = 1;
72
73 uint8_t result = EQ; // until found otherwise
74
75 for(size_t i = 0; i != len; ++i) {
76 const auto is_eq = CT::Mask<uint8_t>::is_equal(x[i], y[i]);
77 const auto is_lt = CT::Mask<uint8_t>::is_lt(x[i], y[i]);
78 result = is_eq.select(result, is_lt.select(LT, GT));
79 }
80
81 return static_cast<int8_t>(result);
82}
83
84int Sodium::sodium_is_zero(const uint8_t b[], size_t len) {
85 uint8_t sum = 0;
86 for(size_t i = 0; i != len; ++i) {
87 sum |= b[i];
88 }
89 return static_cast<int>(CT::Mask<uint8_t>::expand(sum).if_not_set_return(1));
90}
91
92void Sodium::sodium_increment(uint8_t b[], size_t len) {
93 uint8_t carry = 1;
94 for(size_t i = 0; i != len; ++i) {
95 b[i] += carry;
96 carry &= (b[i] == 0);
97 }
98}
99
100void Sodium::sodium_add(uint8_t a[], const uint8_t b[], size_t len) {
101 uint8_t carry = 0;
102 for(size_t i = 0; i != len; ++i) {
103 a[i] += b[i] + carry;
104 carry = (a[i] < b[i]);
105 }
106}
107
108void* Sodium::sodium_malloc(size_t size) {
109 const uint64_t len = size;
110
111 if(size + sizeof(len) < size) {
112 return nullptr;
113 }
114
115 // NOLINTNEXTLINE(*-no-malloc)
116 uint8_t* p = static_cast<uint8_t*>(std::calloc(size + sizeof(len), 1));
117 store_le(len, p);
118 return p + 8;
119}
120
121void Sodium::sodium_free(void* ptr) {
122 if(ptr == nullptr) {
123 return;
124 }
125
126 uint8_t* p = static_cast<uint8_t*>(ptr) - 8;
127 const uint64_t len = load_le<uint64_t>(p, 0);
128 secure_scrub_memory(ptr, static_cast<size_t>(len));
129 // NOLINTNEXTLINE(*-no-malloc)
130 std::free(p);
131}
132
133void* Sodium::sodium_allocarray(size_t count, size_t size) {
134 const size_t bytes = count * size;
135 if(bytes < count || bytes < size) {
136 return nullptr;
137 }
138 return sodium_malloc(bytes);
139}
140
142#if defined(BOTAN_HAS_OS_UTILS)
144 return 0;
145#else
146 BOTAN_UNUSED(ptr);
147 return -1;
148#endif
149}
150
152#if defined(BOTAN_HAS_OS_UTILS)
154 return 0;
155#else
156 BOTAN_UNUSED(ptr);
157 return -1;
158#endif
159}
160
161} // namespace Botan
#define BOTAN_UNUSED
Definition assert.h:118
static constexpr Mask< T > expand(T v)
Definition ct_utils.h:408
static constexpr Mask< T > is_equal(T x, T y)
Definition ct_utils.h:453
static constexpr Mask< T > is_lt(T x, T y)
Definition ct_utils.h:461
void randomize(std::span< uint8_t > output)
Definition rng.h:53
void set_iv(const uint8_t iv[], size_t iv_len)
void write_keystream(uint8_t out[], size_t len)
void set_key(const SymmetricKey &key)
Definition sym_algo.h:113
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
Definition ct_utils.h:788
void page_allow_access(void *page)
Definition os_utils.cpp:607
void page_prohibit_access(void *page)
Definition os_utils.cpp:621
int crypto_verify_32(const uint8_t x[32], const uint8_t y[32])
int crypto_verify_16(const uint8_t x[16], const uint8_t y[16])
void * sodium_allocarray(size_t count, size_t size)
int sodium_memcmp(const void *x, const void *y, size_t len)
@ randombytes_SEEDBYTES
Definition sodium.h:149
int crypto_verify_64(const uint8_t x[64], const uint8_t y[64])
void sodium_add(uint8_t a[], const uint8_t b[], size_t len)
void * sodium_malloc(size_t size)
void sodium_increment(uint8_t n[], size_t nlen)
int sodium_compare(const uint8_t x[], const uint8_t y[], size_t len)
int sodium_mprotect_noaccess(void *ptr)
void randombytes_buf_deterministic(void *buf, size_t size, const uint8_t seed[randombytes_SEEDBYTES])
int sodium_is_zero(const uint8_t nonce[], size_t nlen)
void sodium_free(void *ptr)
uint32_t randombytes_uniform(uint32_t upper_bound)
int sodium_mprotect_readwrite(void *ptr)
void sodium_memzero(void *ptr, size_t len)
void randombytes_buf(void *buf, size_t size)
RandomNumberGenerator & system_rng()
void secure_scrub_memory(void *ptr, size_t n)
Definition mem_utils.cpp:19
constexpr auto store_le(ParamTs &&... params)
Definition loadstor.h:764
void carry(int64_t &h0, int64_t &h1)
constexpr auto load_le(ParamTs &&... params)
Definition loadstor.h:521
const SIMD_8x32 & b