123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- /*++
- Copyright (c) 2015 Minoca Corp.
- This file is licensed under the terms of the GNU General Public License
- version 3. Alternative licensing terms are available. Contact
- info@minocacorp.com for details. See the LICENSE file at the root of this
- project for complete licensing information.
- Module Name:
- random.c
- Abstract:
- This module implements kernel-wide entropy management.
- Author:
- Evan Green 14-Jan-2015
- Environment:
- Kernel
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include <minoca/kernel/kernel.h>
- #include <minoca/intrface/random.h>
- #include "kep.h"
- //
- // ---------------------------------------------------------------- Definitions
- //
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- VOID
- KepPseudoRandomInterfaceCallback (
- PVOID Context,
- PDEVICE Device,
- PVOID InterfaceBuffer,
- ULONG InterfaceBufferSize,
- BOOL Arrival
- );
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // Set this to TRUE to disable entropy gathering in the kernel. This is only
- // polled once during boot.
- //
- BOOL KeDisableEntropyGathering = FALSE;
- UUID KePseudoRandomInterfaceUuid = UUID_PSEUDO_RANDOM_SOURCE_INTERFACE;
- PINTERFACE_PSEUDO_RANDOM_SOURCE KePseudoRandomInterface;
- //
- // ------------------------------------------------------------------ Functions
- //
- KERNEL_API
- KSTATUS
- KeGetRandomBytes (
- PVOID Buffer,
- UINTN Size
- )
- /*++
- Routine Description:
- This routine returns pseudo-random bytes from the system's random source.
- Arguments:
- Buffer - Supplies a pointer where the random bytes will be returned on
- success.
- Size - Supplies the number of bytes of random data to get.
- Return Value:
- STATUS_SUCCESS on success.
- STATUS_NO_SUCH_DEVICE if no pseudo-random interface is present.
- --*/
- {
- PINTERFACE_PSEUDO_RANDOM_SOURCE Interface;
- Interface = KePseudoRandomInterface;
- if (Interface == NULL) {
- return STATUS_NO_SUCH_DEVICE;
- }
- Interface->GetBytes(Interface, Buffer, Size);
- return STATUS_SUCCESS;
- }
- KSTATUS
- KepInitializeEntropy (
- VOID
- )
- /*++
- Routine Description:
- This routine initializes the kernel's entropy support. It signs up for
- a pseudo-random generator source.
- Arguments:
- None.
- Return Value:
- Status code.
- --*/
- {
- KSTATUS Status;
- if (KeDisableEntropyGathering == FALSE) {
- Status = IoRegisterForInterfaceNotifications(
- &KePseudoRandomInterfaceUuid,
- KepPseudoRandomInterfaceCallback,
- NULL,
- NULL,
- TRUE);
- if (!KSUCCESS(Status)) {
- return Status;
- }
- }
- return STATUS_SUCCESS;
- }
- VOID
- KepAddTimePointEntropy (
- VOID
- )
- /*++
- Routine Description:
- This routine adds entropy in the form of a timestamp to the pseudo random
- interface, if one exists.
- Arguments:
- None.
- Return Value:
- None.
- --*/
- {
- PINTERFACE_PSEUDO_RANDOM_SOURCE Interface;
- Interface = KePseudoRandomInterface;
- if (Interface != NULL) {
- Interface->AddTimePointEntropy(Interface);
- }
- return;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
- VOID
- KepPseudoRandomInterfaceCallback (
- PVOID Context,
- PDEVICE Device,
- PVOID InterfaceBuffer,
- ULONG InterfaceBufferSize,
- BOOL Arrival
- )
- /*++
- Routine Description:
- This routine is called to notify listeners that an interface has arrived
- or departed.
- Arguments:
- Context - Supplies the caller's context pointer, supplied when the caller
- requested interface notifications.
- Device - Supplies a pointer to the device exposing or deleting the
- interface.
- InterfaceBuffer - Supplies a pointer to the interface buffer of the
- interface.
- InterfaceBufferSize - Supplies the buffer size.
- Arrival - Supplies TRUE if a new interface is arriving, or FALSE if an
- interface is departing.
- Return Value:
- None.
- --*/
- {
- ASSERT(InterfaceBufferSize == sizeof(INTERFACE_PSEUDO_RANDOM_SOURCE));
- if (Arrival != FALSE) {
- if (KePseudoRandomInterface == NULL) {
- KePseudoRandomInterface = InterfaceBuffer;
- }
- } else {
- if (InterfaceBuffer == KePseudoRandomInterface) {
- //
- // Pseudo-random interfaces aren't really expected to disappear.
- // This operation is not entirely safe, as there is no
- // synchronization with other processors that might be about to
- // use the interface.
- //
- ASSERT(FALSE);
- KePseudoRandomInterface = NULL;
- }
- }
- return;
- }
|