public static void Dispose() { if (s_instance != null) { s_instance.Dispose(); s_instance = null; } }
public static MemoryProtectionAction Generate() { if (s_instance == null) { s_instance = ChaCha20.Create(); } s_instance.GenerateKey(); var defaultKey = s_instance.Key; return((bytes, state, action) => { var mpb = (MemoryProtectedBytes)state; var key = defaultKey; // TODO: add ToBytes method that incorporates offset Span <byte> id = stackalloc byte[sizeof(long)]; BinaryPrimitives.TryWriteInt64LittleEndian(id, mpb.Id); var iv = ArrayPool <byte> .Shared.Rent(12); id.Slice(4).CopyTo(iv); try { var transform = action == MemoryProtectionActionType.Encrypt ? s_instance.CreateEncryptor(key, iv) : s_instance.CreateDecryptor(key, iv); var data = bytes.ToArray(); var result = transform.TransformFinalBlock(bytes.ToArray(), 0, bytes.Length); Array.Clear(data, 0, data.Length); return result; } finally { ArrayPool <byte> .Shared.Return(iv); } }); }