1/*
2 * Copyright (C) 2004-2007, 2009  Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001  Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* $Id: entropy.h,v 1.35 2009/10/19 02:37:08 marka Exp $ */
19
20#ifndef ISC_ENTROPY_H
21#define ISC_ENTROPY_H 1
22
23/*****
24 ***** Module Info
25 *****/
26
27/*! \file isc/entropy.h
28 * \brief The entropy API
29 *
30 * \li MP:
31 *	The entropy object is locked internally.  All callbacks into
32 *	application-provided functions (for setup, gathering, and
33 *	shutdown of sources) are guaranteed to be called with the
34 *	entropy API lock held.  This means these functions are
35 *	not permitted to call back into the entropy API.
36 *
37 * \li Reliability:
38 *	No anticipated impact.
39 *
40 * \li Resources:
41 *	A buffer, used as an entropy pool.
42 *
43 * \li Security:
44 *	While this code is believed to implement good entropy gathering
45 *	and distribution, it has not been reviewed by a cryptographic
46 *	expert.
47 *	Since the added entropy is only as good as the sources used,
48 *	this module could hand out bad data and never know it.
49 *
50 * \li Standards:
51 *	None.
52 */
53
54/***
55 *** Imports
56 ***/
57
58#include <stdio.h>
59
60#include <isc/lang.h>
61#include <isc/types.h>
62
63/*@{*/
64/*% Entropy callback function. */
65typedef isc_result_t (*isc_entropystart_t)(isc_entropysource_t *source,
66					   void *arg, isc_boolean_t blocking);
67typedef isc_result_t (*isc_entropyget_t)(isc_entropysource_t *source,
68					 void *arg, isc_boolean_t blocking);
69typedef void (*isc_entropystop_t)(isc_entropysource_t *source, void *arg);
70/*@}*/
71
72/***
73 *** Flags.
74 ***/
75
76/*!
77 * \brief
78 *	Extract only "good" data; return failure if there is not enough
79 *	data available and there are no sources which we can poll to get
80 *	data, or those sources are empty.
81 *
82 *
83 */
84#define ISC_ENTROPY_GOODONLY	0x00000001U
85/*!
86 * \brief
87 *	Extract as much good data as possible, but if there isn't enough
88 *	at hand, return what is available.  This flag only makes sense
89 *	when used with _GOODONLY.
90 */
91#define ISC_ENTROPY_PARTIAL	0x00000002U
92/*!
93 * \brief
94 *	Block the task until data is available.  This is contrary to the
95 *	ISC task system, where tasks should never block.  However, if
96 *	this is a special purpose application where blocking a task is
97 *	acceptable (say, an offline zone signer) this flag may be set.
98 *	This flag only makes sense when used with _GOODONLY, and will
99 *	block regardless of the setting for _PARTIAL.
100 */
101#define ISC_ENTROPY_BLOCKING	0x00000004U
102
103/*!
104 * \brief
105 *	Estimate the amount of entropy contained in the sample pool.
106 *	If this is not set, the source will be gathered and periodically
107 *	mixed into the entropy pool, but no increment in contained entropy
108 *	will be assumed.  This flag only makes sense on sample sources.
109 */
110#define ISC_ENTROPYSOURCE_ESTIMATE	0x00000001U
111
112/*
113 * For use with isc_entropy_usebestsource().
114 */
115/*!
116 * \brief
117 *	Use the keyboard as the only entropy source.
118 */
119#define ISC_ENTROPY_KEYBOARDYES		1
120/*!
121 * \brief
122 *	Never use the keyboard as an entropy source.
123 */
124#define ISC_ENTROPY_KEYBOARDNO		2
125/*!
126 * \brief
127 *	Use the keyboard as an entropy source only if opening the
128 *	random device fails.
129 */
130#define ISC_ENTROPY_KEYBOARDMAYBE	3
131
132ISC_LANG_BEGINDECLS
133
134/***
135 *** Functions
136 ***/
137
138isc_result_t
139isc_entropy_create(isc_mem_t *mctx, isc_entropy_t **entp);
140/*!<
141 * \brief Create a new entropy object.
142 */
143
144void
145isc_entropy_attach(isc_entropy_t *ent, isc_entropy_t **entp);
146/*!<
147 * Attaches to an entropy object.
148 */
149
150void
151isc_entropy_detach(isc_entropy_t **entp);
152/*!<
153 * \brief Detaches from an entropy object.
154 */
155
156isc_result_t
157isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname);
158/*!<
159 * \brief Create a new entropy source from a file.
160 *
161 * The file is assumed to contain good randomness, and will be mixed directly
162 * into the pool with every byte adding 8 bits of entropy.
163 *
164 * The file will be put into non-blocking mode, so it may be a device file,
165 * such as /dev/random.  /dev/urandom should not be used here if it can
166 * be avoided, since it will always provide data even if it isn't good.
167 * We will make as much pseudorandom data as we need internally if our
168 * caller asks for it.
169 *
170 * If we hit end-of-file, we will stop reading from this source.  Callers
171 * who require strong random data will get failure when our pool drains.
172 * The file will never be opened/read again once EOF is reached.
173 */
174
175void
176isc_entropy_destroysource(isc_entropysource_t **sourcep);
177/*!<
178 * \brief Removes an entropy source from the entropy system.
179 */
180
181isc_result_t
182isc_entropy_createsamplesource(isc_entropy_t *ent,
183			       isc_entropysource_t **sourcep);
184/*!<
185 * \brief Create an entropy source that consists of samples.  Each sample is
186 * added to the source via isc_entropy_addsamples(), below.
187 */
188
189isc_result_t
190isc_entropy_createcallbacksource(isc_entropy_t *ent,
191				 isc_entropystart_t start,
192				 isc_entropyget_t get,
193				 isc_entropystop_t stop,
194				 void *arg,
195				 isc_entropysource_t **sourcep);
196/*!<
197 * \brief Create an entropy source that is polled via a callback.
198 *
199 * This would
200 * be used when keyboard input is used, or a GUI input method.  It can
201 * also be used to hook in any external entropy source.
202 *
203 * Samples are added via isc_entropy_addcallbacksample(), below.
204 * _addcallbacksample() is the only function which may be called from
205 * within an entropy API callback function.
206 */
207
208void
209isc_entropy_stopcallbacksources(isc_entropy_t *ent);
210/*!<
211 * \brief Call the stop functions for callback sources that have had their
212 * start functions called.
213 */
214
215/*@{*/
216isc_result_t
217isc_entropy_addcallbacksample(isc_entropysource_t *source, isc_uint32_t sample,
218			      isc_uint32_t extra);
219isc_result_t
220isc_entropy_addsample(isc_entropysource_t *source, isc_uint32_t sample,
221		      isc_uint32_t extra);
222/*!<
223 * \brief Add a sample to the sample source.
224 *
225 * The sample MUST be a timestamp
226 * that increases over time, with the exception of wrap-around for
227 * extremely high resolution timers which will quickly wrap-around
228 * a 32-bit integer.
229 *
230 * The "extra" parameter is used only to add a bit more unpredictable
231 * data.  It is not used other than included in the hash of samples.
232 *
233 * When in an entropy API callback function, _addcallbacksource() must be
234 * used.  At all other times, _addsample() must be used.
235 */
236/*@}*/
237
238isc_result_t
239isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length,
240		    unsigned int *returned, unsigned int flags);
241/*!<
242 * \brief Extract data from the entropy pool.  This may load the pool from various
243 * sources.
244 *
245 * Do this by stiring the pool and returning a part of hash as randomness.
246 * Note that no secrets are given away here since parts of the hash are
247 * xored together before returned.
248 *
249 * Honor the request from the caller to only return good data, any data,
250 * etc.
251 */
252
253void
254isc_entropy_putdata(isc_entropy_t *ent, void *data, unsigned int length,
255		    isc_uint32_t entropy);
256/*!<
257 * \brief Add "length" bytes in "data" to the entropy pool, incrementing the
258 * pool's entropy count by "entropy."
259 *
260 * These bytes will prime the pseudorandom portion even if no entropy is
261 * actually added.
262 */
263
264void
265isc_entropy_stats(isc_entropy_t *ent, FILE *out);
266/*!<
267 * \brief Dump some (trivial) stats to the stdio stream "out".
268 */
269
270unsigned int
271isc_entropy_status(isc_entropy_t *end);
272/*
273 * Returns the number of bits the pool currently contains.  This is just
274 * an estimate.
275 */
276
277isc_result_t
278isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source,
279			  const char *randomfile, int use_keyboard);
280/*!<
281 * \brief Use whatever source of entropy is best.
282 *
283 * Notes:
284 *\li	If "randomfile" is not NULL, open it with
285 *	isc_entropy_createfilesource().
286 *
287 *\li	If "randomfile" is NULL and the system's random device was detected
288 *	when the program was configured and built, open that device with
289 *	isc_entropy_createfilesource().
290 *
291 *\li	If "use_keyboard" is #ISC_ENTROPY_KEYBOARDYES, then always open
292 *	the keyboard as an entropy source (possibly in addition to
293 *	"randomfile" or the random device).
294 *
295 *\li	If "use_keyboard" is #ISC_ENTROPY_KEYBOARDMAYBE, open the keyboard only
296 *	if opening the random file/device fails.  A message will be
297 *	printed describing the need for keyboard input.
298 *
299 *\li	If "use_keyboard" is #ISC_ENTROPY_KEYBOARDNO, the keyboard will
300 *	never be opened.
301 *
302 * Returns:
303 *\li	#ISC_R_SUCCESS if at least one source of entropy could be started.
304 *
305 *\li	#ISC_R_NOENTROPY if use_keyboard is #ISC_ENTROPY_KEYBOARDNO and
306 *	there is no random device pathname compiled into the program.
307 *
308 *\li	A return code from isc_entropy_createfilesource() or
309 *	isc_entropy_createcallbacksource().
310 */
311
312ISC_LANG_ENDDECLS
313
314#endif /* ISC_ENTROPY_H */
315