Imported Upstream version 5.10.0.47

Former-commit-id: d0813289fa2d35e1f8ed77530acb4fb1df441bc0
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-01-24 17:04:36 +00:00
parent 88ff76fe28
commit e46a49ecf1
5927 changed files with 226314 additions and 129848 deletions

View File

@ -6,6 +6,5 @@
<AssemblyKey>MSFT</AssemblyKey>
<IsNETCoreApp>true</IsNETCoreApp>
<IsUAP>true</IsUAP>
<IsNetFxNETStandard>true</IsNetFxNETStandard>
</PropertyGroup>
</Project>

View File

@ -3,8 +3,6 @@
<PropertyGroup>
<BuildConfigurations>
netcoreapp;
netfx;
net47;
uap;
</BuildConfigurations>
</PropertyGroup>

View File

@ -5,18 +5,15 @@
<ProjectGuid>{102247C1-3DB9-4DB5-80B3-EE9F80DD4E8F}</ProjectGuid>
<IsPartialFacadeAssembly Condition="'$(TargetGroup)' == 'netfx' or '$(TargetGroup)' == 'net47'">true</IsPartialFacadeAssembly>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net47-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net47-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Release|AnyCPU'" />
<ItemGroup>
<Compile Include="System.Security.Cryptography.Algorithms.cs" />
</ItemGroup>
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true'">
<Compile Include="System.Security.Cryptography.Algorithms.netcoreapp.cs" />
<ProjectReference Include="..\..\System.Runtime\ref\System.Runtime.csproj" />
<ProjectReference Include="..\..\System.Runtime.Extensions\ref\System.Runtime.Extensions.csproj" />
<ProjectReference Include="..\..\System.IO\ref\System.IO.csproj" />

View File

