Beispiel #1
0
static inline void
_rs_init(u_char *buf, size_t n)
{
	if (n < KEYSZ + IVSZ)
		return;

	if (rs == NULL) {
#ifndef GETDNS_ON_WINDOWS
		if ((rs = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
		    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
			abort();
#ifdef MAP_INHERIT_ZERO
		if (minherit(rs, sizeof(*rs), MAP_INHERIT_ZERO) == -1)
			abort();
#endif
#else /* WINDOWS */
		rs = malloc(sizeof(*rs));
		if(!rs)
			abort();
#endif
	}
	if (rsx == NULL) {
#ifndef GETDNS_ON_WINDOWS
		if ((rsx = mmap(NULL, sizeof(*rsx), PROT_READ|PROT_WRITE,
		    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
			abort();
#else /* WINDOWS */
		rsx = malloc(sizeof(*rsx));
		if(!rsx)
			abort();
#endif
	}

	chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0);
	chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
}
Beispiel #2
0
int64_t s2n_public_random(int64_t max)
{
    uint64_t r;

    gt_check(max, 0);

    while(1) {
        struct s2n_blob blob = { .data = (void *) &r, sizeof(r) };
        GUARD(s2n_get_public_random_data(&blob));

        /* Imagine an int was one byte and UINT_MAX was 256. If the
         * caller asked for s2n_random(129, ...) we'd end up in
         * trouble. Each number in the range 0...127 would be twice
         * as likely as 128. That's because r == 0 % 129 -> 0, and
         * r == 129 % 129 -> 0, but only r == 128 returns 128,
         * r == 257 is out of range.
         *
         * To de-bias the dice, we discard values of r that are higher
         * that the highest multiple of 'max' an int can support. If
         * max is a uint, then in the worst case we discard 50% - 1 r's.
         * But since 'max' is an int and INT_MAX is <= UINT_MAX / 2,
         * in the worst case we discard 25% - 1 r's.
         */
        if (r < (UINT64_MAX - (UINT64_MAX % max))) {
            return r % max;
        }
    }

    return -1;
}

#ifndef OPENSSL_IS_BORINGSSL

int s2n_openssl_compat_rand(unsigned char *buf, int num)
{
    struct s2n_blob out = {.data = buf, .size = num};

    if(s2n_get_private_random_data(&out) < 0) {
        return 0;
    }
    return 1;
}

int s2n_openssl_compat_status(void)
{
    return 1;
}

int s2n_openssl_compat_init(ENGINE *unused)
{
    return 1;
}

RAND_METHOD s2n_openssl_rand_method = {
    .seed = NULL,
    .bytes = s2n_openssl_compat_rand,
    .cleanup = NULL,
    .add = NULL,
    .pseudorand = s2n_openssl_compat_rand,
    .status = s2n_openssl_compat_status
};
#endif

int s2n_init(void)
{
    GUARD(s2n_mem_init());

    OPEN:
    entropy_fd = open(ENTROPY_SOURCE, O_RDONLY);
    if (entropy_fd == -1) {
        if (errno == EINTR) {
            goto OPEN;
        }
        S2N_ERROR(S2N_ERR_OPEN_RANDOM);
    }

#if defined(MAP_INHERIT_ZERO)
    if ((zero_if_forked_ptr = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE,
                                   MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
        S2N_ERROR(S2N_ERR_OPEN_RANDOM);
    }

    if (minherit(zero_if_forked_ptr, sizeof(int), MAP_INHERIT_ZERO) == -1) {
        S2N_ERROR(S2N_ERR_OPEN_RANDOM);
    }
#else

    if (pthread_atfork(NULL, NULL, s2n_on_fork) != 0) {
        S2N_ERROR(S2N_ERR_OPEN_RANDOM);
    }
#endif

    GUARD(s2n_check_fork());

#ifndef OPENSSL_IS_BORINGSSL
    /* Create an engine */
    ENGINE *e = ENGINE_new();
    if (e == NULL ||
        ENGINE_set_id(e, "s2n") != 1 ||
        ENGINE_set_name(e, "s2n entropy generator") != 1 ||
        ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) != 1 ||
        ENGINE_set_init_function(e, s2n_openssl_compat_init) != 1 ||
        ENGINE_set_RAND(e, &s2n_openssl_rand_method) != 1 ||
        ENGINE_add(e) != 1 ||
        ENGINE_free(e) != 1) {
        S2N_ERROR(S2N_ERR_OPEN_RANDOM);
    }

    /* Use that engine for rand() */
    e = ENGINE_by_id("s2n");
    if (e == NULL ||
        ENGINE_init(e) != 1 ||
        ENGINE_set_default(e, ENGINE_METHOD_RAND) != 1) {
        S2N_ERROR(S2N_ERR_OPEN_RANDOM);
    }

#endif

    return 0;
}
Beispiel #3
0
int
main(int argc, char *argv[])
{
	u_char filebuffer[FILESIZE];
	char temppath[PATH_MAX];
	struct sockaddr_in sin;
	int ch, error, i;
	char *pagebuffer;
	ssize_t len;
	pid_t pid;


	while ((ch = getopt(argc, argv, "t")) != -1) {
		switch (ch) {
		case 't':
			threaded = 1;
			break;

		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc != 1 && argc != 2)
		usage();

	len = roundup(sizeof(struct state), getpagesize());
	pagebuffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0);
	if (pagebuffer == MAP_FAILED)
		err(-1, "mmap");
	if (minherit(pagebuffer, len, INHERIT_SHARE) < 0)
		err(-1, "minherit");
	statep = (struct state *)pagebuffer;

	if (uname(&statep->utsname) < 0)
		err(-1, "utsname");

	statep->listen_sock = socket(PF_INET, SOCK_STREAM, 0);
	if (statep->listen_sock < 0)
		err(-1, "socket(PF_INET, SOCK_STREAM)");

	bzero(&sin, sizeof(sin));
	sin.sin_len = sizeof(sin);
	sin.sin_family = AF_INET;
	sin.sin_port = htons(atoi(argv[0]));

	/*
	 * If a path is specified, use it.  Otherwise, create temporary files
	 * with some data for each thread.
	 */
	statep->path = argv[1];
	if (statep->path != NULL) {
		statep->data_file = open(statep->path, O_RDONLY);
		if (statep->data_file < 0)
			err(-1, "open: %s", statep->path);
		for (i = 0; i < THREADS; i++)
			statep->hts[i].hts_fd = statep->data_file;
	} else {
		memset(filebuffer, 'A', FILESIZE - 1);
		filebuffer[FILESIZE - 1] = '\n';
		for (i = 0; i < THREADS; i++) {
			snprintf(temppath, PATH_MAX, "/tmp/httpd.XXXXXXXXXXX");
			statep->hts[i].hts_fd = mkstemp(temppath);
			if (statep->hts[i].hts_fd < 0)
				err(-1, "mkstemp");
			(void)unlink(temppath);
			len = write(statep->hts[i].hts_fd, filebuffer,
			    FILESIZE);
			if (len < 0)
				err(-1, "write");
			if (len < FILESIZE)
				errx(-1, "write: short");
		}
	}

	if (bind(statep->listen_sock, (struct sockaddr *)&sin,
	    sizeof(sin)) < 0)
		err(-1, "bind");

	if (listen(statep->listen_sock, -1) < 0)
		err(-1, "listen");

	for (i = 0; i < THREADS; i++) {
		if (threaded) {
			if (pthread_create(&statep->hts[i].hts_thread, NULL,
			    httpd_worker, &statep->hts[i]) != 0)
				err(-1, "pthread_create");
		} else {
			pid = fork();
			if (pid < 0) {
				error = errno;
				killall();
				errno = error;
				err(-1, "fork");
			}
			if (pid == 0)
				httpd_worker(&statep->hts[i]);
			statep->hts[i].hts_pid = pid;
		}
	}

	for (i = 0; i < THREADS; i++) {
		if (threaded) {
			if (pthread_join(statep->hts[i].hts_thread, NULL)
			    != 0)
				err(-1, "pthread_join");
		} else {
			pid = waitpid(statep->hts[i].hts_pid, NULL, 0);
			if (pid == statep->hts[i].hts_pid)
				statep->hts[i].hts_pid = 0;
		}
	}
	if (!threaded)
		killall();
	return (0);
}
Beispiel #4
0
int
main(int argc, char *argv[])
{
	int ch, error, i;
	char *pagebuffer;
	uintmax_t total;
	size_t len;
	pid_t pid;

	numthreads = DEFAULTTHREADS;
	numseconds = DEFAULTSECONDS;
	while ((ch = getopt(argc, argv, "n:s:t")) != -1) {
		switch (ch) {
		case 'n':
			numthreads = atoi(optarg);
			break;

		case 's':
			numseconds = atoi(optarg);
			break;

		case 't':
			threaded = 1;
			break;

		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc != 3)
		usage();

	if (numthreads > MAXTHREADS)
		errx(-1, "%d exceeds max threads %d", numthreads,
		    MAXTHREADS);

	len = roundup(sizeof(struct state), getpagesize());
	pagebuffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0);
	if (pagebuffer == MAP_FAILED)
		err(-1, "mmap");
	if (minherit(pagebuffer, len, INHERIT_SHARE) < 0)
		err(-1, "minherit");
	statep = (struct state *)pagebuffer;

	bzero(&statep->sin, sizeof(statep->sin));
	statep->sin.sin_len = sizeof(statep->sin);
	statep->sin.sin_family = AF_INET;
	statep->sin.sin_addr.s_addr = inet_addr(argv[0]);
	statep->sin.sin_port = htons(atoi(argv[1]));
	statep->path = argv[2];

	/*
	 * Do one test retrieve so we can report the error from it, if any.
	 */
	if (http_fetch(&statep->sin, statep->path, 0) < 0)
		exit(-1);

	if (threaded) {
		if (pthread_barrier_init(&statep->start_barrier, NULL,
		    numthreads) != 0)
			err(-1, "pthread_barrier_init");
	}

	for (i = 0; i < numthreads; i++) {
		statep->hwd[i].hwd_count = 0;
		if (threaded) {
			if (pthread_create(&statep->hwd[i].hwd_thread, NULL,
			    http_worker, &statep->hwd[i]) != 0)
				err(-1, "pthread_create");
		} else {
			curthread = i;
			pid = fork();
			if (pid < 0) {
				error = errno;
				killall();
				errno = error;
				err(-1, "fork");
			}
			if (pid == 0) {
				http_worker(&statep->hwd[i]);
				printf("Doh\n");
				exit(0);
			}
			statep->hwd[i].hwd_pid = pid;
		}
	}
	if (!threaded) {
		signal(SIGHUP, main_sighup);
		sleep(2);
		signal_barrier_wakeup();
	}
	sleep(numseconds);
	statep->run_done = 1;
	if (!threaded)
		sleep(2);
	for (i = 0; i < numthreads; i++) {
		if (threaded) {
			if (pthread_join(statep->hwd[i].hwd_thread, NULL)
			    != 0)
				err(-1, "pthread_join");
		} else {
			pid = waitpid(statep->hwd[i].hwd_pid, NULL, 0);
			if (pid == statep->hwd[i].hwd_pid)
				statep->hwd[i].hwd_pid = 0;
		}
	}
	if (!threaded)
		killall();
	total = 0;
	for (i = 0; i < numthreads; i++)
		total += statep->hwd[i].hwd_count;
	printf("%ju transfers/second\n", total / numseconds);
	total = 0;
	for (i = 0; i < numthreads; i++)
		total += statep->hwd[i].hwd_errorcount;
	printf("%ju errors/second\n", total / numseconds);
	return (0);
}