XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Runtime.InteropServices;
using System.Security.Cryptography;

namespace XFESystem.NativeEntropy;

/// <summary>Native-only BC entropy port. There is no OpenSSL, host RNG or public-material fallback.</summary>
public static unsafe class NativeEntropy
{
    public const int MaximumRequestBytes = 1_048_576;
    [DllImport("xfe_pal", EntryPoint = "xfe_runtime_random_fill", CallingConvention = CallingConvention.Cdecl)]
    private static extern int FillNative(byte* destination, uint length);

    public static void Fill(Span<byte> destination)
    {
        if (destination.Length > MaximumRequestBytes) throw new ArgumentOutOfRangeException(nameof(destination));
        if (destination.IsEmpty) return;
        int result;
        try { fixed (byte* pointer = destination) result = FillNative(pointer, (uint)destination.Length); }
        catch { destination.Clear(); throw; }
        if (result != 1)
        {
            destination.Clear();
            throw new CryptographicException("The native hardware entropy source failed; no fallback is permitted.");
        }
    }
    public static RandomNumberGenerator Create() => new HardwareRandomNumberGenerator();
    private static void RequireHardware(RandomNumberGenerator source)
    {
        ArgumentNullException.ThrowIfNull(source);
        if (source is not HardwareRandomNumberGenerator)
            throw new CryptographicException("The native BC port only accepts its explicit hardware entropy provider.");
    }
    public static void GetBytes(RandomNumberGenerator source, byte[] destination)
    { RequireHardware(source); source.GetBytes(destination); }
    public static void GetBytes(RandomNumberGenerator source, byte[] destination, int offset, int count)
    { RequireHardware(source); source.GetBytes(destination, offset, count); }
    public static void GetBytes(RandomNumberGenerator source, Span<byte> destination)
    { RequireHardware(source); source.GetBytes(destination); }
    public static void Dispose(RandomNumberGenerator source)
    { RequireHardware(source); source.Dispose(); }

    // The base constructor has no OS initialization. All byte production uses
    // our checked native ABI; BCL RNGImplementation/OpenSSL is never instantiated.
    private sealed class HardwareRandomNumberGenerator : RandomNumberGenerator
    {
        private bool disposed;
        private void Check() => ObjectDisposedException.ThrowIf(disposed, this);
        public override void GetBytes(byte[] data)
        { Check(); ArgumentNullException.ThrowIfNull(data); Fill(data); }
        public override void GetBytes(byte[] data, int offset, int count)
        { Check(); ArgumentNullException.ThrowIfNull(data); Fill(data.AsSpan(offset, count)); }
        public override void GetBytes(Span<byte> data) { Check(); Fill(data); }
        protected override void Dispose(bool disposing) { disposed = true; base.Dispose(disposing); }
    }
}