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