aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/libsodium/src/libsodium/sodium
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/libsodium/src/libsodium/sodium')
-rw-r--r--sys/contrib/libsodium/src/libsodium/sodium/codecs.c333
-rw-r--r--sys/contrib/libsodium/src/libsodium/sodium/core.c231
-rw-r--r--sys/contrib/libsodium/src/libsodium/sodium/runtime.c297
-rw-r--r--sys/contrib/libsodium/src/libsodium/sodium/utils.c733
-rw-r--r--sys/contrib/libsodium/src/libsodium/sodium/version.c30
5 files changed, 1624 insertions, 0 deletions
diff --git a/sys/contrib/libsodium/src/libsodium/sodium/codecs.c b/sys/contrib/libsodium/src/libsodium/sodium/codecs.c
new file mode 100644
index 000000000000..77fa464cc4b7
--- /dev/null
+++ b/sys/contrib/libsodium/src/libsodium/sodium/codecs.c
@@ -0,0 +1,333 @@
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "core.h"
+#include "utils.h"
+
+/* Derived from original code by CodesInChaos */
+char *
+sodium_bin2hex(char *const hex, const size_t hex_maxlen,
+ const unsigned char *const bin, const size_t bin_len)
+{
+ size_t i = (size_t) 0U;
+ unsigned int x;
+ int b;
+ int c;
+
+ if (bin_len >= SIZE_MAX / 2 || hex_maxlen <= bin_len * 2U) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ while (i < bin_len) {
+ c = bin[i] & 0xf;
+ b = bin[i] >> 4;
+ x = (unsigned char) (87U + c + (((c - 10U) >> 8) & ~38U)) << 8 |
+ (unsigned char) (87U + b + (((b - 10U) >> 8) & ~38U));
+ hex[i * 2U] = (char) x;
+ x >>= 8;
+ hex[i * 2U + 1U] = (char) x;
+ i++;
+ }
+ hex[i * 2U] = 0U;
+
+ return hex;
+}
+
+int
+sodium_hex2bin(unsigned char *const bin, const size_t bin_maxlen,
+ const char *const hex, const size_t hex_len,
+ const char *const ignore, size_t *const bin_len,
+ const char **const hex_end)
+{
+ size_t bin_pos = (size_t) 0U;
+ size_t hex_pos = (size_t) 0U;
+ int ret = 0;
+ unsigned char c;
+ unsigned char c_acc = 0U;
+ unsigned char c_alpha0, c_alpha;
+ unsigned char c_num0, c_num;
+ unsigned char c_val;
+ unsigned char state = 0U;
+
+ while (hex_pos < hex_len) {
+ c = (unsigned char) hex[hex_pos];
+ c_num = c ^ 48U;
+ c_num0 = (c_num - 10U) >> 8;
+ c_alpha = (c & ~32U) - 55U;
+ c_alpha0 = ((c_alpha - 10U) ^ (c_alpha - 16U)) >> 8;
+ if ((c_num0 | c_alpha0) == 0U) {
+ if (ignore != NULL && state == 0U && strchr(ignore, c) != NULL) {
+ hex_pos++;
+ continue;
+ }
+ break;
+ }
+ c_val = (c_num0 & c_num) | (c_alpha0 & c_alpha);
+ if (bin_pos >= bin_maxlen) {
+ ret = -1;
+ errno = ERANGE;
+ break;
+ }
+ if (state == 0U) {
+ c_acc = c_val * 16U;
+ } else {
+ bin[bin_pos++] = c_acc | c_val;
+ }
+ state = ~state;
+ hex_pos++;
+ }
+ if (state != 0U) {
+ hex_pos--;
+ errno = EINVAL;
+ ret = -1;
+ }
+ if (ret != 0) {
+ bin_pos = (size_t) 0U;
+ }
+ if (hex_end != NULL) {
+ *hex_end = &hex[hex_pos];
+ } else if (hex_pos != hex_len) {
+ errno = EINVAL;
+ ret = -1;
+ }
+ if (bin_len != NULL) {
+ *bin_len = bin_pos;
+ }
+ return ret;
+}
+
+/*
+ * Some macros for constant-time comparisons. These work over values in
+ * the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".
+ *
+ * Original code by Thomas Pornin.
+ */
+#define EQ(x, y) \
+ ((((0U - ((unsigned int) (x) ^ (unsigned int) (y))) >> 8) & 0xFF) ^ 0xFF)
+#define GT(x, y) ((((unsigned int) (y) - (unsigned int) (x)) >> 8) & 0xFF)
+#define GE(x, y) (GT(y, x) ^ 0xFF)
+#define LT(x, y) GT(y, x)
+#define LE(x, y) GE(y, x)
+
+static int
+b64_byte_to_char(unsigned int x)
+{
+ return (LT(x, 26) & (x + 'A')) |
+ (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
+ (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
+ (EQ(x, 63) & '/');
+}
+
+static unsigned int
+b64_char_to_byte(int c)
+{
+ const unsigned int x =
+ (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) |
+ (GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) |
+ (GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '+') & 62) |
+ (EQ(c, '/') & 63);
+
+ return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF));
+}
+
+static int
+b64_byte_to_urlsafe_char(unsigned int x)
+{
+ return (LT(x, 26) & (x + 'A')) |
+ (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
+ (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '-') |
+ (EQ(x, 63) & '_');
+}
+
+static unsigned int
+b64_urlsafe_char_to_byte(int c)
+{
+ const unsigned x =
+ (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) |
+ (GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) |
+ (GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '-') & 62) |
+ (EQ(c, '_') & 63);
+
+ return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF));
+}
+
+
+#define VARIANT_NO_PADDING_MASK 0x2U
+#define VARIANT_URLSAFE_MASK 0x4U
+
+static void
+sodium_base64_check_variant(const int variant)
+{
+ if ((((unsigned int) variant) & ~ 0x6U) != 0x1U) {
+ sodium_misuse();
+ }
+}
+
+size_t
+sodium_base64_encoded_len(const size_t bin_len, const int variant)
+{
+ sodium_base64_check_variant(variant);
+
+ return sodium_base64_ENCODED_LEN(bin_len, variant);
+}
+
+char *
+sodium_bin2base64(char * const b64, const size_t b64_maxlen,
+ const unsigned char * const bin, const size_t bin_len,
+ const int variant)
+{
+ size_t acc_len = (size_t) 0;
+ size_t b64_len;
+ size_t b64_pos = (size_t) 0;
+ size_t bin_pos = (size_t) 0;
+ size_t nibbles;
+ size_t remainder;
+ unsigned int acc = 0U;
+
+ sodium_base64_check_variant(variant);
+ nibbles = bin_len / 3;
+ remainder = bin_len - 3 * nibbles;
+ b64_len = nibbles * 4;
+ if (remainder != 0) {
+ if ((((unsigned int) variant) & VARIANT_NO_PADDING_MASK) == 0U) {
+ b64_len += 4;
+ } else {
+ b64_len += 2 + (remainder >> 1);
+ }
+ }
+ if (b64_maxlen <= b64_len) {
+ sodium_misuse();
+ }
+ if ((((unsigned int) variant) & VARIANT_URLSAFE_MASK) != 0U) {
+ while (bin_pos < bin_len) {
+ acc = (acc << 8) + bin[bin_pos++];
+ acc_len += 8;
+ while (acc_len >= 6) {
+ acc_len -= 6;
+ b64[b64_pos++] = (char) b64_byte_to_urlsafe_char((acc >> acc_len) & 0x3F);
+ }
+ }
+ if (acc_len > 0) {
+ b64[b64_pos++] = (char) b64_byte_to_urlsafe_char((acc << (6 - acc_len)) & 0x3F);
+ }
+ } else {
+ while (bin_pos < bin_len) {
+ acc = (acc << 8) + bin[bin_pos++];
+ acc_len += 8;
+ while (acc_len >= 6) {
+ acc_len -= 6;
+ b64[b64_pos++] = (char) b64_byte_to_char((acc >> acc_len) & 0x3F);
+ }
+ }
+ if (acc_len > 0) {
+ b64[b64_pos++] = (char) b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
+ }
+ }
+ assert(b64_pos <= b64_len);
+ while (b64_pos < b64_len) {
+ b64[b64_pos++] = '=';
+ }
+ do {
+ b64[b64_pos++] = 0U;
+ } while (b64_pos < b64_maxlen);
+
+ return b64;
+}
+
+static int
+_sodium_base642bin_skip_padding(const char * const b64, const size_t b64_len,
+ size_t * const b64_pos_p,
+ const char * const ignore, size_t padding_len)
+{
+ int c;
+
+ while (padding_len > 0) {
+ if (*b64_pos_p >= b64_len) {
+ errno = ERANGE;
+ return -1;
+ }
+ c = b64[*b64_pos_p];
+ if (c == '=') {
+ padding_len--;
+ } else if (ignore == NULL || strchr(ignore, c) == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ (*b64_pos_p)++;
+ }
+ return 0;
+}
+
+int
+sodium_base642bin(unsigned char * const bin, const size_t bin_maxlen,
+ const char * const b64, const size_t b64_len,
+ const char * const ignore, size_t * const bin_len,
+ const char ** const b64_end, const int variant)
+{
+ size_t acc_len = (size_t) 0;
+ size_t b64_pos = (size_t) 0;
+ size_t bin_pos = (size_t) 0;
+ int is_urlsafe;
+ int ret = 0;
+ unsigned int acc = 0U;
+ unsigned int d;
+ char c;
+
+ sodium_base64_check_variant(variant);
+ is_urlsafe = ((unsigned int) variant) & VARIANT_URLSAFE_MASK;
+ while (b64_pos < b64_len) {
+ c = b64[b64_pos];
+ if (is_urlsafe) {
+ d = b64_urlsafe_char_to_byte(c);
+ } else {
+ d = b64_char_to_byte(c);
+ }
+ if (d == 0xFF) {
+ if (ignore != NULL && strchr(ignore, c) != NULL) {
+ b64_pos++;
+ continue;
+ }
+ break;
+ }
+ acc = (acc << 6) + d;
+ acc_len += 6;
+ if (acc_len >= 8) {
+ acc_len -= 8;
+ if (bin_pos >= bin_maxlen) {
+ errno = ERANGE;
+ ret = -1;
+ break;
+ }
+ bin[bin_pos++] = (acc >> acc_len) & 0xFF;
+ }
+ b64_pos++;
+ }
+ if (acc_len > 4U || (acc & ((1U << acc_len) - 1U)) != 0U) {
+ ret = -1;
+ } else if (ret == 0 &&
+ (((unsigned int) variant) & VARIANT_NO_PADDING_MASK) == 0U) {
+ ret = _sodium_base642bin_skip_padding(b64, b64_len, &b64_pos, ignore,
+ acc_len / 2);
+ }
+ if (ret != 0) {
+ bin_pos = (size_t) 0U;
+ } else if (ignore != NULL) {
+ while (b64_pos < b64_len && strchr(ignore, b64[b64_pos]) != NULL) {
+ b64_pos++;
+ }
+ }
+ if (b64_end != NULL) {
+ *b64_end = &b64[b64_pos];
+ } else if (b64_pos != b64_len) {
+ errno = EINVAL;
+ ret = -1;
+ }
+ if (bin_len != NULL) {
+ *bin_len = bin_pos;
+ }
+ return ret;
+}
diff --git a/sys/contrib/libsodium/src/libsodium/sodium/core.c b/sys/contrib/libsodium/src/libsodium/sodium/core.c
new file mode 100644
index 000000000000..d667312f1904
--- /dev/null
+++ b/sys/contrib/libsodium/src/libsodium/sodium/core.c
@@ -0,0 +1,231 @@
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef _WIN32
+# include <windows.h>
+#elif defined(HAVE_PTHREAD)
+# include <pthread.h>
+#endif
+
+#include "core.h"
+#include "crypto_generichash.h"
+#include "crypto_onetimeauth.h"
+#include "crypto_scalarmult.h"
+#include "crypto_stream_chacha20.h"
+#include "crypto_stream_salsa20.h"
+#include "randombytes.h"
+#include "runtime.h"
+#include "utils.h"
+#include "private/implementations.h"
+#include "private/mutex.h"
+
+#if !defined(_MSC_VER) && 1
+# warning *** This is unstable, untested, development code.
+# warning It might not compile. It might not work as expected.
+# warning It might be totally insecure.
+# warning Do not use this in production.
+# warning Use releases available at https://download.libsodium.org/libsodium/releases/ instead.
+# warning Alternatively, use the "stable" branch in the git repository.
+#endif
+
+#if !defined(_MSC_VER) && (!defined(CONFIGURED) || CONFIGURED != 1)
+# warning *** The library is being compiled using an undocumented method.
+# warning This is not supported. It has not been tested, it might not
+# warning work as expected, and performance is likely to be suboptimal.
+#endif
+
+static volatile int initialized;
+static volatile int locked;
+
+int
+sodium_init(void)
+{
+ if (sodium_crit_enter() != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ if (initialized != 0) {
+ if (sodium_crit_leave() != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return 1;
+ }
+ _sodium_runtime_get_cpu_features();
+ randombytes_stir();
+ _sodium_alloc_init();
+ _crypto_pwhash_argon2_pick_best_implementation();
+ _crypto_generichash_blake2b_pick_best_implementation();
+ _crypto_onetimeauth_poly1305_pick_best_implementation();
+ _crypto_scalarmult_curve25519_pick_best_implementation();
+ _crypto_stream_chacha20_pick_best_implementation();
+ _crypto_stream_salsa20_pick_best_implementation();
+ initialized = 1;
+ if (sodium_crit_leave() != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return 0;
+}
+
+#ifdef _WIN32
+
+static CRITICAL_SECTION _sodium_lock;
+static volatile LONG _sodium_lock_initialized;
+
+int
+_sodium_crit_init(void)
+{
+ LONG status = 0L;
+
+ while ((status = InterlockedCompareExchange(&_sodium_lock_initialized,
+ 1L, 0L)) == 1L) {
+ Sleep(0);
+ }
+
+ switch (status) {
+ case 0L:
+ InitializeCriticalSection(&_sodium_lock);
+ return InterlockedExchange(&_sodium_lock_initialized, 2L) == 1L ? 0 : -1;
+ case 2L:
+ return 0;
+ default: /* should never be reached */
+ return -1;
+ }
+}
+
+int
+sodium_crit_enter(void)
+{
+ if (_sodium_crit_init() != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ EnterCriticalSection(&_sodium_lock);
+ assert(locked == 0);
+ locked = 1;
+
+ return 0;
+}
+
+int
+sodium_crit_leave(void)
+{
+ if (locked == 0) {
+# ifdef EPERM
+ errno = EPERM;
+# endif
+ return -1;
+ }
+ locked = 0;
+ LeaveCriticalSection(&_sodium_lock);
+
+ return 0;
+}
+
+#elif defined(HAVE_PTHREAD) && !defined(__EMSCRIPTEN__)
+
+static pthread_mutex_t _sodium_lock = PTHREAD_MUTEX_INITIALIZER;
+
+int
+sodium_crit_enter(void)
+{
+ int ret;
+
+ if ((ret = pthread_mutex_lock(&_sodium_lock)) == 0) {
+ assert(locked == 0);
+ locked = 1;
+ }
+ return ret;
+}
+
+int
+sodium_crit_leave(void)
+{
+ int ret;
+
+ if (locked == 0) {
+# ifdef EPERM
+ errno = EPERM;
+# endif
+ return -1;
+ }
+ locked = 0;
+
+ return pthread_mutex_unlock(&_sodium_lock);
+}
+
+#elif defined(HAVE_ATOMIC_OPS) && !defined(__EMSCRIPTEN__) && !defined(__native_client__)
+
+static volatile int _sodium_lock;
+
+int
+sodium_crit_enter(void)
+{
+# ifdef HAVE_NANOSLEEP
+ struct timespec q;
+ memset(&q, 0, sizeof q);
+# endif
+ while (__sync_lock_test_and_set(&_sodium_lock, 1) != 0) {
+# ifdef HAVE_NANOSLEEP
+ (void) nanosleep(&q, NULL);
+# elif defined(__x86_64__) || defined(__i386__)
+ __asm__ __volatile__ ("pause");
+# endif
+ }
+ return 0;
+}
+
+int
+sodium_crit_leave(void)
+{
+ __sync_lock_release(&_sodium_lock);
+
+ return 0;
+}
+
+#else
+
+int
+sodium_crit_enter(void)
+{
+ return 0;
+}
+
+int
+sodium_crit_leave(void)
+{
+ return 0;
+}
+
+#endif
+
+static void (*_misuse_handler)(void);
+
+void
+sodium_misuse(void)
+{
+ void (*handler)(void);
+
+ (void) sodium_crit_leave();
+ if (sodium_crit_enter() == 0) {
+ handler = _misuse_handler;
+ if (handler != NULL) {
+ handler();
+ }
+ }
+/* LCOV_EXCL_START */
+ abort();
+}
+/* LCOV_EXCL_STOP */
+
+int
+sodium_set_misuse_handler(void (*handler)(void))
+{
+ if (sodium_crit_enter() != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ _misuse_handler = handler;
+ if (sodium_crit_leave() != 0) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ return 0;
+}
diff --git a/sys/contrib/libsodium/src/libsodium/sodium/runtime.c b/sys/contrib/libsodium/src/libsodium/sodium/runtime.c
new file mode 100644
index 000000000000..f5c805cf5544
--- /dev/null
+++ b/sys/contrib/libsodium/src/libsodium/sodium/runtime.c
@@ -0,0 +1,297 @@
+#include <stddef.h>
+#include <stdint.h>
+#ifdef HAVE_ANDROID_GETCPUFEATURES
+# include <cpu-features.h>
+#endif
+
+#include "private/common.h"
+#include "runtime.h"
+
+typedef struct CPUFeatures_ {
+ int initialized;
+ int has_neon;
+ int has_sse2;
+ int has_sse3;
+ int has_ssse3;
+ int has_sse41;
+ int has_avx;
+ int has_avx2;
+ int has_avx512f;
+ int has_pclmul;
+ int has_aesni;
+ int has_rdrand;
+} CPUFeatures;
+
+static CPUFeatures _cpu_features;
+
+#define CPUID_EBX_AVX2 0x00000020
+#define CPUID_EBX_AVX512F 0x00010000
+
+#define CPUID_ECX_SSE3 0x00000001
+#define CPUID_ECX_PCLMUL 0x00000002
+#define CPUID_ECX_SSSE3 0x00000200
+#define CPUID_ECX_SSE41 0x00080000
+#define CPUID_ECX_AESNI 0x02000000
+#define CPUID_ECX_XSAVE 0x04000000
+#define CPUID_ECX_OSXSAVE 0x08000000
+#define CPUID_ECX_AVX 0x10000000
+#define CPUID_ECX_RDRAND 0x40000000
+
+#define CPUID_EDX_SSE2 0x04000000
+
+#define XCR0_SSE 0x00000002
+#define XCR0_AVX 0x00000004
+
+static int
+_sodium_runtime_arm_cpu_features(CPUFeatures * const cpu_features)
+{
+#ifndef __arm__
+ cpu_features->has_neon = 0;
+ return -1;
+#else
+# ifdef __APPLE__
+# ifdef __ARM_NEON__
+ cpu_features->has_neon = 1;
+# else
+ cpu_features->has_neon = 0;
+# endif
+# elif defined(HAVE_ANDROID_GETCPUFEATURES) && \
+ defined(ANDROID_CPU_ARM_FEATURE_NEON)
+ cpu_features->has_neon =
+ (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0x0;
+# else
+ cpu_features->has_neon = 0;
+# endif
+ return 0;
+#endif
+}
+
+static void
+_cpuid(unsigned int cpu_info[4U], const unsigned int cpu_info_type)
+{
+#if defined(_MSC_VER) && \
+ (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86))
+ __cpuid((int *) cpu_info, cpu_info_type);
+#elif defined(HAVE_CPUID)
+ cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0;
+# ifdef __i386__
+ __asm__ __volatile__(
+ "pushfl; pushfl; "
+ "popl %0; "
+ "movl %0, %1; xorl %2, %0; "
+ "pushl %0; "
+ "popfl; pushfl; popl %0; popfl"
+ : "=&r"(cpu_info[0]), "=&r"(cpu_info[1])
+ : "i"(0x200000));
+ if (((cpu_info[0] ^ cpu_info[1]) & 0x200000) == 0x0) {
+ return; /* LCOV_EXCL_LINE */
+ }
+# endif
+# ifdef __i386__
+ __asm__ __volatile__("xchgl %%ebx, %k1; cpuid; xchgl %%ebx, %k1"
+ : "=a"(cpu_info[0]), "=&r"(cpu_info[1]),
+ "=c"(cpu_info[2]), "=d"(cpu_info[3])
+ : "0"(cpu_info_type), "2"(0U));
+# elif defined(__x86_64__)
+ __asm__ __volatile__("xchgq %%rbx, %q1; cpuid; xchgq %%rbx, %q1"
+ : "=a"(cpu_info[0]), "=&r"(cpu_info[1]),
+ "=c"(cpu_info[2]), "=d"(cpu_info[3])
+ : "0"(cpu_info_type), "2"(0U));
+# else
+ __asm__ __volatile__("cpuid"
+ : "=a"(cpu_info[0]), "=b"(cpu_info[1]),
+ "=c"(cpu_info[2]), "=d"(cpu_info[3])
+ : "0"(cpu_info_type), "2"(0U));
+# endif
+#else
+ (void) cpu_info_type;
+ cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0;
+#endif
+}
+
+static int
+_sodium_runtime_intel_cpu_features(CPUFeatures * const cpu_features)
+{
+ unsigned int cpu_info[4];
+ unsigned int id;
+
+ _cpuid(cpu_info, 0x0);
+ if ((id = cpu_info[0]) == 0U) {
+ return -1; /* LCOV_EXCL_LINE */
+ }
+ _cpuid(cpu_info, 0x00000001);
+#ifdef HAVE_EMMINTRIN_H
+ cpu_features->has_sse2 = ((cpu_info[3] & CPUID_EDX_SSE2) != 0x0);
+#else
+ cpu_features->has_sse2 = 0;
+#endif
+
+#ifdef HAVE_PMMINTRIN_H
+ cpu_features->has_sse3 = ((cpu_info[2] & CPUID_ECX_SSE3) != 0x0);
+#else
+ cpu_features->has_sse3 = 0;
+#endif
+
+#ifdef HAVE_TMMINTRIN_H
+ cpu_features->has_ssse3 = ((cpu_info[2] & CPUID_ECX_SSSE3) != 0x0);
+#else
+ cpu_features->has_ssse3 = 0;
+#endif
+
+#ifdef HAVE_SMMINTRIN_H
+ cpu_features->has_sse41 = ((cpu_info[2] & CPUID_ECX_SSE41) != 0x0);
+#else
+ cpu_features->has_sse41 = 0;
+#endif
+
+ cpu_features->has_avx = 0;
+#ifdef HAVE_AVXINTRIN_H
+ if ((cpu_info[2] & (CPUID_ECX_AVX | CPUID_ECX_XSAVE | CPUID_ECX_OSXSAVE)) ==
+ (CPUID_ECX_AVX | CPUID_ECX_XSAVE | CPUID_ECX_OSXSAVE)) {
+ uint32_t xcr0 = 0U;
+# if defined(HAVE__XGETBV) || \
+ (defined(_MSC_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) && _MSC_FULL_VER >= 160040219)
+ xcr0 = (uint32_t) _xgetbv(0);
+# elif defined(_MSC_VER) && defined(_M_IX86)
+ /*
+ * Visual Studio documentation states that eax/ecx/edx don't need to
+ * be preserved in inline assembly code. But that doesn't seem to
+ * always hold true on Visual Studio 2010.
+ */
+ __asm {
+ push eax
+ push ecx
+ push edx
+ xor ecx, ecx
+ _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0
+ mov xcr0, eax
+ pop edx
+ pop ecx
+ pop eax
+ }
+# elif defined(HAVE_AVX_ASM)
+ __asm__ __volatile__(".byte 0x0f, 0x01, 0xd0" /* XGETBV */
+ : "=a"(xcr0)
+ : "c"((uint32_t) 0U)
+ : "%edx");
+# endif
+ if ((xcr0 & (XCR0_SSE | XCR0_AVX)) == (XCR0_SSE | XCR0_AVX)) {
+ cpu_features->has_avx = 1;
+ }
+ }
+#endif
+
+ cpu_features->has_avx2 = 0;
+#ifdef HAVE_AVX2INTRIN_H
+ if (cpu_features->has_avx) {
+ unsigned int cpu_info7[4];
+
+ _cpuid(cpu_info7, 0x00000007);
+ cpu_features->has_avx2 = ((cpu_info7[1] & CPUID_EBX_AVX2) != 0x0);
+ }
+#endif
+
+ cpu_features->has_avx512f = 0;
+#ifdef HAVE_AVX512FINTRIN_H
+ if (cpu_features->has_avx2) {
+ unsigned int cpu_info7[4];
+
+ _cpuid(cpu_info7, 0x00000007);
+ cpu_features->has_avx512f = ((cpu_info7[1] & CPUID_EBX_AVX512F) != 0x0);
+ }
+#endif
+
+#ifdef HAVE_WMMINTRIN_H
+ cpu_features->has_pclmul = ((cpu_info[2] & CPUID_ECX_PCLMUL) != 0x0);
+ cpu_features->has_aesni = ((cpu_info[2] & CPUID_ECX_AESNI) != 0x0);
+#else
+ cpu_features->has_pclmul = 0;
+ cpu_features->has_aesni = 0;
+#endif
+
+#ifdef HAVE_RDRAND
+ cpu_features->has_rdrand = ((cpu_info[2] & CPUID_ECX_RDRAND) != 0x0);
+#else
+ cpu_features->has_rdrand = 0;
+#endif
+
+ return 0;
+}
+
+int
+_sodium_runtime_get_cpu_features(void)
+{
+ int ret = -1;
+
+ ret &= _sodium_runtime_arm_cpu_features(&_cpu_features);
+ ret &= _sodium_runtime_intel_cpu_features(&_cpu_features);
+ _cpu_features.initialized = 1;
+
+ return ret;
+}
+
+int
+sodium_runtime_has_neon(void)
+{
+ return _cpu_features.has_neon;
+}
+
+int
+sodium_runtime_has_sse2(void)
+{
+ return _cpu_features.has_sse2;
+}
+
+int
+sodium_runtime_has_sse3(void)
+{
+ return _cpu_features.has_sse3;
+}
+
+int
+sodium_runtime_has_ssse3(void)
+{
+ return _cpu_features.has_ssse3;
+}
+
+int
+sodium_runtime_has_sse41(void)
+{
+ return _cpu_features.has_sse41;
+}
+
+int
+sodium_runtime_has_avx(void)
+{
+ return _cpu_features.has_avx;
+}
+
+int
+sodium_runtime_has_avx2(void)
+{
+ return _cpu_features.has_avx2;
+}
+
+int
+sodium_runtime_has_avx512f(void)
+{
+ return _cpu_features.has_avx512f;
+}
+
+int
+sodium_runtime_has_pclmul(void)
+{
+ return _cpu_features.has_pclmul;
+}
+
+int
+sodium_runtime_has_aesni(void)
+{
+ return _cpu_features.has_aesni;
+}
+
+int
+sodium_runtime_has_rdrand(void)
+{
+ return _cpu_features.has_rdrand;
+}
diff --git a/sys/contrib/libsodium/src/libsodium/sodium/utils.c b/sys/contrib/libsodium/src/libsodium/sodium/utils.c
new file mode 100644
index 000000000000..3a5f835b9f0d
--- /dev/null
+++ b/sys/contrib/libsodium/src/libsodium/sodium/utils.c
@@ -0,0 +1,733 @@
+#ifndef __STDC_WANT_LIB_EXT1__
+# define __STDC_WANT_LIB_EXT1__ 1
+#endif
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+#endif
+
+#ifdef _WIN32
+# include <windows.h>
+# include <wincrypt.h>
+#else
+# include <unistd.h>
+#endif
+
+#ifndef HAVE_C_VARARRAYS
+# ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# elif !defined(alloca)
+# if defined(__clang__) || defined(__GNUC__)
+# define alloca __builtin_alloca
+# elif defined _AIX
+# define alloca __alloca
+# elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# include <stddef.h>
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+# endif
+# endif
+#endif
+
+#include "core.h"
+#include "randombytes.h"
+#include "utils.h"
+
+#ifndef ENOSYS
+# define ENOSYS ENXIO
+#endif
+
+#if defined(_WIN32) && \
+ (!defined(WINAPI_FAMILY) || WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
+# define WINAPI_DESKTOP
+#endif
+
+#define CANARY_SIZE 16U
+#define GARBAGE_VALUE 0xdb
+
+#ifndef MAP_NOCORE
+# define MAP_NOCORE 0
+#endif
+#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
+# define MAP_ANON MAP_ANONYMOUS
+#endif
+#if defined(WINAPI_DESKTOP) || (defined(MAP_ANON) && defined(HAVE_MMAP)) || \
+ defined(HAVE_POSIX_MEMALIGN)
+# define HAVE_ALIGNED_MALLOC
+#endif
+#if defined(HAVE_MPROTECT) && \
+ !(defined(PROT_NONE) && defined(PROT_READ) && defined(PROT_WRITE))
+# undef HAVE_MPROTECT
+#endif
+#if defined(HAVE_ALIGNED_MALLOC) && \
+ (defined(WINAPI_DESKTOP) || defined(HAVE_MPROTECT))
+# define HAVE_PAGE_PROTECTION
+#endif
+#if !defined(MADV_DODUMP) && defined(MADV_CORE)
+# define MADV_DODUMP MADV_CORE
+# define MADV_DONTDUMP MADV_NOCORE
+#endif
+
+static size_t page_size;
+static unsigned char canary[CANARY_SIZE];
+
+/* LCOV_EXCL_START */
+#ifdef HAVE_WEAK_SYMBOLS
+__attribute__((weak)) void
+_sodium_dummy_symbol_to_prevent_memzero_lto(void *const pnt,
+ const size_t len);
+__attribute__((weak)) void
+_sodium_dummy_symbol_to_prevent_memzero_lto(void *const pnt,
+ const size_t len)
+{
+ (void) pnt; /* LCOV_EXCL_LINE */
+ (void) len; /* LCOV_EXCL_LINE */
+}
+#endif
+/* LCOV_EXCL_STOP */
+
+void
+sodium_memzero(void *const pnt, const size_t len)
+{
+#ifdef _WIN32
+ SecureZeroMemory(pnt, len);
+#elif defined(HAVE_MEMSET_S)
+ if (len > 0U && memset_s(pnt, (rsize_t) len, 0, (rsize_t) len) != 0) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+#elif defined(HAVE_EXPLICIT_BZERO)
+ explicit_bzero(pnt, len);
+#elif HAVE_WEAK_SYMBOLS
+ memset(pnt, 0, len);
+ _sodium_dummy_symbol_to_prevent_memzero_lto(pnt, len);
+# ifdef HAVE_INLINE_ASM
+ __asm__ __volatile__ ("" : : "r"(pnt) : "memory");
+# endif
+#else
+ volatile unsigned char *volatile pnt_ =
+ (volatile unsigned char *volatile) pnt;
+ size_t i = (size_t) 0U;
+
+ while (i < len) {
+ pnt_[i++] = 0U;
+ }
+#endif
+}
+
+void
+sodium_stackzero(const size_t len)
+{
+#ifdef HAVE_C_VARARRAYS
+ unsigned char fodder[len];
+ sodium_memzero(fodder, len);
+#elif HAVE_ALLOCA
+ sodium_memzero(alloca(len), len);
+#endif
+}
+
+#ifdef HAVE_WEAK_SYMBOLS
+__attribute__((weak)) void
+_sodium_dummy_symbol_to_prevent_memcmp_lto(const unsigned char *b1,
+ const unsigned char *b2,
+ const size_t len);
+__attribute__((weak)) void
+_sodium_dummy_symbol_to_prevent_memcmp_lto(const unsigned char *b1,
+ const unsigned char *b2,
+ const size_t len)
+{
+ (void) b1;
+ (void) b2;
+ (void) len;
+}
+#endif
+
+int
+sodium_memcmp(const void *const b1_, const void *const b2_, size_t len)
+{
+#ifdef HAVE_WEAK_SYMBOLS
+ const unsigned char *b1 = (const unsigned char *) b1_;
+ const unsigned char *b2 = (const unsigned char *) b2_;
+#else
+ const volatile unsigned char *volatile b1 =
+ (const volatile unsigned char *volatile) b1_;
+ const volatile unsigned char *volatile b2 =
+ (const volatile unsigned char *volatile) b2_;
+#endif
+ size_t i;
+ volatile unsigned char d = 0U;
+
+#if HAVE_WEAK_SYMBOLS
+ _sodium_dummy_symbol_to_prevent_memcmp_lto(b1, b2, len);
+#endif
+ for (i = 0U; i < len; i++) {
+ d |= b1[i] ^ b2[i];
+ }
+ return (1 & ((d - 1) >> 8)) - 1;
+}
+
+#ifdef HAVE_WEAK_SYMBOLS
+__attribute__((weak)) void
+_sodium_dummy_symbol_to_prevent_compare_lto(const unsigned char *b1,
+ const unsigned char *b2,
+ const size_t len);
+__attribute__((weak)) void
+_sodium_dummy_symbol_to_prevent_compare_lto(const unsigned char *b1,
+ const unsigned char *b2,
+ const size_t len)
+{
+ (void) b1;
+ (void) b2;
+ (void) len;
+}
+#endif
+
+int
+sodium_compare(const unsigned char *b1_, const unsigned char *b2_, size_t len)
+{
+#ifdef HAVE_WEAK_SYMBOLS
+ const unsigned char *b1 = b1_;
+ const unsigned char *b2 = b2_;
+#else
+ const volatile unsigned char *volatile b1 =
+ (const volatile unsigned char *volatile) b1_;
+ const volatile unsigned char *volatile b2 =
+ (const volatile unsigned char *volatile) b2_;
+#endif
+ size_t i;
+ volatile unsigned char gt = 0U;
+ volatile unsigned char eq = 1U;
+ uint16_t x1, x2;
+
+#if HAVE_WEAK_SYMBOLS
+ _sodium_dummy_symbol_to_prevent_compare_lto(b1, b2, len);
+#endif
+ i = len;
+ while (i != 0U) {
+ i--;
+ x1 = b1[i];
+ x2 = b2[i];
+ gt |= ((x2 - x1) >> 8) & eq;
+ eq &= ((x2 ^ x1) - 1) >> 8;
+ }
+ return (int) (gt + gt + eq) - 1;
+}
+
+int
+sodium_is_zero(const unsigned char *n, const size_t nlen)
+{
+ size_t i;
+ volatile unsigned char d = 0U;
+
+ for (i = 0U; i < nlen; i++) {
+ d |= n[i];
+ }
+ return 1 & ((d - 1) >> 8);
+}
+
+void
+sodium_increment(unsigned char *n, const size_t nlen)
+{
+ size_t i = 0U;
+ uint_fast16_t c = 1U;
+
+#ifdef HAVE_AMD64_ASM
+ uint64_t t64, t64_2;
+ uint32_t t32;
+
+ if (nlen == 12U) {
+ __asm__ __volatile__(
+ "xorq %[t64], %[t64] \n"
+ "xorl %[t32], %[t32] \n"
+ "stc \n"
+ "adcq %[t64], (%[out]) \n"
+ "adcl %[t32], 8(%[out]) \n"
+ : [t64] "=&r"(t64), [t32] "=&r"(t32)
+ : [out] "D"(n)
+ : "memory", "flags", "cc");
+ return;
+ } else if (nlen == 24U) {
+ __asm__ __volatile__(
+ "movq $1, %[t64] \n"
+ "xorq %[t64_2], %[t64_2] \n"
+ "addq %[t64], (%[out]) \n"
+ "adcq %[t64_2], 8(%[out]) \n"
+ "adcq %[t64_2], 16(%[out]) \n"
+ : [t64] "=&r"(t64), [t64_2] "=&r"(t64_2)
+ : [out] "D"(n)
+ : "memory", "flags", "cc");
+ return;
+ } else if (nlen == 8U) {
+ __asm__ __volatile__("incq (%[out]) \n"
+ :
+ : [out] "D"(n)
+ : "memory", "flags", "cc");
+ return;
+ }
+#endif
+ for (; i < nlen; i++) {
+ c += (uint_fast16_t) n[i];
+ n[i] = (unsigned char) c;
+ c >>= 8;
+ }
+}
+
+void
+sodium_add(unsigned char *a, const unsigned char *b, const size_t len)
+{
+ size_t i = 0U;
+ uint_fast16_t c = 0U;
+
+#ifdef HAVE_AMD64_ASM
+ uint64_t t64, t64_2, t64_3;
+ uint32_t t32;
+
+ if (len == 12U) {
+ __asm__ __volatile__(
+ "movq (%[in]), %[t64] \n"
+ "movl 8(%[in]), %[t32] \n"
+ "addq %[t64], (%[out]) \n"
+ "adcl %[t32], 8(%[out]) \n"
+ : [t64] "=&r"(t64), [t32] "=&r"(t32)
+ : [in] "S"(b), [out] "D"(a)
+ : "memory", "flags", "cc");
+ return;
+ } else if (len == 24U) {
+ __asm__ __volatile__(
+ "movq (%[in]), %[t64] \n"
+ "movq 8(%[in]), %[t64_2] \n"
+ "movq 16(%[in]), %[t64_3] \n"
+ "addq %[t64], (%[out]) \n"
+ "adcq %[t64_2], 8(%[out]) \n"
+ "adcq %[t64_3], 16(%[out]) \n"
+ : [t64] "=&r"(t64), [t64_2] "=&r"(t64_2), [t64_3] "=&r"(t64_3)
+ : [in] "S"(b), [out] "D"(a)
+ : "memory", "flags", "cc");
+ return;
+ } else if (len == 8U) {
+ __asm__ __volatile__(
+ "movq (%[in]), %[t64] \n"
+ "addq %[t64], (%[out]) \n"
+ : [t64] "=&r"(t64)
+ : [in] "S"(b), [out] "D"(a)
+ : "memory", "flags", "cc");
+ return;
+ }
+#endif
+ for (; i < len; i++) {
+ c += (uint_fast16_t) a[i] + (uint_fast16_t) b[i];
+ a[i] = (unsigned char) c;
+ c >>= 8;
+ }
+}
+
+int
+_sodium_alloc_init(void)
+{
+#ifdef HAVE_ALIGNED_MALLOC
+# if defined(_SC_PAGESIZE)
+ long page_size_ = sysconf(_SC_PAGESIZE);
+ if (page_size_ > 0L) {
+ page_size = (size_t) page_size_;
+ }
+# elif defined(WINAPI_DESKTOP)
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ page_size = (size_t) si.dwPageSize;
+# endif
+ if (page_size < CANARY_SIZE || page_size < sizeof(size_t)) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+#endif
+ randombytes_buf(canary, sizeof canary);
+
+ return 0;
+}
+
+int
+sodium_mlock(void *const addr, const size_t len)
+{
+#if defined(MADV_DONTDUMP) && defined(HAVE_MADVISE)
+ (void) madvise(addr, len, MADV_DONTDUMP);
+#endif
+#ifdef HAVE_MLOCK
+ return mlock(addr, len);
+#elif defined(WINAPI_DESKTOP)
+ return -(VirtualLock(addr, len) == 0);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int
+sodium_munlock(void *const addr, const size_t len)
+{
+ sodium_memzero(addr, len);
+#if defined(MADV_DODUMP) && defined(HAVE_MADVISE)
+ (void) madvise(addr, len, MADV_DODUMP);
+#endif
+#ifdef HAVE_MLOCK
+ return munlock(addr, len);
+#elif defined(WINAPI_DESKTOP)
+ return -(VirtualUnlock(addr, len) == 0);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int
+_mprotect_noaccess(void *ptr, size_t size)
+{
+#ifdef HAVE_MPROTECT
+ return mprotect(ptr, size, PROT_NONE);
+#elif defined(WINAPI_DESKTOP)
+ DWORD old;
+ return -(VirtualProtect(ptr, size, PAGE_NOACCESS, &old) == 0);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int
+_mprotect_readonly(void *ptr, size_t size)
+{
+#ifdef HAVE_MPROTECT
+ return mprotect(ptr, size, PROT_READ);
+#elif defined(WINAPI_DESKTOP)
+ DWORD old;
+ return -(VirtualProtect(ptr, size, PAGE_READONLY, &old) == 0);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int
+_mprotect_readwrite(void *ptr, size_t size)
+{
+#ifdef HAVE_MPROTECT
+ return mprotect(ptr, size, PROT_READ | PROT_WRITE);
+#elif defined(WINAPI_DESKTOP)
+ DWORD old;
+ return -(VirtualProtect(ptr, size, PAGE_READWRITE, &old) == 0);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+#ifdef HAVE_ALIGNED_MALLOC
+
+__attribute__((noreturn)) static void
+_out_of_bounds(void)
+{
+# ifdef SIGSEGV
+ raise(SIGSEGV);
+# elif defined(SIGKILL)
+ raise(SIGKILL);
+# endif
+ abort(); /* not something we want any higher-level API to catch */
+} /* LCOV_EXCL_LINE */
+
+static inline size_t
+_page_round(const size_t size)
+{
+ const size_t page_mask = page_size - 1U;
+
+ return (size + page_mask) & ~page_mask;
+}
+
+static __attribute__((malloc)) unsigned char *
+_alloc_aligned(const size_t size)
+{
+ void *ptr;
+
+# if defined(MAP_ANON) && defined(HAVE_MMAP)
+ if ((ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE | MAP_NOCORE, -1, 0)) ==
+ MAP_FAILED) {
+ ptr = NULL; /* LCOV_EXCL_LINE */
+ } /* LCOV_EXCL_LINE */
+# elif defined(HAVE_POSIX_MEMALIGN)
+ if (posix_memalign(&ptr, page_size, size) != 0) {
+ ptr = NULL; /* LCOV_EXCL_LINE */
+ } /* LCOV_EXCL_LINE */
+# elif defined(WINAPI_DESKTOP)
+ ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+# else
+# error Bug
+# endif
+ return (unsigned char *) ptr;
+}
+
+static void
+_free_aligned(unsigned char *const ptr, const size_t size)
+{
+# if defined(MAP_ANON) && defined(HAVE_MMAP)
+ (void) munmap(ptr, size);
+# elif defined(HAVE_POSIX_MEMALIGN)
+ free(ptr);
+# elif defined(WINAPI_DESKTOP)
+ VirtualFree(ptr, 0U, MEM_RELEASE);
+# else
+# error Bug
+#endif
+}
+
+static unsigned char *
+_unprotected_ptr_from_user_ptr(void *const ptr)
+{
+ uintptr_t unprotected_ptr_u;
+ unsigned char *canary_ptr;
+ size_t page_mask;
+
+ canary_ptr = ((unsigned char *) ptr) - sizeof canary;
+ page_mask = page_size - 1U;
+ unprotected_ptr_u = ((uintptr_t) canary_ptr & (uintptr_t) ~page_mask);
+ if (unprotected_ptr_u <= page_size * 2U) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ return (unsigned char *) unprotected_ptr_u;
+}
+
+#endif /* HAVE_ALIGNED_MALLOC */
+
+#ifndef HAVE_ALIGNED_MALLOC
+static __attribute__((malloc)) void *
+_sodium_malloc(const size_t size)
+{
+ return malloc(size > (size_t) 0U ? size : (size_t) 1U);
+}
+#else
+static __attribute__((malloc)) void *
+_sodium_malloc(const size_t size)
+{
+ void *user_ptr;
+ unsigned char *base_ptr;
+ unsigned char *canary_ptr;
+ unsigned char *unprotected_ptr;
+ size_t size_with_canary;
+ size_t total_size;
+ size_t unprotected_size;
+
+ if (size >= (size_t) SIZE_MAX - page_size * 4U) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ if (page_size <= sizeof canary || page_size < sizeof unprotected_size) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ size_with_canary = (sizeof canary) + size;
+ unprotected_size = _page_round(size_with_canary);
+ total_size = page_size + page_size + unprotected_size + page_size;
+ if ((base_ptr = _alloc_aligned(total_size)) == NULL) {
+ return NULL; /* LCOV_EXCL_LINE */
+ }
+ unprotected_ptr = base_ptr + page_size * 2U;
+ _mprotect_noaccess(base_ptr + page_size, page_size);
+# ifndef HAVE_PAGE_PROTECTION
+ memcpy(unprotected_ptr + unprotected_size, canary, sizeof canary);
+# endif
+ _mprotect_noaccess(unprotected_ptr + unprotected_size, page_size);
+ sodium_mlock(unprotected_ptr, unprotected_size);
+ canary_ptr =
+ unprotected_ptr + _page_round(size_with_canary) - size_with_canary;
+ user_ptr = canary_ptr + sizeof canary;
+ memcpy(canary_ptr, canary, sizeof canary);
+ memcpy(base_ptr, &unprotected_size, sizeof unprotected_size);
+ _mprotect_readonly(base_ptr, page_size);
+ assert(_unprotected_ptr_from_user_ptr(user_ptr) == unprotected_ptr);
+
+ return user_ptr;
+}
+#endif /* !HAVE_ALIGNED_MALLOC */
+
+__attribute__((malloc)) void *
+sodium_malloc(const size_t size)
+{
+ void *ptr;
+
+ if ((ptr = _sodium_malloc(size)) == NULL) {
+ return NULL;
+ }
+ memset(ptr, (int) GARBAGE_VALUE, size);
+
+ return ptr;
+}
+
+__attribute__((malloc)) void *
+sodium_allocarray(size_t count, size_t size)
+{
+ if (count > (size_t) 0U && size >= (size_t) SIZE_MAX / count) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ return sodium_malloc(count * size);
+}
+
+#ifndef HAVE_ALIGNED_MALLOC
+void
+sodium_free(void *ptr)
+{
+ free(ptr);
+}
+#else
+void
+sodium_free(void *ptr)
+{
+ unsigned char *base_ptr;
+ unsigned char *canary_ptr;
+ unsigned char *unprotected_ptr;
+ size_t total_size;
+ size_t unprotected_size;
+
+ if (ptr == NULL) {
+ return;
+ }
+ canary_ptr = ((unsigned char *) ptr) - sizeof canary;
+ unprotected_ptr = _unprotected_ptr_from_user_ptr(ptr);
+ base_ptr = unprotected_ptr - page_size * 2U;
+ memcpy(&unprotected_size, base_ptr, sizeof unprotected_size);
+ total_size = page_size + page_size + unprotected_size + page_size;
+ _mprotect_readwrite(base_ptr, total_size);
+ if (sodium_memcmp(canary_ptr, canary, sizeof canary) != 0) {
+ _out_of_bounds();
+ }
+# ifndef HAVE_PAGE_PROTECTION
+ if (sodium_memcmp(unprotected_ptr + unprotected_size, canary,
+ sizeof canary) != 0) {
+ _out_of_bounds();
+ }
+# endif
+ sodium_munlock(unprotected_ptr, unprotected_size);
+ _free_aligned(base_ptr, total_size);
+}
+#endif /* HAVE_ALIGNED_MALLOC */
+
+#ifndef HAVE_PAGE_PROTECTION
+static int
+_sodium_mprotect(void *ptr, int (*cb)(void *ptr, size_t size))
+{
+ (void) ptr;
+ (void) cb;
+ errno = ENOSYS;
+ return -1;
+}
+#else
+static int
+_sodium_mprotect(void *ptr, int (*cb)(void *ptr, size_t size))
+{
+ unsigned char *base_ptr;
+ unsigned char *unprotected_ptr;
+ size_t unprotected_size;
+
+ unprotected_ptr = _unprotected_ptr_from_user_ptr(ptr);
+ base_ptr = unprotected_ptr - page_size * 2U;
+ memcpy(&unprotected_size, base_ptr, sizeof unprotected_size);
+
+ return cb(unprotected_ptr, unprotected_size);
+}
+#endif
+
+int
+sodium_mprotect_noaccess(void *ptr)
+{
+ return _sodium_mprotect(ptr, _mprotect_noaccess);
+}
+
+int
+sodium_mprotect_readonly(void *ptr)
+{
+ return _sodium_mprotect(ptr, _mprotect_readonly);
+}
+
+int
+sodium_mprotect_readwrite(void *ptr)
+{
+ return _sodium_mprotect(ptr, _mprotect_readwrite);
+}
+
+int
+sodium_pad(size_t *padded_buflen_p, unsigned char *buf,
+ size_t unpadded_buflen, size_t blocksize, size_t max_buflen)
+{
+ unsigned char *tail;
+ size_t i;
+ size_t xpadlen;
+ size_t xpadded_len;
+ volatile unsigned char mask;
+ unsigned char barrier_mask;
+
+ if (blocksize <= 0U) {
+ return -1;
+ }
+ xpadlen = blocksize - 1U;
+ if ((blocksize & (blocksize - 1U)) == 0U) {
+ xpadlen -= unpadded_buflen & (blocksize - 1U);
+ } else {
+ xpadlen -= unpadded_buflen % blocksize;
+ }
+ if ((size_t) SIZE_MAX - unpadded_buflen <= xpadlen) {
+ sodium_misuse();
+ }
+ xpadded_len = unpadded_buflen + xpadlen;
+ if (xpadded_len >= max_buflen) {
+ return -1;
+ }
+ tail = &buf[xpadded_len];
+ if (padded_buflen_p != NULL) {
+ *padded_buflen_p = xpadded_len + 1U;
+ }
+ mask = 0U;
+ for (i = 0; i < blocksize; i++) {
+ barrier_mask = (unsigned char) (((i ^ xpadlen) - 1U) >> 8);
+ tail[-i] = (tail[-i] & mask) | (0x80 & barrier_mask);
+ mask |= barrier_mask;
+ }
+ return 0;
+}
+
+int
+sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf,
+ size_t padded_buflen, size_t blocksize)
+{
+ const unsigned char *tail;
+ unsigned char acc = 0U;
+ unsigned char c;
+ unsigned char valid = 0U;
+ volatile size_t pad_len = 0U;
+ size_t i;
+ size_t is_barrier;
+
+ if (padded_buflen < blocksize || blocksize <= 0U) {
+ return -1;
+ }
+ tail = &buf[padded_buflen - 1U];
+
+ for (i = 0U; i < blocksize; i++) {
+ c = tail[-i];
+ is_barrier =
+ (( (acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U) ) >> 8) & 1U;
+ acc |= c;
+ pad_len |= i & (1U + ~is_barrier);
+ valid |= (unsigned char) is_barrier;
+ }
+ *unpadded_buflen_p = padded_buflen - 1U - pad_len;
+
+ return (int) (valid - 1U);
+}
diff --git a/sys/contrib/libsodium/src/libsodium/sodium/version.c b/sys/contrib/libsodium/src/libsodium/sodium/version.c
new file mode 100644
index 000000000000..4e584a6ea0f1
--- /dev/null
+++ b/sys/contrib/libsodium/src/libsodium/sodium/version.c
@@ -0,0 +1,30 @@
+
+#include "version.h"
+
+const char *
+sodium_version_string(void)
+{
+ return SODIUM_VERSION_STRING;
+}
+
+int
+sodium_library_version_major(void)
+{
+ return SODIUM_LIBRARY_VERSION_MAJOR;
+}
+
+int
+sodium_library_version_minor(void)
+{
+ return SODIUM_LIBRARY_VERSION_MINOR;
+}
+
+int
+sodium_library_minimal(void)
+{
+#ifdef SODIUM_LIBRARY_MINIMAL
+ return 1;
+#else
+ return 0;
+#endif
+}