diff options
author | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2014-04-23 14:15:04 +0000 |
---|---|---|
committer | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2014-04-23 14:15:04 +0000 |
commit | 164ea08aaffe2c26ed2a04fec6662cc3cf593c34 (patch) | |
tree | 6e7b047027597e8ccaf06e4c26c8dee4f813a81d | |
parent | 1ebc6d495d5de7c9a7bd6e95022594c7dc92e893 (diff) |
Use arc4random as PRNG backend, instead of libcrypto RAND.
Feedback and ok guenther@ deraadt@
Discussed with upstream, who is preparing an arc4random backend.
-rw-r--r-- | usr.sbin/unbound/util/random.c | 123 |
1 files changed, 15 insertions, 108 deletions
diff --git a/usr.sbin/unbound/util/random.c b/usr.sbin/unbound/util/random.c index 1458104fe34..e145b14123a 100644 --- a/usr.sbin/unbound/util/random.c +++ b/usr.sbin/unbound/util/random.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -60,23 +60,7 @@ #include "config.h" #include "util/random.h" #include "util/log.h" -#include <openssl/rand.h> -#include <openssl/rc4.h> -#include <openssl/err.h> - -/** - * Struct with per-thread random state. - * Keeps SSL types away from the header file. - */ -struct ub_randstate { - /** key used for arc4random generation */ - RC4_KEY rc4; - /** keeps track of key usage */ - int rc4_ready; -}; - -/** Size of key to use */ -#define SEED_SIZE 20 +#include <time.h> /** * Max random value. Similar to RAND_MAX, but more portable @@ -84,109 +68,33 @@ struct ub_randstate { */ #define MAX_VALUE 0x7fffffff -/** Number of bytes to reseed after */ -#define REKEY_BYTES (1 << 24) - -/* (re)setup system seed */ void ub_systemseed(unsigned int seed) { - /* RAND_ is threadsafe, by the way */ - if(!RAND_status()) { - /* try to seed it */ - unsigned char buf[256]; - unsigned int v = seed; - size_t i; - for(i=0; i<256/sizeof(seed); i++) { - memmove(buf+i*sizeof(seed), &v, sizeof(seed)); - v = v*seed + (unsigned int)i; - } - RAND_seed(buf, 256); - if(!RAND_status()) { - log_err("Random generator has no entropy " - "(error %ld)", ERR_get_error()); - } else { - verbose(VERB_OPS, "openssl has no entropy, " - "seeding with time and pid"); - } - } -} - -/** reseed random generator */ -static void -ub_arc4random_stir(struct ub_randstate* s, struct ub_randstate* from) -{ - unsigned char rand_buf[SEED_SIZE]; - int i; - - memset(&s->rc4, 0, sizeof(s->rc4)); - memset(rand_buf, 0xc, sizeof(rand_buf)); - if (from) { - for(i=0; i<SEED_SIZE; i++) - rand_buf[i] = (unsigned char)ub_random(from); - } else { - if(!RAND_status()) - ub_systemseed((unsigned)getpid()^(unsigned)time(NULL)); - if (RAND_bytes(rand_buf, (int)sizeof(rand_buf)) <= 0) { - /* very unlikely that this happens, since we seeded - * above, if it does; complain and keep going */ - log_err("Couldn't obtain random bytes (error %ld)", - ERR_get_error()); - s->rc4_ready = 256; - return; - } - } - RC4_set_key(&s->rc4, SEED_SIZE, rand_buf); - - /* - * Discard early keystream, as per recommendations in: - * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps - */ - for(i = 0; i <= 256; i += sizeof(rand_buf)) - RC4(&s->rc4, sizeof(rand_buf), rand_buf, rand_buf); - - memset(rand_buf, 0, sizeof(rand_buf)); - - s->rc4_ready = REKEY_BYTES; } struct ub_randstate* ub_initstate(unsigned int seed, struct ub_randstate* from) { - struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s)); + struct ub_randstate* s = (struct ub_randstate*)malloc(0); if(!s) { log_err("malloc failure in random init"); return NULL; } - ub_systemseed(seed); - ub_arc4random_stir(s, from); return s; } long int ub_random(struct ub_randstate* s) { - unsigned int r = 0; - if (s->rc4_ready <= 0) { - ub_arc4random_stir(s, NULL); - } - - RC4(&s->rc4, sizeof(r), - (unsigned char *)&r, (unsigned char *)&r); - s->rc4_ready -= sizeof(r); - return (long int)((r) % (((unsigned)MAX_VALUE + 1))); + /* This relies on MAX_VALUE being 0x7fffffff. */ + return (long)arc4random() & MAX_VALUE; } long int ub_random_max(struct ub_randstate* state, long int x) { - /* make sure we fetch in a range that is divisible by x. ignore - * values from d .. MAX_VALUE, instead draw a new number */ - long int d = MAX_VALUE - (MAX_VALUE % x); /* d is divisible by x */ - long int v = ub_random(state); - while(d <= v) - v = ub_random(state); - return (v % x); + return (long)arc4random_uniform(x); } void @@ -194,5 +102,4 @@ ub_randfree(struct ub_randstate* s) { if(s) free(s); - /* user app must do RAND_cleanup(); */ } |