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