xref: /aosp_15_r20/external/cronet/third_party/apache-portable-runtime/src/test/testrand.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "apr_general.h"
18 #include "apr_pools.h"
19 #include "apr_random.h"
20 #include "apr_thread_proc.h"
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "testutil.h"
24 
25 #define RANDOM_BUF_SZ 128
26 
hexdump(const char * msg,const unsigned char * b,int n)27 static void hexdump(const char *msg, const unsigned char *b, int n)
28 {
29     int i;
30 
31     printf("\n%s", msg);
32     for (i = 0; i < n; ++i) {
33 #if 0
34         if ((i & 0xf) == 0)
35             printf("%04x", i);
36         printf(" %02x", b[i]);
37         if ((i & 0xf) == 0xf)
38             printf("\n");
39 #else
40         printf("0x%02x,", b[i]);
41         if ((i & 7) == 7)
42             printf("\n");
43 #endif
44     }
45     printf("\n");
46 }
47 
48 static apr_random_t *r;
49 
50 typedef apr_status_t APR_THREAD_FUNC rnd_fn(apr_random_t * r, void *b,
51                                             apr_size_t n);
52 
rand_run_kat(abts_case * tc,rnd_fn * f,apr_random_t * r,const unsigned char expected[RANDOM_BUF_SZ])53 static void rand_run_kat(abts_case *tc, rnd_fn *f, apr_random_t *r,
54                          const unsigned char expected[RANDOM_BUF_SZ])
55 {
56     unsigned char c[RANDOM_BUF_SZ];
57     apr_status_t rv;
58 
59     rv = f(r, c, RANDOM_BUF_SZ);
60     ABTS_INT_EQUAL(tc, 0, rv);
61     if (rv)
62         return;
63     if (memcmp(c, expected, RANDOM_BUF_SZ)) {
64         hexdump("Generated: ", c, RANDOM_BUF_SZ);
65         hexdump("Expected:  ", expected, RANDOM_BUF_SZ);
66         ABTS_FAIL(tc, "Randomness mismatch");
67     }
68 }
69 
70 #if APR_HAS_FORK
rand_check_kat(rnd_fn * f,apr_random_t * r,const unsigned char expected[RANDOM_BUF_SZ],apr_file_t * readp,apr_file_t * writep)71 static int rand_check_kat(rnd_fn *f, apr_random_t *r,
72                           const unsigned char expected[RANDOM_BUF_SZ],
73                           apr_file_t *readp, apr_file_t *writep)
74 {
75     apr_size_t nbytes = RANDOM_BUF_SZ;
76     apr_size_t cmd_size = 1;
77     unsigned char c[RANDOM_BUF_SZ];
78     char ack;
79     apr_status_t rv;
80 
81     rv = f(r, c, RANDOM_BUF_SZ);
82     if (rv)
83         return 2;
84     rv = 0;
85     if (memcmp(c, expected, RANDOM_BUF_SZ)) {
86         rv = 1;
87     } else {
88         hexdump("Generated: ", c, RANDOM_BUF_SZ);
89         hexdump("Previous:  ", expected, RANDOM_BUF_SZ);
90     }
91     /* Report back our random values for comparison in another child */
92     apr_file_write(writep, c, &nbytes);
93     /* Wait for our parent ack the data */
94     apr_file_read(readp, &ack, &cmd_size);
95     return rv;
96 }
97 #endif
98 
rand_add_zeroes(apr_random_t * r)99 static void rand_add_zeroes(apr_random_t *r)
100 {
101     static unsigned char c[2048];
102 
103     apr_random_add_entropy(r, c, sizeof c);
104 }
105 
rand_run_seed_short(abts_case * tc,rnd_fn * f,apr_random_t * r,int count)106 static void rand_run_seed_short(abts_case *tc, rnd_fn *f, apr_random_t *r,
107                                 int count)
108 {
109     int i;
110     apr_status_t rv;
111     char c[1];
112 
113     for (i = 0; i < count; ++i)
114         rand_add_zeroes(r);
115     rv = f(r, c, 1);
116     ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_ENOTENOUGHENTROPY(rv));
117 }
118 
rand_seed_short(abts_case * tc,void * data)119 static void rand_seed_short(abts_case *tc, void *data)
120 {
121     r = apr_random_standard_new(p);
122     rand_run_seed_short(tc, apr_random_insecure_bytes, r, 32);
123 }
124 
rand_kat(abts_case * tc,void * data)125 static void rand_kat(abts_case *tc, void *data)
126 {
127     unsigned char expected[RANDOM_BUF_SZ] = {
128         0x82, 0x04, 0xad, 0xd2, 0x0b, 0xd5, 0xac, 0xda,
129         0x3d, 0x85, 0x58, 0x38, 0x54, 0x6b, 0x69, 0x45,
130         0x37, 0x4c, 0xc7, 0xd7, 0x87, 0xeb, 0xbf, 0xd9,
131         0xb1, 0xb8, 0xb8, 0x2d, 0x9b, 0x33, 0x6e, 0x97,
132         0x04, 0x1d, 0x4c, 0xb0, 0xd1, 0xdf, 0x3d, 0xac,
133         0xd2, 0xaa, 0xfa, 0xcd, 0x96, 0xb7, 0xcf, 0xb1,
134         0x8e, 0x3d, 0xb3, 0xe5, 0x37, 0xa9, 0x95, 0xb4,
135         0xaa, 0x3d, 0x11, 0x1a, 0x08, 0x20, 0x21, 0x9f,
136         0xdb, 0x08, 0x3a, 0xb9, 0x57, 0x9f, 0xf2, 0x1f,
137         0x27, 0xdc, 0xb6, 0xc0, 0x85, 0x08, 0x05, 0xbb,
138         0x13, 0xbe, 0xb1, 0xe9, 0x63, 0x2a, 0xe2, 0xa4,
139         0x23, 0x15, 0x2a, 0x10, 0xbf, 0xdf, 0x09, 0xb3,
140         0xc7, 0xfb, 0x2d, 0x87, 0x48, 0x19, 0xfb, 0xc0,
141         0x15, 0x8c, 0xcb, 0xc6, 0xbd, 0x89, 0x38, 0x69,
142         0xa3, 0xae, 0xa3, 0x21, 0x58, 0x50, 0xe7, 0xc4,
143         0x87, 0xec, 0x2e, 0xb1, 0x2d, 0x6a, 0xbd, 0x46
144     };
145 
146     rand_add_zeroes(r);
147     rand_run_kat(tc, apr_random_insecure_bytes, r, expected);
148 }
149 
rand_seed_short2(abts_case * tc,void * data)150 static void rand_seed_short2(abts_case *tc, void *data)
151 {
152     rand_run_seed_short(tc, apr_random_secure_bytes, r, 320);
153 }
154 
rand_kat2(abts_case * tc,void * data)155 static void rand_kat2(abts_case *tc, void *data)
156 {
157     unsigned char expected[RANDOM_BUF_SZ] = {
158         0x38, 0x8f, 0x01, 0x29, 0x5a, 0x5c, 0x1f, 0xa8,
159         0x00, 0xde, 0x16, 0x4c, 0xe5, 0xf7, 0x1f, 0x58,
160         0xc0, 0x67, 0xe2, 0x98, 0x3d, 0xde, 0x4a, 0x75,
161         0x61, 0x3f, 0x23, 0xd8, 0x45, 0x7a, 0x10, 0x60,
162         0x59, 0x9b, 0xd6, 0xaf, 0xcb, 0x0a, 0x2e, 0x34,
163         0x9c, 0x39, 0x5b, 0xd0, 0xbc, 0x9a, 0xf0, 0x7b,
164         0x7f, 0x40, 0x8b, 0x33, 0xc0, 0x0e, 0x2a, 0x56,
165         0xfc, 0xe5, 0xab, 0xde, 0x7b, 0x13, 0xf5, 0xec,
166         0x15, 0x68, 0xb8, 0x09, 0xbc, 0x2c, 0x15, 0xf0,
167         0x7b, 0xef, 0x2a, 0x97, 0x19, 0xa8, 0x69, 0x51,
168         0xdf, 0xb0, 0x5f, 0x1a, 0x4e, 0xdf, 0x42, 0x02,
169         0x71, 0x36, 0xa7, 0x25, 0x64, 0x85, 0xe2, 0x72,
170         0xc7, 0x87, 0x4d, 0x7d, 0x15, 0xbb, 0x15, 0xd1,
171         0xb1, 0x62, 0x0b, 0x25, 0xd9, 0xd3, 0xd9, 0x5a,
172         0xe3, 0x47, 0x1e, 0xae, 0x67, 0xb4, 0x19, 0x9e,
173         0xed, 0xd2, 0xde, 0xce, 0x18, 0x70, 0x57, 0x12
174     };
175 
176     rand_add_zeroes(r);
177     rand_run_kat(tc, apr_random_secure_bytes, r, expected);
178 }
179 
rand_barrier(abts_case * tc,void * data)180 static void rand_barrier(abts_case *tc, void *data)
181 {
182     apr_random_barrier(r);
183     rand_run_seed_short(tc, apr_random_secure_bytes, r, 320);
184 }
185 
rand_kat3(abts_case * tc,void * data)186 static void rand_kat3(abts_case *tc, void *data)
187 {
188     unsigned char expected[RANDOM_BUF_SZ] = {
189         0xe8, 0xe7, 0xc9, 0x45, 0xe2, 0x2a, 0x54, 0xb2,
190         0xdd, 0xe0, 0xf9, 0xbc, 0x3d, 0xf9, 0xce, 0x3c,
191         0x4c, 0xbd, 0xc9, 0xe2, 0x20, 0x4a, 0x35, 0x1c,
192         0x04, 0x52, 0x7f, 0xb8, 0x0f, 0x60, 0x89, 0x63,
193         0x8a, 0xbe, 0x0a, 0x44, 0xac, 0x5d, 0xd8, 0xeb,
194         0x24, 0x7d, 0xd1, 0xda, 0x4d, 0x86, 0x9b, 0x94,
195         0x26, 0x56, 0x4a, 0x5e, 0x30, 0xea, 0xd4, 0xa9,
196         0x9a, 0xdf, 0xdd, 0xb6, 0xb1, 0x15, 0xe0, 0xfa,
197         0x28, 0xa4, 0xd6, 0x95, 0xa4, 0xf1, 0xd8, 0x6e,
198         0xeb, 0x8c, 0xa4, 0xac, 0x34, 0xfe, 0x06, 0x92,
199         0xc5, 0x09, 0x99, 0x86, 0xdc, 0x5a, 0x3c, 0x92,
200         0xc8, 0x3e, 0x52, 0x00, 0x4d, 0x01, 0x43, 0x6f,
201         0x69, 0xcf, 0xe2, 0x60, 0x9c, 0x23, 0xb3, 0xa5,
202         0x5f, 0x51, 0x47, 0x8c, 0x07, 0xde, 0x60, 0xc6,
203         0x04, 0xbf, 0x32, 0xd6, 0xdc, 0xb7, 0x31, 0x01,
204         0x29, 0x51, 0x51, 0xb3, 0x19, 0x6e, 0xe4, 0xf8
205     };
206 
207     rand_run_kat(tc, apr_random_insecure_bytes, r, expected);
208 }
209 
rand_kat4(abts_case * tc,void * data)210 static void rand_kat4(abts_case *tc, void *data)
211 {
212     unsigned char expected[RANDOM_BUF_SZ] = {
213         0x7d, 0x0e, 0xc4, 0x4e, 0x3e, 0xac, 0x86, 0x50,
214         0x37, 0x95, 0x7a, 0x98, 0x23, 0x26, 0xa7, 0xbf,
215         0x60, 0xfb, 0xa3, 0x70, 0x90, 0xc3, 0x58, 0xc6,
216         0xbd, 0xd9, 0x5e, 0xa6, 0x77, 0x62, 0x7a, 0x5c,
217         0x96, 0x83, 0x7f, 0x80, 0x3d, 0xf4, 0x9c, 0xcc,
218         0x9b, 0x0c, 0x8c, 0xe1, 0x72, 0xa8, 0xfb, 0xc9,
219         0xc5, 0x43, 0x91, 0xdc, 0x9d, 0x92, 0xc2, 0xce,
220         0x1c, 0x5e, 0x36, 0xc7, 0x87, 0xb1, 0xb4, 0xa3,
221         0xc8, 0x69, 0x76, 0xfc, 0x35, 0x75, 0xcb, 0x08,
222         0x2f, 0xe3, 0x98, 0x76, 0x37, 0x80, 0x04, 0x5c,
223         0xb8, 0xb0, 0x7f, 0xb2, 0xda, 0xe3, 0xa3, 0xba,
224         0xed, 0xff, 0xf5, 0x9d, 0x3b, 0x7b, 0xf3, 0x32,
225         0x6c, 0x50, 0xa5, 0x3e, 0xcc, 0xe1, 0x84, 0x9c,
226         0x17, 0x9e, 0x80, 0x64, 0x09, 0xbb, 0x62, 0xf1,
227         0x95, 0xf5, 0x2c, 0xc6, 0x9f, 0x6a, 0xee, 0x6d,
228         0x17, 0x35, 0x5f, 0x35, 0x8d, 0x55, 0x0c, 0x07
229     };
230 
231     rand_add_zeroes(r);
232     rand_run_kat(tc, apr_random_secure_bytes, r, expected);
233 }
234 
235 #if APR_HAS_FORK
rand_fork(abts_case * tc,void * data)236 static void rand_fork(abts_case *tc, void *data)
237 {
238     apr_proc_t proc;
239     apr_status_t rv;
240     apr_size_t nbytes = RANDOM_BUF_SZ;
241     apr_size_t cmd_size = 1;
242     char cmd = 'X';
243     unsigned char expected[RANDOM_BUF_SZ] = {
244         0xac, 0x93, 0xd2, 0x5c, 0xc7, 0xf5, 0x8d, 0xc2,
245         0xd8, 0x8d, 0xb6, 0x7a, 0x94, 0xe1, 0x83, 0x4c,
246         0x26, 0xe2, 0x38, 0x6d, 0xf5, 0xbd, 0x9d, 0x6e,
247         0x91, 0x77, 0x3a, 0x4b, 0x9b, 0xef, 0x9b, 0xa3,
248         0x9f, 0xf6, 0x6d, 0x0c, 0xdc, 0x4b, 0x02, 0xe9,
249         0x5d, 0x3d, 0xfc, 0x92, 0x6b, 0xdf, 0xc9, 0xef,
250         0xb9, 0xa8, 0x74, 0x09, 0xa3, 0xff, 0x64, 0x8d,
251         0x19, 0xc1, 0x31, 0x31, 0x17, 0xe1, 0xb7, 0x7a,
252         0xe7, 0x55, 0x14, 0x92, 0x05, 0xe3, 0x1e, 0xb8,
253         0x9b, 0x1b, 0xdc, 0xac, 0x0e, 0x15, 0x08, 0xa2,
254         0x93, 0x13, 0xf6, 0x04, 0xc6, 0x9d, 0xf8, 0x7f,
255         0x26, 0x32, 0x68, 0x43, 0x2e, 0x5a, 0x4f, 0x47,
256         0xe8, 0xf8, 0x59, 0xb7, 0xfb, 0xbe, 0x30, 0x04,
257         0xb6, 0x63, 0x6f, 0x19, 0xf3, 0x2c, 0xd4, 0xeb,
258         0x32, 0x8a, 0x54, 0x01, 0xd0, 0xaf, 0x3f, 0x13,
259         0xc1, 0x7f, 0x10, 0x2e, 0x08, 0x1c, 0x28, 0x4b,
260     };
261 
262     apr_file_t *readdatap = NULL;
263     apr_file_t *writedatap = NULL;
264     apr_file_t *readcmdp = NULL;
265     apr_file_t *writecmdp = NULL;
266     apr_pool_t *p;
267     int i;
268 
269     apr_pool_create(&p, NULL);
270     /* Set up data pipe for children */
271     rv = apr_file_pipe_create(&readdatap, &writedatap, p);
272     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
273     ABTS_PTR_NOTNULL(tc, readdatap);
274     ABTS_PTR_NOTNULL(tc, writedatap);
275     /* Set up cmd pipe for children */
276     rv = apr_file_pipe_create(&readcmdp, &writecmdp, p);
277     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
278     ABTS_PTR_NOTNULL(tc, readcmdp);
279     ABTS_PTR_NOTNULL(tc, writecmdp);
280 
281     rand_run_kat(tc, apr_random_secure_bytes, r, expected);
282 
283     for (i = 0; i< 10; i++)
284     {
285         rv = apr_proc_fork(&proc, p);
286         if (rv == APR_INCHILD) {
287             int n = rand_check_kat(apr_random_secure_bytes, r, expected, readcmdp, writedatap);
288             exit(n);
289         }
290         else if (rv == APR_INPARENT) {
291             int exitcode;
292             apr_exit_why_e why;
293 
294             /* Read the random data generated by child */
295             rv = apr_file_read(readdatap, expected, &nbytes);
296             ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
297             /* Tell child to finish */
298             rv = apr_file_write(writecmdp, &cmd, &cmd_size);
299             ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
300             apr_proc_wait(&proc, &exitcode, &why, APR_WAIT);
301             if (why != APR_PROC_EXIT) {
302                 ABTS_FAIL(tc, "Child terminated abnormally");
303             }
304             else if (exitcode == 0) {
305                 if (i == 0)
306                 {
307                     ABTS_FAIL(tc, "Child produced our randomness");
308                 } else
309                 {
310                     ABTS_FAIL(tc, "Child produced randomness of previous child");
311                 }
312             }
313             else if (exitcode == 2) {
314                 ABTS_FAIL(tc, "Child randomness failed");
315             }
316             else if (exitcode != 1) {
317                 ABTS_FAIL(tc, "Unknown child error");
318             }
319         } else {
320             ABTS_FAIL(tc, "Fork failed");
321         }
322     }
323 
324 }
325 #endif
326 
rand_exists(abts_case * tc,void * data)327 static void rand_exists(abts_case *tc, void *data)
328 {
329 #if !APR_HAS_RANDOM
330     ABTS_NOT_IMPL(tc, "apr_generate_random_bytes");
331 #else
332     unsigned char c[42];
333 
334     /* There must be a better way to test random-ness, but I don't know
335      * what it is right now.
336      */
337     APR_ASSERT_SUCCESS(tc, "apr_generate_random_bytes failed",
338                        apr_generate_random_bytes(c, sizeof c));
339 #endif
340 }
341 
testrand(abts_suite * suite)342 abts_suite *testrand(abts_suite *suite)
343 {
344     suite = ADD_SUITE(suite)
345 
346     abts_run_test(suite, rand_exists, NULL);
347     abts_run_test(suite, rand_seed_short, NULL);
348     abts_run_test(suite, rand_kat, NULL);
349     abts_run_test(suite, rand_seed_short2, NULL);
350     abts_run_test(suite, rand_kat2, NULL);
351     abts_run_test(suite, rand_barrier, NULL);
352     abts_run_test(suite, rand_kat3, NULL);
353     abts_run_test(suite, rand_kat4, NULL);
354 #if APR_HAS_FORK
355     abts_run_test(suite, rand_fork, NULL);
356 #endif
357 
358     return suite;
359 }
360