rand.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22 
23 #include "curl_setup.h"
24 
25 #ifdef HAVE_FCNTL_H
26 #include <fcntl.h>
27 #endif
28 
29 #include <curl/curl.h>
30 #include "vtls/vtls.h"
31 #include "sendf.h"
32 #include "rand.h"
33 
34 /* The last 3 #include files should be in this order */
35 #include "curl_printf.h"
36 #include "curl_memory.h"
37 #include "memdebug.h"
38 
39 static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
40 {
41  unsigned int r;
43  static unsigned int randseed;
44  static bool seeded = FALSE;
45 
46 #ifdef CURLDEBUG
47  char *force_entropy = getenv("CURL_ENTROPY");
48  if(force_entropy) {
49  if(!seeded) {
50  unsigned int seed = 0;
51  size_t elen = strlen(force_entropy);
52  size_t clen = sizeof(seed);
53  size_t min = elen < clen ? elen : clen;
54  memcpy((char *)&seed, force_entropy, min);
55  randseed = ntohl(seed);
56  seeded = TRUE;
57  }
58  else
59  randseed++;
60  *rnd = randseed;
61  return CURLE_OK;
62  }
63 #endif
64 
65  /* data may be NULL! */
66  result = Curl_ssl_random(data, (unsigned char *)rnd, sizeof(*rnd));
67  if(result != CURLE_NOT_BUILT_IN)
68  /* only if there is no random function in the TLS backend do the non crypto
69  version, otherwise return result */
70  return result;
71 
72  /* ---- non-cryptographic version following ---- */
73 
74 #ifdef RANDOM_FILE
75  if(!seeded) {
76  /* if there's a random file to read a seed from, use it */
77  int fd = open(RANDOM_FILE, O_RDONLY);
78  if(fd > -1) {
79  /* read random data into the randseed variable */
80  ssize_t nread = read(fd, &randseed, sizeof(randseed));
81  if(nread == sizeof(randseed))
82  seeded = TRUE;
83  close(fd);
84  }
85  }
86 #endif
87 
88  if(!seeded) {
89  struct curltime now = curlx_tvnow();
90  infof(data, "WARNING: Using weak random seed\n");
91  randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec;
92  randseed = randseed * 1103515245 + 12345;
93  randseed = randseed * 1103515245 + 12345;
94  randseed = randseed * 1103515245 + 12345;
95  seeded = TRUE;
96  }
97 
98  /* Return an unsigned 32-bit pseudo-random number. */
99  r = randseed = randseed * 1103515245 + 12345;
100  *rnd = (r << 16) | ((r >> 16) & 0xFFFF);
101  return CURLE_OK;
102 }
103 
104 /*
105  * Curl_rand() stores 'num' number of random unsigned integers in the buffer
106  * 'rndptr' points to.
107  *
108  * If libcurl is built without TLS support or with a TLS backend that lacks a
109  * proper random API (Gskit, PolarSSL or mbedTLS), this function will use
110  * "weak" random.
111  *
112  * When built *with* TLS support and a backend that offers strong random, it
113  * will return error if it cannot provide strong random values.
114  *
115  * NOTE: 'data' may be passed in as NULL when coming from external API without
116  * easy handle!
117  *
118  */
119 
120 CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num)
121 {
123 
124  DEBUGASSERT(num > 0);
125 
126  while(num) {
127  unsigned int r;
128  size_t left = num < sizeof(unsigned int) ? num : sizeof(unsigned int);
129 
130  result = randit(data, &r);
131  if(result)
132  return result;
133 
134  while(left) {
135  *rnd++ = (unsigned char)(r & 0xFF);
136  r >>= 8;
137  --num;
138  --left;
139  }
140  }
141 
142  return result;
143 }
144 
145 /*
146  * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random
147  * hexadecimal digits PLUS a zero terminating byte. It must be an odd number
148  * size.
149  */
150 
151 CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd,
152  size_t num)
153 {
155  const char *hex = "0123456789abcdef";
156  unsigned char buffer[128];
157  unsigned char *bufp = buffer;
158  DEBUGASSERT(num > 1);
159 
160  if((num/2 >= sizeof(buffer)) || !(num&1))
161  /* make sure it fits in the local buffer and that it is an odd number! */
163 
164  num--; /* save one for zero termination */
165 
166  result = Curl_rand(data, buffer, num/2);
167  if(result)
168  return result;
169 
170  while(num) {
171  *rnd++ = hex[(*bufp & 0xF0)>>4];
172  *rnd++ = hex[*bufp & 0x0F];
173  bufp++;
174  num -= 2;
175  }
176  *rnd = 0;
177 
178  return result;
179 }
#define getenv
Definition: setup-vms.h:52
#define Curl_ssl_random(x, y, z)
Definition: vtls.h:269
time_t tv_sec
Definition: timeval.h:33
struct curltime curlx_tvnow(void)
Definition: timeval.c:106
#define DEBUGASSERT(x)
CURLcode
Definition: curl.h:454
UNITTEST_START int result
Definition: unit1304.c:49
char buffer[]
Definition: unit1308.c:48
static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
Definition: rand.c:39
memcpy(filename, filename1, strlen(filename1))
#define FALSE
CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, size_t num)
Definition: rand.c:151
double min(double a, double b)
Definition: curl.h:455
#define RANDOM_FILE
#define ssize_t
Definition: config-win32.h:382
CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num)
Definition: rand.c:120
#define infof
Definition: sendf.h:44
#define TRUE
Definition: debug.c:29
unsigned int tv_usec
Definition: timeval.h:34


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:16