From dfc517b05395d925a4d7b1ce9633a849f9468e70 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 23 Feb 2006 15:52:24 +0000 Subject: r13658: More moving around of files: - Collect the generic utility functions into a lib/util/ (a la GLib is for the GNOME folks) - Remove even more files from include/ (This used to be commit ba62880f5b05c2a505dc7f54676b231197a7e707) --- source4/lib/util/genrand.c | 314 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 source4/lib/util/genrand.c (limited to 'source4/lib/util/genrand.c') diff --git a/source4/lib/util/genrand.c b/source4/lib/util/genrand.c new file mode 100644 index 0000000000..1149314d0b --- /dev/null +++ b/source4/lib/util/genrand.c @@ -0,0 +1,314 @@ +/* + Unix SMB/CIFS implementation. + + Functions to create reasonable random numbers for crypto use. + + Copyright (C) Jeremy Allison 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "system/iconv.h" +#include "system/filesys.h" +#include "lib/crypto/crypto.h" + +static unsigned char hash[258]; +static uint32_t counter; + +static BOOL done_reseed = False; +static void (*reseed_callback)(int *newseed); + +/**************************************************************** + Copy any user given reseed data. +*****************************************************************/ + +void set_rand_reseed_callback(void (*fn)(int *)) +{ + reseed_callback = fn; + set_need_random_reseed(); +} + +void set_need_random_reseed(void) +{ + done_reseed = False; +} + +static void get_rand_reseed_data(int *reseed_data) +{ + if (reseed_callback) { + reseed_callback(reseed_data); + } else { + *reseed_data = 0; + } +} + +/**************************************************************** + Setup the seed. +*****************************************************************/ + +static void seed_random_stream(unsigned char *seedval, size_t seedlen) +{ + unsigned char j = 0; + size_t ind; + + for (ind = 0; ind < 256; ind++) + hash[ind] = (unsigned char)ind; + + for( ind = 0; ind < 256; ind++) { + unsigned char tc; + + j += (hash[ind] + seedval[ind%seedlen]); + + tc = hash[ind]; + hash[ind] = hash[j]; + hash[j] = tc; + } + + hash[256] = 0; + hash[257] = 0; +} + +/**************************************************************** + Get datasize bytes worth of random data. +*****************************************************************/ + +static void get_random_stream(unsigned char *data, size_t datasize) +{ + unsigned char index_i = hash[256]; + unsigned char index_j = hash[257]; + size_t ind; + + for( ind = 0; ind < datasize; ind++) { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += hash[index_i]; + + tc = hash[index_i]; + hash[index_i] = hash[index_j]; + hash[index_j] = tc; + + t = hash[index_i] + hash[index_j]; + data[ind] = hash[t]; + } + + hash[256] = index_i; + hash[257] = index_j; +} + +/**************************************************************** + Get a 16 byte hash from the contents of a file. + + Note that the hash is initialised, because the extra entropy is not + worth the valgrind pain. +*****************************************************************/ + +static void do_filehash(const char *fname, unsigned char *the_hash) +{ + unsigned char buf[1011]; /* deliberate weird size */ + unsigned char tmp_md4[16]; + int fd, n; + + ZERO_STRUCT(tmp_md4); + + fd = open(fname,O_RDONLY,0); + if (fd == -1) + return; + + while ((n = read(fd, (char *)buf, sizeof(buf))) > 0) { + mdfour(tmp_md4, buf, n); + for (n=0;n<16;n++) + the_hash[n] ^= tmp_md4[n]; + } + close(fd); +} + +/************************************************************** + Try and get a good random number seed. Try a number of + different factors. Firstly, try /dev/urandom - use if exists. + + We use /dev/urandom as a read of /dev/random can block if + the entropy pool dries up. This leads clients to timeout + or be very slow on connect. + + If we can't use /dev/urandom then seed the stream random generator + above... +**************************************************************/ + +static int do_reseed(BOOL use_fd, int fd) +{ + unsigned char seed_inbuf[40]; + uint32_t v1, v2; struct timeval tval; pid_t mypid; + int reseed_data = 0; + + if (use_fd) { + if (fd != -1) + return fd; + + fd = open( "/dev/urandom", O_RDONLY,0); + if(fd >= 0) + return fd; + } + + /* Add in some secret file contents */ + + do_filehash("/etc/shadow", &seed_inbuf[0]); + + /* + * Add the counter, time of day, and pid. + */ + + GetTimeOfDay(&tval); + mypid = getpid(); + v1 = (counter++) + mypid + tval.tv_sec; + v2 = (counter++) * mypid + tval.tv_usec; + + SIVAL(seed_inbuf, 32, v1 ^ IVAL(seed_inbuf, 32)); + SIVAL(seed_inbuf, 36, v2 ^ IVAL(seed_inbuf, 36)); + + /* + * Add any user-given reseed data. + */ + + get_rand_reseed_data(&reseed_data); + if (reseed_data) { + size_t i; + for (i = 0; i < sizeof(seed_inbuf); i++) + seed_inbuf[i] ^= ((char *)(&reseed_data))[i % sizeof(reseed_data)]; + } + + seed_random_stream(seed_inbuf, sizeof(seed_inbuf)); + + return -1; +} + +/* + Interface to the (hopefully) good crypto random number generator. +*/ +void generate_random_buffer(uint8_t *out, int len) +{ + static int urand_fd = -1; + unsigned char md4_buf[64]; + unsigned char tmp_buf[16]; + unsigned char *p; + + if(!done_reseed) { + urand_fd = do_reseed(True, urand_fd); + done_reseed = True; + } + + if (urand_fd != -1 && len > 0) { + + if (read(urand_fd, out, len) == len) + return; /* len bytes of random data read from urandom. */ + + /* Read of urand error, drop back to non urand method. */ + close(urand_fd); + urand_fd = -1; + do_reseed(False, -1); + done_reseed = True; + } + + /* + * Generate random numbers in chunks of 64 bytes, + * then md4 them & copy to the output buffer. + * This way the raw state of the stream is never externally + * seen. + */ + + p = out; + while(len > 0) { + int copy_len = len > 16 ? 16 : len; + + get_random_stream(md4_buf, sizeof(md4_buf)); + mdfour(tmp_buf, md4_buf, sizeof(md4_buf)); + memcpy(p, tmp_buf, copy_len); + p += copy_len; + len -= copy_len; + } +} + +/* + generate a single random uint32_t +*/ +uint32_t generate_random(void) +{ + uint8_t v[4]; + generate_random_buffer(v, 4); + return IVAL(v, 0); +} + + +/* + very basic password quality checker +*/ +BOOL check_password_quality(const char *s) +{ + int has_digit=0, has_capital=0, has_lower=0; + while (*s) { + if (isdigit((unsigned char)*s)) { + has_digit++; + } else if (isupper((unsigned char)*s)) { + has_capital++; + } else if (islower((unsigned char)*s)) { + has_lower++; + } + s++; + } + + return has_digit && has_lower && has_capital; +} + +/******************************************************************* + Use the random number generator to generate a random string. +********************************************************************/ + +char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const char *list) +{ + size_t i; + size_t list_len = strlen(list); + + char *retstr = talloc_array(mem_ctx, char, len + 1); + if (!retstr) return NULL; + + generate_random_buffer((uint8_t *)retstr, len); + for (i = 0; i < len; i++) { + retstr[i] = list[retstr[i] % list_len]; + } + retstr[i] = '\0'; + + return retstr; +} + +char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len) +{ + char *retstr; + const char *c_list = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,"; + +again: + retstr = generate_random_str_list(mem_ctx, len, c_list); + if (!retstr) return NULL; + + /* we need to make sure the random string passes basic quality tests + or it might be rejected by windows as a password */ + if (len >= 7 && !check_password_quality(retstr)) { + talloc_free(retstr); + goto again; + } + + return retstr; +} -- cgit From aa04388943fe5d7d8c873a6ee8a4cc9af2491532 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 28 Feb 2006 13:12:39 +0000 Subject: r13752: Add doxyfile and fix formatting of comments. Current output is available at http://samba.org/~jelmer/util-api/ (This used to be commit 90812203df151a5e62394306827c72adfe13c63c) --- source4/lib/util/genrand.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'source4/lib/util/genrand.c') diff --git a/source4/lib/util/genrand.c b/source4/lib/util/genrand.c index 1149314d0b..a264ac4e31 100644 --- a/source4/lib/util/genrand.c +++ b/source4/lib/util/genrand.c @@ -25,15 +25,20 @@ #include "system/filesys.h" #include "lib/crypto/crypto.h" +/** + * @file + * @brief Random number generation + */ + static unsigned char hash[258]; static uint32_t counter; static BOOL done_reseed = False; static void (*reseed_callback)(int *newseed); -/**************************************************************** +/** Copy any user given reseed data. -*****************************************************************/ +**/ void set_rand_reseed_callback(void (*fn)(int *)) { @@ -196,9 +201,9 @@ static int do_reseed(BOOL use_fd, int fd) return -1; } -/* +/** Interface to the (hopefully) good crypto random number generator. -*/ +**/ void generate_random_buffer(uint8_t *out, int len) { static int urand_fd = -1; @@ -242,9 +247,9 @@ void generate_random_buffer(uint8_t *out, int len) } } -/* +/** generate a single random uint32_t -*/ +**/ uint32_t generate_random(void) { uint8_t v[4]; @@ -253,9 +258,9 @@ uint32_t generate_random(void) } -/* +/** very basic password quality checker -*/ +**/ BOOL check_password_quality(const char *s) { int has_digit=0, has_capital=0, has_lower=0; @@ -273,9 +278,9 @@ BOOL check_password_quality(const char *s) return has_digit && has_lower && has_capital; } -/******************************************************************* +/** Use the random number generator to generate a random string. -********************************************************************/ +**/ char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const char *list) { -- cgit From af30a32b6924b0f2b701186e435defbca2ebd1aa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 5 Mar 2006 17:15:19 +0000 Subject: r13840: Mark some functions as public. (This used to be commit 9a188eb1f48a50d92a67a4fc2b3899b90074059a) --- source4/lib/util/genrand.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/lib/util/genrand.c') diff --git a/source4/lib/util/genrand.c b/source4/lib/util/genrand.c index a264ac4e31..f2b038f161 100644 --- a/source4/lib/util/genrand.c +++ b/source4/lib/util/genrand.c @@ -40,13 +40,13 @@ static void (*reseed_callback)(int *newseed); Copy any user given reseed data. **/ -void set_rand_reseed_callback(void (*fn)(int *)) +_PUBLIC_ void set_rand_reseed_callback(void (*fn)(int *)) { reseed_callback = fn; set_need_random_reseed(); } -void set_need_random_reseed(void) +_PUBLIC_ void set_need_random_reseed(void) { done_reseed = False; } @@ -204,7 +204,7 @@ static int do_reseed(BOOL use_fd, int fd) /** Interface to the (hopefully) good crypto random number generator. **/ -void generate_random_buffer(uint8_t *out, int len) +_PUBLIC_ void generate_random_buffer(uint8_t *out, int len) { static int urand_fd = -1; unsigned char md4_buf[64]; @@ -250,7 +250,7 @@ void generate_random_buffer(uint8_t *out, int len) /** generate a single random uint32_t **/ -uint32_t generate_random(void) +_PUBLIC_ uint32_t generate_random(void) { uint8_t v[4]; generate_random_buffer(v, 4); @@ -261,7 +261,7 @@ uint32_t generate_random(void) /** very basic password quality checker **/ -BOOL check_password_quality(const char *s) +_PUBLIC_ BOOL check_password_quality(const char *s) { int has_digit=0, has_capital=0, has_lower=0; while (*s) { @@ -282,7 +282,7 @@ BOOL check_password_quality(const char *s) Use the random number generator to generate a random string. **/ -char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const char *list) +_PUBLIC_ char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const char *list) { size_t i; size_t list_len = strlen(list); @@ -299,7 +299,7 @@ char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const char *list return retstr; } -char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len) +_PUBLIC_ char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len) { char *retstr; const char *c_list = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,"; -- cgit From c287cc247d90c996894cab18e870c992e7f84f85 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 6 Mar 2006 00:24:51 +0000 Subject: r13851: More doc improvements. (This used to be commit 936d26ae64b93ef8f8b2fbc632b1c2fd60840405) --- source4/lib/util/genrand.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source4/lib/util/genrand.c') diff --git a/source4/lib/util/genrand.c b/source4/lib/util/genrand.c index f2b038f161..5bdf1f7e08 100644 --- a/source4/lib/util/genrand.c +++ b/source4/lib/util/genrand.c @@ -46,6 +46,9 @@ _PUBLIC_ void set_rand_reseed_callback(void (*fn)(int *)) set_need_random_reseed(); } +/** + * Tell the random number generator it needs to reseed. + */ _PUBLIC_ void set_need_random_reseed(void) { done_reseed = False; @@ -299,6 +302,13 @@ _PUBLIC_ char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const c return retstr; } +/** + * Generate a random text string consisting of the specified length. + * The returned string will be allocated. + * + * Characters used are: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#., + */ + _PUBLIC_ char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len) { char *retstr; -- cgit From 172a83d72491f90f6191be1040ef8b2e1789bd2e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 13 May 2006 19:14:12 +0000 Subject: r15573: Fix build of systems that have iconv headers in non-standard locations Split of system/locale.h header from system/iconv.h Previously, iconv wasn't being used on these systems (This used to be commit aa6d66fda69779d1c2948a1aca85dbd5208f1cba) --- source4/lib/util/genrand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/util/genrand.c') diff --git a/source4/lib/util/genrand.c b/source4/lib/util/genrand.c index 5bdf1f7e08..8424ad8fd7 100644 --- a/source4/lib/util/genrand.c +++ b/source4/lib/util/genrand.c @@ -21,9 +21,9 @@ */ #include "includes.h" -#include "system/iconv.h" #include "system/filesys.h" #include "lib/crypto/crypto.h" +#include "system/locale.h" /** * @file -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/lib/util/genrand.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/lib/util/genrand.c') diff --git a/source4/lib/util/genrand.c b/source4/lib/util/genrand.c index 8424ad8fd7..b1fde41ee3 100644 --- a/source4/lib/util/genrand.c +++ b/source4/lib/util/genrand.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From edca65915afbfde51ab75a27d5ebcb5ab0c85f20 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 8 Aug 2007 02:41:12 +0000 Subject: r24273: Fix bug #4817 by . (Unable to add a computer from MMC Active Directory Users and Computers). Windows sets a 14 UCS2 char buffer as the password in this case. We need to allow random buffers to be accepted as complex passwords, even if they don't have ASCII upper or lower case characters. (If half the bytes are > 127, then it's likely a random buffer). Also make the test match the documented windows behaviour of '3 of the 4 classes: upper, lower, digit, special'. Andrew Bartlett (This used to be commit 5ef26a2ba3561580f0a73ee61eb707573cc98cd3) --- source4/lib/util/genrand.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source4/lib/util/genrand.c') diff --git a/source4/lib/util/genrand.c b/source4/lib/util/genrand.c index b1fde41ee3..2c3875750e 100644 --- a/source4/lib/util/genrand.c +++ b/source4/lib/util/genrand.c @@ -265,19 +265,24 @@ _PUBLIC_ uint32_t generate_random(void) **/ _PUBLIC_ BOOL check_password_quality(const char *s) { - int has_digit=0, has_capital=0, has_lower=0; + int has_digit=0, has_capital=0, has_lower=0, has_special=0, has_high=0; while (*s) { if (isdigit((unsigned char)*s)) { - has_digit++; + has_digit |= 1; } else if (isupper((unsigned char)*s)) { - has_capital++; + has_capital |= 1; } else if (islower((unsigned char)*s)) { - has_lower++; + has_lower |= 1; + } else if (isascii((unsigned char)*s)) { + has_special |= 1; + } else { + has_high++; } s++; } - return has_digit && has_lower && has_capital; + return ((has_digit + has_lower + has_capital + has_special) >= 3 + || (has_high > strlen(s)/2)); } /** -- cgit From 4fb038b0b8e7a4bb69ac0d9022684eeaca8a491a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Aug 2007 17:21:16 +0000 Subject: r24710: Use standard boolean type for easier use by external users. (This used to be commit 99f4124137d4a61216e8189f26d4da32882c0f4a) --- source4/lib/util/genrand.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/lib/util/genrand.c') diff --git a/source4/lib/util/genrand.c b/source4/lib/util/genrand.c index 2c3875750e..4d976cecf8 100644 --- a/source4/lib/util/genrand.c +++ b/source4/lib/util/genrand.c @@ -32,7 +32,7 @@ static unsigned char hash[258]; static uint32_t counter; -static BOOL done_reseed = False; +static bool done_reseed = false; static void (*reseed_callback)(int *newseed); /** @@ -50,7 +50,7 @@ _PUBLIC_ void set_rand_reseed_callback(void (*fn)(int *)) */ _PUBLIC_ void set_need_random_reseed(void) { - done_reseed = False; + done_reseed = false; } static void get_rand_reseed_data(int *reseed_data) @@ -156,7 +156,7 @@ static void do_filehash(const char *fname, unsigned char *the_hash) above... **************************************************************/ -static int do_reseed(BOOL use_fd, int fd) +static int do_reseed(bool use_fd, int fd) { unsigned char seed_inbuf[40]; uint32_t v1, v2; struct timeval tval; pid_t mypid; @@ -214,8 +214,8 @@ _PUBLIC_ void generate_random_buffer(uint8_t *out, int len) unsigned char *p; if(!done_reseed) { - urand_fd = do_reseed(True, urand_fd); - done_reseed = True; + urand_fd = do_reseed(true, urand_fd); + done_reseed = true; } if (urand_fd != -1 && len > 0) { @@ -226,8 +226,8 @@ _PUBLIC_ void generate_random_buffer(uint8_t *out, int len) /* Read of urand error, drop back to non urand method. */ close(urand_fd); urand_fd = -1; - do_reseed(False, -1); - done_reseed = True; + do_reseed(false, -1); + done_reseed = true; } /* @@ -263,7 +263,7 @@ _PUBLIC_ uint32_t generate_random(void) /** very basic password quality checker **/ -_PUBLIC_ BOOL check_password_quality(const char *s) +_PUBLIC_ bool check_password_quality(const char *s) { int has_digit=0, has_capital=0, has_lower=0, has_special=0, has_high=0; while (*s) { -- cgit From 6554433fc227baab93398576db703c91db1541f2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 16 Oct 2007 01:27:15 +0200 Subject: r25660: Add a new interface 'generate_secret_buffer()', to be used when we require top-quality entropy. We don't want to waste system enropy generating challenges (which simply need to be unpredictable, not secret) or when generating UUIDs. Rework generate_random_buffer() to use /dev/urandom less often, only to seed the existing RC4 based PRNG. (With an exception to ensure we don't waste this setup cost for very small entropy requests). Perhaps we should be using heimdal's code for this instead? This should drasticly reduce our entropy use, particularly in the build farm (automated Samba build on hosts without much other source of entropy). Andrew Bartlett (This used to be commit 6a5630d37191542022f02fae519227b7829ef620) --- source4/lib/util/genrand.c | 68 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 18 deletions(-) (limited to 'source4/lib/util/genrand.c') diff --git a/source4/lib/util/genrand.c b/source4/lib/util/genrand.c index 4d976cecf8..31c0fce633 100644 --- a/source4/lib/util/genrand.c +++ b/source4/lib/util/genrand.c @@ -33,6 +33,10 @@ static unsigned char hash[258]; static uint32_t counter; static bool done_reseed = false; +static unsigned int bytes_since_reseed = 0; + +static int urand_fd = -1; + static void (*reseed_callback)(int *newseed); /** @@ -51,6 +55,7 @@ _PUBLIC_ void set_rand_reseed_callback(void (*fn)(int *)) _PUBLIC_ void set_need_random_reseed(void) { done_reseed = false; + bytes_since_reseed = 0; } static void get_rand_reseed_data(int *reseed_data) @@ -163,12 +168,16 @@ static int do_reseed(bool use_fd, int fd) int reseed_data = 0; if (use_fd) { - if (fd != -1) - return fd; - - fd = open( "/dev/urandom", O_RDONLY,0); - if(fd >= 0) + if (fd == -1) { + fd = open( "/dev/urandom", O_RDONLY,0); + } + if (fd != -1 + && (read(fd, seed_inbuf, sizeof(seed_inbuf)) == sizeof(seed_inbuf))) { + DEBUG(0, ("do_reseed: need %d\n", sizeof(seed_inbuf))); + call_backtrace(); + seed_random_stream(seed_inbuf, sizeof(seed_inbuf)); return fd; + } } /* Add in some secret file contents */ @@ -205,28 +214,33 @@ static int do_reseed(bool use_fd, int fd) /** Interface to the (hopefully) good crypto random number generator. + Will use our internal PRNG if more than 40 bytes of random generation + has been requested, otherwise tries to read from /dev/random **/ _PUBLIC_ void generate_random_buffer(uint8_t *out, int len) { - static int urand_fd = -1; unsigned char md4_buf[64]; unsigned char tmp_buf[16]; unsigned char *p; if(!done_reseed) { - urand_fd = do_reseed(true, urand_fd); - done_reseed = true; - } - - if (urand_fd != -1 && len > 0) { - - if (read(urand_fd, out, len) == len) - return; /* len bytes of random data read from urandom. */ + bytes_since_reseed += len; + + /* Magic constant to try and avoid reading 40 bytes + * and setting up the PRNG if the app only ever wants + * a few bytes */ + if (bytes_since_reseed < 40) { + if (urand_fd == -1) { + urand_fd = open( "/dev/urandom", O_RDONLY,0); + } + DEBUG(0, ("generate_random_buffer: need %d\n", len)); + call_backtrace(); + if(urand_fd != -1 && (read(urand_fd, out, len) == len)) { + return; + } + } - /* Read of urand error, drop back to non urand method. */ - close(urand_fd); - urand_fd = -1; - do_reseed(false, -1); + urand_fd = do_reseed(true, urand_fd); done_reseed = true; } @@ -249,6 +263,24 @@ _PUBLIC_ void generate_random_buffer(uint8_t *out, int len) } } +/** + Interface to the (hopefully) good crypto random number generator. + Will always use /dev/urandom if available. +**/ +_PUBLIC_ void generate_secret_buffer(uint8_t *out, int len) +{ + if (urand_fd == -1) { + urand_fd = open( "/dev/urandom", O_RDONLY,0); + } + DEBUG(0, ("generate_random_buffer: need %d\n", len)); + call_backtrace(); + if(urand_fd != -1 && (read(urand_fd, out, len) == len)) { + return; + } + + generate_random_buffer(out, len); +} + /** generate a single random uint32_t **/ -- cgit From e19d281cb74054baf017f710ecb83d461e4a0971 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 16 Oct 2007 05:26:15 +0200 Subject: r25661: We don't actually need to know with DEBUG(0, ... every time we ask for some random bytes. Andrew Bartlett (This used to be commit 606c82f6254b8dc6fb32740a7bb55a1989081fe7) --- source4/lib/util/genrand.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source4/lib/util/genrand.c') diff --git a/source4/lib/util/genrand.c b/source4/lib/util/genrand.c index 31c0fce633..5751db23d6 100644 --- a/source4/lib/util/genrand.c +++ b/source4/lib/util/genrand.c @@ -173,8 +173,6 @@ static int do_reseed(bool use_fd, int fd) } if (fd != -1 && (read(fd, seed_inbuf, sizeof(seed_inbuf)) == sizeof(seed_inbuf))) { - DEBUG(0, ("do_reseed: need %d\n", sizeof(seed_inbuf))); - call_backtrace(); seed_random_stream(seed_inbuf, sizeof(seed_inbuf)); return fd; } @@ -233,8 +231,6 @@ _PUBLIC_ void generate_random_buffer(uint8_t *out, int len) if (urand_fd == -1) { urand_fd = open( "/dev/urandom", O_RDONLY,0); } - DEBUG(0, ("generate_random_buffer: need %d\n", len)); - call_backtrace(); if(urand_fd != -1 && (read(urand_fd, out, len) == len)) { return; } @@ -272,8 +268,6 @@ _PUBLIC_ void generate_secret_buffer(uint8_t *out, int len) if (urand_fd == -1) { urand_fd = open( "/dev/urandom", O_RDONLY,0); } - DEBUG(0, ("generate_random_buffer: need %d\n", len)); - call_backtrace(); if(urand_fd != -1 && (read(urand_fd, out, len) == len)) { return; } -- cgit From 7fd96c5b04177a412d9ef12b2f4620b587fe8ed6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 1 Apr 2008 15:17:18 +0200 Subject: Add userdata argument to reseed callback function. (This used to be commit d4272bc6bcfcd71fa93edb25bb33d6458e8b33cd) --- source4/lib/util/genrand.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/lib/util/genrand.c') diff --git a/source4/lib/util/genrand.c b/source4/lib/util/genrand.c index 5751db23d6..7df4ec4e20 100644 --- a/source4/lib/util/genrand.c +++ b/source4/lib/util/genrand.c @@ -37,15 +37,17 @@ static unsigned int bytes_since_reseed = 0; static int urand_fd = -1; -static void (*reseed_callback)(int *newseed); +static void (*reseed_callback)(void *userdata, int *newseed); +static void *reseed_callback_userdata = NULL; /** Copy any user given reseed data. **/ -_PUBLIC_ void set_rand_reseed_callback(void (*fn)(int *)) +_PUBLIC_ void set_rand_reseed_callback(void (*fn)(void *, int *), void *userdata) { reseed_callback = fn; + reseed_callback_userdata = userdata; set_need_random_reseed(); } @@ -61,7 +63,7 @@ _PUBLIC_ void set_need_random_reseed(void) static void get_rand_reseed_data(int *reseed_data) { if (reseed_callback) { - reseed_callback(reseed_data); + reseed_callback(reseed_callback_userdata, reseed_data); } else { *reseed_data = 0; } -- cgit