[RFC PATCH] Prepare random/win32.c fast poll for 64-bit Windows

Jussi Kivilinna jussi.kivilinna at iki.fi
Sun Apr 26 14:37:35 CEST 2015


On 07.08.2013 10:59, Jussi Kivilinna wrote:
> * random/win32.c (_gcry_rndw32_gather_random_fast) [ADD]: Rename to
> ADDINT.
> (_gcry_rndw32_gather_random_fast): Add ADDPTR.
> (_gcry_rndw32_gather_random_fast): Disable entropy gathering from
> GetQueueStatus(QS_ALLEVENTS).
> (_gcry_rndw32_gather_random_fast): Change minimumWorkingSetSize and
> maximumWorkingSetSize to SIZE_T from DWORD.
> (_gcry_rndw32_gather_random_fast): Only add lower 32-bits of
> minimumWorkingSetSize and maximumWorkingSetSize to random poll.
> (_gcry_rndw32_gather_random_fast) [__WIN64__]: Read TSC directly
> using intrinsic.
> --
> 
> Introduce entropy gatherer changes related to 64-bit Windows platform as done
> in cryptlib fast poll:
>  - Change ADD macro to ADDPTR/ADDINT to handle pointer values. ADDPTR
>    discards high 32-bits of 64-bit pointer values.
>  - minimum/maximumWorkingSetSize changed to SIZE_T type to avoid stack
>    corruption on 64-bit; only low 32-bits are used for entropy.
>  - Use __rdtsc() intrinsic on 64-bit (as TSC is always available).
> 
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
> 
> --
> Would this be enough for 64-bit Windows support?
> 
> Slow poll differences cryptlib vs libgcrypt appear to be limited to sensor
> data reading from third party programs and reading of PnP data.

Any comments on this?

-Jussi

