Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add cryptographic operation counts to prevent process crashes
Browse files Browse the repository at this point in the history
vcsjones committed Apr 30, 2024

Unverified

This user has not yet uploaded their public signing key.
1 parent ca4f0fe commit ec2d805
Showing 5 changed files with 116 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -273,6 +273,9 @@
<data name="Cryptography_CipherModeNotSupported" xml:space="preserve">
<value>The specified CipherMode '{0}' is not supported.</value>
</data>
<data name="Cryptography_ConcurrentUseNotSupported" xml:space="preserve">
<value>Concurrent operations from multiple threads on this type are not supported.</value>
</data>
<data name="Cryptography_CngKeyWrongAlgorithm" xml:space="preserve">
<value>This key is for algorithm '{0}'. Expected '{1}'.</value>
</data>
Original file line number Diff line number Diff line change
@@ -817,6 +817,7 @@
<Compile Include="System\Security\Cryptography\CapiHelper.Unix.cs" />
<Compile Include="System\Security\Cryptography\ChaCha20Poly1305.OpenSsl.cs" />
<Compile Include="System\Security\Cryptography\Cng.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\ConcurrencyBlock.cs" />
<Compile Include="System\Security\Cryptography\CspKeyContainerInfo.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\DESCryptoServiceProvider.Unix.cs" />
<Compile Include="System\Security\Cryptography\DesImplementation.OpenSsl.cs" />
@@ -977,6 +978,7 @@
<Compile Include="System\Security\Cryptography\CapiHelper.Shared.cs" />
<Compile Include="System\Security\Cryptography\CapiHelper.Unix.cs" />
<Compile Include="System\Security\Cryptography\Cng.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\ConcurrencyBlock.NoOp.cs" />
<Compile Include="System\Security\Cryptography\CspKeyContainerInfo.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\ChaCha20Poly1305.Android.cs" />
<Compile Include="System\Security\Cryptography\DESCryptoServiceProvider.Unix.cs" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Threading;

namespace System.Security.Cryptography
{
internal struct ConcurrencyBlock
{
private int _count;

internal static Scope Enter(ref ConcurrencyBlock block)
{
int count = Interlocked.Increment(ref block._count);

if (count != 1)
{
Interlocked.Decrement(ref block._count);
throw new CryptographicException(SR.Cryptography_ConcurrentUseNotSupported);
}

return new Scope(ref block._count);
}

internal ref struct Scope
{
private ref int _parentCount;

internal Scope(ref int parentCount)
{
_parentCount = ref parentCount;
}

internal void Dispose()
{
Interlocked.Decrement(ref _parentCount);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Threading;

namespace System.Security.Cryptography
{
internal struct ConcurrencyBlock
{
internal static Scope Enter(ref ConcurrencyBlock block)
{
_ = block;
return default;
}

internal ref struct Scope
{
#pragma warning disable CA1822 // Member can be marked static
internal void Dispose()
{
}
#pragma warning restore CA1822
}
}
}
Original file line number Diff line number Diff line change
@@ -102,6 +102,7 @@ private sealed class EvpHashProvider : HashProvider
{
private readonly LiteHash _liteHash;
private bool _running;
private ConcurrencyBlock _block;

public EvpHashProvider(string hashAlgorithmId)
{
@@ -110,21 +111,30 @@ public EvpHashProvider(string hashAlgorithmId)

public override void AppendHashData(ReadOnlySpan<byte> data)
{
_liteHash.Append(data);
_running = true;
using (ConcurrencyBlock.Enter(ref _block))
{
_liteHash.Append(data);
_running = true;
}
}

public override int FinalizeHashAndReset(Span<byte> destination)
{
int written = _liteHash.Finalize(destination);
_liteHash.Reset();
_running = false;
return written;
using (ConcurrencyBlock.Enter(ref _block))
{
int written = _liteHash.Finalize(destination);
_liteHash.Reset();
_running = false;
return written;
}
}

public override int GetCurrentHash(Span<byte> destination)
{
return _liteHash.Current(destination);
using (ConcurrencyBlock.Enter(ref _block))
{
return _liteHash.Current(destination);
}
}

public override int HashSizeInBytes => _liteHash.HashSizeInBytes;
@@ -139,10 +149,13 @@ public override void Dispose(bool disposing)

public override void Reset()
{
if (_running)
using (ConcurrencyBlock.Enter(ref _block))
{
_liteHash.Reset();
_running = false;
if (_running)
{
_liteHash.Reset();
_running = false;
}
}
}
}
@@ -151,6 +164,7 @@ private sealed class HmacHashProvider : HashProvider
{
private readonly LiteHmac _liteHmac;
private bool _running;
private ConcurrencyBlock _block;

public HmacHashProvider(string hashAlgorithmId, ReadOnlySpan<byte> key)
{
@@ -159,21 +173,30 @@ public HmacHashProvider(string hashAlgorithmId, ReadOnlySpan<byte> key)

public override void AppendHashData(ReadOnlySpan<byte> data)
{
_liteHmac.Append(data);
_running = true;
using (ConcurrencyBlock.Enter(ref _block))
{
_liteHmac.Append(data);
_running = true;
}
}

public override int FinalizeHashAndReset(Span<byte> destination)
{
int written = _liteHmac.Finalize(destination);
_liteHmac.Reset();
_running = false;
return written;
using (ConcurrencyBlock.Enter(ref _block))
{
int written = _liteHmac.Finalize(destination);
_liteHmac.Reset();
_running = false;
return written;
}
}

public override int GetCurrentHash(Span<byte> destination)
{
return _liteHmac.Current(destination);
using (ConcurrencyBlock.Enter(ref _block))
{
return _liteHmac.Current(destination);
}
}

public override int HashSizeInBytes => _liteHmac.HashSizeInBytes;
@@ -188,10 +211,13 @@ public override void Dispose(bool disposing)

public override void Reset()
{
if (_running)
using (ConcurrencyBlock.Enter(ref _block))
{
_liteHmac.Reset();
_running = false;
if (_running)
{
_liteHmac.Reset();
_running = false;
}
}
}
}

0 comments on commit ec2d805

Please sign in to comment.