@ -0,0 +1,47 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ------------------------------------------------------------------------------
// Changes to this file must follow the http://aka.ms/api-review process.
// ------------------------------------------------------------------------------
namespace System.Security.Cryptography
{
public abstract partial class DSA : System.Security.Cryptography.AsymmetricAlgorithm
{
public virtual bool TryCreateSignature(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten) { throw null; }
protected virtual bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool VerifyData(ReadOnlySpan<byte> data, ReadOnlySpan<byte> signature, HashAlgorithmName hashAlgorithm) { throw null; }
public virtual bool VerifySignature(ReadOnlySpan<byte> rgbHash, ReadOnlySpan<byte> rgbSignature) { throw null; }
}
public abstract partial class ECDsa : System.Security.Cryptography.AsymmetricAlgorithm
{
protected virtual bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignHash(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten) { throw null; }
public virtual bool VerifyData(ReadOnlySpan<byte> data, ReadOnlySpan<byte> signature, HashAlgorithmName hashAlgorithm) { throw null; }
public virtual bool VerifyHash(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> signature) { throw null; }
}
public sealed partial class IncrementalHash : System.IDisposable
{
public void AppendData(System.ReadOnlySpan<byte> data) { }
public bool TryGetHashAndReset(System.Span<byte> destination, out int bytesWritten) { throw null; }
}
public abstract partial class RandomNumberGenerator : System.IDisposable
{
public virtual void GetBytes(System.Span<byte> data) { }
public virtual void GetNonZeroBytes(System.Span<byte> data) { }
}
public abstract partial class RSA : System.Security.Cryptography.AsymmetricAlgorithm
{
public virtual bool TryDecrypt(System.ReadOnlySpan<byte> source, System.Span<byte> destination, RSAEncryptionPadding padding, out int bytesWritten) { throw null; }
public virtual bool TryEncrypt(System.ReadOnlySpan<byte> source, System.Span<byte> destination, RSAEncryptionPadding padding, out int bytesWritten) { throw null; }
protected virtual bool TryHashData(System.ReadOnlySpan<byte> source, System.Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignData(System.ReadOnlySpan<byte> source, System.Span<byte> destination, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, out int bytesWritten) { throw null; }
public virtual bool TrySignHash(System.ReadOnlySpan<byte> source, System.Span<byte> destination, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, out int bytesWritten) { throw null; }
public virtual bool VerifyData(System.ReadOnlySpan<byte> data, System.ReadOnlySpan<byte> signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { throw null; }
public virtual bool VerifyHash(System.ReadOnlySpan<byte> hash, System.ReadOnlySpan<byte> signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { throw null; }
}
}

View File

@ -5,8 +5,6 @@
netcoreapp-Unix;
netcoreapp-OSX;
netcoreapp-Windows_NT;
netfx-Windows_NT;
net47-Windows_NT;
uap-Windows_NT;
</BuildConfigurations>
</PropertyGroup>

View File

@ -4,9 +4,6 @@
using System;
using System.Diagnostics;
using System.Security.Cryptography;
using Internal.Cryptography;
namespace Internal.Cryptography
{
@ -30,13 +27,7 @@ namespace Internal.Cryptography
ChangeKey(key);
}
public int HashSizeInBits
{
get
{
return _hMacProvider.HashSizeInBytes * 8;
}
}
public int HashSizeInBits => _hMacProvider.HashSizeInBytes * 8;
public void ChangeKey(byte[] key)
{
@ -46,15 +37,16 @@ namespace Internal.Cryptography
{
// Perform RFC 2104, section 2 key adjustment.
if (_lazyHashProvider == null)
{
_lazyHashProvider = HashProviderDispenser.CreateHashProvider(_hashAlgorithmId);
}
_lazyHashProvider.AppendHashData(key, 0, key.Length);
key = _lazyHashProvider.FinalizeHashAndReset();
}
HashProvider oldHashProvider = _hMacProvider;
_hMacProvider = null;
if (oldHashProvider != null)
oldHashProvider.Dispose(true);
oldHashProvider?.Dispose(true);
_hMacProvider = HashProviderDispenser.CreateMacProvider(_hashAlgorithmId, key);
ActualKey = key;
@ -65,31 +57,31 @@ namespace Internal.Cryptography
public byte[] ActualKey { get; private set; }
// Adds new data to be hashed. This can be called repeatedly in order to hash data from noncontiguous sources.
public void AppendHashData(byte[] data, int offset, int count)
{
public void AppendHashData(byte[] data, int offset, int count) =>
_hMacProvider.AppendHashData(data, offset, count);
}
public void AppendHashData(ReadOnlySpan<byte> source) =>
_hMacProvider.AppendHashData(source);
// Compute the hash based on the appended data and resets the HashProvider for more hashing.
public byte[] FinalizeHashAndReset()
{
return _hMacProvider.FinalizeHashAndReset();
}
public byte[] FinalizeHashAndReset() =>
_hMacProvider.FinalizeHashAndReset();
public bool TryFinalizeHashAndReset(Span<byte> destination, out int bytesWritten) =>
_hMacProvider.TryFinalizeHashAndReset(destination, out bytesWritten);
public void Dispose(bool disposing)
{
if (disposing)
if (disposing && _hMacProvider != null)
{
if (_hMacProvider != null)
_hMacProvider.Dispose(true);
_hMacProvider.Dispose(true);
_hMacProvider = null;
}
}
private readonly String _hashAlgorithmId;
private readonly string _hashAlgorithmId;
private HashProvider _hMacProvider;
private volatile HashProvider _lazyHashProvider;
private readonly int _blockSize;
}
}

View File

@ -86,43 +86,22 @@ namespace Internal.Cryptography
HashSizeInBytes = hashSizeInBytes;
}
public override unsafe void AppendHashDataCore(byte[] data, int offset, int count)
public override void AppendHashData(ReadOnlySpan<byte> data)
{
Debug.Assert(data != null);
Debug.Assert(offset >= 0);
Debug.Assert(offset < data.Length);
Debug.Assert(count >= 0);
Debug.Assert(data.Length - offset > count);
if (!_running)
{
SetKey();
}
int ret;
fixed (byte* pData = data)
{
byte* pbData = pData + offset;
ret = Interop.AppleCrypto.HmacUpdate(_ctx, pbData, count);
}
if (ret != 1)
if (Interop.AppleCrypto.HmacUpdate(_ctx, data, data.Length) != 1)
{
throw new CryptographicException();
}
}
private unsafe void SetKey()
private void SetKey()
{
int ret;
fixed (byte* pbKey = _key)
{
ret = Interop.AppleCrypto.HmacInit(_ctx, pbKey, _key.Length);
}
if (ret != 1)
if (Interop.AppleCrypto.HmacInit(_ctx, _key, _key.Length) != 1)
{
throw new CryptographicException();
}
@ -132,26 +111,34 @@ namespace Internal.Cryptography
public override unsafe byte[] FinalizeHashAndReset()
{
var output = new byte[HashSizeInBytes];
bool success = TryFinalizeHashAndReset(output, out int bytesWritten);
Debug.Assert(success);
Debug.Assert(bytesWritten == output.Length);
return output;
}
public override bool TryFinalizeHashAndReset(Span<byte> destination, out int bytesWritten)
{
if (destination.Length < HashSizeInBytes)
{
bytesWritten = 0;
return false;
}
if (!_running)
{
SetKey();
}
byte[] output = new byte[HashSizeInBytes];
int ret;
fixed (byte* pbOutput = output)
{
ret = Interop.AppleCrypto.HmacFinal(_ctx, pbOutput, output.Length);
}
if (ret != 1)
if (Interop.AppleCrypto.HmacFinal(_ctx, destination, destination.Length) != 1)
{
throw new CryptographicException();
}
bytesWritten = HashSizeInBytes;
_running = false;
return output;
return true;
}
public override void Dispose(bool disposing)
@ -193,22 +180,9 @@ namespace Internal.Cryptography
HashSizeInBytes = hashSizeInBytes;
}
public override unsafe void AppendHashDataCore(byte[] data, int offset, int count)
public override void AppendHashData(ReadOnlySpan<byte> data)
{
Debug.Assert(data != null);
Debug.Assert(offset >= 0);
Debug.Assert(offset < data.Length);
Debug.Assert(count >= 0);
Debug.Assert(data.Length - offset > count);
int ret;
fixed (byte* pData = data)
{
byte* pbData = pData + offset;
ret = Interop.AppleCrypto.DigestUpdate(_ctx, pbData, count);
}
int ret = Interop.AppleCrypto.DigestUpdate(_ctx, data, data.Length);
if (ret != 1)
{
Debug.Assert(ret == 0, $"DigestUpdate return value {ret} was not 0 or 1");
@ -216,23 +190,32 @@ namespace Internal.Cryptography
}
}
public override unsafe byte[] FinalizeHashAndReset()
public override byte[] FinalizeHashAndReset()
{
byte[] hash = new byte[HashSizeInBytes];
int ret;
var hash = new byte[HashSizeInBytes];
bool success = TryFinalizeHashAndReset(hash, out int bytesWritten);
Debug.Assert(success);
Debug.Assert(bytesWritten == hash.Length);
return hash;
}
fixed (byte* pHash = hash)
public override bool TryFinalizeHashAndReset(Span<byte> destination, out int bytesWritten)
{
if (destination.Length < HashSizeInBytes)
{
ret = Interop.AppleCrypto.DigestFinal(_ctx, pHash, hash.Length);
bytesWritten = 0;
return false;
}
int ret = Interop.AppleCrypto.DigestFinal(_ctx, destination, destination.Length);
if (ret != 1)
{
Debug.Assert(ret == 0, $"DigestFinal return value {ret} was not 0 or 1");
throw new CryptographicException();
}
return hash;
bytesWritten = HashSizeInBytes;
return true;
}
public override void Dispose(bool disposing)

View File

@ -74,35 +74,40 @@ namespace Internal.Cryptography
Interop.Crypto.CheckValidOpenSslHandle(_ctx);
}
public sealed override unsafe void AppendHashDataCore(byte[] data, int offset, int count)
public override void AppendHashData(ReadOnlySpan<byte> data) =>
Check(Interop.Crypto.EvpDigestUpdate(_ctx, data, data.Length));
public override byte[] FinalizeHashAndReset()
{
fixed (byte* md = data)
{
Check(Interop.Crypto.EvpDigestUpdate(_ctx, md + offset, count));
}
var result = new byte[_hashSize];
bool success = TryFinalizeHashAndReset(result, out int bytesWritten);
Debug.Assert(success);
Debug.Assert(result.Length == bytesWritten);
return result;
}
public sealed override unsafe byte[] FinalizeHashAndReset()
public override bool TryFinalizeHashAndReset(Span<byte> destination, out int bytesWritten)
{
byte* md = stackalloc byte[Interop.Crypto.EVP_MAX_MD_SIZE];
uint length = (uint)Interop.Crypto.EVP_MAX_MD_SIZE;
Check(Interop.Crypto.EvpDigestFinalEx(_ctx, md, ref length));
if (destination.Length < _hashSize)
{
bytesWritten = 0;
return false;
}
uint length = (uint)destination.Length;
Check(Interop.Crypto.EvpDigestFinalEx(_ctx, ref destination.DangerousGetPinnableReference(), ref length));
Debug.Assert(length == _hashSize);
bytesWritten = (int)length;
// Reset the algorithm provider.
Check(Interop.Crypto.EvpDigestReset(_ctx, _algorithmEvp));
byte[] result = new byte[(int)length];
Marshal.Copy((IntPtr)md, result, 0, (int)length);
return result;
return true;
}
public sealed override int HashSizeInBytes
{
get { return _hashSize; }
}
public override int HashSizeInBytes => _hashSize;
public sealed override void Dispose(bool disposing)
public override void Dispose(bool disposing)
{
if (disposing)
{
@ -116,7 +121,7 @@ namespace Internal.Cryptography
private readonly int _hashSize;
private SafeHmacCtxHandle _hmacCtx;
public unsafe HmacHashProvider(IntPtr algorithmEvp, byte[] key)
public HmacHashProvider(IntPtr algorithmEvp, byte[] key)
{
Debug.Assert(algorithmEvp != IntPtr.Zero);
Debug.Assert(key != null);
@ -127,49 +132,47 @@ namespace Internal.Cryptography
throw new CryptographicException();
}
fixed (byte* keyPtr = key)
{
_hmacCtx = Interop.Crypto.HmacCreate(keyPtr, key.Length, algorithmEvp);
Interop.Crypto.CheckValidOpenSslHandle(_hmacCtx);
}
_hmacCtx = Interop.Crypto.HmacCreate(ref new Span<byte>(key).DangerousGetPinnableReference(), key.Length, algorithmEvp);
Interop.Crypto.CheckValidOpenSslHandle(_hmacCtx);
}
public sealed override unsafe void AppendHashDataCore(byte[] data, int offset, int count)
public override void AppendHashData(ReadOnlySpan<byte> data) =>
Check(Interop.Crypto.HmacUpdate(_hmacCtx, data, data.Length));
public override byte[] FinalizeHashAndReset()
{
fixed (byte* md = data)
{
Check(Interop.Crypto.HmacUpdate(_hmacCtx, md + offset, count));
}
var hash = new byte[_hashSize];
bool success = TryFinalizeHashAndReset(hash, out int bytesWritten);
Debug.Assert(success);
Debug.Assert(hash.Length == bytesWritten);
return hash;
}
public sealed override unsafe byte[] FinalizeHashAndReset()
public override unsafe bool TryFinalizeHashAndReset(Span<byte> destination, out int bytesWritten)
{
byte* md = stackalloc byte[Interop.Crypto.EVP_MAX_MD_SIZE];
int length = Interop.Crypto.EVP_MAX_MD_SIZE;
Check(Interop.Crypto.HmacFinal(_hmacCtx, md, ref length));
if (destination.Length < _hashSize)
{
bytesWritten = 0;
return false;
}
int length = destination.Length;
Check(Interop.Crypto.HmacFinal(_hmacCtx, ref destination.DangerousGetPinnableReference(), ref length));
Debug.Assert(length == _hashSize);
bytesWritten = length;
Check(Interop.Crypto.HmacReset(_hmacCtx));
byte[] result = new byte[length];
Marshal.Copy((IntPtr)md, result, 0, length);
return result;
return true;
}
public sealed override int HashSizeInBytes
{
get { return _hashSize; }
}
public override int HashSizeInBytes => _hashSize;
public sealed override void Dispose(bool disposing)
public override void Dispose(bool disposing)
{
if (disposing)
if (disposing && _hmacCtx != null)
{
if (_hmacCtx != null)
{
_hmacCtx.Dispose();
_hmacCtx = null;
}
_hmacCtx.Dispose();
_hmacCtx = null;
}
}
}

