1 /*******************************************************************************
2 
3     D language bindings for libsodium's utils.h
4 
5     License: ISC (see LICENSE.txt)
6 
7 *******************************************************************************/
8 
9 module libsodium.utils;
10 
11 @nogc nothrow:
12 
13 import libsodium.export_;
14 
15 extern (C):
16 
17 extern (D) auto SODIUM_C99(T)(auto ref T X)
18 {
19     return X;
20 }
21 
22 void sodium_memzero (void* pnt, const size_t len);
23 
24 void sodium_stackzero (const size_t len);
25 
26 /*
27  * WARNING: sodium_memcmp() must be used to verify if two secret keys
28  * are equal, in constant time.
29  * It returns 0 if the keys are equal, and -1 if they differ.
30  * This function is not designed for lexicographical comparisons.
31  */
32 int sodium_memcmp (const void* b1_, const void* b2_, size_t len);
33 
34 /*
35  * sodium_compare() returns -1 if b1_ < b2_, 1 if b1_ > b2_ and 0 if b1_ == b2_
36  * It is suitable for lexicographical comparisons, or to compare nonces
37  * and counters stored in little-endian format.
38  * However, it is slower than sodium_memcmp().
39  */
40 int sodium_compare (const(ubyte)* b1_, const(ubyte)* b2_, size_t len);
41 
42 int sodium_is_zero (const(ubyte)* n, const size_t nlen);
43 
44 void sodium_increment (ubyte* n, const size_t nlen);
45 
46 void sodium_add (ubyte* a, const(ubyte)* b, const size_t len);
47 
48 void sodium_sub (ubyte* a, const(ubyte)* b, const size_t len);
49 
50 char* sodium_bin2hex (
51     char* hex,
52     const size_t hex_maxlen,
53     const ubyte* bin,
54     const size_t bin_len);
55 
56 int sodium_hex2bin (
57     ubyte* bin,
58     const size_t bin_maxlen,
59     const char* hex,
60     const size_t hex_len,
61     const char* ignore,
62     size_t* bin_len,
63     const char** hex_end);
64 
65 enum sodium_base64_VARIANT_ORIGINAL = 1;
66 enum sodium_base64_VARIANT_ORIGINAL_NO_PADDING = 3;
67 enum sodium_base64_VARIANT_URLSAFE = 5;
68 enum sodium_base64_VARIANT_URLSAFE_NO_PADDING = 7;
69 
70 /*
71  * Computes the required length to encode BIN_LEN bytes as a base64 string
72  * using the given variant. The computed length includes a trailing \0.
73  */
74 extern (D) auto sodium_base64_ENCODED_LEN(T0, T1)(auto ref T0 BIN_LEN, auto ref T1 VARIANT)
75 {
76     return (BIN_LEN / 3U) * 4U + (((BIN_LEN - (BIN_LEN / 3U) * 3U) | ((BIN_LEN - (BIN_LEN / 3U) * 3U) >> 1)) & 1U) * (4U - (~(((VARIANT & 2U) >> 1) - 1U) & (3U - (BIN_LEN - (BIN_LEN / 3U) * 3U)))) + 1U;
77 }
78 
79 size_t sodium_base64_encoded_len (const size_t bin_len, const int variant);
80 
81 char* sodium_bin2base64 (
82     char* b64,
83     const size_t b64_maxlen,
84     const ubyte* bin,
85     const size_t bin_len,
86     const int variant);
87 
88 int sodium_base642bin (
89     ubyte* bin,
90     const size_t bin_maxlen,
91     const char* b64,
92     const size_t b64_len,
93     const char* ignore,
94     size_t* bin_len,
95     const char** b64_end,
96     const int variant);
97 
98 int sodium_mlock (void* addr, const size_t len);
99 
100 int sodium_munlock (void* addr, const size_t len);
101 
102 /* WARNING: sodium_malloc() and sodium_allocarray() are not general-purpose
103  * allocation functions.
104  *
105  * They return a pointer to a region filled with 0xd0 bytes, immediately
106  * followed by a guard page.
107  * As a result, accessing a single byte after the requested allocation size
108  * will intentionally trigger a segmentation fault.
109  *
110  * A canary and an additional guard page placed before the beginning of the
111  * region may also kill the process if a buffer underflow is detected.
112  *
113  * The memory layout is:
114  * [unprotected region size (read only)][guard page (no access)][unprotected pages (read/write)][guard page (no access)]
115  * With the layout of the unprotected pages being:
116  * [optional padding][16-bytes canary][user region]
117  *
118  * However:
119  * - These functions are significantly slower than standard functions
120  * - Each allocation requires 3 or 4 additional pages
121  * - The returned address will not be aligned if the allocation size is not
122  *   a multiple of the required alignment. For this reason, these functions
123  *   are designed to store data, such as secret keys and messages.
124  *
125  * sodium_malloc() can be used to allocate any libsodium data structure.
126  *
127  * The crypto_generichash_state structure is packed and its length is
128  * either 357 or 361 bytes. For this reason, when using sodium_malloc() to
129  * allocate a crypto_generichash_state structure, padding must be added in
130  * order to ensure proper alignment. crypto_generichash_statebytes()
131  * returns the rounded up structure size, and should be prefered to sizeof():
132  * state = sodium_malloc(crypto_generichash_statebytes());
133  */
134 
135 void* sodium_malloc (const size_t size);
136 
137 void* sodium_allocarray (size_t count, size_t size);
138 
139 void sodium_free (void* ptr);
140 
141 int sodium_mprotect_noaccess (void* ptr);
142 
143 int sodium_mprotect_readonly (void* ptr);
144 
145 int sodium_mprotect_readwrite (void* ptr);
146 
147 int sodium_pad (
148     size_t* padded_buflen_p,
149     ubyte* buf,
150     size_t unpadded_buflen,
151     size_t blocksize,
152     size_t max_buflen);
153 
154 int sodium_unpad (
155     size_t* unpadded_buflen_p,
156     const(ubyte)* buf,
157     size_t padded_buflen,
158     size_t blocksize);
159 
160 /* -------- */
161 
162 int _sodium_alloc_init ();