entropy.c revision 0c27b3fe77ac1d5094ba3521e8142d9e7973133f
/*
* Copyright (C) 2000-2002, 2004, 2007, 2009, 2013, 2016 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* $Id: entropy.c,v 1.10 2009/01/18 23:48:14 tbox Exp $ */
/*
* This is the system dependent part of the ISC entropy API.
*/
#include <config.h>
#include <windows.h>
#include <wincrypt.h>
#include <process.h>
#include <io.h>
#include <share.h>
/*
* There is only one variable in the entropy data structures that is not
* system independent, but pulling the structure that uses it into this file
* ultimately means pulling several other independent structures here also to
* resolve their interdependencies. Thus only the problem variable's type
* is defined here.
*/
#define FILESOURCE_HANDLE_TYPE HCRYPTPROV
typedef struct {
int dummy;
#include "../entropy.c"
static unsigned int
unsigned char buf[128];
unsigned int added;
return (0);
added = 0;
while (desired > 0) {
goto out;
}
(unsigned int)ndesired,
(unsigned int)ndesired * 8);
}
out:
return (added);
}
/*
* Poll each source, trying to get data from it to stuff into the entropy
* pool.
*/
static void
unsigned int added;
unsigned int remaining;
unsigned int needed;
unsigned int nsource;
/*
* This logic is a little strange, so an explanation is in order.
*
* If needed is 0, it means we are being asked to "fill to whatever
* we think is best." This means that if we have at least a
* partially full pool (say, > 1/4th of the pool) we probably don't
* need to add anything.
*
* Also, we will check to see if the "pseudo" count is too high.
* If it is, try to mix in better data. Too high is currently
* defined as 1/4th of the pool.
*
* Next, if we are asked to add a specific bit of entropy, make
* certain that we will do so. Clamp how much we try to add to
* (DIGEST_SIZE * 8 < needed < POOLBITS - entropy).
*
* Note that if we are in a blocking mode, we will only try to
* get as much data as we need, not as much as we might want
* to build up.
*/
if (needed == 0) {
return;
} else {
}
/*
* In any case, clamp how much we need to how much we can add.
*/
/*
* But wait! If we're not yet initialized, we need at least
* THRESHOLD_BITS
* of randomness.
*/
/*
* Poll each file source to see if we can read anything useful from
* it. XXXMLG When where are multiple sources, we should keep a
* record of which one we last used so we can start from it (or the
* next one) to avoid letting some sources build up entropy while
* others are always drained.
*/
added = 0;
return;
}
/*
* Remember the first source so we can break if we have looped back to
* the beginning and still have nothing
*/
unsigned int got;
if (remaining == 0)
break;
got = 0;
}
/*
* Go again only if there's been progress and we've not
* gone back to the beginning
*/
goto again_file;
}
}
/*
* Here, if there are bits remaining to be had and we can block,
* check to see if we have a callback source. If so, call them.
*/
unsigned int got;
got = 0;
break;
}
/*
* Mark as initialized if we've added enough data.
*/
}
/*
* Requires "ent" be locked.
*/
static void
}
static void
}
/*
* The first time we just try to acquire the context
*/
if (!err){
(void)GetLastError();
ret = ISC_R_IOERROR;
goto errout;
}
goto closecontext;
}
/*
* From here down, no failures can occur.
*/
/*
* Hook it into the entropy system.
*/
return (ISC_R_SUCCESS);
return (ret);
}