View File

@ -8,12 +8,11 @@ namespace System.Security.Cryptography
{
partial class RandomNumberGeneratorImplementation
{
private unsafe void GetBytes(byte* pbBuffer, int count)
private void GetBytes(ref byte pbBuffer, int count)
{
Debug.Assert(pbBuffer != null);
Debug.Assert(count > 0);
Interop.AppleCrypto.GetRandomBytes(pbBuffer, count);
Interop.AppleCrypto.GetRandomBytes(ref pbBuffer, count);
}
}
}

View File

@ -8,12 +8,11 @@ namespace System.Security.Cryptography
{
partial class RandomNumberGeneratorImplementation
{
private unsafe void GetBytes(byte* pbBuffer, int count)
private void GetBytes(ref byte pbBuffer, int count)
{
Debug.Assert(pbBuffer != null);
Debug.Assert(count > 0);
if (!Interop.Crypto.GetRandomBytes(pbBuffer, count))
if (!Interop.Crypto.GetRandomBytes(ref pbBuffer, count))
{
throw Interop.Crypto.CreateOpenSslCryptographicException();
}

View File

@ -8,12 +8,11 @@ namespace System.Security.Cryptography
{
partial class RandomNumberGeneratorImplementation
{
private unsafe void GetBytes(byte* pbBuffer, int count)
private void GetBytes(ref byte pbBuffer, int count)
{
Debug.Assert(pbBuffer != null);
Debug.Assert(count > 0);
Interop.BCrypt.NTSTATUS status = Interop.BCrypt.BCryptGenRandom(pbBuffer, count);
Interop.BCrypt.NTSTATUS status = Interop.BCrypt.BCryptGenRandom(ref pbBuffer, count);
if (status != Interop.BCrypt.NTSTATUS.STATUS_SUCCESS)
throw Interop.BCrypt.CreateCryptographicException(status);
}

View File

@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
namespace System.Security.Cryptography
{
internal sealed partial class RandomNumberGeneratorImplementation : RandomNumberGenerator
@ -11,29 +9,39 @@ namespace System.Security.Cryptography
public override void GetBytes(byte[] data)
{
if (data == null) throw new ArgumentNullException(nameof(data));
GetBytesInternal(data, 0, data.Length);
GetBytes(new Span<byte>(data));
}
public override void GetBytes(byte[] data, int offset, int count)
{
VerifyGetBytes(data, offset, count);
GetBytesInternal(data, offset, count);
GetBytes(new Span<byte>(data, offset, count));
}
public override void GetBytes(Span<byte> data)
{
if (data.Length > 0)
{
GetBytes(ref data.DangerousGetPinnableReference(), data.Length);
}
}
public override void GetNonZeroBytes(byte[] data)
{
if (data == null) throw new ArgumentNullException(nameof(data));
GetNonZeroBytes(new Span<byte>(data));
}
int offset = 0;
while (offset < data.Length)
public override void GetNonZeroBytes(Span<byte> data)
{
while (data.Length > 0)
{
// Fill the remaining portion of the array with random bytes.
GetBytesInternal(data, offset, data.Length - offset);
// Fill the remaining portion of the span with random bytes.
GetBytes(data);
// Find the first zero in the remaining portion.
int indexOfFirst0Byte = data.Length;
for (int i = offset; i < data.Length; i++)
for (int i = 0; i < data.Length; i++)
{
if (data[i] == 0)
{
@ -53,26 +61,7 @@ namespace System.Security.Cryptography
// Request new random bytes if necessary; dont re-use
// existing bytes since they were shifted down.
offset = indexOfFirst0Byte;
}
}
private void GetBytesInternal(byte[] data, int offset, int count)
{
Debug.Assert(data != null);
Debug.Assert(offset >= 0);
Debug.Assert(count >= 0);
Debug.Assert(count <= data.Length - offset);
if (count > 0)
{
unsafe
{
fixed (byte* pb = &data[offset])
{
GetBytes(pb, count);
}
}
data = data.Slice(indexOfFirst0Byte);
}
}
}

View File

@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Security.Cryptography;
namespace Internal.Cryptography
@ -11,7 +12,7 @@ namespace Internal.Cryptography
/// Internal implementation of Rijndael.
/// This class is returned from Rijndael.Create() instead of the public RijndaelManaged to
/// be consistent with the rest of the static Create() methods which return opaque types.
/// They both have have the same implementation.
/// They both have the same implementation.
/// </summary>
internal sealed class RijndaelImplementation : Rijndael
{
@ -30,12 +31,15 @@ namespace Internal.Cryptography
get { return _impl.BlockSize; }
set
{
Debug.Assert(BlockSizeValue == 128);
// Values which were legal in desktop RijndaelManaged but not here in this wrapper type
if (value == 192 || value == 256)
throw new PlatformNotSupportedException(SR.Cryptography_Rijndael_BlockSize);
// Any other invalid block size will get the normal "invalid block size" exception.
_impl.BlockSize = value;
if (value != 128)
throw new CryptographicException(SR.Cryptography_Rijndael_BlockSize);
}
}

View File

@ -12,16 +12,12 @@
<IsPartialFacadeAssembly Condition="'$(TargetGroup)' == 'netfx' or '$(TargetGroup)' == 'net47'">true</IsPartialFacadeAssembly>
<GenFacadesIgnoreMissingTypes Condition="'$(TargetGroup)' == 'netfx'">true</GenFacadesIgnoreMissingTypes>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net47-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net47-Windows_NT-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-OSX-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-OSX-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Unix-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Unix-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Windows_NT-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Windows_NT-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Windows_NT-Release|AnyCPU'" />
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true'">
@ -480,6 +476,7 @@
</Compile>
</ItemGroup>
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true'">
<Reference Include="System.Buffers" />
<Reference Include="System.Collections" />
<Reference Include="System.Diagnostics.Contracts" />
<Reference Include="System.Diagnostics.Debug" />

View File

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Buffers;
using System.IO;
namespace System.Security.Cryptography
@ -69,6 +70,10 @@ namespace System.Security.Cryptography
public byte[] SignData(byte[] data, HashAlgorithmName hashAlgorithm)
{
if (data == null)
{
throw new ArgumentNullException(nameof(data));
}
return SignData(data, 0, data.Length, hashAlgorithm);
}
@ -77,7 +82,7 @@ namespace System.Security.Cryptography
if (data == null) { throw new ArgumentNullException(nameof(data)); }
if (offset < 0 || offset > data.Length) { throw new ArgumentOutOfRangeException(nameof(offset)); }
if (count < 0 || count > data.Length - offset) { throw new ArgumentOutOfRangeException(nameof(count)); }
if (String.IsNullOrEmpty(hashAlgorithm.Name)) { throw HashAlgorithmNameNullOrEmpty(); }
if (string.IsNullOrEmpty(hashAlgorithm.Name)) { throw HashAlgorithmNameNullOrEmpty(); }
byte[] hash = HashData(data, offset, count, hashAlgorithm);
return CreateSignature(hash);
@ -86,7 +91,7 @@ namespace System.Security.Cryptography
public virtual byte[] SignData(Stream data, HashAlgorithmName hashAlgorithm)
{
if (data == null) { throw new ArgumentNullException(nameof(data)); }
if (String.IsNullOrEmpty(hashAlgorithm.Name)) { throw HashAlgorithmNameNullOrEmpty(); }
if (string.IsNullOrEmpty(hashAlgorithm.Name)) { throw HashAlgorithmNameNullOrEmpty(); }
byte[] hash = HashData(data, hashAlgorithm);
return CreateSignature(hash);
@ -94,6 +99,11 @@ namespace System.Security.Cryptography
public bool VerifyData(byte[] data, byte[] signature, HashAlgorithmName hashAlgorithm)
{
if (data == null)
{
throw new ArgumentNullException(nameof(data));
}
return VerifyData(data, 0, data.Length, signature, hashAlgorithm);
}
@ -103,7 +113,7 @@ namespace System.Security.Cryptography
if (offset < 0 || offset > data.Length) { throw new ArgumentOutOfRangeException(nameof(offset)); }
if (count < 0 || count > data.Length - offset) { throw new ArgumentOutOfRangeException(nameof(count)); }
if (signature == null) { throw new ArgumentNullException(nameof(signature)); }
if (String.IsNullOrEmpty(hashAlgorithm.Name)) { throw HashAlgorithmNameNullOrEmpty(); }
if (string.IsNullOrEmpty(hashAlgorithm.Name)) { throw HashAlgorithmNameNullOrEmpty(); }
byte[] hash = HashData(data, offset, count, hashAlgorithm);
return VerifySignature(hash, signature);
@ -113,20 +123,104 @@ namespace System.Security.Cryptography
{
if (data == null) { throw new ArgumentNullException(nameof(data)); }
if (signature == null) { throw new ArgumentNullException(nameof(signature)); }
if (String.IsNullOrEmpty(hashAlgorithm.Name)) { throw HashAlgorithmNameNullOrEmpty(); }
if (string.IsNullOrEmpty(hashAlgorithm.Name)) { throw HashAlgorithmNameNullOrEmpty(); }
byte[] hash = HashData(data, hashAlgorithm);
return VerifySignature(hash, signature);
}
private static Exception DerivedClassMustOverride()
public virtual bool TryCreateSignature(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten)
{
return new NotImplementedException(SR.NotSupported_SubclassOverride);
byte[] sig = CreateSignature(source.ToArray());
if (sig.Length <= destination.Length)
{
new ReadOnlySpan<byte>(sig).CopyTo(destination);
bytesWritten = sig.Length;
return true;
}
else
{
bytesWritten = 0;
return false;
}
}
internal static Exception HashAlgorithmNameNullOrEmpty()
protected virtual bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten)
{
return new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, "hashAlgorithm");
byte[] array = ArrayPool<byte>.Shared.Rent(source.Length);
try
{
source.CopyTo(array);
byte[] hash = HashData(array, 0, source.Length, hashAlgorithm);
if (destination.Length >= hash.Length)
{
new ReadOnlySpan<byte>(hash).CopyTo(destination);
bytesWritten = hash.Length;
return true;
}
else
{
bytesWritten = 0;
return false;
}
}
finally
{
Array.Clear(array, 0, source.Length);
ArrayPool<byte>.Shared.Return(array);
}
}
public virtual bool TrySignData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten)
{
if (string.IsNullOrEmpty(hashAlgorithm.Name))
{
throw HashAlgorithmNameNullOrEmpty();
}
if (TryHashData(source, destination, hashAlgorithm, out int hashLength) &&
TryCreateSignature(destination.Slice(0, hashLength), destination, out bytesWritten))
{
return true;
}
bytesWritten = 0;
return false;
}
public virtual bool VerifyData(ReadOnlySpan<byte> data, ReadOnlySpan<byte> signature, HashAlgorithmName hashAlgorithm)
{
if (string.IsNullOrEmpty(hashAlgorithm.Name))
{
throw HashAlgorithmNameNullOrEmpty();
}
for (int i = 256; ; i = checked(i * 2))
{
int hashLength = 0;
byte[] hash = ArrayPool<byte>.Shared.Rent(i);
try
{
if (TryHashData(data, hash, hashAlgorithm, out hashLength))
{
return VerifySignature(new ReadOnlySpan<byte>(hash, 0, hashLength), signature);
}
}
finally
{
Array.Clear(hash, 0, hashLength);
ArrayPool<byte>.Shared.Return(hash);
}
}
}
public virtual bool VerifySignature(ReadOnlySpan<byte> rgbHash, ReadOnlySpan<byte> rgbSignature) =>
VerifySignature(rgbHash.ToArray(), rgbSignature.ToArray());
private static Exception DerivedClassMustOverride() =>
new NotImplementedException(SR.NotSupported_SubclassOverride);
internal static Exception HashAlgorithmNameNullOrEmpty() =>
new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, "hashAlgorithm");
}
}

View File

@ -15,7 +15,7 @@ namespace System.Security.Cryptography
public byte[] G;
public byte[] Y;
public byte[] J;
[NonSerialized] public byte[] X;
public byte[] X;
public byte[] Seed;
public int Counter;
}

View File

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Buffers;
using System.IO;
namespace System.Security.Cryptography
@ -82,6 +83,23 @@ namespace System.Security.Cryptography
return SignHash(hash);
}
public virtual bool TrySignData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten)
{
if (string.IsNullOrEmpty(hashAlgorithm.Name))
{
throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm));
}
if (TryHashData(source, destination, hashAlgorithm, out int hashLength) &&
TrySignHash(destination.Slice(0, hashLength), destination, out bytesWritten))
{
return true;
}
bytesWritten = 0;
return false;
}
public virtual byte[] SignData(Stream data, HashAlgorithmName hashAlgorithm)
{
if (data == null)
@ -118,6 +136,32 @@ namespace System.Security.Cryptography
return VerifyHash(hash, signature);
}
public virtual bool VerifyData(ReadOnlySpan<byte> data, ReadOnlySpan<byte> signature, HashAlgorithmName hashAlgorithm)
{
if (string.IsNullOrEmpty(hashAlgorithm.Name))
{
throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm));
}
for (int i = 256; ; i = checked(i * 2))
{
int hashLength = 0;
byte[] hash = ArrayPool<byte>.Shared.Rent(i);
try
{
if (TryHashData(data, hash, hashAlgorithm, out hashLength))
{
return VerifyHash(new ReadOnlySpan<byte>(hash, 0, hashLength), signature);
}
}
finally
{
Array.Clear(hash, 0, hashLength);
ArrayPool<byte>.Shared.Return(hash);
}
}
}
public bool VerifyData(Stream data, byte[] signature, HashAlgorithmName hashAlgorithm)
{
if (data == null)
@ -146,5 +190,50 @@ namespace System.Security.Cryptography
{
throw new NotSupportedException(SR.NotSupported_SubclassOverride);
}
protected virtual bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten)
{
byte[] array = ArrayPool<byte>.Shared.Rent(source.Length);
try
{
source.CopyTo(array);
byte[] hash = HashData(array, 0, source.Length, hashAlgorithm);
if (hash.Length <= destination.Length)
{
new ReadOnlySpan<byte>(hash).CopyTo(destination);
bytesWritten = hash.Length;
return true;
}
else
{
bytesWritten = 0;
return false;
}
}
finally
{
Array.Clear(array, 0, source.Length);
ArrayPool<byte>.Shared.Return(array);
}
}
public virtual bool TrySignHash(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten)
{
byte[] result = SignHash(source.ToArray());
if (result.Length <= destination.Length)
{
new ReadOnlySpan<byte>(result).CopyTo(destination);
bytesWritten = result.Length;
return true;
}
else
{
bytesWritten = 0;
return false;
}
}
public virtual bool VerifyHash(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> signature) =>
VerifyHash(hash.ToArray(), signature.ToArray());
}
}

