]> granicus.if.org Git - nethack/commitdiff
some system-specific adjustments for RNG routines
authornhmall <nhmall@nethack.org>
Mon, 14 Jan 2019 01:54:11 +0000 (20:54 -0500)
committerPatric Mueller <bhaak@gmx.net>
Mon, 28 Jan 2019 09:02:08 +0000 (10:02 +0100)
move some system-specific seed-related stuff from hacklib.c to
a system-specific source file and #define SYS_RANDOM_SEED to
utilize it during build.

Windows changes for random seed generation using
crypto next gen (CNG) api routines.

Corresponding vms changes due to disentangling of VMS and
unix when the unix seed bits got moved (untested).

include/extern.h
include/integer.h
include/ntconf.h
include/unixconf.h
include/vmsconf.h
src/hacklib.c
src/rnd.c
sys/unix/unixmain.c
sys/vms/vmsmain.c
sys/winnt/Makefile.msc
sys/winnt/winnt.c

index 9bc4e5a244901a2c267d7b5bdc30e940b1a8d66d..24df9cd6ac2980e96985a5fe7158e616a3fc4405 100644 (file)
@@ -2106,6 +2106,7 @@ E void FDECL(genl_outrip, (winid, int, time_t));
 
 #ifdef USE_ISAAC64
 E void FDECL(init_isaac64, (unsigned long));
+E long NDECL(nhrand);
 #endif
 E int FDECL(rn2, (int));
 E int FDECL(rnl, (int));
index d340e4177b112a3e5bb586937fe4d4ba88eab9cc..9f16a592dfda74c761e204d2f6aa14cea18fae30 100644 (file)
@@ -8,37 +8,46 @@
 #define INTEGER_H
 
 #if defined(__STDC__) && __STDC_VERSION__ >= 199101L
-
 /* The compiler claims to conform to C99. Use stdint.h */
 #include <stdint.h>
-typedef uint8_t uint8;
-typedef int16_t int16;
-typedef uint16_t uint16;
-typedef int32_t int32;
-typedef uint32_t uint32;
-
-#else /* !C99 */
+#define SKIP_STDINT_WORKAROUND
+#else
+# if defined(HAS_STDINT_H)
+/* Some compilers have stdint.h but don't conform to all of C99. */
+#include <stdint.h>
+#define SKIP_STDINT_WORKAROUND
+# endif
+#endif
 
-/* Provide uint8, int16, uint16, int32 and uint32 */
-typedef unsigned char uint8;
-typedef short int16;
-typedef unsigned short uint16;
+#ifndef SKIP_STDINT_WORKAROUND /* !C99 */
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
 
 #if defined(__WATCOMC__) && !defined(__386__)
 /* Open Watcom providing a 16 bit build for MS-DOS or OS/2 */
 /* int is 16 bits; use long for 32 bits */
-typedef long int32;
-typedef unsigned long uint32;
+typedef long int32_t;
+typedef unsigned long uint32_t;
 #else
 /* Otherwise, assume either a 32- or 64-bit compiler */
 /* long may be 64 bits; use int for 32 bits */
-typedef int int32;
-typedef unsigned int uint32;
+typedef int int32_t;
+typedef unsigned int uint32_t;
 #endif
 
-typedef unsigned long uint32_t;
+typedef long long int64_t;
 typedef unsigned long long uint64_t;
 
 #endif /* !C99 */
 
+/* Provide uint8, int16, uint16, int32, uint32, int64 and uint64 */
+typedef uint8_t uint8;
+typedef int16_t int16;
+typedef uint16_t uint16;
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+
 #endif /* INTEGER_H */
index 6859d52b074342f8d3ef5ee459205b07c33922e2..b681680d26e44f2f74fa7b3cf51eab224116bccb 100644 (file)
@@ -7,7 +7,9 @@
 
 /* #define SHELL */    /* nt use of pcsys routines caused a hang */
 
-#define RANDOM    /* have Berkeley random(3) */
+/* #define RANDOM  */  /* have Berkeley random(3) */
+#define USE_ISAAC64
+
 #define TEXTCOLOR /* Color text */
 
 #define EXEPATH              /* Allow .exe location to be used as HACKDIR */
