Changeset View
Changeset View
Standalone View
Standalone View
entropy.c
Show All 18 Lines | |||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
*/ | */ | ||||
#include "includes.h" | #include "includes.h" | ||||
#define RANDOM_SEED_SIZE 48 | |||||
#ifdef WITH_OPENSSL | #ifdef WITH_OPENSSL | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#ifdef HAVE_SYS_UN_H | #ifdef HAVE_SYS_UN_H | ||||
# include <sys/un.h> | # include <sys/un.h> | ||||
#endif | #endif | ||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <arpa/inet.h> | #include <arpa/inet.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <signal.h> | #include <signal.h> | ||||
#include <stdlib.h> | |||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <stddef.h> /* for offsetof */ | #include <stddef.h> /* for offsetof */ | ||||
#include <openssl/rand.h> | #include <openssl/rand.h> | ||||
#include <openssl/crypto.h> | #include <openssl/crypto.h> | ||||
#include <openssl/err.h> | #include <openssl/err.h> | ||||
Show All 11 Lines | |||||
/* | /* | ||||
* Portable OpenSSH PRNG seeding: | * Portable OpenSSH PRNG seeding: | ||||
* If OpenSSL has not "internally seeded" itself (e.g. pulled data from | * If OpenSSL has not "internally seeded" itself (e.g. pulled data from | ||||
* /dev/random), then collect RANDOM_SEED_SIZE bytes of randomness from | * /dev/random), then collect RANDOM_SEED_SIZE bytes of randomness from | ||||
* PRNGd. | * PRNGd. | ||||
*/ | */ | ||||
#ifndef OPENSSL_PRNG_ONLY | #ifndef OPENSSL_PRNG_ONLY | ||||
#define RANDOM_SEED_SIZE 48 | |||||
/* | /* | ||||
* Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon | * Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon | ||||
* listening either on 'tcp_port', or via Unix domain socket at * | * listening either on 'tcp_port', or via Unix domain socket at * | ||||
* 'socket_path'. | * 'socket_path'. | ||||
* Either a non-zero tcp_port or a non-null socket_path must be | * Either a non-zero tcp_port or a non-null socket_path must be | ||||
* supplied. | * supplied. | ||||
* Returns 0 on success, -1 on error | * Returns 0 on success, -1 on error | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 119 Lines • ▼ Show 20 Lines | rexec_send_rng_seed(struct sshbuf *m) | ||||
if ((r = sshbuf_put_string(m, buf, len)) != 0) | if ((r = sshbuf_put_string(m, buf, len)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
explicit_bzero(buf, sizeof(buf)); | explicit_bzero(buf, sizeof(buf)); | ||||
} | } | ||||
void | void | ||||
rexec_recv_rng_seed(struct sshbuf *m) | rexec_recv_rng_seed(struct sshbuf *m) | ||||
{ | { | ||||
u_char *buf = NULL; | const u_char *buf = NULL; | ||||
size_t len = 0; | size_t len = 0; | ||||
int r; | int r; | ||||
if ((r = sshbuf_get_string_direct(m, &buf, &len)) != 0 | if ((r = sshbuf_get_string_direct(m, &buf, &len)) != 0) | ||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
debug3("rexec_recv_rng_seed: seeding rng with %u bytes", len); | debug3("rexec_recv_rng_seed: seeding rng with %lu bytes", | ||||
(unsigned long)len); | |||||
RAND_add(buf, len, len); | RAND_add(buf, len, len); | ||||
} | } | ||||
#endif /* OPENSSL_PRNG_ONLY */ | #endif /* OPENSSL_PRNG_ONLY */ | ||||
void | void | ||||
seed_rng(void) | seed_rng(void) | ||||
{ | { | ||||
#ifndef OPENSSL_PRNG_ONLY | |||||
unsigned char buf[RANDOM_SEED_SIZE]; | unsigned char buf[RANDOM_SEED_SIZE]; | ||||
#endif | |||||
if (!ssh_compatible_openssl(OPENSSL_VERSION_NUMBER, SSLeay())) | /* Initialise libcrypto */ | ||||
ssh_libcrypto_init(); | |||||
if (!ssh_compatible_openssl(OPENSSL_VERSION_NUMBER, | |||||
OpenSSL_version_num())) | |||||
fatal("OpenSSL version mismatch. Built against %lx, you " | fatal("OpenSSL version mismatch. Built against %lx, you " | ||||
"have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); | "have %lx", (u_long)OPENSSL_VERSION_NUMBER, | ||||
OpenSSL_version_num()); | |||||
#ifndef OPENSSL_PRNG_ONLY | #ifndef OPENSSL_PRNG_ONLY | ||||
if (RAND_status() == 1) { | if (RAND_status() == 1) | ||||
debug3("RNG is ready, skipping seeding"); | debug3("RNG is ready, skipping seeding"); | ||||
return; | else { | ||||
} | |||||
if (seed_from_prngd(buf, sizeof(buf)) == -1) | if (seed_from_prngd(buf, sizeof(buf)) == -1) | ||||
fatal("Could not obtain seed from PRNGd"); | fatal("Could not obtain seed from PRNGd"); | ||||
RAND_add(buf, sizeof(buf), sizeof(buf)); | RAND_add(buf, sizeof(buf), sizeof(buf)); | ||||
memset(buf, '\0', sizeof(buf)); | } | ||||
#endif /* OPENSSL_PRNG_ONLY */ | #endif /* OPENSSL_PRNG_ONLY */ | ||||
if (RAND_status() != 1) | if (RAND_status() != 1) | ||||
fatal("PRNG is not seeded"); | fatal("PRNG is not seeded"); | ||||
/* Ensure arc4random() is primed */ | |||||
arc4random_buf(buf, sizeof(buf)); | |||||
explicit_bzero(buf, sizeof(buf)); | |||||
} | } | ||||
#else /* WITH_OPENSSL */ | #else /* WITH_OPENSSL */ | ||||
/* Handled in arc4random() */ | #include <stdlib.h> | ||||
#include <string.h> | |||||
/* Actual initialisation is handled in arc4random() */ | |||||
void | void | ||||
seed_rng(void) | seed_rng(void) | ||||
{ | { | ||||
unsigned char buf[RANDOM_SEED_SIZE]; | |||||
/* Ensure arc4random() is primed */ | |||||
arc4random_buf(buf, sizeof(buf)); | |||||
explicit_bzero(buf, sizeof(buf)); | |||||
} | } | ||||
#endif /* WITH_OPENSSL */ | #endif /* WITH_OPENSSL */ |