View File

@ -2,10 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Security.Cryptography;
using Internal.Cryptography;
namespace System.Security.Cryptography
@ -46,21 +42,22 @@ namespace System.Security.Cryptography
}
}
protected override void HashCore(byte[] rgb, int ib, int cb)
{
protected override void HashCore(byte[] rgb, int ib, int cb) =>
_hMacCommon.AppendHashData(rgb, ib, cb);
}
protected override byte[] HashFinal()
{
return _hMacCommon.FinalizeHashAndReset();
}
protected override void HashCore(ReadOnlySpan<byte> source) =>
_hMacCommon.AppendHashData(source);
protected override byte[] HashFinal() =>
_hMacCommon.FinalizeHashAndReset();
protected override bool TryHashFinal(Span<byte> destination, out int bytesWritten) =>
_hMacCommon.TryFinalizeHashAndReset(destination, out bytesWritten);
public override void Initialize()
{
// Nothing to do here. We expect HashAlgorithm to invoke HashFinal() and Initialize() as a pair. This reflects the
// reality that our native crypto providers (e.g. CNG) expose hash finalization and object reinitialization as an atomic operation.
return;
}
protected override void Dispose(bool disposing)
@ -68,9 +65,11 @@ namespace System.Security.Cryptography
if (disposing)
{
HMACCommon hMacCommon = _hMacCommon;
_hMacCommon = null;
if (hMacCommon != null)
{
_hMacCommon = null;
hMacCommon.Dispose(disposing);
}
}
base.Dispose(disposing);
}

