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