//------------------------------------------------------------------------------------------------------- // Copyright (C) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. //------------------------------------------------------------------------------------------------------- #include "RuntimeBasePch.h" const uint32 Entropy::kInitIterationCount = 3; void Entropy::BeginAdd() { previousValue = u.value; } void Entropy::AddCurrentTime() { LARGE_INTEGER time = {0}; QueryPerformanceCounter(&time); if (time.LowPart) u.value ^= time.LowPart; } void Entropy::Add(const char byteValue) { if (byteValue) { u.array[currentIndex++] ^= byteValue; currentIndex %= sizeof(unsigned __int32); } } /* public API */ void Entropy::Initialize() { for (uint32 times = 0; times < Entropy::kInitIterationCount; times++) { AddIoCounters(); AddThreadCycleTime(); } AddCurrentTime(); } void Entropy::Add(const char *buffer, size_t size) { BeginAdd(); for (size_t index = 0; index < size; index++) { Add(buffer[index]); } } void Entropy::AddIoCounters() { IO_COUNTERS ioc = {0}; if (GetProcessIoCounters(GetCurrentProcess(), &ioc)) { Add((char *)&ioc.ReadOperationCount, sizeof(ioc.ReadOperationCount)); Add((char *)&ioc.WriteOperationCount, sizeof(ioc.WriteOperationCount)); Add((char *)&ioc.OtherOperationCount, sizeof(ioc.OtherOperationCount)); Add((char *)&ioc.ReadTransferCount, sizeof(ioc.ReadTransferCount)); Add((char *)&ioc.WriteTransferCount, sizeof(ioc.WriteTransferCount)); Add((char *)&ioc.OtherTransferCount, sizeof(ioc.OtherTransferCount)); } AddCurrentTime(); } void Entropy::AddThreadCycleTime() { LARGE_INTEGER threadCycleTime = {0}; QueryThreadCycleTime(GetCurrentThread(), (PULONG64)&threadCycleTime); Add((char *)&threadCycleTime.LowPart, sizeof(threadCycleTime.LowPart)); AddCurrentTime(); } unsigned __int64 Entropy::GetRand() const { return (((unsigned __int64)previousValue) << 32) | u.value; }