| File: System\Security\Cryptography\FixedMemoryKeyBox.cs | Web Access |
| Project: src\runtime\src\libraries\System.Security.Cryptography\src\System.Security.Cryptography.csproj (System.Security.Cryptography) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; namespace System.Security.Cryptography { internal sealed unsafe class FixedMemoryKeyBox : SafeHandle { private readonly int _length; internal FixedMemoryKeyBox(ReadOnlySpan<byte> key) : base(IntPtr.Zero, ownsHandle: true) { void* memory = NativeMemory.Alloc((nuint)key.Length); key.CopyTo(new Span<byte>(memory, key.Length)); SetHandle((IntPtr)memory); _length = key.Length; } internal ReadOnlySpan<byte> DangerousKeySpan => new ReadOnlySpan<byte>((void*)handle, _length); protected override bool ReleaseHandle() { CryptographicOperations.ZeroMemory(new Span<byte>((void*)handle, _length)); NativeMemory.Free((void*)handle); return true; } public override bool IsInvalid => handle == IntPtr.Zero; internal TRet UseKey<TState, TRet>( TState state, Func<TState, ReadOnlySpan<byte>, TRet> func) { bool addedRef = false; try { DangerousAddRef(ref addedRef); return func(state, DangerousKeySpan); } finally { if (addedRef) { DangerousRelease(); } } } internal TRet UseKey<TState, TRet>( ReadOnlySpan<byte> state1, TState state2, Func<ReadOnlySpan<byte>, TState, ReadOnlySpan<byte>, TRet> func) { bool addedRef = false; try { DangerousAddRef(ref addedRef); return func(state1, state2, DangerousKeySpan); } finally { if (addedRef) { DangerousRelease(); } } } } }