@@ -25,8 +27,7 @@
                         game */
 
 #define SYSCF                /* Use a global configuration */
-#define SYSCF_FILE "sysconf" /* Use a file to hold the SYSCF configuration \
-                                */
+#define SYSCF_FILE "sysconf" /* Use a file to hold the SYSCF configuration */
 
 #define DUMPLOG      /* Enable dumplog files */
 /*#define DUMPLOG_FILE "nethack-%n-%d.log"*/
@@ -35,9 +36,9 @@
 #define USER_SOUNDS
 
 /*#define CHANGE_COLOR*/ /* allow palette changes */
-#define SELECTSAVED /* Provide menu of saved games to choose from at start \
-                       */
+#define SELECTSAVED /* Provide menu of saved games to choose from at start */
 
+#define SYS_RANDOM_SEED  /* Use random seed derived from CNG */
 /*
  * -----------------------------------------------------------------
  *  The remaining code shouldn't need modification.
@@ -131,6 +132,7 @@ extern void FDECL(interject, (int));
 /* suppress a warning in cppregex.cpp */
 #pragma warning(disable : 4101) /* unreferenced local variable */
 #endif
+#define HAS_STDINT_H    /* force include of stdint.h in integer.h */
 #endif /* _MSC_VER */
 
 /* The following is needed for prototypes of certain functions */
index 3e4748ea2a2ee75bb08833062ecbe5e3d04a3068..e4c23cd8d8965d7272189eab5b749ff97623282a 100644 (file)
 #  define DEV_RANDOM "/dev/random"
 # endif
 #endif
+#define SYS_RANDOM_SEED
 
 #endif /* UNIXCONF_H */
 #endif /* UNIX */
index 7674e8558b52294fdecdf30576a3b6e4015292b2..dfee1cb42e2bc86fc3919e09402d0c2ec16cdf19 100644 (file)
@@ -255,6 +255,7 @@ typedef __mode_t mode_t;
 #else
 #define Rand() rand()
 #endif
+#define SYS_RANDOM_SEED
 
 #ifndef __GNUC__
 #ifndef bcopy
index 74a326efd88a1b5731aac1116ef9f27f0211b932..f70a4440ff826369508e6fe400c5344692498f29 100644 (file)
@@ -51,6 +51,8 @@
         boolean         fuzzymatch      (const char *, const char *,
                                          const char *, boolean)
         void            setrandom       (void)
+        void            init_random     (void)
+        void            reseed_random   (void)
         time_t          getnow          (void)
         int             getyear         (void)
         char *          yymmdd          (time_t)
@@ -848,34 +850,20 @@ extern struct tm *FDECL(localtime, (time_t *));
 #endif
 STATIC_DCL struct tm *NDECL(getlt);
 
+#ifdef SYS_RANDOM_SEED
+extern unsigned long NDECL(sys_random_seed);
+#endif
+
 /* Returns a number suitable as seed for the random number generator. */
 static unsigned long
 get_random_seed()
 {
     unsigned long seed = 0;
-#ifdef DEV_RANDOM
-    FILE *fptr = NULL;
-
-    fptr = fopen(DEV_RANDOM, "r");
-    if (fptr) {
-        fread(&seed, sizeof(long), 1, fptr);
-    }
-    fclose(fptr);
+#ifdef SYS_RANDOM_SEED
+    /* Platform-specific seed if one is provided */
+    seed = sys_random_seed();
 #else
     seed = (unsigned long) getnow(); /* time((TIME_type) 0) */
-
-# if defined(UNIX) || defined(VMS)
-    {
-        unsigned long pid = (unsigned long) getpid();
-
-        /* Quick dirty band-aid to prevent PRNG prediction */
-        if (pid) {
-            if (!(pid & 3L))
-                pid -= 1L;
-            seed *= pid;
-        }
-    }
-# endif
 #endif
     return seed;
 }
@@ -927,7 +915,7 @@ reseed_random()
 {
     /* only reseed if we are certain that the seed generation is unguessable
      * by the players. */
-#ifdef DEV_RANDOM
+#if defined(SYS_RANDOM_SEED)
     init_random();
 #endif
 }
