diff options
Diffstat (limited to 'src/libsodium/sodium')
-rw-r--r-- | src/libsodium/sodium/compat.c | 361 | ||||
-rw-r--r-- | src/libsodium/sodium/core.c | 23 | ||||
-rw-r--r-- | src/libsodium/sodium/runtime.c | 134 | ||||
-rw-r--r-- | src/libsodium/sodium/utils.c | 204 | ||||
-rw-r--r-- | src/libsodium/sodium/version.c | 20 |
5 files changed, 742 insertions, 0 deletions
diff --git a/src/libsodium/sodium/compat.c b/src/libsodium/sodium/compat.c new file mode 100644 index 0000000..ece2dbc --- /dev/null +++ b/src/libsodium/sodium/compat.c @@ -0,0 +1,361 @@ + +#include "crypto_auth_hmacsha256.h" +#include "crypto_auth_hmacsha512256.h" +#include "crypto_box_curve25519xsalsa20poly1305.h" +#include "crypto_hash_sha256.h" +#include "crypto_hash_sha512.h" +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_pwhash_scryptsalsa208sha256.h" +#include "crypto_scalarmult_curve25519.h" +#include "crypto_secretbox_xsalsa20poly1305.h" +#include "crypto_sign_ed25519.h" +#include "crypto_stream_salsa20.h" +#include "crypto_stream_xsalsa20.h" +#include "crypto_verify_16.h" +#include "crypto_verify_32.h" +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#undef crypto_pwhash_scryptxsalsa208sha256_saltbytes +SODIUM_EXPORT size_t +crypto_pwhash_scryptxsalsa208sha256_saltbytes(void) +{ + return crypto_pwhash_scryptsalsa208sha256_saltbytes(); +} + +#undef crypto_pwhash_scryptxsalsa208sha256_strbytes +SODIUM_EXPORT size_t +crypto_pwhash_scryptxsalsa208sha256_strbytes(void) +{ + return crypto_pwhash_scryptsalsa208sha256_strbytes(); +} + +#undef crypto_pwhash_scryptxsalsa208sha256 +SODIUM_EXPORT int +crypto_pwhash_scryptxsalsa208sha256(unsigned char * const out, + unsigned long long outlen, + const char * const passwd, + unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, + size_t memlimit) +{ + return crypto_pwhash_scryptsalsa208sha256(out, outlen, passwd, passwdlen, + salt, opslimit, memlimit); +} + +#undef crypto_pwhash_scryptxsalsa208sha256_str +SODIUM_EXPORT int +crypto_pwhash_scryptxsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char * const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, + size_t memlimit) +{ + return crypto_pwhash_scryptsalsa208sha256_str(out, passwd, passwdlen, + opslimit, memlimit); +} + +#undef crypto_pwhash_scryptxsalsa208sha256_str_verify +SODIUM_EXPORT int +crypto_pwhash_scryptxsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) +{ + return crypto_pwhash_scryptsalsa208sha256_str_verify(str, + passwd, passwdlen); +} + +#ifdef EXPORT_ORIGINAL_IMPLEMENTATIONS + +#undef crypto_hash_sha256_ref +SODIUM_EXPORT int +crypto_hash_sha256_ref(unsigned char *out, const unsigned char *in, + unsigned long long inlen) +{ + return crypto_hash_sha256(out, in, inlen); +} + +#undef crypto_hash_sha512_ref +SODIUM_EXPORT int +crypto_hash_sha512_ref(unsigned char *out, const unsigned char *in, + unsigned long long inlen) +{ + return crypto_hash_sha512(out, in, inlen); +} + +#undef crypto_auth_hmacsha256_ref +SODIUM_EXPORT int +crypto_auth_hmacsha256_ref(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return crypto_auth_hmacsha256(out, in, inlen, k); +} + +#undef crypto_auth_hmacsha256_ref_verify +SODIUM_EXPORT int +crypto_auth_hmacsha256_ref_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) +{ + return crypto_auth_hmacsha256_verify(h, in, inlen, k); +} + +#undef crypto_auth_hmacsha512256_ref +SODIUM_EXPORT int +crypto_auth_hmacsha512256_ref(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return crypto_auth_hmacsha512256(out, in, inlen, k); +} + +#undef crypto_auth_hmacsha512256_ref_verify +SODIUM_EXPORT int +crypto_auth_hmacsha512256_ref_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) +{ + return crypto_auth_hmacsha512256_verify(h, in, inlen, k); +} + +#undef crypto_box_curve25519xsalsa20poly1305_ref_keypair +SODIUM_EXPORT int +crypto_box_curve25519xsalsa20poly1305_ref_keypair(unsigned char *pk, + unsigned char *sk) +{ + return crypto_box_curve25519xsalsa20poly1305_keypair(pk, sk); +} + +#undef crypto_box_curve25519xsalsa20poly1305_ref_beforenm +SODIUM_EXPORT int +crypto_box_curve25519xsalsa20poly1305_ref_beforenm(unsigned char *k, + const unsigned char *pk, + const unsigned char *sk) +{ + return crypto_box_curve25519xsalsa20poly1305_beforenm(k, pk, sk); +} + +#undef crypto_box_curve25519xsalsa20poly1305_ref_afternm +SODIUM_EXPORT int +crypto_box_curve25519xsalsa20poly1305_ref_afternm(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_box_curve25519xsalsa20poly1305_afternm(c, m, mlen, n, k); +} + +#undef crypto_box_curve25519xsalsa20poly1305_ref_open_afternm +SODIUM_EXPORT int +crypto_box_curve25519xsalsa20poly1305_ref_open_afternm(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_box_curve25519xsalsa20poly1305_open_afternm(m, c, clen, n, k); +} + +#undef crypto_box_curve25519xsalsa20poly1305_ref +SODIUM_EXPORT int +crypto_box_curve25519xsalsa20poly1305_ref(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) +{ + return crypto_box_curve25519xsalsa20poly1305(c, m, mlen, n, pk, sk); +} + +#undef crypto_box_curve25519xsalsa20poly1305_ref_open +SODIUM_EXPORT int +crypto_box_curve25519xsalsa20poly1305_ref_open(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) +{ + return crypto_box_curve25519xsalsa20poly1305_open(m, c, clen, n, pk, sk); +} + +#undef crypto_scalarmult_curve25519_ref_base +SODIUM_EXPORT int +crypto_scalarmult_curve25519_ref_base(unsigned char *q, const unsigned char *n) +{ + return crypto_scalarmult_curve25519_base(q, n); +} + +#undef crypto_scalarmult_curve25519_ref +SODIUM_EXPORT int +crypto_scalarmult_curve25519_ref(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + return crypto_scalarmult_curve25519(q, n, p); +} + +#undef crypto_scalarmult_curve25519_donna_c64_base +SODIUM_EXPORT int +crypto_scalarmult_curve25519_donna_c64_base(unsigned char *q, const unsigned char *n) +{ + return crypto_scalarmult_curve25519_base(q, n); +} + +#undef crypto_scalarmult_curve25519_donna_c64 +SODIUM_EXPORT int +crypto_scalarmult_curve25519_donna_c64(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + return crypto_scalarmult_curve25519(q, n, p); +} + +#undef crypto_secretbox_xsalsa20poly1305_ref +SODIUM_EXPORT int +crypto_secretbox_xsalsa20poly1305_ref(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_secretbox_xsalsa20poly1305(c, m, mlen, n, k); +} + +#undef crypto_secretbox_xsalsa20poly1305_ref_open +SODIUM_EXPORT int +crypto_secretbox_xsalsa20poly1305_ref_open(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_secretbox_xsalsa20poly1305_open(m, c, clen, n, k); +} + +#undef crypto_sign_ed25519_ref_seed_keypair +SODIUM_EXPORT int +crypto_sign_ed25519_ref_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) +{ + return crypto_sign_ed25519_seed_keypair(pk, sk, seed); +} + +#undef crypto_sign_ed25519_ref_keypair +SODIUM_EXPORT int +crypto_sign_ed25519_ref_keypair(unsigned char *pk, unsigned char *sk) +{ + return crypto_sign_ed25519_keypair(pk, sk); +} + +#undef crypto_sign_ed25519_ref +SODIUM_EXPORT int +crypto_sign_ed25519_ref(unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) +{ + return crypto_sign_ed25519(sm, smlen, m, mlen, sk); +} + +#undef crypto_sign_ed25519_ref_open +SODIUM_EXPORT int +crypto_sign_ed25519_ref_open(unsigned char *m, unsigned long long *mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) +{ + return crypto_sign_ed25519_open(m, mlen, sm, smlen, pk); +} + +#undef crypto_stream_xsalsa20_ref +SODIUM_EXPORT int +crypto_stream_xsalsa20_ref(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + return crypto_stream_xsalsa20(c, clen, n, k); +} + +#undef crypto_stream_xsalsa20_ref_xor +SODIUM_EXPORT int +crypto_stream_xsalsa20_ref_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_stream_xsalsa20_xor(c, m, mlen, n, k); +} + +#undef crypto_verify_16_ref +SODIUM_EXPORT int +crypto_verify_16_ref(const unsigned char *x, const unsigned char *y) +{ + return crypto_verify_16(x, y); +} + +#undef crypto_verify_32_ref +SODIUM_EXPORT int +crypto_verify_32_ref(const unsigned char *x, const unsigned char *y) +{ + return crypto_verify_32(x, y); +} + +#undef crypto_onetimeauth_poly1305_ref +SODIUM_EXPORT int +crypto_onetimeauth_poly1305_ref(unsigned char *out, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) +{ + return crypto_onetimeauth_poly1305(out, in, inlen, k); +} + +#undef crypto_stream_salsa20_amd64_xmm6 +SODIUM_EXPORT int +crypto_stream_salsa20_amd64_xmm6(unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_stream_salsa20(c, clen, n, k); +} + +#undef crypto_stream_salsa20_ref +SODIUM_EXPORT int +crypto_stream_salsa20_ref(unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_stream_salsa20(c, clen, n, k); +} + +#undef crypto_stream_salsa20_amd64_xmm6_xor +SODIUM_EXPORT int +crypto_stream_salsa20_amd64_xmm6_xor(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_stream_salsa20_xor(c, m, mlen, n, k); +} + +#undef crypto_stream_salsa20_ref_xor +SODIUM_EXPORT int +crypto_stream_salsa20_ref_xor(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_stream_salsa20_xor(c, m, mlen, n, k); +} + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/src/libsodium/sodium/core.c b/src/libsodium/sodium/core.c new file mode 100644 index 0000000..652f31e --- /dev/null +++ b/src/libsodium/sodium/core.c @@ -0,0 +1,23 @@ + +#include "core.h" +#include "crypto_onetimeauth.h" +#include "randombytes.h" +#include "runtime.h" + +static int initialized; + +int +sodium_init(void) +{ + if (initialized != 0) { + return 1; + } + sodium_runtime_get_cpu_features(); + if (crypto_onetimeauth_pick_best_implementation() == NULL) { + return -1; + } + randombytes_stir(); + initialized = 1; + + return 0; +} diff --git a/src/libsodium/sodium/runtime.c b/src/libsodium/sodium/runtime.c new file mode 100644 index 0000000..52b3707 --- /dev/null +++ b/src/libsodium/sodium/runtime.c @@ -0,0 +1,134 @@ + +#ifdef HAVE_ANDROID_GETCPUFEATURES +# include <cpu-features.h> +#endif + +#include "runtime.h" + +typedef struct CPUFeatures_ { + int initialized; + int has_neon; + int has_sse2; + int has_sse3; +} CPUFeatures; + +static CPUFeatures _cpu_features; + +#define CPUID_SSE2 0x04000000 +#define CPUIDECX_SSE3 0x00000001 + +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) +{ +#ifdef _MSC_VER + __cpuidex((int *) cpu_info, cpu_info_type, 0); +#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; + } +# 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 + 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; + } + _cpuid(cpu_info, 0x00000001); +#ifndef HAVE_EMMINTRIN_H + cpu_features->has_sse2 = 0; +#else + cpu_features->has_sse2 = ((cpu_info[3] & CPUID_SSE2) != 0x0); +#endif + +#ifndef HAVE_PMMINTRIN_H + cpu_features->has_sse3 = 0; +#else + cpu_features->has_sse3 = ((cpu_info[2] & CPUIDECX_SSE3) != 0x0); +#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; +} diff --git a/src/libsodium/sodium/utils.c b/src/libsodium/sodium/utils.c new file mode 100644 index 0000000..eff9d0c --- /dev/null +++ b/src/libsodium/sodium/utils.c @@ -0,0 +1,204 @@ +#ifndef __STDC_WANT_LIB_EXT1__ +# define __STDC_WANT_LIB_EXT1__ 1 +#endif +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#ifdef HAVE_SYS_MMAN_H +# include <sys/mman.h> +#endif + +#include "utils.h" +#include "randombytes.h" +#ifdef _WIN32 +# include <windows.h> +# include <wincrypt.h> +#endif + +#ifdef HAVE_WEAK_SYMBOLS +__attribute__((weak)) void +__sodium_dummy_symbol_to_prevent_lto(void * const pnt, const size_t len) +{ + (void) pnt; + (void) len; +} +#endif + +void +sodium_memzero(void * const pnt, const size_t len) +{ +#ifdef HAVE_SECUREZEROMEMORY + SecureZeroMemory(pnt, len); +#elif defined(HAVE_MEMSET_S) + if (memset_s(pnt, (rsize_t) len, 0, (rsize_t) len) != 0) { + abort(); + } +#elif defined(HAVE_EXPLICIT_BZERO) + explicit_bzero(pnt, len); +#elif HAVE_WEAK_SYMBOLS + memset(pnt, 0, len); + __sodium_dummy_symbol_to_prevent_lto(pnt, len); +#else + volatile unsigned char *pnt_ = (volatile unsigned char *) pnt; + size_t i = (size_t) 0U; + + while (i < len) { + pnt_[i++] = 0U; + } +#endif +} + +int +sodium_memcmp(const void * const b1_, const void * const b2_, size_t len) +{ + const unsigned char *b1 = (const unsigned char *) b1_; + const unsigned char *b2 = (const unsigned char *) b2_; + size_t i; + unsigned char d = (unsigned char) 0U; + + for (i = 0U; i < len; i++) { + d |= b1[i] ^ b2[i]; + } + return (int) ((1 & ((d - 1) >> 8)) - 1); +} + +unsigned char * +_sodium_alignedcalloc(unsigned char ** const unaligned_p, const size_t len) +{ + unsigned char *aligned; + unsigned char *unaligned; + size_t i; + + if (SIZE_MAX - (size_t) 256U < len || + (unaligned = (unsigned char *) malloc(len + (size_t) 256U)) == NULL) { + *unaligned_p = NULL; + return NULL; + } + *unaligned_p = unaligned; +#ifdef HAVE_ARC4RANDOM_BUF + (void) i; + arc4random_buf(unaligned, len + (size_t) 256U); +#else + for (i = (size_t) 0U; i < len + (size_t) 256U; ++i) { + unaligned[i] = (unsigned char) rand(); + } +#endif + aligned = unaligned + 64; + aligned += (ptrdiff_t) 63 & (-(ptrdiff_t) aligned); + memset(aligned, 0, len); + + return aligned; +} + +char * +sodium_bin2hex(char * const hex, const size_t hex_maxlen, + const unsigned char * const bin, const size_t bin_len) +{ + static const char hexdigits[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + size_t i = (size_t) 0U; + size_t j = (size_t) 0U; + + if (bin_len >= SIZE_MAX / 2 || hex_maxlen < bin_len * 2U) { + abort(); + } + while (i < bin_len) { + hex[j++] = hexdigits[bin[i] >> 4]; + hex[j++] = hexdigits[bin[i] & 0xf]; + i++; + } + hex[j] = 0; + + 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_num; + unsigned char c_val; + unsigned char state = 0U; + + while (hex_pos < hex_len) { + c = (unsigned char) hex[hex_pos]; + if ((c_num = c ^ 48U) < 10U) { + c_val = c_num; + } else if ((c_num = (c & ~32U)) > 64 && c_num < 71U) { + c_val = c_num - 55U; + } else if (ignore != NULL && strchr(ignore, c) != NULL && state == 0U) { + hex_pos++; + continue; + } else { + break; + } + 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--; + } + if (hex_end != NULL) { + *hex_end = &hex[hex_pos]; + } + if (bin_len != NULL) { + *bin_len = bin_pos; + } + return ret; +} + +int +sodium_mlock(void * const addr, const size_t len) +{ +#ifdef MADV_DONTDUMP + (void) madvise(addr, len, MADV_DONTDUMP); +#endif +#ifdef HAVE_MLOCK + return mlock(addr, len); +#elif defined(HAVE_VIRTUALLOCK) + 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); +#ifdef MADV_DODUMP + (void) madvise(addr, len, MADV_DODUMP); +#endif +#ifdef HAVE_MLOCK + return munlock(addr, len); +#elif defined(HAVE_VIRTUALLOCK) + return -(VirtualUnlock(addr, len) == 0); +#else + errno = ENOSYS; + return -1; +#endif +} diff --git a/src/libsodium/sodium/version.c b/src/libsodium/sodium/version.c new file mode 100644 index 0000000..4083c81 --- /dev/null +++ b/src/libsodium/sodium/version.c @@ -0,0 +1,20 @@ + +#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; +} |