private static void Pbkdf2Core( ReadOnlySpan <byte> password, ReadOnlySpan <byte> salt, Span <byte> destination, int iterations, HashAlgorithmName hashAlgorithm) { Debug.Assert(hashAlgorithm.Name is not null); Debug.Assert(iterations > 0); if (destination.IsEmpty) { return; } Pbkdf2Implementation.Fill(password, salt, iterations, hashAlgorithm, destination); }
private static void Pbkdf2Core( ReadOnlySpan <char> password, ReadOnlySpan <byte> salt, Span <byte> destination, int iterations, HashAlgorithmName hashAlgorithm) { Debug.Assert(hashAlgorithm.Name is not null); Debug.Assert(iterations > 0); if (destination.IsEmpty) { return; } const int MaxPasswordStackSize = 256; byte[]? rentedPasswordBuffer = null; int maxEncodedSize = s_throwingUtf8Encoding.GetMaxByteCount(password.Length); Span <byte> passwordBuffer = maxEncodedSize > MaxPasswordStackSize ? (rentedPasswordBuffer = CryptoPool.Rent(maxEncodedSize)) : stackalloc byte[MaxPasswordStackSize]; int passwordBytesWritten = s_throwingUtf8Encoding.GetBytes(password, passwordBuffer); Span <byte> passwordBytes = passwordBuffer.Slice(0, passwordBytesWritten); try { Pbkdf2Implementation.Fill(passwordBytes, salt, iterations, hashAlgorithm, destination); } finally { CryptographicOperations.ZeroMemory(passwordBytes); } if (rentedPasswordBuffer is not null) { CryptoPool.Return(rentedPasswordBuffer, clearSize: 0); // manually cleared above. } }