index 9745d9ef25fa987b06b04bdac90c2fa73ffab16f..67f2e40125c2487330fe589e15dee4a18f82cb4a 100644 (file)
--- a/src/rnd.c
+++ b/src/rnd.c
@@ -27,6 +27,7 @@ RND(int x)
 {
     return (isaac64_next_uint64(&rng_state) % x);
 }
+
 #else
 /* "Rand()"s definition is determined by [OS]conf.h */
 #if defined(LINT) && defined(UNIX) /* rand() is long... */
index f798fa16394d9caace5da2b93928e87d7deb9597..ac6d3c2904d4bbdd7aaa6cadcceb558d0188bae8 100644 (file)
@@ -765,4 +765,31 @@ error:
 }
 #endif
 
+#ifdef SYS_RANDOM_SEED
+unsigned long
+sys_random_seed()
+{
+    unsigned long seed;
+    unsigned long pid = (unsigned long) getpid();
+#ifdef DEV_RANDOM
+    FILE *fptr = NULL;
+
+    fptr = fopen(DEV_RANDOM, "r");
+    if (fptr) {
+        fread(&seed, sizeof(long), 1, fptr);
+    }
+    fclose(fptr);
+#else
+    seed = (unsigned long) getnow(); /* time((TIME_type) 0) */
+    /* Quick dirty band-aid to prevent PRNG prediction */
+    if (pid) {
+        if (!(pid & 3L))
+            pid -= 1L;
+        seed *= pid;
+    }
+#endif
+    return seed;
+}
+#endif /* SYS_RANDOM_SEED */
+
 /*unixmain.c*/
index 75f321cb0ade5a23068b88c12853a57046f61948..b3be6e4d18397bb2d60a1cf00520d8c3aff0aeab 100644 (file)
@@ -465,4 +465,22 @@ wd_message()
         You("are in non-scoring explore/discovery mode.");
 }
 
+#ifdef SYS_RANDOM_SEED
+unsigned long
+sys_random_seed()
+{
+    unsigned long seed;
+    unsigned long pid = (unsigned long) getpid();
+
+    seed = (unsigned long) getnow(); /* time((TIME_type) 0) */
+    /* Quick dirty band-aid to prevent PRNG prediction */
+    if (pid) {
+        if (!(pid & 3L))
+            pid -= 1L;
+        seed *= pid;
+    }
+    return seed;
+}
+#endif
+
 /*vmsmain.c*/
index 6dcd10d4d96f54ef70739f530be8eb8696a41a0c..e41dcac05d4f38b257e4a54954f78a9b01f9aacf 100644 (file)
@@ -73,8 +73,8 @@ DEBUGINFO = Y
 #    PDCurses header (.h) files and PDCURSES_C to the location
 #    of your PDCurses C files.
 #
-#ADD_CURSES=Y
-#PDCURSES_TOP=..\..\pdcurses
+ADD_CURSES=Y
+PDCURSES_TOP=..\..\pdcurses
 #
 #==============================================================================
 # This marks the end of the BUILD DECISIONS section.
@@ -129,9 +129,13 @@ OBJ     = o
 # (see pcconf.h). Set to nothing if not used.
 #
 
-RANDOM = $(OBJ)\random.o
+RANDOM = $(OBJ)\isaac64.o
+#RANDOM        = $(OBJ)\random.o
 #RANDOM        =
-
+BCRYPT=
+! IF ("$(RANDOM)"=="$(OBJ)\isaac64.o")
+BCRYPT=bcrypt.lib
+! ENDIF
 WINPFLAG= -DTILES -DMSWIN_GRAPHICS -DWIN32CON
 
 # To store all the level files,
@@ -801,7 +805,7 @@ $(GAMEDIR)\NetHack.exe : $(O)gamedir.tag $(PDCLIB) $(O)tile.o $(O)nttty.o $(O)gu
        @if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR)
         @echo Linking $(@:\=/)
        $(link) $(lflagsBuild) $(conlflags) /STACK:2048 /PDB:$(GAMEDIR)\$(@B).PDB /MAP:$(O)$(@B).MAP \
-               $(LIBS) $(PDCLIB) $(conlibs) -out:$@ @<<$(@B).lnk
+               $(LIBS) $(PDCLIB) $(conlibs) $(BCRYPT) -out:$@ @<<$(@B).lnk
                $(GAMEOBJ)
                $(TTYOBJ)
                $(O)nttty.o