View File

@ -49,21 +49,22 @@ namespace System.Security.Cryptography
}
}
protected override void HashCore(byte[] rgb, int ib, int cb)
{
protected override void HashCore(byte[] rgb, int ib, int cb) =>
_hMacCommon.AppendHashData(rgb, ib, cb);
}
protected override byte[] HashFinal()
{
return _hMacCommon.FinalizeHashAndReset();
}
protected override void HashCore(ReadOnlySpan<byte> source) =>
_hMacCommon.AppendHashData(source);
protected override byte[] HashFinal() =>
_hMacCommon.FinalizeHashAndReset();
protected override bool TryHashFinal(Span<byte> destination, out int bytesWritten) =>
_hMacCommon.TryFinalizeHashAndReset(destination, out bytesWritten);
public override void Initialize()
{
// Nothing to do here. We expect HashAlgorithm to invoke HashFinal() and Initialize() as a pair. This reflects the
// reality that our native crypto providers (e.g. CNG) expose hash finalization and object reinitialization as an atomic operation.
return;
}
protected override void Dispose(bool disposing)
@ -71,9 +72,11 @@ namespace System.Security.Cryptography
if (disposing)
{
HMACCommon hMacCommon = _hMacCommon;
_hMacCommon = null;
if (hMacCommon != null)
{
_hMacCommon = null;
hMacCommon.Dispose(disposing);
}
}
base.Dispose(disposing);
}

