Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
3.9 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: rng.c
  7. //
  8. // Contents: Random Number Generator
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 5-12-93 RichardW Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <security.h>
  21. #include <cryptdll.h>
  22. #include <windows.h>
  23. #include <randlib.h>
  24. #include <crypt.h>
  25. #ifdef KERNEL_MODE
  26. int _fltused = 0x9875;
  27. #endif
  28. #ifdef WIN32_CHICAGO
  29. NTSTATUS MyNtQuerySystemTime (PTimeStamp PTime);
  30. #define NtQuerySystemTime(x) (MyNtQuerySystemTime(x))
  31. #endif // WIN32_CHICAGO
  32. BOOLEAN NTAPI DefaultRngFn(PUCHAR, ULONG);
  33. #ifdef KERNEL_MODE
  34. #pragma alloc_text( PAGEMSG, DefaultRngFn )
  35. #endif
  36. #define MAX_RNGS 4
  37. RANDOM_NUMBER_GENERATOR Rngs[MAX_RNGS];
  38. ULONG cRngs = 0;
  39. RANDOM_NUMBER_GENERATOR DefaultRng = {CD_BUILTIN_RNG,
  40. RNG_PSEUDO_RANDOM,
  41. 0,
  42. DefaultRngFn };
  43. BOOLEAN NTAPI
  44. CDGenerateRandomBits( PUCHAR pBuffer,
  45. ULONG cbBuffer);
  46. BOOLEAN NTAPI
  47. CDRegisterRng(PRANDOM_NUMBER_GENERATOR pRng);
  48. BOOLEAN NTAPI
  49. CDLocateRng(ULONG Id,
  50. PRANDOM_NUMBER_GENERATOR * ppRng);
  51. BOOLEAN NTAPI
  52. DefaultRngFn( PUCHAR pbBuffer,
  53. ULONG cbBuffer);
  54. #ifdef KERNEL_MODE
  55. #pragma alloc_text( PAGEMSG, CDGenerateRandomBits )
  56. #pragma alloc_text( PAGEMSG, CDRegisterRng )
  57. #pragma alloc_text( PAGEMSG, CDLocateRng )
  58. #pragma alloc_text( PAGEMSG, DefaultRngFn )
  59. #endif
  60. //
  61. // Management functions:
  62. //
  63. BOOLEAN NTAPI
  64. CDGenerateRandomBits( PUCHAR pBuffer,
  65. ULONG cbBuffer)
  66. {
  67. return(Rngs[cRngs-1].GenerateBitstream(pBuffer, cbBuffer));
  68. }
  69. BOOLEAN NTAPI
  70. CDRegisterRng(PRANDOM_NUMBER_GENERATOR pRng)
  71. {
  72. if (cRngs < MAX_RNGS)
  73. {
  74. Rngs[cRngs++] = *pRng;
  75. return(TRUE);
  76. }
  77. return(FALSE);
  78. }
  79. BOOLEAN NTAPI
  80. CDLocateRng(ULONG Id,
  81. PRANDOM_NUMBER_GENERATOR * ppRng)
  82. {
  83. ULONG i;
  84. for (i = 0; i < MAX_RNGS ; i++ )
  85. {
  86. if (Rngs[i].GeneratorId == Id)
  87. {
  88. *ppRng = &Rngs[i];
  89. return(TRUE);
  90. }
  91. }
  92. *ppRng = NULL;
  93. return(FALSE);
  94. }
  95. #ifndef KERNEL_MODE
  96. #define RND_A 16807
  97. #define RND_M 2147483647
  98. #define RND_Q 127773
  99. #define RND_R 2836
  100. //+-----------------------------------------------------------------------
  101. //
  102. // Function: Random, private
  103. //
  104. // Synopsis: Generates a random number [0,1] based on a seed.
  105. //
  106. // Effects: Modifies seed parameter for multiple calls
  107. //
  108. // Arguments: [plSeed] -- Pointer to long seed value
  109. //
  110. // Returns: random number in the range [0,1]
  111. //
  112. // Algorithm: see CACM, Oct 1988
  113. //
  114. // History: 10 Dec 91 RichardW Created
  115. //
  116. //------------------------------------------------------------------------
  117. float
  118. Random(ULONG * plSeed)
  119. {
  120. long int lo, hi, test;
  121. hi = *plSeed / RND_Q;
  122. lo = *plSeed % RND_Q;
  123. test = RND_A * lo - RND_R * hi;
  124. if (test > 0)
  125. {
  126. *plSeed = test;
  127. } else
  128. {
  129. *plSeed = test + RND_M;
  130. }
  131. // This code is correct. The compiler has a conniption fit about floating
  132. // point constants, so I am forced to disable this warning for this line.
  133. #pragma warning(disable:4056)
  134. return((float) *plSeed / (float) RND_M);
  135. }
  136. #endif
  137. BOOLEAN NTAPI
  138. DefaultRngFn( PUCHAR pbBuffer,
  139. ULONG cbBuffer)
  140. {
  141. //
  142. // use the crypto group provided random number generator.
  143. //
  144. #ifdef WIN32_CHICAGO
  145. NewGenRandom(NULL, NULL, pbBuffer, cbBuffer);
  146. return TRUE;
  147. #else
  148. #ifdef KERNEL_MODE
  149. NewGenRandom(NULL, NULL, pbBuffer, cbBuffer);
  150. return TRUE;
  151. #else
  152. return RtlGenRandom( pbBuffer, cbBuffer );
  153. #endif
  154. #endif // WIN32_CHICAGO
  155. }