public static Task <byte[]> Get32()
 {
     return(Task.Run(() =>
     {
         var entropy = GetLongsForDigest();
         var digest = ByteArrayHelpers.LongsToDigestBytes(entropy.ToArray());
         return digest;
     }));
 }
Exemple #2
0
        protected override Task <byte[]> GetInternalEntropyAsync(EntropyPriority priority)
        {
            // This reads details of all processes running on the system, and uses them as inputs to a hash for final result.
            // Often, different properties or processes will throw exceptions.
            // Given this isn't trivial work, we run in a separate threadpool task.

            return(Task.Run(() =>
            {
                Log.Trace("Beginning to gather entropy.");
                var ps = Process.GetProcesses();        // TODO: assert we can do this during initialisation?
                Log.Trace("Found {0:N0} processes.", ps.Length);

                var processStats = new long[ps.Length * _ItemsPerProcess];

                // Read details from all processes.
                // PERF: This takes several seconds, which isn't helped by the fact a large number of these will throw exceptions when not running as admin.
                for (int i = 0; i < ps.Length; i++)
                {
                    var p = ps[i];
                    processStats[(i * _ItemsPerProcess) + 0] = p.TryAndIgnoreException(x => x.Id);
                    processStats[(i * _ItemsPerProcess) + 1] = p.TryAndIgnoreException(x => x.MainWindowHandle.ToInt64());
                    processStats[(i * _ItemsPerProcess) + 2] = p.TryAndIgnoreException(x => x.MaxWorkingSet.ToInt64());
                    processStats[(i * _ItemsPerProcess) + 3] = p.TryAndIgnoreException(x => x.NonpagedSystemMemorySize64);
                    processStats[(i * _ItemsPerProcess) + 4] = p.TryAndIgnoreException(x => x.PagedMemorySize64);
                    processStats[(i * _ItemsPerProcess) + 5] = p.TryAndIgnoreException(x => x.PagedSystemMemorySize64);
                    processStats[(i * _ItemsPerProcess) + 6] = p.TryAndIgnoreException(x => x.PeakPagedMemorySize64);
                    processStats[(i * _ItemsPerProcess) + 7] = p.TryAndIgnoreException(x => x.PeakVirtualMemorySize64);
                    processStats[(i * _ItemsPerProcess) + 8] = p.TryAndIgnoreException(x => x.PeakWorkingSet64);
                    processStats[(i * _ItemsPerProcess) + 9] = p.TryAndIgnoreException(x => x.PrivateMemorySize64);
                    processStats[(i * _ItemsPerProcess) + 10] = p.TryAndIgnoreException(x => x.WorkingSet64);
                    processStats[(i * _ItemsPerProcess) + 11] = p.TryAndIgnoreException(x => x.VirtualMemorySize64);
                    processStats[(i * _ItemsPerProcess) + 12] = p.TryAndIgnoreException(x => x.UserProcessorTime.Ticks);
                    processStats[(i * _ItemsPerProcess) + 13] = p.TryAndIgnoreException(x => x.TotalProcessorTime.Ticks);
                    processStats[(i * _ItemsPerProcess) + 14] = p.TryAndIgnoreException(x => x.PrivilegedProcessorTime.Ticks);
                    processStats[(i * _ItemsPerProcess) + 15] = p.TryAndIgnoreException(x => x.StartTime.Ticks);
                    processStats[(i * _ItemsPerProcess) + 16] = p.TryAndIgnoreException(x => x.HandleCount);
                }

                // Remove all zero items (to prevent silly things like a mostly, or all, zero hash result).
                var processStatsNoZero = processStats.Where(x => x != 0L).ToArray();
                Log.Trace("Read {0:N0} non-zero stat items.", processStatsNoZero.Length);
                if (LogRawStats)
                {
                    Log.Trace("Raw stats: ", processStatsNoZero.LongsToHexString());
                }

                // Shuffle the details, so there isn't a repetition of similar stats.
                processStatsNoZero.ShuffleInPlace(_Rng);

                // Get digests of the stats to return.
                var result = ByteArrayHelpers.LongsToDigestBytes(processStatsNoZero, _ItemsPerResultChunk);
                Log.Trace("Converted stats to {0:N0} bytes of entropy.", result.Length);

                return result;
            }));
        }
        protected override Task <byte[]> GetInternalEntropyAsync(EntropyPriority priority)
        {
            // This reads details of all network interfaces running on the system, and uses them as inputs to a hash for final result.
            // Given this isn't trivial work, we run in a separate threadpool task.

            return(Task.Run(() =>
            {
                Log.Trace("Beginning to gather entropy.");
                var ins = NetworkInterface.GetAllNetworkInterfaces();
                Log.Trace("Found {0:N0} interfaces.", ins.Length);

                // First result includes IP address, hardware address, etc.
                var allStats = new List <long>();
                if (!_HasRunOnce)
                {
                    Log.Trace("Including static properties on first run.");
                    allStats.AddRange(GetNetworkInterfaceStaticProperties(ins));
                    _HasRunOnce = true;
                }

                // After that, its just the number of packets, etc.
                foreach (var i in ins)
                {
                    // Most of these will be zero.
                    // Note that these can throw on some platforms, so we do a bunch of exception wrapping.
                    var stats = i.GetIPStatistics();
                    if (!_BytesReceivedFailed)
                    {
                        ExceptionHelper.TryAndIgnoreException(() => Uh.ToUnit(() => allStats.Add(stats.BytesReceived)), ref _BytesReceivedFailed);
                    }
                    if (!_BytesSentFailed)
                    {
                        ExceptionHelper.TryAndIgnoreException(() => Uh.ToUnit(() => allStats.Add(stats.BytesSent)), ref _BytesSentFailed);
                    }
                    if (!_IncomingPacketsDiscardedFailed)
                    {
                        ExceptionHelper.TryAndIgnoreException(() => Uh.ToUnit(() => allStats.Add(stats.IncomingPacketsDiscarded)), ref _IncomingPacketsDiscardedFailed);
                    }
                    if (!_IncomingPacketsWithErrorsFailed)
                    {
                        ExceptionHelper.TryAndIgnoreException(() => Uh.ToUnit(() => allStats.Add(stats.IncomingPacketsWithErrors)), ref _IncomingPacketsWithErrorsFailed);
                    }
                    if (!_IncomingUnknownProtocolPacketsFailed)
                    {
                        ExceptionHelper.TryAndIgnoreException(() => Uh.ToUnit(() => allStats.Add(stats.IncomingUnknownProtocolPackets)), ref _IncomingUnknownProtocolPacketsFailed);
                    }
                    if (!_NonUnicastPacketsReceivedFailed)
                    {
                        ExceptionHelper.TryAndIgnoreException(() => Uh.ToUnit(() => allStats.Add(stats.NonUnicastPacketsReceived)), ref _NonUnicastPacketsReceivedFailed);
                    }
                    if (!_NonUnicastPacketsSentFailed)
                    {
                        ExceptionHelper.TryAndIgnoreException(() => Uh.ToUnit(() => allStats.Add(stats.NonUnicastPacketsSent)), ref _NonUnicastPacketsSentFailed);
                    }
                    if (!_OutgoingPacketsDiscardedFailed)
                    {
                        ExceptionHelper.TryAndIgnoreException(() => Uh.ToUnit(() => allStats.Add(stats.OutgoingPacketsDiscarded)), ref _OutgoingPacketsDiscardedFailed);
                    }
                    if (!_OutgoingPacketsWithErrorsFailed)
                    {
                        ExceptionHelper.TryAndIgnoreException(() => Uh.ToUnit(() => allStats.Add(stats.OutgoingPacketsWithErrors)), ref _OutgoingPacketsWithErrorsFailed);
                    }
                    if (!_OutputQueueLengthFailed)
                    {
                        ExceptionHelper.TryAndIgnoreException(() => Uh.ToUnit(() => allStats.Add(stats.OutputQueueLength)), ref _OutputQueueLengthFailed);
                    }
                    if (!_UnicastPacketsReceivedFailed)
                    {
                        ExceptionHelper.TryAndIgnoreException(() => Uh.ToUnit(() => allStats.Add(stats.UnicastPacketsReceived)), ref _UnicastPacketsReceivedFailed);
                    }
                    if (!_UnicastPacketsSentFailed)
                    {
                        ExceptionHelper.TryAndIgnoreException(() => Uh.ToUnit(() => allStats.Add(stats.UnicastPacketsSent)), ref _UnicastPacketsSentFailed);
                    }

                    // Remaining lease duration.
                    if (!_AddressValidLifetimeFailed)
                    {
                        ExceptionHelper.TryAndIgnoreException(() => Uh.ToUnit(() =>
                        {
                            var props = i.GetIPProperties();
                            allStats.AddRange(props.UnicastAddresses.Select(x => x.AddressValidLifetime));
                        }), ref _AddressValidLifetimeFailed);
                    }
                }

                // Remove zeros and shuffle to prevent obvious correlations.
                var statsNoZero = allStats.Where(x => x != 0L).ToArray();
                Log.Trace("Read {0:N0} non-zero stat items.", statsNoZero.Length);
                if (LogRawStats)
                {
                    Log.Trace("Raw stats: ", statsNoZero.LongsToHexString());
                }

                // Shuffle the details, so there isn't a repetition of similar stats.
                statsNoZero.ShuffleInPlace(_Rng);

                // Convert to digest byte array to return.
                var result = ByteArrayHelpers.LongsToDigestBytes(statsNoZero, _ItemsPerResultChunk);
                Log.Trace("Converted stats to {0:N0} bytes of entropy.", result.Length);

                return result;
            }));
        }