summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremie Courreges-Anglas <jca@cvs.openbsd.org>2014-04-23 14:15:04 +0000
committerJeremie Courreges-Anglas <jca@cvs.openbsd.org>2014-04-23 14:15:04 +0000
commit164ea08aaffe2c26ed2a04fec6662cc3cf593c34 (patch)
tree6e7b047027597e8ccaf06e4c26c8dee4f813a81d
parent1ebc6d495d5de7c9a7bd6e95022594c7dc92e893 (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.c123
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(); */
}