View File

@ -46,21 +46,22 @@ namespace System.Security.Cryptography
}
}
protected override void HashCore(byte[] rgb, int ib, int cb)
{
protected override void HashCore(byte[] rgb, int ib, int cb) =>
_hMacCommon.AppendHashData(rgb, ib, cb);
}
protected override byte[] HashFinal()
{
return _hMacCommon.FinalizeHashAndReset();
}
protected override void HashCore(ReadOnlySpan<byte> source) =>
_hMacCommon.AppendHashData(source);
protected override byte[] HashFinal() =>
_hMacCommon.FinalizeHashAndReset();
protected override bool TryHashFinal(Span<byte> destination, out int bytesWritten) =>
_hMacCommon.TryFinalizeHashAndReset(destination, out bytesWritten);
public override void Initialize()
{
// Nothing to do here. We expect HashAlgorithm to invoke HashFinal() and Initialize() as a pair. This reflects the
// reality that our native crypto providers (e.g. CNG) expose hash finalization and object reinitialization as an atomic operation.
return;
}
protected override void Dispose(bool disposing)
@ -68,9 +69,11 @@ namespace System.Security.Cryptography
if (disposing)
{
HMACCommon hMacCommon = _hMacCommon;
_hMacCommon = null;
if (hMacCommon != null)
{
_hMacCommon = null;
hMacCommon.Dispose(disposing);
}
}
base.Dispose(disposing);
}

Some files were not shown because too many files have changed in this diff Show More