entropy.c revision f1b68725503ff3e46001eee5a1751e29a43a09d1
990d0e893f5b70e735cdf990af66e9ec6e91fa78Tinderbox User * Copyright (C) 2000, 2001 Internet Software Consortium.
3e02c9e33656dcd9c364633d42dd785d3e6fdd66Automatic Updater * Permission to use, copy, modify, and distribute this software for any
c6fb85f9500350e5ce58c9a24f5d264c8a8bd6f4Automatic Updater * purpose with or without fee is hereby granted, provided that the above
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * copyright notice and this permission notice appear in all copies.
3e02c9e33656dcd9c364633d42dd785d3e6fdd66Automatic Updater * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
3e02c9e33656dcd9c364633d42dd785d3e6fdd66Automatic Updater * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt/* $Id: entropy.c,v 1.4 2001/11/27 00:56:21 gson Exp $ */
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * This is the system depenedent part of the ISC entropy API.
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * There is only one variable in the entropy data structures that is not
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * system independent, but pulling the structure that uses it into this file
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater * ultimately means pulling several other independent structures here also to
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * resolve their interdependencies. Thus only the problem variable's type
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * is defined here.
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Huntstatic unsigned int
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Huntget_from_filesource(isc_entropysource_t *source, isc_uint32_t desired) {
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt HCRYPTPROV hcryptprov = source->sources.file.handle;
6f1205897504b8f50b1785975482c995888dd630Tinderbox User unsigned int added;
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt desired = desired / 8 + (((desired & 0x07) > 0) ? 1 : 0);
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt while (desired > 0) {
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt entropypool_adddata(ent, buf, ndesired, ndesired * 8);
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * Poll each source, trying to get data from it to stuff into the entropy
6f1205897504b8f50b1785975482c995888dd630Tinderbox Userfillpool(isc_entropy_t *ent, unsigned int desired, isc_boolean_t blocking) {
6f1205897504b8f50b1785975482c995888dd630Tinderbox User unsigned int added;
6f1205897504b8f50b1785975482c995888dd630Tinderbox User unsigned int needed;
6ea2385360e9e2167e65f9286447da9eea189457Tinderbox User * This logic is a little strange, so an explanation is in order.
6ea2385360e9e2167e65f9286447da9eea189457Tinderbox User * If needed is 0, it means we are being asked to "fill to whatever
6ea2385360e9e2167e65f9286447da9eea189457Tinderbox User * we think is best." This means that if we have at least a
6ea2385360e9e2167e65f9286447da9eea189457Tinderbox User * partially full pool (say, > 1/4th of the pool) we probably don't
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * need to add anything.
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * Also, we will check to see if the "pseudo" count is too high.
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * If it is, try to mix in better data. Too high is currently
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * defined as 1/4th of the pool.
12bfbed87cfffa65ac300b72c5665ab38a355c2fAutomatic Updater * Next, if we are asked to add a specific bit of entropy, make
12bfbed87cfffa65ac300b72c5665ab38a355c2fAutomatic Updater * certain that we will do so. Clamp how much we try to add to
12bfbed87cfffa65ac300b72c5665ab38a355c2fAutomatic Updater * (DIGEST_SIZE * 8 < needed < POOLBITS - entropy).
12bfbed87cfffa65ac300b72c5665ab38a355c2fAutomatic Updater * Note that if we are in a blocking mode, we will only try to
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * get as much data as we need, not as much as we might want
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * to build up.
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * In any case, clamp how much we need to how much we can add.
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt needed = ISC_MIN(needed, RND_POOLBITS - ent->pool.entropy);
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater * But wait! If we're not yet initialized, we need at least
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * THRESHOLD_BITS
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * of randomness.
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt needed = ISC_MAX(needed, THRESHOLD_BITS - ent->initialized);
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * Poll each file source to see if we can read anything useful from
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * it. XXXMLG When where are multiple sources, we should keep a
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * record of which one we last used so we can start from it (or the
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * next one) to avoid letting some sources build up entropy while
1bc5499c2a0fc5d2b11849e97cdd6305a64eb242Evan Hunt * others are always drained.
added = 0;
unsigned int got;
if (remaining == 0)
got = 0;
goto again_file;
unsigned int got;
got = 0;
if (!err){
goto errout;
goto closecontext;
return (ISC_R_SUCCESS);
return (ret);