diff options
author | Alistair Delva <adelva@google.com> | 2020-08-20 16:14:23 -0700 |
---|---|---|
committer | Alistair Delva <adelva@google.com> | 2020-08-20 16:53:18 -0700 |
commit | d9da10d147d633fdb6ec65e17ff4b8447419d83e (patch) | |
tree | 8f93e8fdc2907f141e0924910bfec26669819f0b /entropy.c | |
parent | 22246b08952d746a7cc5a292570636cf4277598f (diff) | |
parent | ecb2c02d994b3e21994f31a70ff911667c262f1f (diff) |
Merge upstream-master into master
Commit ecb2c02d994b3e21994f31a70ff911667c262f1f upstream
This nearly (but not quite) corresponds to V_8_3_P1; subsequent
cherry-picks will correct this.
Bug: 162492243
Change-Id: I3c079d86435b7c25aefff4538dc89a3002b1e25b
Diffstat (limited to 'entropy.c')
-rw-r--r-- | entropy.c | 84 |
1 files changed, 53 insertions, 31 deletions
@@ -24,6 +24,8 @@ #include "includes.h" +#define RANDOM_SEED_SIZE 48 + #ifdef WITH_OPENSSL #include <sys/types.h> @@ -37,6 +39,7 @@ #include <errno.h> #include <signal.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> #include <stddef.h> /* for offsetof */ @@ -53,7 +56,8 @@ #include "atomicio.h" #include "pathnames.h" #include "log.h" -#include "buffer.h" +#include "sshbuf.h" +#include "ssherr.h" /* * Portable OpenSSH PRNG seeding: @@ -63,8 +67,6 @@ */ #ifndef OPENSSL_PRNG_ONLY -#define RANDOM_SEED_SIZE 48 - /* * Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon * listening either on 'tcp_port', or via Unix domain socket at * @@ -82,7 +84,7 @@ get_random_bytes_prngd(unsigned char *buf, int len, struct sockaddr_storage addr; struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; struct sockaddr_un *addr_un = (struct sockaddr_un *)&addr; - mysig_t old_sigpipe; + sshsig_t old_sigpipe; /* Sanity checks */ if (socket_path == NULL && tcp_port == 0) @@ -108,7 +110,7 @@ get_random_bytes_prngd(unsigned char *buf, int len, strlen(socket_path) + 1; } - old_sigpipe = mysignal(SIGPIPE, SIG_IGN); + old_sigpipe = ssh_signal(SIGPIPE, SIG_IGN); errors = 0; rval = -1; @@ -158,7 +160,7 @@ reopen: rval = 0; done: - mysignal(SIGPIPE, old_sigpipe); + ssh_signal(SIGPIPE, old_sigpipe); if (fd != -1) close(fd); return rval; @@ -181,64 +183,84 @@ seed_from_prngd(unsigned char *buf, size_t bytes) } void -rexec_send_rng_seed(Buffer *m) +rexec_send_rng_seed(struct sshbuf *m) { u_char buf[RANDOM_SEED_SIZE]; + size_t len = sizeof(buf); + int r; if (RAND_bytes(buf, sizeof(buf)) <= 0) { error("Couldn't obtain random bytes (error %ld)", ERR_get_error()); - buffer_put_string(m, "", 0); - } else - buffer_put_string(m, buf, sizeof(buf)); + len = 0; + } + if ((r = sshbuf_put_string(m, buf, len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + explicit_bzero(buf, sizeof(buf)); } void -rexec_recv_rng_seed(Buffer *m) +rexec_recv_rng_seed(struct sshbuf *m) { - u_char *buf; - u_int len; + const u_char *buf = NULL; + size_t len = 0; + int r; - buf = buffer_get_string_ret(m, &len); - if (buf != NULL) { - debug3("rexec_recv_rng_seed: seeding rng with %u bytes", len); - RAND_add(buf, len, len); - } + if ((r = sshbuf_get_string_direct(m, &buf, &len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + debug3("rexec_recv_rng_seed: seeding rng with %lu bytes", + (unsigned long)len); + RAND_add(buf, len, len); } #endif /* OPENSSL_PRNG_ONLY */ void seed_rng(void) { -#ifndef OPENSSL_PRNG_ONLY 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 " - "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); + "have %lx", (u_long)OPENSSL_VERSION_NUMBER, + OpenSSL_version_num()); #ifndef OPENSSL_PRNG_ONLY - if (RAND_status() == 1) { + if (RAND_status() == 1) debug3("RNG is ready, skipping seeding"); - return; + else { + if (seed_from_prngd(buf, sizeof(buf)) == -1) + fatal("Could not obtain seed from PRNGd"); + RAND_add(buf, sizeof(buf), sizeof(buf)); } - - if (seed_from_prngd(buf, sizeof(buf)) == -1) - fatal("Could not obtain seed from PRNGd"); - RAND_add(buf, sizeof(buf), sizeof(buf)); - memset(buf, '\0', sizeof(buf)); - #endif /* OPENSSL_PRNG_ONLY */ + if (RAND_status() != 1) fatal("PRNG is not seeded"); + + /* Ensure arc4random() is primed */ + arc4random_buf(buf, sizeof(buf)); + explicit_bzero(buf, sizeof(buf)); } #else /* WITH_OPENSSL */ -/* Handled in arc4random() */ +#include <stdlib.h> +#include <string.h> + +/* Actual initialisation is handled in arc4random() */ 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 */ |