1324c9471Sopenharmony_ciFrom 823df3b989e59465d17b0a2eb1239a5fc048b4e5 Mon Sep 17 00:00:00 2001 2324c9471Sopenharmony_ciFrom: Brad House <brad@brad-house.com> 3324c9471Sopenharmony_ciDate: Mon, 22 May 2023 06:51:06 -0400 4324c9471Sopenharmony_ciSubject: [PATCH] Merge pull request from GHSA-8r8p-23f3-64c2 5324c9471Sopenharmony_ci 6324c9471Sopenharmony_ci* segment random number generation into own file 7324c9471Sopenharmony_ci 8324c9471Sopenharmony_ci* abstract random code to make it more modular so we can have multiple backends 9324c9471Sopenharmony_ci 10324c9471Sopenharmony_ci* rand: add support for arc4random_buf() and also direct CARES_RANDOM_FILE reading 11324c9471Sopenharmony_ci 12324c9471Sopenharmony_ci* autotools: fix detection of arc4random_buf 13324c9471Sopenharmony_ci 14324c9471Sopenharmony_ci* rework initial rc4 seed for PRNG as last fallback 15324c9471Sopenharmony_ci 16324c9471Sopenharmony_ci* rc4: more proper implementation, simplified for clarity 17324c9471Sopenharmony_ci 18324c9471Sopenharmony_ci* clarifications 19324c9471Sopenharmony_ci 20324c9471Sopenharmony_ciConflict:NA 21324c9471Sopenharmony_ciReference:https://github.com/c-ares/c-ares/commit/823df3b989e59465d17b0a2eb1239a5fc048b4e5 22324c9471Sopenharmony_ci--- 23324c9471Sopenharmony_ci CMakeLists.txt | 2 + 24324c9471Sopenharmony_ci configure.ac | 1 + 25324c9471Sopenharmony_ci m4/cares-functions.m4 | 85 +++++++++++ 26324c9471Sopenharmony_ci src/lib/Makefile.inc | 1 + 27324c9471Sopenharmony_ci src/lib/ares_config.h.cmake | 3 + 28324c9471Sopenharmony_ci src/lib/ares_destroy.c | 3 + 29324c9471Sopenharmony_ci src/lib/ares_init.c | 89 ++---------- 30324c9471Sopenharmony_ci src/lib/ares_private.h | 19 ++- 31324c9471Sopenharmony_ci src/lib/ares_query.c | 36 +---- 32324c9471Sopenharmony_ci src/lib/ares_rand.c | 274 ++++++++++++++++++++++++++++++++++++ 33324c9471Sopenharmony_ci 10 files changed, 387 insertions(+), 126 deletions(-) 34324c9471Sopenharmony_ci create mode 100644 src/lib/ares_rand.c 35324c9471Sopenharmony_ci 36324c9471Sopenharmony_cidiff --git a/CMakeLists.txt b/CMakeLists.txt 37324c9471Sopenharmony_ciindex 3987d0ab7..e2290af10 100644 38324c9471Sopenharmony_ci--- a/CMakeLists.txt 39324c9471Sopenharmony_ci+++ b/CMakeLists.txt 40324c9471Sopenharmony_ci@@ -393,6 +393,8 @@ CHECK_SYMBOL_EXISTS (strncasecmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNCAS 41324c9471Sopenharmony_ci CHECK_SYMBOL_EXISTS (strncmpi "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNCMPI) 42324c9471Sopenharmony_ci CHECK_SYMBOL_EXISTS (strnicmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNICMP) 43324c9471Sopenharmony_ci CHECK_SYMBOL_EXISTS (writev "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_WRITEV) 44324c9471Sopenharmony_ci+CHECK_SYMBOL_EXISTS (arc4random_buf "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_ARC4RANDOM_BUF) 45324c9471Sopenharmony_ci+ 46324c9471Sopenharmony_ci 47324c9471Sopenharmony_ci # On Android, the system headers may define __system_property_get(), but excluded 48324c9471Sopenharmony_ci # from libc. We need to perform a link test instead of a header/symbol test. 49324c9471Sopenharmony_cidiff --git a/configure.ac b/configure.ac 50324c9471Sopenharmony_ciindex 7884cbb26..54e79d6e2 100644 51324c9471Sopenharmony_ci--- a/configure.ac 52324c9471Sopenharmony_ci+++ b/configure.ac 53324c9471Sopenharmony_ci@@ -683,6 +683,7 @@ CARES_CHECK_FUNC_STRNCASECMP 54324c9471Sopenharmony_ci CARES_CHECK_FUNC_STRNCMPI 55324c9471Sopenharmony_ci CARES_CHECK_FUNC_STRNICMP 56324c9471Sopenharmony_ci CARES_CHECK_FUNC_WRITEV 57324c9471Sopenharmony_ci+CARES_CHECK_FUNC_ARC4RANDOM_BUF 58324c9471Sopenharmony_ci 59324c9471Sopenharmony_ci 60324c9471Sopenharmony_ci dnl check for AF_INET6 61324c9471Sopenharmony_cidiff --git a/m4/cares-functions.m4 b/m4/cares-functions.m4 62324c9471Sopenharmony_ciindex 0f3992c7f..d4f4f994c 100644 63324c9471Sopenharmony_ci--- a/m4/cares-functions.m4 64324c9471Sopenharmony_ci+++ b/m4/cares-functions.m4 65324c9471Sopenharmony_ci@@ -3753,3 +3753,88 @@ AC_DEFUN([CARES_CHECK_FUNC_WRITEV], [ 66324c9471Sopenharmony_ci ac_cv_func_writev="no" 67324c9471Sopenharmony_ci fi 68324c9471Sopenharmony_ci ]) 69324c9471Sopenharmony_ci+ 70324c9471Sopenharmony_ci+dnl CARES_CHECK_FUNC_ARC4RANDOM_BUF 71324c9471Sopenharmony_ci+dnl ------------------------------------------------- 72324c9471Sopenharmony_ci+dnl Verify if arc4random_buf is available, prototyped, and 73324c9471Sopenharmony_ci+dnl can be compiled. If all of these are true, and 74324c9471Sopenharmony_ci+dnl usage has not been previously disallowed with 75324c9471Sopenharmony_ci+dnl shell variable cares_disallow_arc4random_buf, then 76324c9471Sopenharmony_ci+dnl HAVE_ARC4RANDOM_BUF will be defined. 77324c9471Sopenharmony_ci+ 78324c9471Sopenharmony_ci+AC_DEFUN([CARES_CHECK_FUNC_ARC4RANDOM_BUF], [ 79324c9471Sopenharmony_ci+ AC_REQUIRE([CARES_INCLUDES_STDLIB])dnl 80324c9471Sopenharmony_ci+ # 81324c9471Sopenharmony_ci+ tst_links_arc4random_buf="unknown" 82324c9471Sopenharmony_ci+ tst_proto_arc4random_buf="unknown" 83324c9471Sopenharmony_ci+ tst_compi_arc4random_buf="unknown" 84324c9471Sopenharmony_ci+ tst_allow_arc4random_buf="unknown" 85324c9471Sopenharmony_ci+ # 86324c9471Sopenharmony_ci+ AC_MSG_CHECKING([if arc4random_buf can be linked]) 87324c9471Sopenharmony_ci+ AC_LINK_IFELSE([ 88324c9471Sopenharmony_ci+ AC_LANG_FUNC_LINK_TRY([arc4random_buf]) 89324c9471Sopenharmony_ci+ ],[ 90324c9471Sopenharmony_ci+ AC_MSG_RESULT([yes]) 91324c9471Sopenharmony_ci+ tst_links_arc4random_buf="yes" 92324c9471Sopenharmony_ci+ ],[ 93324c9471Sopenharmony_ci+ AC_MSG_RESULT([no]) 94324c9471Sopenharmony_ci+ tst_links_arc4random_buf="no" 95324c9471Sopenharmony_ci+ ]) 96324c9471Sopenharmony_ci+ # 97324c9471Sopenharmony_ci+ if test "$tst_links_arc4random_buf" = "yes"; then 98324c9471Sopenharmony_ci+ AC_MSG_CHECKING([if arc4random_buf is prototyped]) 99324c9471Sopenharmony_ci+ AC_EGREP_CPP([arc4random_buf],[ 100324c9471Sopenharmony_ci+ $cares_includes_stdlib 101324c9471Sopenharmony_ci+ ],[ 102324c9471Sopenharmony_ci+ AC_MSG_RESULT([yes]) 103324c9471Sopenharmony_ci+ tst_proto_arc4random_buf="yes" 104324c9471Sopenharmony_ci+ ],[ 105324c9471Sopenharmony_ci+ AC_MSG_RESULT([no]) 106324c9471Sopenharmony_ci+ tst_proto_arc4random_buf="no" 107324c9471Sopenharmony_ci+ ]) 108324c9471Sopenharmony_ci+ fi 109324c9471Sopenharmony_ci+ # 110324c9471Sopenharmony_ci+ if test "$tst_proto_arc4random_buf" = "yes"; then 111324c9471Sopenharmony_ci+ AC_MSG_CHECKING([if arc4random_buf is compilable]) 112324c9471Sopenharmony_ci+ AC_COMPILE_IFELSE([ 113324c9471Sopenharmony_ci+ AC_LANG_PROGRAM([[ 114324c9471Sopenharmony_ci+ $cares_includes_stdlib 115324c9471Sopenharmony_ci+ ]],[[ 116324c9471Sopenharmony_ci+ arc4random_buf(NULL, 0); 117324c9471Sopenharmony_ci+ return 1; 118324c9471Sopenharmony_ci+ ]]) 119324c9471Sopenharmony_ci+ ],[ 120324c9471Sopenharmony_ci+ AC_MSG_RESULT([yes]) 121324c9471Sopenharmony_ci+ tst_compi_arc4random_buf="yes" 122324c9471Sopenharmony_ci+ ],[ 123324c9471Sopenharmony_ci+ AC_MSG_RESULT([no]) 124324c9471Sopenharmony_ci+ tst_compi_arc4random_buf="no" 125324c9471Sopenharmony_ci+ ]) 126324c9471Sopenharmony_ci+ fi 127324c9471Sopenharmony_ci+ # 128324c9471Sopenharmony_ci+ if test "$tst_compi_arc4random_buf" = "yes"; then 129324c9471Sopenharmony_ci+ AC_MSG_CHECKING([if arc4random_buf usage allowed]) 130324c9471Sopenharmony_ci+ if test "x$cares_disallow_arc4random_buf" != "xyes"; then 131324c9471Sopenharmony_ci+ AC_MSG_RESULT([yes]) 132324c9471Sopenharmony_ci+ tst_allow_arc4random_buf="yes" 133324c9471Sopenharmony_ci+ else 134324c9471Sopenharmony_ci+ AC_MSG_RESULT([no]) 135324c9471Sopenharmony_ci+ tst_allow_arc4random_buf="no" 136324c9471Sopenharmony_ci+ fi 137324c9471Sopenharmony_ci+ fi 138324c9471Sopenharmony_ci+ # 139324c9471Sopenharmony_ci+ AC_MSG_CHECKING([if arc4random_buf might be used]) 140324c9471Sopenharmony_ci+ if test "$tst_links_arc4random_buf" = "yes" && 141324c9471Sopenharmony_ci+ test "$tst_proto_arc4random_buf" = "yes" && 142324c9471Sopenharmony_ci+ test "$tst_compi_arc4random_buf" = "yes" && 143324c9471Sopenharmony_ci+ test "$tst_allow_arc4random_buf" = "yes"; then 144324c9471Sopenharmony_ci+ AC_MSG_RESULT([yes]) 145324c9471Sopenharmony_ci+ AC_DEFINE_UNQUOTED(HAVE_ARC4RANDOM_BUF, 1, 146324c9471Sopenharmony_ci+ [Define to 1 if you have the arc4random_buf function.]) 147324c9471Sopenharmony_ci+ ac_cv_func_arc4random_buf="yes" 148324c9471Sopenharmony_ci+ else 149324c9471Sopenharmony_ci+ AC_MSG_RESULT([no]) 150324c9471Sopenharmony_ci+ ac_cv_func_arc4random_buf="no" 151324c9471Sopenharmony_ci+ fi 152324c9471Sopenharmony_ci+]) 153324c9471Sopenharmony_ci+ 154324c9471Sopenharmony_cidiff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc 155324c9471Sopenharmony_ciindex 140378d67..49bbe6016 100644 156324c9471Sopenharmony_ci--- a/src/lib/Makefile.inc 157324c9471Sopenharmony_ci+++ b/src/lib/Makefile.inc 158324c9471Sopenharmony_ci@@ -45,6 +45,7 @@ CSOURCES = ares__addrinfo2hostent.c \ 159324c9471Sopenharmony_ci ares_platform.c \ 160324c9471Sopenharmony_ci ares_process.c \ 161324c9471Sopenharmony_ci ares_query.c \ 162324c9471Sopenharmony_ci+ ares_rand.c \ 163324c9471Sopenharmony_ci ares_search.c \ 164324c9471Sopenharmony_ci ares_send.c \ 165324c9471Sopenharmony_ci ares_strcasecmp.c \ 166324c9471Sopenharmony_cidiff --git a/src/lib/ares_config.h.cmake b/src/lib/ares_config.h.cmake 167324c9471Sopenharmony_ciindex fddb78535..798820a3a 100644 168324c9471Sopenharmony_ci--- a/src/lib/ares_config.h.cmake 169324c9471Sopenharmony_ci+++ b/src/lib/ares_config.h.cmake 170324c9471Sopenharmony_ci@@ -346,6 +346,9 @@ 171324c9471Sopenharmony_ci /* Define to 1 if you need the memory.h header file even with stdlib.h */ 172324c9471Sopenharmony_ci #cmakedefine NEED_MEMORY_H 173324c9471Sopenharmony_ci 174324c9471Sopenharmony_ci+/* Define if have arc4random_buf() */ 175324c9471Sopenharmony_ci+#cmakedefine HAVE_ARC4RANDOM_BUF 176324c9471Sopenharmony_ci+ 177324c9471Sopenharmony_ci /* a suitable file/device to read random data from */ 178324c9471Sopenharmony_ci #cmakedefine CARES_RANDOM_FILE "@CARES_RANDOM_FILE@" 179324c9471Sopenharmony_ci 180324c9471Sopenharmony_cidiff --git a/src/lib/ares_destroy.c b/src/lib/ares_destroy.c 181324c9471Sopenharmony_ciindex 7ec2bde5a..62c899f82 100644 182324c9471Sopenharmony_ci--- a/src/lib/ares_destroy.c 183324c9471Sopenharmony_ci+++ b/src/lib/ares_destroy.c 184324c9471Sopenharmony_ci@@ -95,6 +95,9 @@ void ares_destroy(ares_channel channel) 185324c9471Sopenharmony_ci if (channel->resolvconf_path) 186324c9471Sopenharmony_ci ares_free(channel->resolvconf_path); 187324c9471Sopenharmony_ci 188324c9471Sopenharmony_ci+ if (channel->rand_state) 189324c9471Sopenharmony_ci+ ares__destroy_rand_state(channel->rand_state); 190324c9471Sopenharmony_ci+ 191324c9471Sopenharmony_ci ares_free(channel); 192324c9471Sopenharmony_ci } 193324c9471Sopenharmony_ci 194324c9471Sopenharmony_cidiff --git a/src/lib/ares_init.c b/src/lib/ares_init.c 195324c9471Sopenharmony_ciindex c7ca7af1b..0519f43e5 100644 196324c9471Sopenharmony_ci--- a/src/lib/ares_init.c 197324c9471Sopenharmony_ci+++ b/src/lib/ares_init.c 198324c9471Sopenharmony_ci@@ -87,7 +76,6 @@ static int config_nameserver(struct server_state **servers, int *nservers, 199324c9471Sopenharmony_ci static int set_search(ares_channel channel, const char *str); 200324c9471Sopenharmony_ci static int set_options(ares_channel channel, const char *str); 201324c9471Sopenharmony_ci static const char *try_option(const char *p, const char *q, const char *opt); 202324c9471Sopenharmony_ci-static int init_id_key(rc4_key* key,int key_data_len); 203324c9471Sopenharmony_ci 204324c9471Sopenharmony_ci static int config_sortlist(struct apattern **sortlist, int *nsort, 205324c9471Sopenharmony_ci const char *str); 206324c9471Sopenharmony_ci@@ -165,6 +153,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, 207324c9471Sopenharmony_ci channel->sock_funcs = NULL; 208324c9471Sopenharmony_ci channel->sock_func_cb_data = NULL; 209324c9471Sopenharmony_ci channel->resolvconf_path = NULL; 210324c9471Sopenharmony_ci+ channel->rand_state = NULL; 211324c9471Sopenharmony_ci 212324c9471Sopenharmony_ci channel->last_server = 0; 213324c9471Sopenharmony_ci channel->last_timeout_processed = (time_t)now.tv_sec; 214324c9471Sopenharmony_ci@@ -218,9 +207,13 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, 215324c9471Sopenharmony_ci /* Generate random key */ 216324c9471Sopenharmony_ci 217324c9471Sopenharmony_ci if (status == ARES_SUCCESS) { 218324c9471Sopenharmony_ci- status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN); 219324c9471Sopenharmony_ci+ channel->rand_state = ares__init_rand_state(); 220324c9471Sopenharmony_ci+ if (channel->rand_state == NULL) { 221324c9471Sopenharmony_ci+ status = ARES_ENOMEM; 222324c9471Sopenharmony_ci+ } 223324c9471Sopenharmony_ci+ 224324c9471Sopenharmony_ci if (status == ARES_SUCCESS) 225324c9471Sopenharmony_ci- channel->next_id = ares__generate_new_id(&channel->id_key); 226324c9471Sopenharmony_ci+ channel->next_id = ares__generate_new_id(channel->rand_state); 227324c9471Sopenharmony_ci else 228324c9471Sopenharmony_ci DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n", 229324c9471Sopenharmony_ci ares_strerror(status))); 230324c9471Sopenharmony_ci@@ -242,6 +235,8 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, 231324c9471Sopenharmony_ci ares_free(channel->lookups); 232324c9471Sopenharmony_ci if(channel->resolvconf_path) 233324c9471Sopenharmony_ci ares_free(channel->resolvconf_path); 234324c9471Sopenharmony_ci+ if (channel->rand_state) 235324c9471Sopenharmony_ci+ ares__destroy_rand_state(channel->rand_state); 236324c9471Sopenharmony_ci ares_free(channel); 237324c9471Sopenharmony_ci return status; 238324c9471Sopenharmony_ci } 239324c9471Sopenharmony_ci@@ -2182,76 +2177,6 @@ static int sortlist_alloc(struct apattern **sortlist, int *nsort, 240324c9471Sopenharmony_ci return 1; 241324c9471Sopenharmony_ci } 242324c9471Sopenharmony_ci 243324c9471Sopenharmony_ci-/* initialize an rc4 key. If possible a cryptographically secure random key 244324c9471Sopenharmony_ci- is generated using a suitable function (for example win32's RtlGenRandom as 245324c9471Sopenharmony_ci- described in 246324c9471Sopenharmony_ci- http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx 247324c9471Sopenharmony_ci- otherwise the code defaults to cross-platform albeit less secure mechanism 248324c9471Sopenharmony_ci- using rand 249324c9471Sopenharmony_ci-*/ 250324c9471Sopenharmony_ci-static void randomize_key(unsigned char* key,int key_data_len) 251324c9471Sopenharmony_ci-{ 252324c9471Sopenharmony_ci- int randomized = 0; 253324c9471Sopenharmony_ci- int counter=0; 254324c9471Sopenharmony_ci-#ifdef WIN32 255324c9471Sopenharmony_ci- BOOLEAN res; 256324c9471Sopenharmony_ci- if (ares_fpSystemFunction036) 257324c9471Sopenharmony_ci- { 258324c9471Sopenharmony_ci- res = (*ares_fpSystemFunction036) (key, key_data_len); 259324c9471Sopenharmony_ci- if (res) 260324c9471Sopenharmony_ci- randomized = 1; 261324c9471Sopenharmony_ci- } 262324c9471Sopenharmony_ci-#else /* !WIN32 */ 263324c9471Sopenharmony_ci-#ifdef CARES_RANDOM_FILE 264324c9471Sopenharmony_ci- FILE *f = fopen(CARES_RANDOM_FILE, "rb"); 265324c9471Sopenharmony_ci- if(f) { 266324c9471Sopenharmony_ci- setvbuf(f, NULL, _IONBF, 0); 267324c9471Sopenharmony_ci- counter = aresx_uztosi(fread(key, 1, key_data_len, f)); 268324c9471Sopenharmony_ci- fclose(f); 269324c9471Sopenharmony_ci- } 270324c9471Sopenharmony_ci-#endif 271324c9471Sopenharmony_ci-#endif /* WIN32 */ 272324c9471Sopenharmony_ci- 273324c9471Sopenharmony_ci- if (!randomized) { 274324c9471Sopenharmony_ci- for (;counter<key_data_len;counter++) 275324c9471Sopenharmony_ci- key[counter]=(unsigned char)(rand() % 256); /* LCOV_EXCL_LINE */ 276324c9471Sopenharmony_ci- } 277324c9471Sopenharmony_ci-} 278324c9471Sopenharmony_ci- 279324c9471Sopenharmony_ci-static int init_id_key(rc4_key* key,int key_data_len) 280324c9471Sopenharmony_ci-{ 281324c9471Sopenharmony_ci- unsigned char index1; 282324c9471Sopenharmony_ci- unsigned char index2; 283324c9471Sopenharmony_ci- unsigned char* state; 284324c9471Sopenharmony_ci- short counter; 285324c9471Sopenharmony_ci- unsigned char *key_data_ptr = 0; 286324c9471Sopenharmony_ci- 287324c9471Sopenharmony_ci- key_data_ptr = ares_malloc(key_data_len); 288324c9471Sopenharmony_ci- if (!key_data_ptr) 289324c9471Sopenharmony_ci- return ARES_ENOMEM; 290324c9471Sopenharmony_ci- memset(key_data_ptr, 0, key_data_len); 291324c9471Sopenharmony_ci- 292324c9471Sopenharmony_ci- state = &key->state[0]; 293324c9471Sopenharmony_ci- for(counter = 0; counter < 256; counter++) 294324c9471Sopenharmony_ci- /* unnecessary AND but it keeps some compilers happier */ 295324c9471Sopenharmony_ci- state[counter] = (unsigned char)(counter & 0xff); 296324c9471Sopenharmony_ci- randomize_key(key->state,key_data_len); 297324c9471Sopenharmony_ci- key->x = 0; 298324c9471Sopenharmony_ci- key->y = 0; 299324c9471Sopenharmony_ci- index1 = 0; 300324c9471Sopenharmony_ci- index2 = 0; 301324c9471Sopenharmony_ci- for(counter = 0; counter < 256; counter++) 302324c9471Sopenharmony_ci- { 303324c9471Sopenharmony_ci- index2 = (unsigned char)((key_data_ptr[index1] + state[counter] + 304324c9471Sopenharmony_ci- index2) % 256); 305324c9471Sopenharmony_ci- ARES_SWAP_BYTE(&state[counter], &state[index2]); 306324c9471Sopenharmony_ci- 307324c9471Sopenharmony_ci- index1 = (unsigned char)((index1 + 1) % key_data_len); 308324c9471Sopenharmony_ci- } 309324c9471Sopenharmony_ci- ares_free(key_data_ptr); 310324c9471Sopenharmony_ci- return ARES_SUCCESS; 311324c9471Sopenharmony_ci-} 312324c9471Sopenharmony_ci- 313324c9471Sopenharmony_ci void ares_set_local_ip4(ares_channel channel, unsigned int local_ip) 314324c9471Sopenharmony_ci { 315324c9471Sopenharmony_ci channel->local_ip4 = local_ip; 316324c9471Sopenharmony_cidiff --git a/src/lib/ares_private.h b/src/lib/ares_private.h 317324c9471Sopenharmony_ciindex 53043a651..b6eab8a7d 100644 318324c9471Sopenharmony_ci--- a/src/lib/ares_private.h 319324c9471Sopenharmony_ci+++ b/src/lib/ares_private.h 320324c9471Sopenharmony_ci@@ -101,8 +101,6 @@ W32_FUNC const char *_w32_GetHostsFile (void); 321324c9471Sopenharmony_ci 322324c9471Sopenharmony_ci #endif 323324c9471Sopenharmony_ci 324324c9471Sopenharmony_ci-#define ARES_ID_KEY_LEN 31 325324c9471Sopenharmony_ci- 326324c9471Sopenharmony_ci #include "ares_ipv6.h" 327324c9471Sopenharmony_ci #include "ares_llist.h" 328324c9471Sopenharmony_ci 329324c9471Sopenharmony_ci@@ -262,12 +260,8 @@ struct apattern { 330324c9471Sopenharmony_ci unsigned short type; 331324c9471Sopenharmony_ci }; 332324c9471Sopenharmony_ci 333324c9471Sopenharmony_ci-typedef struct rc4_key 334324c9471Sopenharmony_ci-{ 335324c9471Sopenharmony_ci- unsigned char state[256]; 336324c9471Sopenharmony_ci- unsigned char x; 337324c9471Sopenharmony_ci- unsigned char y; 338324c9471Sopenharmony_ci-} rc4_key; 339324c9471Sopenharmony_ci+struct ares_rand_state; 340324c9471Sopenharmony_ci+typedef struct ares_rand_state ares_rand_state; 341324c9471Sopenharmony_ci 342324c9471Sopenharmony_ci struct ares_channeldata { 343324c9471Sopenharmony_ci /* Configuration data */ 344324c9471Sopenharmony_ci@@ -302,8 +296,8 @@ struct ares_channeldata { 345324c9471Sopenharmony_ci 346324c9471Sopenharmony_ci /* ID to use for next query */ 347324c9471Sopenharmony_ci unsigned short next_id; 348324c9471Sopenharmony_ci- /* key to use when generating new ids */ 349324c9471Sopenharmony_ci- rc4_key id_key; 350324c9471Sopenharmony_ci+ /* random state to use when generating new ids */ 351324c9471Sopenharmony_ci+ ares_rand_state *rand_state; 352324c9471Sopenharmony_ci 353324c9471Sopenharmony_ci /* Generation number to use for the next TCP socket open/close */ 354324c9471Sopenharmony_ci int tcp_connection_generation; 355324c9471Sopenharmony_ci@@ -362,7 +356,10 @@ void ares__close_sockets(ares_channel channel, struct server_state *server); 356324c9471Sopenharmony_ci int ares__get_hostent(FILE *fp, int family, struct hostent **host); 357324c9471Sopenharmony_ci int ares__read_line(FILE *fp, char **buf, size_t *bufsize); 358324c9471Sopenharmony_ci void ares__free_query(struct query *query); 359324c9471Sopenharmony_ci-unsigned short ares__generate_new_id(rc4_key* key); 360324c9471Sopenharmony_ci+ 361324c9471Sopenharmony_ci+ares_rand_state *ares__init_rand_state(void); 362324c9471Sopenharmony_ci+void ares__destroy_rand_state(ares_rand_state *state); 363324c9471Sopenharmony_ci+unsigned short ares__generate_new_id(ares_rand_state *state); 364324c9471Sopenharmony_ci struct timeval ares__tvnow(void); 365324c9471Sopenharmony_ci int ares__expand_name_validated(const unsigned char *encoded, 366324c9471Sopenharmony_ci const unsigned char *abuf, 367324c9471Sopenharmony_cidiff --git a/src/lib/ares_query.c b/src/lib/ares_query.c 368324c9471Sopenharmony_ciindex 508274db3..42323bec5 100644 369324c9471Sopenharmony_ci--- a/src/lib/ares_query.c 370324c9471Sopenharmony_ci+++ b/src/lib/ares_query.c 371324c9471Sopenharmony_ci@@ -33,32 +33,6 @@ struct qquery { 372324c9471Sopenharmony_ci 373324c9471Sopenharmony_ci static void qcallback(void *arg, int status, int timeouts, unsigned char *abuf, int alen); 374324c9471Sopenharmony_ci 375324c9471Sopenharmony_ci-static void rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len) 376324c9471Sopenharmony_ci-{ 377324c9471Sopenharmony_ci- unsigned char x; 378324c9471Sopenharmony_ci- unsigned char y; 379324c9471Sopenharmony_ci- unsigned char* state; 380324c9471Sopenharmony_ci- unsigned char xorIndex; 381324c9471Sopenharmony_ci- int counter; 382324c9471Sopenharmony_ci- 383324c9471Sopenharmony_ci- x = key->x; 384324c9471Sopenharmony_ci- y = key->y; 385324c9471Sopenharmony_ci- 386324c9471Sopenharmony_ci- state = &key->state[0]; 387324c9471Sopenharmony_ci- for(counter = 0; counter < buffer_len; counter ++) 388324c9471Sopenharmony_ci- { 389324c9471Sopenharmony_ci- x = (unsigned char)((x + 1) % 256); 390324c9471Sopenharmony_ci- y = (unsigned char)((state[x] + y) % 256); 391324c9471Sopenharmony_ci- ARES_SWAP_BYTE(&state[x], &state[y]); 392324c9471Sopenharmony_ci- 393324c9471Sopenharmony_ci- xorIndex = (unsigned char)((state[x] + state[y]) % 256); 394324c9471Sopenharmony_ci- 395324c9471Sopenharmony_ci- buffer_ptr[counter] = (unsigned char)(buffer_ptr[counter]^state[xorIndex]); 396324c9471Sopenharmony_ci- } 397324c9471Sopenharmony_ci- key->x = x; 398324c9471Sopenharmony_ci- key->y = y; 399324c9471Sopenharmony_ci-} 400324c9471Sopenharmony_ci- 401324c9471Sopenharmony_ci static struct query* find_query_by_id(ares_channel channel, unsigned short id) 402324c9471Sopenharmony_ci { 403324c9471Sopenharmony_ci unsigned short qid; 404324c9471Sopenharmony_ci@@ -78,7 +52,6 @@ static struct query* find_query_by_id(ares_channel channel, unsigned short id) 405324c9471Sopenharmony_ci return NULL; 406324c9471Sopenharmony_ci } 407324c9471Sopenharmony_ci 408324c9471Sopenharmony_ci- 409324c9471Sopenharmony_ci /* a unique query id is generated using an rc4 key. Since the id may already 410324c9471Sopenharmony_ci be used by a running query (as infrequent as it may be), a lookup is 411324c9471Sopenharmony_ci performed per id generation. In practice this search should happen only 412324c9471Sopenharmony_ci@@ -89,19 +62,12 @@ static unsigned short generate_unique_id(ares_channel channel) 413324c9471Sopenharmony_ci unsigned short id; 414324c9471Sopenharmony_ci 415324c9471Sopenharmony_ci do { 416324c9471Sopenharmony_ci- id = ares__generate_new_id(&channel->id_key); 417324c9471Sopenharmony_ci+ id = ares__generate_new_id(channel->rand_state); 418324c9471Sopenharmony_ci } while (find_query_by_id(channel, id)); 419324c9471Sopenharmony_ci 420324c9471Sopenharmony_ci return (unsigned short)id; 421324c9471Sopenharmony_ci } 422324c9471Sopenharmony_ci 423324c9471Sopenharmony_ci-unsigned short ares__generate_new_id(rc4_key* key) 424324c9471Sopenharmony_ci-{ 425324c9471Sopenharmony_ci- unsigned short r=0; 426324c9471Sopenharmony_ci- rc4(key, (unsigned char *)&r, sizeof(r)); 427324c9471Sopenharmony_ci- return r; 428324c9471Sopenharmony_ci-} 429324c9471Sopenharmony_ci- 430324c9471Sopenharmony_ci void ares_query(ares_channel channel, const char *name, int dnsclass, 431324c9471Sopenharmony_ci int type, ares_callback callback, void *arg) 432324c9471Sopenharmony_ci { 433324c9471Sopenharmony_cidiff --git a/src/lib/ares_rand.c b/src/lib/ares_rand.c 434324c9471Sopenharmony_cinew file mode 100644 435324c9471Sopenharmony_ciindex 000000000..a564bc236 436324c9471Sopenharmony_ci--- /dev/null 437324c9471Sopenharmony_ci+++ b/src/lib/ares_rand.c 438324c9471Sopenharmony_ci@@ -0,0 +1,274 @@ 439324c9471Sopenharmony_ci+/* Copyright 1998 by the Massachusetts Institute of Technology. 440324c9471Sopenharmony_ci+ * Copyright (C) 2007-2013 by Daniel Stenberg 441324c9471Sopenharmony_ci+ * 442324c9471Sopenharmony_ci+ * Permission to use, copy, modify, and distribute this 443324c9471Sopenharmony_ci+ * software and its documentation for any purpose and without 444324c9471Sopenharmony_ci+ * fee is hereby granted, provided that the above copyright 445324c9471Sopenharmony_ci+ * notice appear in all copies and that both that copyright 446324c9471Sopenharmony_ci+ * notice and this permission notice appear in supporting 447324c9471Sopenharmony_ci+ * documentation, and that the name of M.I.T. not be used in 448324c9471Sopenharmony_ci+ * advertising or publicity pertaining to distribution of the 449324c9471Sopenharmony_ci+ * software without specific, written prior permission. 450324c9471Sopenharmony_ci+ * M.I.T. makes no representations about the suitability of 451324c9471Sopenharmony_ci+ * this software for any purpose. It is provided "as is" 452324c9471Sopenharmony_ci+ * without express or implied warranty. 453324c9471Sopenharmony_ci+ */ 454324c9471Sopenharmony_ci+ 455324c9471Sopenharmony_ci+#include "ares_setup.h" 456324c9471Sopenharmony_ci+#include "ares.h" 457324c9471Sopenharmony_ci+#include "ares_private.h" 458324c9471Sopenharmony_ci+#include "ares_nowarn.h" 459324c9471Sopenharmony_ci+#include <stdlib.h> 460324c9471Sopenharmony_ci+ 461324c9471Sopenharmony_ci+typedef enum { 462324c9471Sopenharmony_ci+ ARES_RAND_OS = 1, /* OS-provided such as RtlGenRandom or arc4random */ 463324c9471Sopenharmony_ci+ ARES_RAND_FILE = 2, /* OS file-backed random number generator */ 464324c9471Sopenharmony_ci+ ARES_RAND_RC4 = 3 /* Internal RC4 based PRNG */ 465324c9471Sopenharmony_ci+} ares_rand_backend; 466324c9471Sopenharmony_ci+ 467324c9471Sopenharmony_ci+typedef struct ares_rand_rc4 468324c9471Sopenharmony_ci+{ 469324c9471Sopenharmony_ci+ unsigned char S[256]; 470324c9471Sopenharmony_ci+ size_t i; 471324c9471Sopenharmony_ci+ size_t j; 472324c9471Sopenharmony_ci+} ares_rand_rc4; 473324c9471Sopenharmony_ci+ 474324c9471Sopenharmony_ci+struct ares_rand_state 475324c9471Sopenharmony_ci+{ 476324c9471Sopenharmony_ci+ ares_rand_backend type; 477324c9471Sopenharmony_ci+ union { 478324c9471Sopenharmony_ci+ FILE *rand_file; 479324c9471Sopenharmony_ci+ ares_rand_rc4 rc4; 480324c9471Sopenharmony_ci+ } state; 481324c9471Sopenharmony_ci+}; 482324c9471Sopenharmony_ci+ 483324c9471Sopenharmony_ci+ 484324c9471Sopenharmony_ci+/* Define RtlGenRandom = SystemFunction036. This is in advapi32.dll. There is 485324c9471Sopenharmony_ci+ * no need to dynamically load this, other software used widely does not. 486324c9471Sopenharmony_ci+ * http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx 487324c9471Sopenharmony_ci+ * https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom 488324c9471Sopenharmony_ci+ */ 489324c9471Sopenharmony_ci+#ifdef _WIN32 490324c9471Sopenharmony_ci+BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG RandomBufferLength); 491324c9471Sopenharmony_ci+# ifndef RtlGenRandom 492324c9471Sopenharmony_ci+# define RtlGenRandom(a,b) SystemFunction036(a,b) 493324c9471Sopenharmony_ci+# endif 494324c9471Sopenharmony_ci+#endif 495324c9471Sopenharmony_ci+ 496324c9471Sopenharmony_ci+ 497324c9471Sopenharmony_ci+#define ARES_RC4_KEY_LEN 32 /* 256 bits */ 498324c9471Sopenharmony_ci+ 499324c9471Sopenharmony_ci+static unsigned int ares_u32_from_ptr(void *addr) 500324c9471Sopenharmony_ci+{ 501324c9471Sopenharmony_ci+ if (sizeof(void *) == 8) { 502324c9471Sopenharmony_ci+ return (unsigned int)((((size_t)addr >> 32) & 0xFFFFFFFF) | ((size_t)addr & 0xFFFFFFFF)); 503324c9471Sopenharmony_ci+ } 504324c9471Sopenharmony_ci+ return (unsigned int)((size_t)addr & 0xFFFFFFFF); 505324c9471Sopenharmony_ci+} 506324c9471Sopenharmony_ci+ 507324c9471Sopenharmony_ci+ 508324c9471Sopenharmony_ci+/* initialize an rc4 key as the last possible fallback. */ 509324c9471Sopenharmony_ci+static void ares_rc4_generate_key(ares_rand_rc4 *rc4_state, unsigned char *key, size_t key_len) 510324c9471Sopenharmony_ci+{ 511324c9471Sopenharmony_ci+ size_t i; 512324c9471Sopenharmony_ci+ size_t len = 0; 513324c9471Sopenharmony_ci+ unsigned int data; 514324c9471Sopenharmony_ci+ struct timeval tv; 515324c9471Sopenharmony_ci+ 516324c9471Sopenharmony_ci+ if (key_len != ARES_RC4_KEY_LEN) 517324c9471Sopenharmony_ci+ return; 518324c9471Sopenharmony_ci+ 519324c9471Sopenharmony_ci+ /* Randomness is hard to come by. Maybe the system randomizes heap and stack addresses. 520324c9471Sopenharmony_ci+ * Maybe the current timestamp give us some randomness. 521324c9471Sopenharmony_ci+ * Use rc4_state (heap), &i (stack), and ares__tvnow() 522324c9471Sopenharmony_ci+ */ 523324c9471Sopenharmony_ci+ data = ares_u32_from_ptr(rc4_state); 524324c9471Sopenharmony_ci+ memcpy(key + len, &data, sizeof(data)); 525324c9471Sopenharmony_ci+ len += sizeof(data); 526324c9471Sopenharmony_ci+ 527324c9471Sopenharmony_ci+ data = ares_u32_from_ptr(&i); 528324c9471Sopenharmony_ci+ memcpy(key + len, &data, sizeof(data)); 529324c9471Sopenharmony_ci+ len += sizeof(data); 530324c9471Sopenharmony_ci+ 531324c9471Sopenharmony_ci+ tv = ares__tvnow(); 532324c9471Sopenharmony_ci+ data = (unsigned int)((tv.tv_sec | tv.tv_usec) & 0xFFFFFFFF); 533324c9471Sopenharmony_ci+ memcpy(key + len, &data, sizeof(data)); 534324c9471Sopenharmony_ci+ len += sizeof(data); 535324c9471Sopenharmony_ci+ 536324c9471Sopenharmony_ci+ srand(ares_u32_from_ptr(rc4_state) | ares_u32_from_ptr(&i) | (unsigned int)((tv.tv_sec | tv.tv_usec) & 0xFFFFFFFF)); 537324c9471Sopenharmony_ci+ 538324c9471Sopenharmony_ci+ for (i=len; i<key_len; i++) { 539324c9471Sopenharmony_ci+ key[i]=(unsigned char)(rand() % 256); /* LCOV_EXCL_LINE */ 540324c9471Sopenharmony_ci+ } 541324c9471Sopenharmony_ci+} 542324c9471Sopenharmony_ci+ 543324c9471Sopenharmony_ci+ 544324c9471Sopenharmony_ci+static void ares_rc4_init(ares_rand_rc4 *rc4_state) 545324c9471Sopenharmony_ci+{ 546324c9471Sopenharmony_ci+ unsigned char key[ARES_RC4_KEY_LEN]; 547324c9471Sopenharmony_ci+ size_t i; 548324c9471Sopenharmony_ci+ size_t j; 549324c9471Sopenharmony_ci+ 550324c9471Sopenharmony_ci+ ares_rc4_generate_key(rc4_state, key, sizeof(key)); 551324c9471Sopenharmony_ci+ 552324c9471Sopenharmony_ci+ for (i = 0; i < sizeof(rc4_state->S); i++) { 553324c9471Sopenharmony_ci+ rc4_state->S[i] = i & 0xFF; 554324c9471Sopenharmony_ci+ } 555324c9471Sopenharmony_ci+ 556324c9471Sopenharmony_ci+ for(i = 0, j = 0; i < 256; i++) { 557324c9471Sopenharmony_ci+ j = (j + rc4_state->S[i] + key[i % sizeof(key)]) % 256; 558324c9471Sopenharmony_ci+ ARES_SWAP_BYTE(&rc4_state->S[i], &rc4_state->S[j]); 559324c9471Sopenharmony_ci+ } 560324c9471Sopenharmony_ci+ 561324c9471Sopenharmony_ci+ rc4_state->i = 0; 562324c9471Sopenharmony_ci+ rc4_state->j = 0; 563324c9471Sopenharmony_ci+} 564324c9471Sopenharmony_ci+ 565324c9471Sopenharmony_ci+/* Just outputs the key schedule, no need to XOR with any data since we have none */ 566324c9471Sopenharmony_ci+static void ares_rc4_prng(ares_rand_rc4 *rc4_state, unsigned char *buf, int len) 567324c9471Sopenharmony_ci+{ 568324c9471Sopenharmony_ci+ unsigned char *S = rc4_state->S; 569324c9471Sopenharmony_ci+ size_t i = rc4_state->i; 570324c9471Sopenharmony_ci+ size_t j = rc4_state->j; 571324c9471Sopenharmony_ci+ size_t cnt; 572324c9471Sopenharmony_ci+ 573324c9471Sopenharmony_ci+ for (cnt=0; cnt<len; cnt++) { 574324c9471Sopenharmony_ci+ i = (i + 1) % 256; 575324c9471Sopenharmony_ci+ j = (j + S[i]) % 256; 576324c9471Sopenharmony_ci+ 577324c9471Sopenharmony_ci+ ARES_SWAP_BYTE(&S[i], &S[j]); 578324c9471Sopenharmony_ci+ buf[cnt] = S[(S[i] + S[j]) % 256]; 579324c9471Sopenharmony_ci+ } 580324c9471Sopenharmony_ci+ 581324c9471Sopenharmony_ci+ rc4_state->i = i; 582324c9471Sopenharmony_ci+ rc4_state->j = j; 583324c9471Sopenharmony_ci+} 584324c9471Sopenharmony_ci+ 585324c9471Sopenharmony_ci+ 586324c9471Sopenharmony_ci+static int ares__init_rand_engine(ares_rand_state *state) 587324c9471Sopenharmony_ci+{ 588324c9471Sopenharmony_ci+ memset(state, 0, sizeof(*state)); 589324c9471Sopenharmony_ci+ 590324c9471Sopenharmony_ci+#if defined(HAVE_ARC4RANDOM_BUF) || defined(_WIN32) 591324c9471Sopenharmony_ci+ state->type = ARES_RAND_OS; 592324c9471Sopenharmony_ci+ return 1; 593324c9471Sopenharmony_ci+#elif defined(CARES_RANDOM_FILE) 594324c9471Sopenharmony_ci+ state->type = ARES_RAND_FILE; 595324c9471Sopenharmony_ci+ state->state.rand_file = fopen(CARES_RANDOM_FILE, "rb"); 596324c9471Sopenharmony_ci+ if (state->state.rand_file) { 597324c9471Sopenharmony_ci+ setvbuf(state->state.rand_file, NULL, _IONBF, 0); 598324c9471Sopenharmony_ci+ return 1; 599324c9471Sopenharmony_ci+ } 600324c9471Sopenharmony_ci+ /* Fall-Thru on failure to RC4 */ 601324c9471Sopenharmony_ci+#endif 602324c9471Sopenharmony_ci+ 603324c9471Sopenharmony_ci+ state->type = ARES_RAND_RC4; 604324c9471Sopenharmony_ci+ ares_rc4_init(&state->state.rc4); 605324c9471Sopenharmony_ci+ 606324c9471Sopenharmony_ci+ /* Currently cannot fail */ 607324c9471Sopenharmony_ci+ return 1; 608324c9471Sopenharmony_ci+} 609324c9471Sopenharmony_ci+ 610324c9471Sopenharmony_ci+ 611324c9471Sopenharmony_ci+ares_rand_state *ares__init_rand_state() 612324c9471Sopenharmony_ci+{ 613324c9471Sopenharmony_ci+ ares_rand_state *state = NULL; 614324c9471Sopenharmony_ci+ 615324c9471Sopenharmony_ci+ state = ares_malloc(sizeof(*state)); 616324c9471Sopenharmony_ci+ if (!state) 617324c9471Sopenharmony_ci+ return NULL; 618324c9471Sopenharmony_ci+ 619324c9471Sopenharmony_ci+ if (!ares__init_rand_engine(state)) { 620324c9471Sopenharmony_ci+ ares_free(state); 621324c9471Sopenharmony_ci+ return NULL; 622324c9471Sopenharmony_ci+ } 623324c9471Sopenharmony_ci+ 624324c9471Sopenharmony_ci+ return state; 625324c9471Sopenharmony_ci+} 626324c9471Sopenharmony_ci+ 627324c9471Sopenharmony_ci+ 628324c9471Sopenharmony_ci+static void ares__clear_rand_state(ares_rand_state *state) 629324c9471Sopenharmony_ci+{ 630324c9471Sopenharmony_ci+ if (!state) 631324c9471Sopenharmony_ci+ return; 632324c9471Sopenharmony_ci+ 633324c9471Sopenharmony_ci+ switch (state->type) { 634324c9471Sopenharmony_ci+ case ARES_RAND_OS: 635324c9471Sopenharmony_ci+ break; 636324c9471Sopenharmony_ci+ case ARES_RAND_FILE: 637324c9471Sopenharmony_ci+ fclose(state->state.rand_file); 638324c9471Sopenharmony_ci+ break; 639324c9471Sopenharmony_ci+ case ARES_RAND_RC4: 640324c9471Sopenharmony_ci+ break; 641324c9471Sopenharmony_ci+ } 642324c9471Sopenharmony_ci+} 643324c9471Sopenharmony_ci+ 644324c9471Sopenharmony_ci+ 645324c9471Sopenharmony_ci+static void ares__reinit_rand(ares_rand_state *state) 646324c9471Sopenharmony_ci+{ 647324c9471Sopenharmony_ci+ ares__clear_rand_state(state); 648324c9471Sopenharmony_ci+ ares__init_rand_engine(state); 649324c9471Sopenharmony_ci+} 650324c9471Sopenharmony_ci+ 651324c9471Sopenharmony_ci+ 652324c9471Sopenharmony_ci+void ares__destroy_rand_state(ares_rand_state *state) 653324c9471Sopenharmony_ci+{ 654324c9471Sopenharmony_ci+ if (!state) 655324c9471Sopenharmony_ci+ return; 656324c9471Sopenharmony_ci+ 657324c9471Sopenharmony_ci+ ares__clear_rand_state(state); 658324c9471Sopenharmony_ci+ ares_free(state); 659324c9471Sopenharmony_ci+} 660324c9471Sopenharmony_ci+ 661324c9471Sopenharmony_ci+ 662324c9471Sopenharmony_ci+static void ares__rand_bytes(ares_rand_state *state, unsigned char *buf, size_t len) 663324c9471Sopenharmony_ci+{ 664324c9471Sopenharmony_ci+ 665324c9471Sopenharmony_ci+ while (1) { 666324c9471Sopenharmony_ci+ size_t rv; 667324c9471Sopenharmony_ci+ size_t bytes_read = 0; 668324c9471Sopenharmony_ci+ 669324c9471Sopenharmony_ci+ switch (state->type) { 670324c9471Sopenharmony_ci+ case ARES_RAND_OS: 671324c9471Sopenharmony_ci+#ifdef _WIN32 672324c9471Sopenharmony_ci+ RtlGenRandom(buf, len); 673324c9471Sopenharmony_ci+ return; 674324c9471Sopenharmony_ci+#elif defined(HAVE_ARC4RANDOM_BUF) 675324c9471Sopenharmony_ci+ arc4random_buf(buf, len); 676324c9471Sopenharmony_ci+ return; 677324c9471Sopenharmony_ci+#else 678324c9471Sopenharmony_ci+ /* Shouldn't be possible to be here */ 679324c9471Sopenharmony_ci+ break; 680324c9471Sopenharmony_ci+#endif 681324c9471Sopenharmony_ci+ 682324c9471Sopenharmony_ci+ case ARES_RAND_FILE: 683324c9471Sopenharmony_ci+ while (1) { 684324c9471Sopenharmony_ci+ size_t rv = fread(buf + bytes_read, 1, len - bytes_read, state->state.rand_file); 685324c9471Sopenharmony_ci+ if (rv == 0) 686324c9471Sopenharmony_ci+ break; /* critical error, will reinit rand state */ 687324c9471Sopenharmony_ci+ 688324c9471Sopenharmony_ci+ bytes_read += rv; 689324c9471Sopenharmony_ci+ if (bytes_read == len) 690324c9471Sopenharmony_ci+ return; 691324c9471Sopenharmony_ci+ } 692324c9471Sopenharmony_ci+ break; 693324c9471Sopenharmony_ci+ 694324c9471Sopenharmony_ci+ case ARES_RAND_RC4: 695324c9471Sopenharmony_ci+ ares_rc4_prng(&state->state.rc4, buf, len); 696324c9471Sopenharmony_ci+ return; 697324c9471Sopenharmony_ci+ } 698324c9471Sopenharmony_ci+ 699324c9471Sopenharmony_ci+ /* If we didn't return before we got here, that means we had a critical rand 700324c9471Sopenharmony_ci+ * failure and need to reinitialized */ 701324c9471Sopenharmony_ci+ ares__reinit_rand(state); 702324c9471Sopenharmony_ci+ } 703324c9471Sopenharmony_ci+} 704324c9471Sopenharmony_ci+ 705324c9471Sopenharmony_ci+unsigned short ares__generate_new_id(ares_rand_state *state) 706324c9471Sopenharmony_ci+{ 707324c9471Sopenharmony_ci+ unsigned short r=0; 708324c9471Sopenharmony_ci+ 709324c9471Sopenharmony_ci+ ares__rand_bytes(state, (unsigned char *)&r, sizeof(r)); 710324c9471Sopenharmony_ci+ return r; 711324c9471Sopenharmony_ci+} 712324c9471Sopenharmony_ci+ 713