From 9bfa90768ab83ea5a8571c98d3774377da4bdcbe Mon Sep 17 00:00:00 2001 From: David Lawrence Date: Fri, 22 Jun 2001 17:05:54 +0000 Subject: [PATCH] 907. [func] The ability to get entropy from either the random device, a user-provided file or from the keyboard was migrated from the DNSSEC tools to libisc as isc_entropy_usebestsource(). --- CHANGES | 5 ++ bin/dnssec/dnssectool.c | 101 ++------------------------- lib/isc/entropy.c | 127 +++++++++++++++++++++++++++++++++- lib/isc/include/isc/entropy.h | 56 ++++++++++++++- 4 files changed, 190 insertions(+), 99 deletions(-) diff --git a/CHANGES b/CHANGES index f99ea121e7..0363e81f60 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,9 @@ + 907. [func] The ability to get entropy from either the + random device, a user-provided file or from + the keyboard was migrated from the DNSSEC tools + to libisc as isc_entropy_usebestsource(). + 906. [port] Separated the system independent portion of lib/isc/unix/entropy.c into lib/isc/entropy.c and added lib/isc/win32/entropy.c. diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c index f368e8ddcb..ab271da786 100644 --- a/bin/dnssec/dnssectool.c +++ b/bin/dnssec/dnssectool.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssectool.c,v 1.29 2001/06/08 22:07:16 tale Exp $ */ +/* $Id: dnssectool.c,v 1.30 2001/06/22 17:05:54 tale Exp $ */ #include @@ -43,8 +43,6 @@ extern int verbose; extern const char *program; static isc_entropysource_t *source = NULL; -static isc_keyboard_t kbd; -static isc_boolean_t wantkeyboard = ISC_FALSE; static fatalcallback_t *fatalcallback = NULL; void @@ -201,73 +199,6 @@ cleanup_logging(isc_log_t **logp) { logp = NULL; } -static isc_result_t -kbdstart(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) { - isc_keyboard_t *kbd = (isc_keyboard_t *)arg; - static isc_boolean_t first = ISC_TRUE; - - UNUSED(source); - - if (!blocking) - return (ISC_R_NOENTROPY); - if (first) { - if (!wantkeyboard) { - fprintf(stderr, "You must use the keyboard to create " - "entropy, since your system is lacking\n"); - fprintf(stderr, "/dev/random (or equivalent)\n\n"); - } - first = ISC_FALSE; - } - fprintf(stderr, "start typing:\n"); - return (isc_keyboard_open(kbd)); -} - -static void -kbdstop(isc_entropysource_t *source, void *arg) { - isc_keyboard_t *kbd = (isc_keyboard_t *)arg; - - UNUSED(source); - - if (!isc_keyboard_canceled(kbd)) - fprintf(stderr, "stop typing.\r\n"); - (void)isc_keyboard_close(kbd, 3); -} - -static isc_result_t -kbdget(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) { - isc_keyboard_t *kbd = (isc_keyboard_t *)arg; - isc_result_t result; - isc_time_t t; - isc_uint32_t sample; - isc_uint32_t extra; - unsigned char c; - - if (!blocking) - return (ISC_R_NOTBLOCKING); - - result = isc_keyboard_getchar(kbd, &c); - if (result != ISC_R_SUCCESS) - return (result); - - result = isc_time_now(&t); - if (result != ISC_R_SUCCESS) - return (result); - - sample = isc_time_nanoseconds(&t); - extra = c; - - result = isc_entropy_addcallbacksample(source, sample, extra); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "\r\n"); - return (result); - } - - fprintf(stderr, "."); - fflush(stderr); - - return (result); -} - void setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) { isc_result_t result; @@ -276,32 +207,12 @@ setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) { if (result != ISC_R_SUCCESS) fatal("could not create entropy object"); -#ifdef PATH_RANDOMDEV - if (randomfile == NULL) { - result = isc_entropy_createfilesource(*ectx, PATH_RANDOMDEV); - if (result == ISC_R_SUCCESS) - return; - } -#endif + result = isc_entropy_usebestsource(*ectx, &source, randomfile, + ISC_ENTROPY_KEYBOARDMAYBE); - if (randomfile != NULL && strcasecmp(randomfile, "keyboard") == 0) { - wantkeyboard = ISC_TRUE; - randomfile = NULL; - } - - if (randomfile != NULL) { - result = isc_entropy_createfilesource(*ectx, randomfile); - if (result != ISC_R_SUCCESS) - fatal("could not open randomdev %s: %s", randomfile, - isc_result_totext(result)); - } else { - result = isc_entropy_createcallbacksource(*ectx, kbdstart, - kbdget, kbdstop, - &kbd, &source); - if (result != ISC_R_SUCCESS) - fatal("failed to open keyboard: %s\n", - isc_result_totext(result)); - } + if (result != ISC_R_SUCCESS) + fatal("could not initialize entropy source: %s", + isc_result_totext(result)); } void diff --git a/lib/isc/entropy.c b/lib/isc/entropy.c index c45542040d..82ed9f6458 100644 --- a/lib/isc/entropy.c +++ b/lib/isc/entropy.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: entropy.c,v 1.1 2001/06/21 14:19:18 tale Exp $ */ +/* $Id: entropy.c,v 1.2 2001/06/22 17:05:52 tale Exp $ */ /* * This is the system independent part of the entropy module. It is @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -141,6 +142,8 @@ struct isc_entropysource { ISC_LINK(isc_entropysource_t) link; char name[32]; isc_boolean_t bad; + isc_boolean_t warn_keyboard; + isc_keyboard_t kbd; union { isc_entropysamplesource_t sample; isc_entropyfilesource_t file; @@ -1119,3 +1122,125 @@ isc_entropy_detach(isc_entropy_t **entp) { if (killit) destroy(&ent); } + +static isc_result_t +kbdstart(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) { + /* + * The intent of "first" is to provide a warning message only once + * during the run of a program that might try to gather keyboard + * entropy multiple times. + */ + static isc_boolean_t first = ISC_TRUE; + + UNUSED(arg); + + if (! blocking) + return (ISC_R_NOENTROPY); + + if (first) { + if (source->warn_keyboard) + fprintf(stderr, "You must use the keyboard to create " + "entropy, since your system is lacking\n" + "/dev/random (or equivalent)\n\n"); + first = ISC_FALSE; + } + fprintf(stderr, "start typing:\n"); + + return (isc_keyboard_open(&source->kbd)); +} + +static void +kbdstop(isc_entropysource_t *source, void *arg) { + + UNUSED(arg); + + if (! isc_keyboard_canceled(&source->kbd)) + fprintf(stderr, "stop typing.\r\n"); + + (void)isc_keyboard_close(&source->kbd, 3); +} + +static isc_result_t +kbdget(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) { + isc_result_t result; + isc_time_t t; + isc_uint32_t sample; + isc_uint32_t extra; + unsigned char c; + + UNUSED(arg); + + if (!blocking) + return (ISC_R_NOTBLOCKING); + + result = isc_keyboard_getchar(&source->kbd, &c); + if (result != ISC_R_SUCCESS) + return (result); + + result = isc_time_now(&t); + if (result != ISC_R_SUCCESS) + return (result); + + sample = isc_time_nanoseconds(&t); + extra = c; + + result = isc_entropy_addcallbacksample(source, sample, extra); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "\r\n"); + return (result); + } + + fprintf(stderr, "."); + fflush(stderr); + + return (result); +} + +isc_result_t +isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source, + const char *randomfile, int use_keyboard) +{ + isc_result_t result; + isc_result_t final_result = ISC_R_NOENTROPY; + + REQUIRE(VALID_ENTROPY(ectx)); + REQUIRE(source != NULL && *source == NULL); + REQUIRE(use_keyboard == ISC_ENTROPY_KEYBOARDYES || + use_keyboard == ISC_ENTROPY_KEYBOARDNO || + use_keyboard == ISC_ENTROPY_KEYBOARDMAYBE); + +#ifdef PATH_RANDOMDEV + if (randomfile == NULL) + randomfile = PATH_RANDOMDEV; +#endif + + if (randomfile != NULL) { + result = isc_entropy_createfilesource(ectx, randomfile); + if (result == ISC_R_SUCCESS && + use_keyboard == ISC_ENTROPY_KEYBOARDMAYBE) + use_keyboard = ISC_ENTROPY_KEYBOARDNO; + + final_result = result; + } + + if (use_keyboard != ISC_ENTROPY_KEYBOARDNO) { + result = isc_entropy_createcallbacksource(ectx, kbdstart, + kbdget, kbdstop, + NULL, source); + if (result == ISC_R_SUCCESS) + (*source)->warn_keyboard = + ISC_TF(use_keyboard == + ISC_ENTROPY_KEYBOARDMAYBE); + + if (final_result != ISC_R_SUCCESS) + final_result = result; + } + + /* + * final_result is ISC_R_SUCCESS if at least one source of entropy + * could be started, otherwise it is the error from the most recently + * failed operation (or ISC_R_NOENTROPY if PATH_RANDOMDEV is not + * defined and use_keyboard is ISC_ENTROPY_KEYBOARDNO). + */ + return (final_result); +} diff --git a/lib/isc/include/isc/entropy.h b/lib/isc/include/isc/entropy.h index e4d4c66091..6e5688f555 100644 --- a/lib/isc/include/isc/entropy.h +++ b/lib/isc/include/isc/entropy.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: entropy.h,v 1.22 2001/01/09 21:56:50 bwelling Exp $ */ +/* $Id: entropy.h,v 1.23 2001/06/22 17:05:53 tale Exp $ */ #ifndef ISC_ENTROPY_H #define ISC_ENTROPY_H 1 @@ -63,8 +63,6 @@ #include #include -ISC_LANG_BEGINDECLS - /* * Entropy callback function. */ @@ -110,6 +108,23 @@ typedef void (*isc_entropystop_t)(isc_entropysource_t *source, void *arg); */ #define ISC_ENTROPYSOURCE_ESTIMATE 0x00000001U +/* + * For use with isc_entropy_usebestsource(). + * + * _KEYBOARDYES + * Always use the keyboard as an entropy source. + * _KEYBOARDNO + * Never use the keyboard as an entropy source. + * _KEYBOARDMAYBE + * Use the keyboard as an entropy source only if opening the + * random device or supplied filename fails. + */ +#define ISC_ENTROPY_KEYBOARDYES 1 +#define ISC_ENTROPY_KEYBOARDNO 2 +#define ISC_ENTROPY_KEYBOARDMAYBE 3 + +ISC_LANG_BEGINDECLS + /*** *** Functions ***/ @@ -233,6 +248,41 @@ isc_entropy_stats(isc_entropy_t *ent, FILE *out); * Dump some (trivial) stats to the stdio stream "out". */ +isc_result_t +isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source, + const char *randomfile, int use_keyboard); +/* + * Use whatever source of entropy is best. + * + * Notes: + * If "randomfile" is not NULL, open it with + * isc_entropy_createfilesource(). + * + * If "randomfile" is NULL and the system's random device was detected + * when the program was configured and built, open that device with + * isc_entropy_createfilesource(). + * + * If "use_keyboard" is ISC_ENTROPY_KEYBOARDYES, then always open + * the keyboard as an entropy source (possibly in addition to + * "randomfile" or the random device). + * + * If "use_keyboard" is ISC_ENTROPY_KEYBOARDMAYBE, open the keyboard only + * if opening the random file/device fails. A message will be + * printed describing the need for keyboard input. + * + * If "use_keyboard" is ISC_ENTROPY_KEYBOARDNO, the keyboard will + * never be opened. + * + * Returns: + * ISC_R_SUCCESS if at least one source of entropy could be started. + * + * ISC_R_NOENTROPY if use_keyboard is ISC_ENTROPY_KEYBOARDNO and + * there is no random device pathname compiled into the program. + * + * A return code from isc_entropy_createfilesource() or + * isc_entropy_createcallbacksource(). + */ + ISC_LANG_ENDDECLS #endif /* ISC_ENTROPY_H */