Improve usage of getrandom for generating bytes
This commit is contained in:
parent
a8803bb539
commit
aab2cd3af4
@ -1,4 +1,4 @@
|
|||||||
// Generated by the DN single header generator 2025-07-30 18:54:02
|
// Generated by the DN single header generator 2025-08-02 22:07:04
|
||||||
|
|
||||||
#define DN_BASE_INC_CPP
|
#define DN_BASE_INC_CPP
|
||||||
|
|
||||||
@ -6513,32 +6513,24 @@ DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate(uint64_t time)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API bool DN_OS_SecureRNGBytes(void *buffer, DN_U32 size)
|
DN_API void DN_OS_GenBytesSecure(void *buffer, DN_U32 size)
|
||||||
{
|
{
|
||||||
#if defined(DN_PLATFORM_EMSCRIPTEN)
|
#if defined(DN_PLATFORM_EMSCRIPTEN)
|
||||||
|
DN_InvalidCodePath;
|
||||||
(void)buffer;
|
(void)buffer;
|
||||||
(void)size;
|
(void)size;
|
||||||
return false;
|
|
||||||
#else
|
#else
|
||||||
if (!buffer || size < 0)
|
DN_Assert(buffer && size);
|
||||||
return false;
|
DN_USize bytes_written = 0;
|
||||||
|
while (bytes_written < size) {
|
||||||
if (size == 0)
|
DN_USize bytes_remaining = size - bytes_written;
|
||||||
return true;
|
DN_USize need_amount = DN_Min(bytes_remaining, 32);
|
||||||
|
DN_USize bytes_read = 0;
|
||||||
DN_AssertF(size <= 32,
|
do {
|
||||||
"We can increase this by chunking the buffer and filling 32 bytes at a time. *Nix "
|
bytes_read = getrandom((DN_U8 *)buffer + bytes_written, need_amount, 0);
|
||||||
"guarantees 32 "
|
} while (bytes_read != need_amount || errno == EAGAIN || errno == EINTR);
|
||||||
"bytes can always be fulfilled by this system at a time");
|
bytes_written += bytes_read;
|
||||||
// TODO(doyle):
|
}
|
||||||
// https://github.com/jedisct1/libsodium/blob/master/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c
|
|
||||||
// TODO(doyle): https://man7.org/linux/man-pages/man2/getrandom.2.html
|
|
||||||
DN_U32 read_bytes = 0;
|
|
||||||
do {
|
|
||||||
read_bytes =
|
|
||||||
getrandom(buffer, size, 0); // NOTE: EINTR can not be triggered if size <= 32 bytes
|
|
||||||
} while (read_bytes != size || errno == EAGAIN);
|
|
||||||
return true;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8105,24 +8097,16 @@ DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate(DN_U64 time)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API bool DN_OS_SecureRNGBytes(void *buffer, DN_U32 size)
|
DN_API void DN_OS_GenBytesSecure(void *buffer, DN_U32 size)
|
||||||
{
|
{
|
||||||
DN_Assert(g_dn_os_core_);
|
DN_Assert(g_dn_os_core_);
|
||||||
DN_W32Core *w32 = DN_CAST(DN_W32Core *) g_dn_os_core_->platform_context;
|
DN_W32Core *w32 = DN_CAST(DN_W32Core *) g_dn_os_core_->platform_context;
|
||||||
|
DN_Assert(w32->bcrypt_init_success);
|
||||||
if (!buffer || size < 0 || !w32->bcrypt_init_success)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (size == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
long gen_status = BCryptGenRandom(w32->bcrypt_rng_handle, DN_CAST(unsigned char *) buffer, size, 0 /*flags*/);
|
long gen_status = BCryptGenRandom(w32->bcrypt_rng_handle, DN_CAST(unsigned char *) buffer, size, 0 /*flags*/);
|
||||||
if (gen_status != 0) {
|
// NOTE: This can only fail if the handle is invalid or one or more parameters are invalid. We
|
||||||
DN_LOG_ErrorF("Failed to generate random bytes: %d", gen_status);
|
// validate our parameters so this shouldn't be the case.
|
||||||
return false;
|
DN_Assert(gen_status == 0);
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path)
|
DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Generated by the DN single header generator 2025-07-30 18:54:02
|
// Generated by the DN single header generator 2025-08-02 22:07:04
|
||||||
|
|
||||||
#if !defined(DN_BASE_INC_H)
|
#if !defined(DN_BASE_INC_H)
|
||||||
#define DN_BASE_INC_H
|
#define DN_BASE_INC_H
|
||||||
@ -6097,7 +6097,7 @@ DN_API DN_U64 DN_OS_DateToUnixTimeS (DN_OSDateTime date);
|
|||||||
DN_API bool DN_OS_DateIsValid (DN_OSDateTime date);
|
DN_API bool DN_OS_DateIsValid (DN_OSDateTime date);
|
||||||
|
|
||||||
// NOTE: Other /////////////////////////////////////////////////////////////////////////////////////
|
// NOTE: Other /////////////////////////////////////////////////////////////////////////////////////
|
||||||
DN_API bool DN_OS_SecureRNGBytes (void *buffer, DN_U32 size);
|
DN_API void DN_OS_GenBytesSecure (void *buffer, DN_U32 size);
|
||||||
DN_API bool DN_OS_SetEnvVar (DN_Str8 name, DN_Str8 value);
|
DN_API bool DN_OS_SetEnvVar (DN_Str8 name, DN_Str8 value);
|
||||||
DN_API DN_OSDiskSpace DN_OS_DiskSpace (DN_Str8 path);
|
DN_API DN_OSDiskSpace DN_OS_DiskSpace (DN_Str8 path);
|
||||||
DN_API DN_Str8 DN_OS_EXEPath (DN_Arena *arena);
|
DN_API DN_Str8 DN_OS_EXEPath (DN_Arena *arena);
|
||||||
|
@ -1821,27 +1821,13 @@ static DN_UTCore DN_Tests_OS()
|
|||||||
#if defined(DN_OS_INC_CPP) || 1
|
#if defined(DN_OS_INC_CPP) || 1
|
||||||
DN_UT_LogF(&result, "DN_OS\n");
|
DN_UT_LogF(&result, "DN_OS\n");
|
||||||
{
|
{
|
||||||
for (DN_UT_Test(&result, "Generate secure RNG bytes with nullptr")) {
|
|
||||||
DN_B32 os_result = DN_OS_SecureRNGBytes(nullptr, 1);
|
|
||||||
DN_UT_Assert(&result, os_result == false);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (DN_UT_Test(&result, "Generate secure RNG 32 bytes")) {
|
for (DN_UT_Test(&result, "Generate secure RNG 32 bytes")) {
|
||||||
char const ZERO[32] = {};
|
char const ZERO[32] = {};
|
||||||
char buf[32] = {};
|
char buf[32] = {};
|
||||||
bool os_result = DN_OS_SecureRNGBytes(buf, DN_ArrayCountU(buf));
|
DN_OS_GenBytesSecure(buf, DN_ArrayCountU(buf));
|
||||||
DN_UT_Assert(&result, os_result);
|
|
||||||
DN_UT_Assert(&result, DN_Memcmp(buf, ZERO, DN_ArrayCountU(buf)) != 0);
|
DN_UT_Assert(&result, DN_Memcmp(buf, ZERO, DN_ArrayCountU(buf)) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_UT_Test(&result, "Generate secure RNG 0 bytes")) {
|
|
||||||
char buf[32] = {};
|
|
||||||
buf[0] = 'Z';
|
|
||||||
DN_B32 os_result = DN_OS_SecureRNGBytes(buf, 0);
|
|
||||||
DN_UT_Assert(&result, os_result);
|
|
||||||
DN_UT_Assert(&result, buf[0] == 'Z');
|
|
||||||
}
|
|
||||||
|
|
||||||
for (DN_UT_Test(&result, "Query executable directory")) {
|
for (DN_UT_Test(&result, "Query executable directory")) {
|
||||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||||
DN_Str8 os_result = DN_OS_EXEDir(tmem.arena);
|
DN_Str8 os_result = DN_OS_EXEDir(tmem.arena);
|
||||||
|
@ -331,7 +331,7 @@ DN_API DN_U64 DN_OS_DateToUnixTimeS (DN_OSDateTime date);
|
|||||||
DN_API bool DN_OS_DateIsValid (DN_OSDateTime date);
|
DN_API bool DN_OS_DateIsValid (DN_OSDateTime date);
|
||||||
|
|
||||||
// NOTE: Other /////////////////////////////////////////////////////////////////////////////////////
|
// NOTE: Other /////////////////////////////////////////////////////////////////////////////////////
|
||||||
DN_API bool DN_OS_SecureRNGBytes (void *buffer, DN_U32 size);
|
DN_API void DN_OS_GenBytesSecure (void *buffer, DN_U32 size);
|
||||||
DN_API bool DN_OS_SetEnvVar (DN_Str8 name, DN_Str8 value);
|
DN_API bool DN_OS_SetEnvVar (DN_Str8 name, DN_Str8 value);
|
||||||
DN_API DN_OSDiskSpace DN_OS_DiskSpace (DN_Str8 path);
|
DN_API DN_OSDiskSpace DN_OS_DiskSpace (DN_Str8 path);
|
||||||
DN_API DN_Str8 DN_OS_EXEPath (DN_Arena *arena);
|
DN_API DN_Str8 DN_OS_EXEPath (DN_Arena *arena);
|
||||||
|
@ -162,32 +162,24 @@ DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate(uint64_t time)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API bool DN_OS_SecureRNGBytes(void *buffer, DN_U32 size)
|
DN_API void DN_OS_GenBytesSecure(void *buffer, DN_U32 size)
|
||||||
{
|
{
|
||||||
#if defined(DN_PLATFORM_EMSCRIPTEN)
|
#if defined(DN_PLATFORM_EMSCRIPTEN)
|
||||||
|
DN_InvalidCodePath;
|
||||||
(void)buffer;
|
(void)buffer;
|
||||||
(void)size;
|
(void)size;
|
||||||
return false;
|
|
||||||
#else
|
#else
|
||||||
if (!buffer || size < 0)
|
DN_Assert(buffer && size);
|
||||||
return false;
|
DN_USize bytes_written = 0;
|
||||||
|
while (bytes_written < size) {
|
||||||
if (size == 0)
|
DN_USize bytes_remaining = size - bytes_written;
|
||||||
return true;
|
DN_USize need_amount = DN_Min(bytes_remaining, 32);
|
||||||
|
DN_USize bytes_read = 0;
|
||||||
DN_AssertF(size <= 32,
|
do {
|
||||||
"We can increase this by chunking the buffer and filling 32 bytes at a time. *Nix "
|
bytes_read = getrandom((DN_U8 *)buffer + bytes_written, need_amount, 0);
|
||||||
"guarantees 32 "
|
} while (bytes_read != need_amount || errno == EAGAIN || errno == EINTR);
|
||||||
"bytes can always be fulfilled by this system at a time");
|
bytes_written += bytes_read;
|
||||||
// TODO(doyle):
|
}
|
||||||
// https://github.com/jedisct1/libsodium/blob/master/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c
|
|
||||||
// TODO(doyle): https://man7.org/linux/man-pages/man2/getrandom.2.html
|
|
||||||
DN_U32 read_bytes = 0;
|
|
||||||
do {
|
|
||||||
read_bytes =
|
|
||||||
getrandom(buffer, size, 0); // NOTE: EINTR can not be triggered if size <= 32 bytes
|
|
||||||
} while (read_bytes != size || errno == EAGAIN);
|
|
||||||
return true;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,24 +223,16 @@ DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate(DN_U64 time)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API bool DN_OS_SecureRNGBytes(void *buffer, DN_U32 size)
|
DN_API void DN_OS_GenBytesSecure(void *buffer, DN_U32 size)
|
||||||
{
|
{
|
||||||
DN_Assert(g_dn_os_core_);
|
DN_Assert(g_dn_os_core_);
|
||||||
DN_W32Core *w32 = DN_CAST(DN_W32Core *) g_dn_os_core_->platform_context;
|
DN_W32Core *w32 = DN_CAST(DN_W32Core *) g_dn_os_core_->platform_context;
|
||||||
|
DN_Assert(w32->bcrypt_init_success);
|
||||||
if (!buffer || size < 0 || !w32->bcrypt_init_success)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (size == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
long gen_status = BCryptGenRandom(w32->bcrypt_rng_handle, DN_CAST(unsigned char *) buffer, size, 0 /*flags*/);
|
long gen_status = BCryptGenRandom(w32->bcrypt_rng_handle, DN_CAST(unsigned char *) buffer, size, 0 /*flags*/);
|
||||||
if (gen_status != 0) {
|
// NOTE: This can only fail if the handle is invalid or one or more parameters are invalid. We
|
||||||
DN_LOG_ErrorF("Failed to generate random bytes: %d", gen_status);
|
// validate our parameters so this shouldn't be the case.
|
||||||
return false;
|
DN_Assert(gen_status == 0);
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path)
|
DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user