random.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*++
  2. Copyright (c) 2015 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. random.c
  9. Abstract:
  10. This module implements kernel-wide entropy management.
  11. Author:
  12. Evan Green 14-Jan-2015
  13. Environment:
  14. Kernel
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include <minoca/kernel/kernel.h>
  20. #include <minoca/intrface/random.h>
  21. #include "kep.h"
  22. //
  23. // ---------------------------------------------------------------- Definitions
  24. //
  25. //
  26. // ------------------------------------------------------ Data Type Definitions
  27. //
  28. //
  29. // ----------------------------------------------- Internal Function Prototypes
  30. //
  31. VOID
  32. KepPseudoRandomInterfaceCallback (
  33. PVOID Context,
  34. PDEVICE Device,
  35. PVOID InterfaceBuffer,
  36. ULONG InterfaceBufferSize,
  37. BOOL Arrival
  38. );
  39. //
  40. // -------------------------------------------------------------------- Globals
  41. //
  42. //
  43. // Set this to TRUE to disable entropy gathering in the kernel. This is only
  44. // polled once during boot.
  45. //
  46. BOOL KeDisableEntropyGathering = FALSE;
  47. UUID KePseudoRandomInterfaceUuid = UUID_PSEUDO_RANDOM_SOURCE_INTERFACE;
  48. PINTERFACE_PSEUDO_RANDOM_SOURCE KePseudoRandomInterface;
  49. //
  50. // ------------------------------------------------------------------ Functions
  51. //
  52. KERNEL_API
  53. KSTATUS
  54. KeGetRandomBytes (
  55. PVOID Buffer,
  56. UINTN Size
  57. )
  58. /*++
  59. Routine Description:
  60. This routine returns pseudo-random bytes from the system's random source.
  61. Arguments:
  62. Buffer - Supplies a pointer where the random bytes will be returned on
  63. success.
  64. Size - Supplies the number of bytes of random data to get.
  65. Return Value:
  66. STATUS_SUCCESS on success.
  67. STATUS_NO_SUCH_DEVICE if no pseudo-random interface is present.
  68. --*/
  69. {
  70. PINTERFACE_PSEUDO_RANDOM_SOURCE Interface;
  71. Interface = KePseudoRandomInterface;
  72. if (Interface == NULL) {
  73. return STATUS_NO_SUCH_DEVICE;
  74. }
  75. Interface->GetBytes(Interface, Buffer, Size);
  76. return STATUS_SUCCESS;
  77. }
  78. KSTATUS
  79. KepInitializeEntropy (
  80. VOID
  81. )
  82. /*++
  83. Routine Description:
  84. This routine initializes the kernel's entropy support. It signs up for
  85. a pseudo-random generator source.
  86. Arguments:
  87. None.
  88. Return Value:
  89. Status code.
  90. --*/
  91. {
  92. KSTATUS Status;
  93. if (KeDisableEntropyGathering == FALSE) {
  94. Status = IoRegisterForInterfaceNotifications(
  95. &KePseudoRandomInterfaceUuid,
  96. KepPseudoRandomInterfaceCallback,
  97. NULL,
  98. NULL,
  99. TRUE);
  100. if (!KSUCCESS(Status)) {
  101. return Status;
  102. }
  103. }
  104. return STATUS_SUCCESS;
  105. }
  106. VOID
  107. KepAddTimePointEntropy (
  108. VOID
  109. )
  110. /*++
  111. Routine Description:
  112. This routine adds entropy in the form of a timestamp to the pseudo random
  113. interface, if one exists.
  114. Arguments:
  115. None.
  116. Return Value:
  117. None.
  118. --*/
  119. {
  120. PINTERFACE_PSEUDO_RANDOM_SOURCE Interface;
  121. Interface = KePseudoRandomInterface;
  122. if (Interface != NULL) {
  123. Interface->AddTimePointEntropy(Interface);
  124. }
  125. return;
  126. }
  127. //
  128. // --------------------------------------------------------- Internal Functions
  129. //
  130. VOID
  131. KepPseudoRandomInterfaceCallback (
  132. PVOID Context,
  133. PDEVICE Device,
  134. PVOID InterfaceBuffer,
  135. ULONG InterfaceBufferSize,
  136. BOOL Arrival
  137. )
  138. /*++
  139. Routine Description:
  140. This routine is called to notify listeners that an interface has arrived
  141. or departed.
  142. Arguments:
  143. Context - Supplies the caller's context pointer, supplied when the caller
  144. requested interface notifications.
  145. Device - Supplies a pointer to the device exposing or deleting the
  146. interface.
  147. InterfaceBuffer - Supplies a pointer to the interface buffer of the
  148. interface.
  149. InterfaceBufferSize - Supplies the buffer size.
  150. Arrival - Supplies TRUE if a new interface is arriving, or FALSE if an
  151. interface is departing.
  152. Return Value:
  153. None.
  154. --*/
  155. {
  156. ASSERT(InterfaceBufferSize == sizeof(INTERFACE_PSEUDO_RANDOM_SOURCE));
  157. if (Arrival != FALSE) {
  158. if (KePseudoRandomInterface == NULL) {
  159. KePseudoRandomInterface = InterfaceBuffer;
  160. }
  161. } else {
  162. if (InterfaceBuffer == KePseudoRandomInterface) {
  163. //
  164. // Pseudo-random interfaces aren't really expected to disappear.
  165. // This operation is not entirely safe, as there is no
  166. // synchronization with other processors that might be about to
  167. // use the interface.
  168. //
  169. ASSERT(FALSE);
  170. KePseudoRandomInterface = NULL;
  171. }
  172. }
  173. return;
  174. }