/******************************************************************************/ /* MCrypt, by LoRd_MuldeR */ /* This work has been released under the CC0 1.0 Universal license! */ /******************************************************************************/ #ifdef _WIN32 #define _CRT_RAND_S 1 #endif #include "utils.h" #ifdef __unix__ #include #include #if (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)) || (defined(__FreeBSD__) && (__FreeBSD__ >= 12)) #define HAVE_GENRANDOM_SYSCALL 1 #include #else #undef HAVE_GENRANDOM_SYSCALL #endif #endif int mcrypt_random_bytes(uint8_t* const buffer, const size_t length) { #ifdef _WIN32 size_t pos = 0U; while (pos < length) { const size_t bytes_left = length - pos; const size_t bytes_copy = (bytes_left < sizeof(uint32_t)) ? bytes_left : sizeof(uint32_t); uint32_t temp; if (rand_s(&temp) != 0) { return -1; } for (size_t i = 0; i < bytes_copy; ++i) { buffer[pos++] = (uint8_t)(temp & 0xFF); temp >>= 8; } } return 0; #else #ifdef __unix__ #ifdef HAVE_GENRANDOM_SYSCALL if (getrandom(buffer, length, 0U) >= length) { return 0; } return -1; #else static const char* const PATH[] = { "/dev/urandom", "/dev/arandom", "/dev/random" }; int result = -1; for (size_t i = 0; (i < 3U) && (result < 0); ++i) { const int fd = open(PATH[i], O_RDONLY); if (fd >= 0) { if (read(fd, buffer, length) >= length) { result = 0; } close(fd); } } return result; #endif #else #error Unsupported target platform! #endif #endif } void mcrypt_erase(void* const ptr, const size_t length) { volatile uint8_t* buffer = ptr; for (size_t i = 0U; i < length; ++i) { buffer[i] = 0U; } }