1 /* 2 Written in the D programming language. 3 For git maintenance (ensure at least one congruent line with originating C header): 4 #define sodium_utils_H 5 */ 6 7 /** 8 * Utility functions. 9 */ 10 11 module deimos.sodium.utils; 12 13 extern (C) @nogc nothrow: 14 15 /** Zeroing memory. 16 * 17 * After use, sensitive data should be overwritten, but memset() and hand-written code can be 18 * silently stripped out by an optimizing compiler or by the linker. 19 * The sodium_memzero() function tries to effectively zero `len` bytes starting at `pnt`, even if 20 * optimizations are being applied to the code. 21 * See_Also: https://download.libsodium.org/doc/memory_management#zeroing-memory 22 */ 23 void sodium_memzero(void* pnt, const size_t len) pure; 24 25 /** Clearing the stack. 26 * 27 * The sodium_stackzero() function clears len bytes above the current stack pointer, to 28 * overwrite sensitive values that may have been temporarily stored on the stack. 29 * Note that these values can still be present in registers. 30 * History: This function was introduced in libsodium 1.0.16. 31 * See_Also: https://download.libsodium.org/doc/helpers#clearing-the-stack 32 */ 33 void sodium_stackzero(const size_t len) pure; 34 35 /** Constant-time test for equality. 36 * 37 * WARNING: sodium_memcmp() must be used to verify if two secret keys 38 * are equal, in constant time. 39 * This function is not designed for lexicographical comparisons. 40 * Returns: 0 if the keys are equal, and -1 if they differ. 41 * See_Also: https://download.libsodium.org/doc/helpers#constant-time-test-for-equality 42 */ 43 int sodium_memcmp(const(void*) b1_, const(void*) b2_, size_t len) pure; // __attribute__ ((warn_unused_result)) 44 45 /** Comparing large numbers. 46 * 47 * It is suitable for lexicographical comparisons, or to compare nonces 48 * and counters stored in little-endian format. 49 * However, it is slower than sodium_memcmp(). 50 * The comparison is done in constant time for a given length. 51 * Returns: -1 if b1_ < b2_, 1 if b1_ > b2_ and 0 if b1_ == b2_ 52 * See_Also: https://download.libsodium.org/doc/helpers#comparing-large-numbers 53 */ 54 int sodium_compare(const(ubyte)* b1_, const(ubyte)* b2_, size_t len) pure; // __attribute__ ((warn_unused_result)); 55 56 /** Testing for all zeros. 57 * 58 * It's execution time is constant for a given length. 59 * Returns: 1 if the `nlen` bytes vector pointed by `n` contains only zeros. 60 * 0 if non-zero bits are found. 61 * See_Also: https://download.libsodium.org/doc/helpers#testing-for-all-zeros 62 */ 63 int sodium_is_zero(const(ubyte)* n, const size_t nlen) pure; 64 65 /// See_Also: https://download.libsodium.org/doc/helpers#incrementing-large-numbers 66 void sodium_increment(ubyte* n, const size_t nlen) pure; 67 68 /// See_Also: https://download.libsodium.org/doc/helpers#adding-large-numbers 69 void sodium_add(ubyte* a, const(ubyte)* b, const size_t len) pure; 70 71 version(bin_v1_0_16) {} 72 else { 73 /// See_Also: https://download.libsodium.org/doc/helpers#substracting-large-numbers 74 void sodium_sub(ubyte* a, const(ubyte)* b, const size_t len) pure; 75 } 76 77 /// Returns: hex 78 /// See_Also: https://download.libsodium.org/doc/helpers#hexadecimal-encoding-decoding 79 char* sodium_bin2hex(char* hex, const size_t hex_maxlen, const(ubyte*) bin, const size_t bin_len) pure; // __attribute__ ((nonnull(1))); 80 81 /// Returns: 0 on success, -1 otherwise 82 /// See_Also: https://download.libsodium.org/doc/helpers#hexadecimal-encoding-decoding 83 int sodium_hex2bin(ubyte* bin, const size_t bin_maxlen, const(char*) hex, const size_t hex_len, 84 const(char*) ignore, size_t* bin_len, const(char)** hex_end) pure; // __attribute__ ((nonnull(1))); 85 86 /// See_Also: https://download.libsodium.org/doc/helpers#base64-encoding-decoding 87 enum int sodium_base64_VARIANT_ORIGINAL = 1; 88 /// See_Also: https://download.libsodium.org/doc/helpers#base64-encoding-decoding 89 enum int sodium_base64_VARIANT_ORIGINAL_NO_PADDING = 3; 90 /// See_Also: https://download.libsodium.org/doc/helpers#base64-encoding-decoding 91 enum int sodium_base64_VARIANT_URLSAFE = 5; 92 /// See_Also: https://download.libsodium.org/doc/helpers#base64-encoding-decoding 93 enum int sodium_base64_VARIANT_URLSAFE_NO_PADDING = 7; 94 95 /** #define sodium_base64_ENCODED_LEN(BIN_LEN, VARIANT) 96 * Computes the required length to encode BIN_LEN bytes as a base64 string 97 * using the given variant. The computed length includes a trailing \0. 98 */ 99 size_t sodium_base64_ENCODED_LEN()(const size_t BIN_LEN, const int VARIANT) { 100 return (BIN_LEN / 3) * 4 + 101 (((BIN_LEN - (BIN_LEN / 3) * 3) | (((BIN_LEN) - (BIN_LEN / 3U) * 3U) >> 1)) & 1U) * 102 (4 - (~(((VARIANT & 2U) >> 1) - 1) & (3 - (BIN_LEN - (BIN_LEN / 3) * 3)))) + 1; 103 } 104 105 /// Returns: sodium_base64_encoded length required, e.g. for b64 in sodium_bin2base64. 106 /// See_Also: https://download.libsodium.org/doc/helpers#base64-encoding-decoding 107 size_t sodium_base64_encoded_len(const size_t bin_len, const int variant) pure @trusted; 108 109 /// Returns: b64 110 /// See_Also: https://download.libsodium.org/doc/helpers#base64-encoding-decoding 111 char* sodium_bin2base64(char* b64, const size_t b64_maxlen, const(ubyte*) bin, const size_t bin_len, const int variant) pure; // __attribute__ ((nonnull(1))); 112 113 /// Returns: 0 on success, -1 otherwise 114 /// See_Also: https://download.libsodium.org/doc/helpers#base64-encoding-decoding 115 int sodium_base642bin(ubyte* bin, const size_t bin_maxlen, const(char*) b64, const size_t b64_len, 116 const(char*) ignore, size_t* bin_len, const(char)** b64_end, const int variant) pure; // __attribute__ ((nonnull(1))); 117 118 /** 119 * The sodium_mlock() function locks at least `len` bytes of memory starting at `addr`. 120 * This can help avoid swapping sensitive data to disk. 121 * Returns: 0 on success, -1 otherwise 122 * See_Also: https://download.libsodium.org/doc/memory_management#locking-memory 123 */ 124 int sodium_mlock(scope void* addr, const size_t len); // __attribute__ ((nonnull)); 125 126 /** 127 * The sodium_munlock() function should be called after locked memory is not being used any more. 128 * It will zero `len` bytes starting at `addr` before actually flagging the pages as 129 * swappable again. Calling sodium_memzero() prior to sodium_munlock() is thus not required. 130 * Returns: 0 on success, -1 otherwise 131 * See_Also: https://download.libsodium.org/doc/memory_management#locking-memory 132 */ 133 int sodium_munlock(scope void* addr, const size_t len); // __attribute__ ((nonnull)); 134 135 /* WARNING: sodium_malloc() and sodium_allocarray() are not general-purpose 136 * allocation functions. 137 * 138 * They return a pointer to a region filled with 0xd0 bytes, immediately 139 * followed by a guard page. 140 * As a result, accessing a single byte after the requested allocation size 141 * will intentionally trigger a segmentation fault. 142 * 143 * A canary and an additional guard page placed before the beginning of the 144 * region may also kill the process if a buffer underflow is detected. 145 * 146 * The memory layout is: 147 * [unprotected region size (read only)][guard page (no access)][unprotected pages (read/write)][guard page (no access)] 148 * With the layout of the unprotected pages being: 149 * [optional padding][16-bytes canary][user region] 150 * 151 * However: 152 * - These functions are significantly slower than standard functions 153 * - Each allocation requires 3 or 4 additional pages 154 * - The returned address will not be aligned if the allocation size is not 155 * a multiple of the required alignment. For this reason, these functions 156 * are designed to store data, such as secret keys and messages. 157 * 158 * sodium_malloc() can be used to allocate any libsodium data structure. 159 * 160 * The crypto_generichash_state structure is packed and its length is 161 * either 357 or 361 bytes. For this reason, when using sodium_malloc() to 162 * allocate a crypto_generichash_state structure, padding must be added in 163 * order to ensure proper alignment. crypto_generichash_statebytes() 164 * returns the rounded up structure size, and should be prefered to sizeof(): 165 * state = sodium_malloc(crypto_generichash_statebytes()); 166 */ 167 168 /// See_Also: https://download.libsodium.org/doc/memory_management#guarded-heap-allocations 169 void* sodium_malloc(const size_t size); // __attribute__ ((malloc)); 170 171 /// See_Also: https://download.libsodium.org/doc/memory_management#guarded-heap-allocations 172 void* sodium_allocarray(size_t count, size_t size); // __attribute__ ((malloc)); 173 174 /// See_Also: https://download.libsodium.org/doc/memory_management#guarded-heap-allocations 175 void sodium_free(scope void* ptr); 176 177 /// Returns: 0 on success, -1 otherwise 178 /// See_Also: https://download.libsodium.org/doc/memory_management#guarded-heap-allocations 179 int sodium_mprotect_noaccess(scope void* ptr); // __attribute__ ((nonnull)); 180 181 /// Returns: 0 on success, -1 otherwise 182 /// See_Also: https://download.libsodium.org/doc/memory_management#guarded-heap-allocations 183 int sodium_mprotect_readonly(scope void* ptr); // __attribute__ ((nonnull)); 184 185 /// Returns: 0 on success, -1 otherwise 186 /// See_Also: https://download.libsodium.org/doc/memory_management#guarded-heap-allocations 187 int sodium_mprotect_readwrite(scope void* ptr); // __attribute__ ((nonnull)); 188 189 /// Returns: 0 on success, -1 otherwise 190 /// See_Also: https://download.libsodium.org/doc/padding#usage 191 int sodium_pad(size_t* padded_buflen_p, ubyte* buf, size_t unpadded_buflen, size_t blocksize, size_t max_buflen) pure; // __attribute__ ((nonnull(2))); 192 193 /// Returns: 0 on success, -1 otherwise 194 /// See_Also: https://download.libsodium.org/doc/padding#usage 195 int sodium_unpad(size_t* unpadded_buflen_p, const(ubyte)* buf, size_t padded_buflen, size_t blocksize) pure; // __attribute__ ((nonnull(2)));