未验证 提交 a95da1bf 编写于 作者: K Kevin Jones 提交者: GitHub

Use HMAC one-shot where appropriate

上级 a82c357b
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
namespace System.Security.Cryptography
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "Weak algorithms are used as instructed by the caller")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5351", Justification = "Weak algorithms are used as instructed by the caller")]
internal static class HashOneShotHelpers
{
public static int MacData(
HashAlgorithmName hashAlgorithm,
ReadOnlySpan<byte> key,
ReadOnlySpan<byte> source,
Span<byte> destination)
{
if (hashAlgorithm == HashAlgorithmName.SHA256)
{
return HMACSHA256.HashData(key, source, destination);
}
else if (hashAlgorithm == HashAlgorithmName.SHA1)
{
return HMACSHA1.HashData(key, source, destination);
}
else if (hashAlgorithm == HashAlgorithmName.SHA512)
{
return HMACSHA512.HashData(key, source, destination);
}
else if (hashAlgorithm == HashAlgorithmName.SHA384)
{
return HMACSHA384.HashData(key, source, destination);
}
else if (hashAlgorithm == HashAlgorithmName.MD5)
{
return HMACMD5.HashData(key, source, destination);
}
throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name));
}
}
}
......@@ -126,6 +126,8 @@
Link="Common\System\Security\Cryptography\EccKeyFormatHelper.cs" />
<Compile Include="$(CommonPath)System\Security\Cryptography\KeyBlobHelpers.cs"
Link="Common\System\Security\Cryptography\KeyBlobHelpers.cs" />
<Compile Include="$(CommonPath)System\Security\Cryptography\HashOneShotHelpers.cs"
Link="Common\System\Security\Cryptography\HashOneShotHelpers.cs" />
<Compile Include="$(CommonPath)System\Security\Cryptography\KeyFormatHelper.cs"
Link="Common\System\Security\Cryptography\KeyFormatHelper.cs" />
<Compile Include="$(CommonPath)System\Security\Cryptography\KeySizeHelpers.cs"
......
......@@ -67,12 +67,8 @@ public static int Extract(HashAlgorithmName hashAlgorithmName, ReadOnlySpan<byte
private static void Extract(HashAlgorithmName hashAlgorithmName, int hashLength, ReadOnlySpan<byte> ikm, ReadOnlySpan<byte> salt, Span<byte> prk)
{
Debug.Assert(HashLength(hashAlgorithmName) == hashLength);
using (IncrementalHash hmac = IncrementalHash.CreateHMAC(hashAlgorithmName, salt))
{
hmac.AppendData(ikm);
GetHashAndReset(hmac, prk);
}
int written = HashOneShotHelpers.MacData(hashAlgorithmName, salt, ikm, prk);
Debug.Assert(written == prk.Length, $"Bytes written is {written} bytes which does not match output length ({prk.Length} bytes)");
}
/// <summary>
......
......@@ -475,44 +475,35 @@ private static ArraySegment<byte> EncodeKeys(AsnWriter tmpWriter, SafeBagAsn[] k
return new ArraySegment<byte>(authSafe, 0, authSafeLength);
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "HMACSHA1 is required for compat with other platforms")]
private static unsafe byte[] MacAndEncode(
AsnWriter tmpWriter,
ReadOnlyMemory<byte> encodedAuthSafe,
ReadOnlySpan<char> passwordSpan)
{
// Windows/macOS compatibility: Use HMAC-SHA-1,
// other algorithms may not be understood
byte[] macKey = new byte[20];
Span<byte> macSalt = stackalloc byte[20];
Span<byte> macSpan = stackalloc byte[20];
HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA1;
const int MacSize = 160 / 8; // HMAC-SHA1 is 160 bits.
Span<byte> macKey = stackalloc byte[MacSize];
Span<byte> macSalt = stackalloc byte[MacSize];
Span<byte> macSpan = stackalloc byte[MacSize];
RandomNumberGenerator.Fill(macSalt);
fixed (byte* macKeyPtr = macKey)
{
Span<byte> macKeySpan = macKey;
Pkcs12Kdf.DeriveMacKey(
passwordSpan,
hashAlgorithm,
s_windowsPbe.IterationCount,
macSalt,
macKeySpan);
using (IncrementalHash mac = IncrementalHash.CreateHMAC(hashAlgorithm, macKey))
{
mac.AppendData(encodedAuthSafe.Span);
Pkcs12Kdf.DeriveMacKey(
passwordSpan,
HashAlgorithmName.SHA1,
s_windowsPbe.IterationCount,
macSalt,
macKey);
if (!mac.TryGetHashAndReset(macSpan, out int bytesWritten) || bytesWritten != macSpan.Length)
{
Debug.Fail($"TryGetHashAndReset wrote {bytesWritten} of {macSpan.Length} bytes");
throw new CryptographicException();
}
}
int bytesWritten = HMACSHA1.HashData(macKey, encodedAuthSafe.Span, macSpan);
CryptographicOperations.ZeroMemory(macKeySpan);
if (bytesWritten != MacSize)
{
Debug.Fail($"HMACSHA1.HashData wrote {bytesWritten} of {MacSize} bytes");
throw new CryptographicException();
}
CryptographicOperations.ZeroMemory(macKey);
// https://tools.ietf.org/html/rfc7292#section-4
//
// PFX ::= SEQUENCE {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册