random.c revision 19193bb63b10fe65b6e01f1ce7232407a18a917a
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * CDDL HEADER START
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * The contents of this file are subject to the terms of the
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Common Development and Distribution License (the "License").
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * You may not use this file except in compliance with the License.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * or http://www.opensolaris.org/os/licensing.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * See the License for the specific language governing permissions
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * and limitations under the License.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * When distributing Covered Code, include this CDDL HEADER in each
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * If applicable, add the following below this CDDL HEADER, with the
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * fields enclosed by brackets "[]" replaced with your own identifying
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * information: Portions Copyright [yyyy] [name of copyright owner]
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * CDDL HEADER END
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Use is subject to license terms.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchistatic pthread_mutex_t random_mutex = PTHREAD_MUTEX_INITIALIZER;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchistatic pthread_mutex_t urandom_mutex = PTHREAD_MUTEX_INITIALIZER;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#define RAND_LOCK(x) (void) pthread_mutex_lock(x)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#define RAND_UNLOCK(x) (void) pthread_mutex_unlock(x)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#define RANDOM_DEVICE "/dev/random" /* random device name */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#define URANDOM_DEVICE "/dev/urandom" /* urandom device name */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Equivalent of open(2) insulated from EINTR.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Also sets close-on-exec.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiopen_nointr(const char *path, int oflag, ...)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if ((fd = open(path, oflag, pmode)) >= 0) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* errno definitely set by failed open() */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Equivalent of read(2) insulated from EINTR.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchireadn_nointr(int fd, void *dbuf, size_t dlen)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi for (err = 0; left > 0 && nread != -1; marker += nread, left -= nread) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if ((nread = read(fd, marker, left)) < 0) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi } else if (nread == 0) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Equivalent of write(2) insulated from EINTR.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiwriten_nointr(int fd, void *dbuf, size_t dlen)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi for (err = 0; left > 0 && nwrite != -1; marker += nwrite,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if ((nwrite = write(fd, marker, left)) < 0) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi } else if (nwrite == 0) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Opens the random number generator devices if not already open.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Always returns the opened fd of the device, or error.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi random_fd = open_nointr(RANDOM_DEVICE, O_RDONLY);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi urandom_fd = open_nointr(URANDOM_DEVICE, O_RDONLY);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Close the random number generator devices if already open.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Put the requested amount of random data into a preallocated buffer.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Good for passphrase salts, initialization vectors.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* Read random data directly from /dev/urandom */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (readn_nointr(urandom_fd, dbuf, dlen) == dlen)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Same as pkcs11_random_data but ensures non zero data.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchipkcs11_nzero_random_data(void *dbuf, size_t dlen)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* Start with some random data */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* Walk through data replacing any 0 bytes with more random data */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi while (i < dlen) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (((char *)dbuf)[i] != 0) {