From c73b6c9ba513fea3e18b696e659049df69931171 Mon Sep 17 00:00:00 2001 From: Micah Anderson Date: Tue, 11 Nov 2014 11:18:18 -0500 Subject: update to 1.0.0-1 version of the package --- src/libsodium/sodium/compat.c | 361 ----------------------------------------- src/libsodium/sodium/core.c | 4 +- src/libsodium/sodium/runtime.c | 6 +- src/libsodium/sodium/utils.c | 340 ++++++++++++++++++++++++++++++++++---- 4 files changed, 313 insertions(+), 398 deletions(-) delete mode 100644 src/libsodium/sodium/compat.c (limited to 'src/libsodium/sodium') diff --git a/src/libsodium/sodium/compat.c b/src/libsodium/sodium/compat.c deleted file mode 100644 index ece2dbc..0000000 --- a/src/libsodium/sodium/compat.c +++ /dev/null @@ -1,361 +0,0 @@ - -#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 index 652f31e..367f275 100644 --- a/src/libsodium/sodium/core.c +++ b/src/libsodium/sodium/core.c @@ -3,6 +3,7 @@ #include "crypto_onetimeauth.h" #include "randombytes.h" #include "runtime.h" +#include "utils.h" static int initialized; @@ -14,9 +15,10 @@ sodium_init(void) } sodium_runtime_get_cpu_features(); if (crypto_onetimeauth_pick_best_implementation() == NULL) { - return -1; + return -1; /* LCOV_EXCL_LINE */ } randombytes_stir(); + _sodium_alloc_init(); initialized = 1; return 0; diff --git a/src/libsodium/sodium/runtime.c b/src/libsodium/sodium/runtime.c index 52b3707..3e424a0 100644 --- a/src/libsodium/sodium/runtime.c +++ b/src/libsodium/sodium/runtime.c @@ -44,7 +44,7 @@ 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); + __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__ @@ -56,7 +56,7 @@ _cpuid(unsigned int cpu_info[4U], const unsigned int cpu_info_type) "=&r" (cpu_info[0]), "=&r" (cpu_info[1]) : "i" (0x200000)); if (((cpu_info[0] ^ cpu_info[1]) & 0x200000) == 0x0) { - return; + return; /* LCOV_EXCL_LINE */ } # endif # ifdef __i386__ @@ -88,7 +88,7 @@ _sodium_runtime_intel_cpu_features(CPUFeatures * const cpu_features) _cpuid(cpu_info, 0x0); if ((id = cpu_info[0]) == 0U) { - return -1; + return -1; /* LCOV_EXCL_LINE */ } _cpuid(cpu_info, 0x00000001); #ifndef HAVE_EMMINTRIN_H diff --git a/src/libsodium/sodium/utils.c b/src/libsodium/sodium/utils.c index eff9d0c..e51ae6b 100644 --- a/src/libsodium/sodium/utils.c +++ b/src/libsodium/sodium/utils.c @@ -1,8 +1,10 @@ #ifndef __STDC_WANT_LIB_EXT1__ # define __STDC_WANT_LIB_EXT1__ 1 #endif +#include #include #include +#include #include #include #include @@ -17,8 +19,32 @@ #ifdef _WIN32 # include # include +#else +# include +#endif + +#define CANARY_SIZE 16U +#define GARBAGE_VALUE 0xd0 + +#ifndef MAP_NOCORE +# define MAP_NOCORE 0 +#endif +#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) +# define MAP_ANON MAP_ANONYMOUS +#endif +#if defined(_WIN32) || defined(MAP_ANON) || 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(_WIN32) || defined(HAVE_MPROTECT)) +# define HAVE_PAGE_PROTECTION #endif +static size_t page_size; +static unsigned char canary[CANARY_SIZE]; + #ifdef HAVE_WEAK_SYMBOLS __attribute__((weak)) void __sodium_dummy_symbol_to_prevent_lto(void * const pnt, const size_t len) @@ -31,11 +57,11 @@ __sodium_dummy_symbol_to_prevent_lto(void * const pnt, const size_t len) void sodium_memzero(void * const pnt, const size_t len) { -#ifdef HAVE_SECUREZEROMEMORY +#ifdef _WIN32 SecureZeroMemory(pnt, len); #elif defined(HAVE_MEMSET_S) if (memset_s(pnt, (rsize_t) len, 0, (rsize_t) len) != 0) { - abort(); + abort(); /* LCOV_EXCL_LINE */ } #elif defined(HAVE_EXPLICIT_BZERO) explicit_bzero(pnt, len); @@ -66,34 +92,6 @@ sodium_memcmp(const void * const b1_, const void * const b2_, size_t len) 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) @@ -106,7 +104,7 @@ sodium_bin2hex(char * const hex, const size_t hex_maxlen, size_t j = (size_t) 0U; if (bin_len >= SIZE_MAX / 2 || hex_maxlen < bin_len * 2U) { - abort(); + abort(); /* LCOV_EXCL_LINE */ } while (i < bin_len) { hex[j++] = hexdigits[bin[i] >> 4]; @@ -178,7 +176,7 @@ sodium_mlock(void * const addr, const size_t len) #endif #ifdef HAVE_MLOCK return mlock(addr, len); -#elif defined(HAVE_VIRTUALLOCK) +#elif defined(_WIN32) return -(VirtualLock(addr, len) == 0); #else errno = ENOSYS; @@ -195,10 +193,286 @@ sodium_munlock(void * const addr, const size_t len) #endif #ifdef HAVE_MLOCK return munlock(addr, len); -#elif defined(HAVE_VIRTUALLOCK) +#elif defined(_WIN32) return -(VirtualUnlock(addr, len) == 0); #else errno = ENOSYS; return -1; #endif } + +int +_sodium_alloc_init(void) +{ +#if defined(_SC_PAGESIZE) + long page_size_ = sysconf(_SC_PAGESIZE); + if (page_size_ > 0L) { + page_size = (size_t) page_size_; + } +#elif defined(_WIN32) + SYSTEM_INFO si; + GetSystemInfo(&si); + page_size = (size_t) si.dwPageSize; +#endif + if (page_size < CANARY_SIZE) { + abort(); /* LCOV_EXCL_LINE */ + } + randombytes_buf(canary, sizeof canary); + + return 0; +} + +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 int +_mprotect_noaccess(void *ptr, size_t size) +{ +#if defined(HAVE_MPROTECT) && defined(HAVE_PAGE_PROTECTION) + return mprotect(ptr, size, PROT_NONE); +#elif defined(_WIN32) + { + 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) +{ +#if defined(HAVE_MPROTECT) && defined(HAVE_PAGE_PROTECTION) + return mprotect(ptr, size, PROT_READ); +#elif defined(_WIN32) + { + 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) +{ +#if defined(HAVE_MPROTECT) && defined(HAVE_PAGE_PROTECTION) + return mprotect(ptr, size, PROT_READ | PROT_WRITE); +#elif defined(_WIN32) + { + DWORD old; + return -(VirtualProtect(ptr, size, PAGE_READWRITE, &old) == 0); + } +#else + errno = ENOSYS; + return -1; +#endif +} + +static void +_out_of_bounds(void) +{ +#ifdef SIGSEGV + raise(SIGSEGV); +#elif defined(SIGKILL) + raise(SIGKILL); +#endif + abort(); +} /* LCOV_EXCL_LINE */ + +static __attribute__((malloc)) unsigned char * +_alloc_aligned(const size_t size) +{ + void *ptr; + +#ifdef MAP_ANON + 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(_WIN32) + ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); +#elif !defined(HAVE_ALIGNED_MALLOC) + ptr = malloc(size); +#else +# error Bug +#endif + return (unsigned char *) ptr; +} + +static void +_free_aligned(unsigned char * const ptr, const size_t size) +{ +#ifdef MAP_ANON + (void) munmap(ptr, size); +#elif defined(HAVE_POSIX_MEMALIGN) + free(ptr); +#elif defined(_WIN32) + VirtualFree(ptr, 0U, MEM_RELEASE); +#else + free(ptr); +#endif +} + +static unsigned char * +_unprotected_ptr_from_user_ptr(const void *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) { + abort(); /* LCOV_EXCL_LINE */ + } + return (unsigned char *) unprotected_ptr_u; +} + +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 page_mask; + size_t size_with_canary; + size_t total_size; + size_t unprotected_size; + + if (size >= SIZE_MAX - page_size * 4U) { + errno = ENOMEM; + return NULL; + } + if (page_size <= sizeof canary || page_size < sizeof unprotected_size) { + abort(); /* 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); + page_mask = page_size - 1U; + 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; +} + +__attribute__((malloc)) void * +sodium_malloc(const size_t size) +{ + void *ptr; + + if ((ptr = _sodium_malloc(size)) == NULL) { + return NULL; /* LCOV_EXCL_LINE */ + } + memset(ptr, (int) GARBAGE_VALUE, size); + + return ptr; +} + +__attribute__((malloc)) void * +sodium_allocarray(size_t count, size_t size) +{ + size_t total_size; + + if (size >= SIZE_MAX / count) { + errno = ENOMEM; + return NULL; + } + total_size = count * size; + + return sodium_malloc(total_size); +} + +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; + if (sodium_memcmp(canary_ptr, canary, sizeof canary) != 0) { + _out_of_bounds(); + } + 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); +#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); +} + +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); +} + +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); +} -- cgit v1.2.3