xref: /freebsd/lib/libc/tests/gen/arc4random_test.c (revision 233193f1e6c4f3a3f9c546458cdfc0342dcc3c91)
137074d96SEnji Cooper /*-
237074d96SEnji Cooper  * Copyright (c) 2011 David Schultz
337074d96SEnji Cooper  * All rights reserved.
437074d96SEnji Cooper  *
537074d96SEnji Cooper  * Redistribution and use in source and binary forms, with or without
637074d96SEnji Cooper  * modification, are permitted provided that the following conditions
737074d96SEnji Cooper  * are met:
837074d96SEnji Cooper  * 1. Redistributions of source code must retain the above copyright
937074d96SEnji Cooper  *    notice, this list of conditions and the following disclaimer.
1037074d96SEnji Cooper  * 2. Redistributions in binary form must reproduce the above copyright
1137074d96SEnji Cooper  *    notice, this list of conditions and the following disclaimer in the
1237074d96SEnji Cooper  *    documentation and/or other materials provided with the distribution.
1337074d96SEnji Cooper  *
1437074d96SEnji Cooper  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1537074d96SEnji Cooper  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1637074d96SEnji Cooper  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1737074d96SEnji Cooper  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1837074d96SEnji Cooper  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1937074d96SEnji Cooper  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2037074d96SEnji Cooper  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2137074d96SEnji Cooper  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2237074d96SEnji Cooper  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2337074d96SEnji Cooper  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2437074d96SEnji Cooper  * SUCH DAMAGE.
2537074d96SEnji Cooper  */
2637074d96SEnji Cooper 
2737074d96SEnji Cooper #include <sys/cdefs.h>
2837074d96SEnji Cooper __FBSDID("$FreeBSD$");
2937074d96SEnji Cooper 
3037074d96SEnji Cooper #include <sys/types.h>
3137074d96SEnji Cooper #include <sys/mman.h>
3237074d96SEnji Cooper #include <sys/wait.h>
33*233193f1SEnji Cooper #include <errno.h>
3437074d96SEnji Cooper #include <stdio.h>
3537074d96SEnji Cooper #include <stdlib.h>
3637074d96SEnji Cooper #include <string.h>
3737074d96SEnji Cooper #include <unistd.h>
38*233193f1SEnji Cooper 
3937074d96SEnji Cooper #include <atf-c.h>
4037074d96SEnji Cooper 
4137074d96SEnji Cooper /*
4237074d96SEnji Cooper  * BUFSIZE is the number of bytes of rc4 output to compare.  The probability
4337074d96SEnji Cooper  * that this test fails spuriously is 2**(-BUFSIZE * 8).
4437074d96SEnji Cooper  */
4537074d96SEnji Cooper #define	BUFSIZE		8
4637074d96SEnji Cooper 
4737074d96SEnji Cooper /*
4837074d96SEnji Cooper  * Test whether arc4random_buf() returns the same sequence of bytes in both
4937074d96SEnji Cooper  * parent and child processes.  (Hint: It shouldn't.)
5037074d96SEnji Cooper  */
5137074d96SEnji Cooper ATF_TC_WITHOUT_HEAD(test_arc4random);
5237074d96SEnji Cooper ATF_TC_BODY(test_arc4random, tc)
5337074d96SEnji Cooper {
5437074d96SEnji Cooper 	struct shared_page {
5537074d96SEnji Cooper 		char parentbuf[BUFSIZE];
5637074d96SEnji Cooper 		char childbuf[BUFSIZE];
5737074d96SEnji Cooper 	} *page;
5837074d96SEnji Cooper 	pid_t pid;
5937074d96SEnji Cooper 	char c;
6037074d96SEnji Cooper 
6137074d96SEnji Cooper 	page = mmap(NULL, sizeof(struct shared_page), PROT_READ | PROT_WRITE,
6237074d96SEnji Cooper 		    MAP_ANON | MAP_SHARED, -1, 0);
63*233193f1SEnji Cooper 	ATF_REQUIRE_MSG(page != MAP_FAILED, "mmap failed; errno=%d", errno);
6437074d96SEnji Cooper 
6537074d96SEnji Cooper 	arc4random_buf(&c, 1);
6637074d96SEnji Cooper 
6737074d96SEnji Cooper 	pid = fork();
6837074d96SEnji Cooper 	ATF_REQUIRE(0 <= pid);
6937074d96SEnji Cooper 	if (pid == 0) {
7037074d96SEnji Cooper 		/* child */
7137074d96SEnji Cooper 		arc4random_buf(page->childbuf, BUFSIZE);
7237074d96SEnji Cooper 		exit(0);
7337074d96SEnji Cooper 	} else {
7437074d96SEnji Cooper 		/* parent */
7537074d96SEnji Cooper 		int status;
7637074d96SEnji Cooper 		arc4random_buf(page->parentbuf, BUFSIZE);
7737074d96SEnji Cooper 		wait(&status);
7837074d96SEnji Cooper 	}
7937074d96SEnji Cooper 	ATF_CHECK_MSG(memcmp(page->parentbuf, page->childbuf, BUFSIZE) != 0,
8037074d96SEnji Cooper 	    "sequences are the same");
8137074d96SEnji Cooper }
8237074d96SEnji Cooper 
8337074d96SEnji Cooper ATF_TP_ADD_TCS(tp)
8437074d96SEnji Cooper {
8537074d96SEnji Cooper 
8637074d96SEnji Cooper 	ATF_TP_ADD_TC(tp, test_arc4random);
8737074d96SEnji Cooper 
8837074d96SEnji Cooper 	return (atf_no_error());
8937074d96SEnji Cooper }
90