@@ -824,7 +828,7 @@ $(GAMEDIR)\NetHackW.exe : $(O)gamedir.tag $(O)tile.o $(O)ttystub.o \
        @if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR)
        @echo   Linking $(@:\=/)
        $(link) $(lflagsBuild) $(guilflags) /STACK:2048 /PDB:$(GAMEDIR)\$(@B).PDB \
-               /MAP:$(O)$(@B).MAP $(LIBS) $(PDCLIB) $(guilibs) $(COMCTRL) -out:$@ @<<$(@B).lnk
+               /MAP:$(O)$(@B).MAP $(LIBS) $(PDCLIB) $(guilibs) $(COMCTRL) $(BCRYPT) -out:$@ @<<$(@B).lnk
                $(GAMEOBJ)
                $(GUIOBJ)
                $(O)tile.o
@@ -1514,6 +1518,8 @@ $(O)tos.o: ..\sys\atari\tos.c $(HACK_H) $(INCL)\tcap.h
        @$(CC) $(cflagsBuild) -Fo$@ ..\sys\atari\tos.c
 $(O)pctty.o: ..\sys\share\pctty.c $(HACK_H)
        @$(CC) $(cflagsBuild) -Fo$@ ..\sys\share\pctty.c
+$(O)isaac64.o: ..\src\isaac64.c $(HACK_H) $(INCL)\isaac64.h $(INCL)\integer.h
+       @$(CC) $(cflagsBuild) -Fo$@ ..\src\isaac64.c
 $(O)random.o: ..\sys\share\random.c $(HACK_H)
        @$(CC) $(cflagsBuild) -Fo$@ ..\sys\share\random.c
 $(O)ioctl.o: ..\sys\share\ioctl.c $(HACK_H) $(INCL)\tcap.h
index 035ea7457007f80fe447b17e45e08d8f2c15c02d..b1f5b2b4dd0c81dda7de1004e76b8f3dcc5a8e55 100644 (file)
@@ -680,6 +680,55 @@ char *name;
     }
     return;
 }
+
+#ifdef SYS_RANDOM_SEED
+#ifndef STATUS_SUCCESS
+#define STATUS_SUCCESS 0
+#endif
+#ifndef STATUS_NOT_FOUND
+#define STATUS_NOT_FOUND 0xC0000225
+#endif
+#ifndef STATUS_UNSUCCESSFUL
+#define STATUS_UNSUCCESSFUL 0xC0000001
+#endif
+
+#include <bcrypt.h>     /* Windows Crypto Next Gen (CNG) */
+
+unsigned long
+sys_random_seed(VOID_ARGS)
+{
+    unsigned long ourseed = 0UL;
+    BCRYPT_ALG_HANDLE hRa = (BCRYPT_ALG_HANDLE) 0;
+    NTSTATUS status = STATUS_UNSUCCESSFUL;
+    boolean Plan_B = TRUE;
+
+    status = BCryptOpenAlgorithmProvider(&hRa, BCRYPT_RNG_ALGORITHM,
+                                         (LPCWSTR) 0, 0);
+    if (hRa && status == STATUS_SUCCESS) {
+        status = BCryptGenRandom(hRa, (PUCHAR) &ourseed,
+                                 (ULONG) sizeof ourseed, 0);
+        if (status == STATUS_SUCCESS) {
+            BCryptCloseAlgorithmProvider(hRa,0);
+            Plan_B = FALSE;
+        }
+    }
+
+    if (Plan_B) {
+        time_t datetime = 0;
+        const char *emsg;
+
+        if (status == STATUS_NOT_FOUND)
+            emsg = "BCRYPT_RNG_ALGORITHM not avail, falling back";
+        else
+            emsg = "Other failure than algorithm not avail";
+        paniclog("sys_random_seed", emsg); /* leaves clue, doesn't exit */
+        (void) time(&datetime);
+        ourseed = (unsigned long) datetime;
+    }
+    return ourseed;
+}
+#endif /* SYS_RANDOM_SEED */
+
 #endif /* WIN32 */
 
 /*winnt.c*/