vendor/libsodium/src/libsodium/sodium/utils.c in rbnacl-libsodium-0.4.5 vs vendor/libsodium/src/libsodium/sodium/utils.c in rbnacl-libsodium-0.5.0

- old
+ new

@@ -1,12 +1,19 @@ - +#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> @@ -15,10 +22,16 @@ 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); #else volatile unsigned char *pnt_ = (volatile unsigned char *) pnt; size_t i = (size_t) 0U; while (i < len) { @@ -26,21 +39,21 @@ } #endif } int -sodium_memcmp(const void * const b1_, const void * const b2_, size_t size) +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 < size; i++) { + for (i = 0U; i < len; i++) { d |= b1[i] ^ b2[i]; } - return (int) d; + return (int) ((1 & ((d - 1) >> 8)) - 1); } unsigned char * _sodium_alignedcalloc(unsigned char ** const unaligned_p, const size_t len) { @@ -68,27 +81,106 @@ return aligned; } char * -sodium_bin2hex(char * const hex, const size_t hexlen, - const unsigned char *bin, const size_t binlen) +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 (binlen >= SIZE_MAX / 2 || hexlen < binlen * 2U) { + if (bin_len >= SIZE_MAX / 2 || hex_maxlen < bin_len * 2U) { abort(); } - while (i < binlen) { + 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 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 HAVE_MLOCK + return munlock(addr, len); +#elif defined(HAVE_VIRTUALLOCK) + return -(VirtualUnlock(addr, len) == 0); +#else + errno = ENOSYS; + return -1; +#endif }