> ---
>  random/rndw32.c |   83 ++++++++++++++++++++++++++++++++++---------------------
>  1 file changed, 52 insertions(+), 31 deletions(-)
> 
> diff --git a/random/rndw32.c b/random/rndw32.c
> index 5c5d6c6..7e78b50 100644
> --- a/random/rndw32.c
> +++ b/random/rndw32.c
> @@ -826,39 +826,47 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
>       cursor position for last message, 1 ms time for last message,
>       handle of window with clipboard open, handle of process heap,
>       handle of procs window station, types of events in input queue,
> -     and milliseconds since Windows was started.  */
> +     and milliseconds since Windows was started. On 64-bit platform
> +     some of these return values are pointers and thus 64-bit wide.
> +     We discard the upper 32-bit of those values.  */
>  
>    {
>      byte buffer[20*sizeof(ulong)], *bufptr;
>  
>      bufptr = buffer;
> -#define ADD(f)  do { ulong along = (ulong)(f);                  \
> -                     memcpy (bufptr, &along, sizeof (along) );  \
> -                     bufptr += sizeof (along);                  \
> -                   } while (0)
> -
> -    ADD ( GetActiveWindow ());
> -    ADD ( GetCapture ());
> -    ADD ( GetClipboardOwner ());
> -    ADD ( GetClipboardViewer ());
> -    ADD ( GetCurrentProcess ());
> -    ADD ( GetCurrentProcessId ());
> -    ADD ( GetCurrentThread ());
> -    ADD ( GetCurrentThreadId ());
> -    ADD ( GetDesktopWindow ());
> -    ADD ( GetFocus ());
> -    ADD ( GetInputState ());
> -    ADD ( GetMessagePos ());
> -    ADD ( GetMessageTime ());
> -    ADD ( GetOpenClipboardWindow ());
> -    ADD ( GetProcessHeap ());
> -    ADD ( GetProcessWindowStation ());
> -    ADD ( GetQueueStatus (QS_ALLEVENTS));
> -    ADD ( GetTickCount ());
> +#define ADDINT(f)  do { ulong along = (ulong)(f);                  \
> +                        memcpy (bufptr, &along, sizeof (along) );  \
> +                        bufptr += sizeof (along);                  \
> +                      } while (0)
> +#define ADDPTR(f)  do { void *aptr = (f);                          \
> +                        ADDINT((SIZE_T)aptr);                      \
> +                      } while (0)
> +
> +    ADDPTR ( GetActiveWindow ());
> +    ADDPTR ( GetCapture ());
> +    ADDPTR ( GetClipboardOwner ());
> +    ADDPTR ( GetClipboardViewer ());
> +    ADDPTR ( GetCurrentProcess ());
> +    ADDINT ( GetCurrentProcessId ());
> +    ADDPTR ( GetCurrentThread ());
> +    ADDINT ( GetCurrentThreadId ());
> +    ADDPTR ( GetDesktopWindow ());
> +    ADDPTR ( GetFocus ());
> +    ADDINT ( GetInputState ());
> +    ADDINT ( GetMessagePos ());
> +    ADDINT ( GetMessageTime ());
> +    ADDPTR ( GetOpenClipboardWindow ());
> +    ADDPTR ( GetProcessHeap ());
> +    ADDPTR ( GetProcessWindowStation ());
> +    /* Following function in some cases stops returning events, and cannot
> +       be used as an entropy source.  */
> +    /*ADDINT ( GetQueueStatus (QS_ALLEVENTS));*/
> +    ADDINT ( GetTickCount ());
>  
>      gcry_assert ( bufptr-buffer < sizeof (buffer) );
>      (*add) ( buffer, bufptr-buffer, origin );
> -#undef ADD
> +#undef ADDINT
> +#undef ADDPTR
>    }
>  
>    /* Get multiword system information: Current caret position, current
> @@ -888,7 +896,7 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
>    {
>      HANDLE handle;
>      FILETIME creationTime, exitTime, kernelTime, userTime;
> -    DWORD minimumWorkingSetSize, maximumWorkingSetSize;
> +    SIZE_T minimumWorkingSetSize, maximumWorkingSetSize;
>  
>      handle = GetCurrentThread ();
>      GetThreadTimes (handle, &creationTime, &exitTime,
> @@ -910,10 +918,9 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
>         process.  */
>      GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
>                                &maximumWorkingSetSize);
> -    (*add) ( &minimumWorkingSetSize,
> -             sizeof (minimumWorkingSetSize), origin );
> -    (*add) ( &maximumWorkingSetSize,
> -             sizeof (maximumWorkingSetSize), origin );
> +    /* On 64-bit system, discard the high 32-bits. */
> +    (*add) ( &minimumWorkingSetSize, sizeof (int), origin );
> +    (*add) ( &maximumWorkingSetSize, sizeof (int), origin );
>    }
>  
>  
> @@ -961,7 +968,20 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
>  
>       To make things unambiguous, we detect a CPU new enough to call RDTSC
>       directly by checking for CPUID capabilities, and fall back to QPC if
> -     this isn't present.  */
> +     this isn't present.
> +
> +     On AMD64, TSC is always available and intrinsic is provided for accessing
> +     it.  */
> +#ifdef __WIN64__
> +    {
> +      unsigned __int64 aint64;
> +
> +      /* Note: cryptlib does not discard upper 32 bits of TSC on WIN64, but does
> +       * on WIN32.  Is this correct?  */
> +      aint64 = __rdtsc();
> +      (*add) (&aint64, sizeof(aint64), origin);
> +    }
> +#else
>  #ifdef __GNUC__
>  /*   FIXME: We would need to implement the CPU feature tests first.  */
>  /*   if (cpu_has_feature_rdtsc) */
> @@ -990,6 +1010,7 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
>            (*add) (&aword, sizeof (aword), origin );
>          }
>      }
> +#endif /*__WIN64__*/
>  
>  
>  }
> 
> 
> _______________________________________________
> Gcrypt-devel mailing list
> Gcrypt-devel at gnupg.org
> http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
> 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 648 bytes
Desc: OpenPGP digital signature
URL: </pipermail/attachments/20150426/456f0376/attachment.sig>


More information about the Gcrypt-devel mailing list