lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: 16 Oct 2015 01:29:11 -0400 From: "George Spelvin" <linux@...izon.com> To: andi@...stfloor.org, tytso@....edu Cc: ahferroin7@...il.com, jepler@...ythonic.net, linux-kernel@...r.kernel.org, linux@...izon.com, linux@...musvillemoes.dk Subject: [RFC PATCH 1/4] random: Reduce stack usage in _xfer_secondary_pool Rather than asking extract_entropy to fill a large buffer, transfer bytes in EXTRACT_SIZE chunks using multiple calls to extract_buf. (Which is what extract_entropy does internally.) Signed-off-by: George Spelvin <linux@...izon.com> --- drivers/char/random.c | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index d0da5d85..c8ad49ba 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -964,8 +964,9 @@ EXPORT_SYMBOL_GPL(add_disk_randomness); * *********************************************************************/ -static ssize_t extract_entropy(struct entropy_store *r, void *buf, - size_t nbytes, int min, int rsvd); +static size_t account(struct entropy_store *r, size_t nbytes, int min, + int reserved); +static void extract_buf(struct entropy_store *r, __u8 out[EXTRACT_SIZE]); /* * This utility inline function is responsible for transferring entropy @@ -994,23 +995,46 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes) { - __u32 tmp[OUTPUT_POOL_WORDS]; - - /* For /dev/random's pool, always leave two wakeups' worth */ - int rsvd_bytes = r->limit ? 0 : random_read_wakeup_bits / 4; + u8 tmp[EXTRACT_SIZE]; int bytes = nbytes; /* pull at least as much as a wakeup */ bytes = max_t(int, bytes, random_read_wakeup_bits / 8); /* but never more than the buffer size */ - bytes = min_t(int, bytes, sizeof(tmp)); + bytes = min_t(int, bytes, OUTPUT_POOL_WORDS*sizeof(u32)); + /* + * FIXME: Move this to after account(), so it shows the true amount + * transferred? + */ trace_xfer_secondary_pool(r->name, bytes * 8, nbytes * 8, ENTROPY_BITS(r), ENTROPY_BITS(r->pull)); - bytes = extract_entropy(r->pull, tmp, bytes, - random_read_wakeup_bits / 8, rsvd_bytes); - mix_pool_bytes(r, tmp, bytes); - credit_entropy_bits(r, bytes*8); + + /* + * This is the only place we call account() with non-zero + * "min" and "reserved" values. The minimum is used to + * enforce catastrophic reseeding: if we can't get at least + * random_read_wakeup_bits of entropy, don't bother reseeding + * at all, but wait until a useful amount is available. + * + * The "reserved" is used to prevent reads from /dev/urandom + * from emptying the unput pool; leave two wakeups' worth + * for /dev/random. + */ + bytes = account(r->pull, bytes, random_read_wakeup_bits / 8, + r->limit ? 0 : random_read_wakeup_bits / 4); + + /* Now to the actual transfer, in EXTRACT_SIZE units */ + while (bytes) { + int i = min_t(int, bytes, EXTRACT_SIZE); + + extract_buf(r->pull, tmp); + mix_pool_bytes(r, tmp, i); + credit_entropy_bits(r, i*8); + bytes -= i; + } + + memzero_explicit(tmp, sizeof(tmp)); } /* @@ -1087,7 +1111,7 @@ retry: * * Note: we assume that .poolwords is a multiple of 16 words. */ -static void extract_buf(struct entropy_store *r, __u8 *out) +static void extract_buf(struct entropy_store *r, __u8 out[EXTRACT_SIZE]) { int i; union { -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists