diff --git a/crypto/src/bcpg/ECDHPublicBCPGKey.cs b/crypto/src/bcpg/ECDHPublicBCPGKey.cs
index 05c34ba8b..5b6d9460e 100644
--- a/crypto/src/bcpg/ECDHPublicBCPGKey.cs
+++ b/crypto/src/bcpg/ECDHPublicBCPGKey.cs
@@ -22,9 +22,9 @@ namespace Org.BouncyCastle.Bcpg
throw new InvalidOperationException("KDF parameters size of 3 expected.");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- Span<byte> kdfParameters = stackalloc byte[length];
+ Span<byte> kdfParameters = stackalloc byte[3];
#else
- byte[] kdfParameters = new byte[length];
+ byte[] kdfParameters = new byte[3];
#endif
bcpgIn.ReadFully(kdfParameters);
diff --git a/crypto/src/bcpg/MPInteger.cs b/crypto/src/bcpg/MPInteger.cs
index 2f564b00c..eb59be6e5 100644
--- a/crypto/src/bcpg/MPInteger.cs
+++ b/crypto/src/bcpg/MPInteger.cs
@@ -20,16 +20,13 @@ namespace Org.BouncyCastle.Bcpg
int lengthInBytes = (lengthInBits + 7) / 8;
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- if (lengthInBytes <= 512)
- {
- Span<byte> span = stackalloc byte[lengthInBytes];
- bcpgIn.ReadFully(span);
- m_val = new BigInteger(1, span);
- return;
- }
+ Span<byte> bytes = lengthInBytes <= 512
+ ? stackalloc byte[lengthInBytes]
+ : new byte[lengthInBytes];
+#else
+ byte[] bytes = new byte[lengthInBytes];
#endif
- byte[] bytes = new byte[lengthInBytes];
bcpgIn.ReadFully(bytes);
m_val = new BigInteger(1, bytes);
}
@@ -55,12 +52,15 @@ namespace Org.BouncyCastle.Bcpg
internal static BigInteger ToMpiBigInteger(ECPoint point)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- Span<byte> encoding = stackalloc byte[point.GetEncodedLength(false)];
+ int encodedLength = point.GetEncodedLength(false);
+ Span<byte> encoding = encodedLength <= 512
+ ? stackalloc byte[encodedLength]
+ : new byte[encodedLength];
point.EncodeTo(false, encoding);
- return new BigInteger(1, encoding);
#else
- return new BigInteger(1, point.GetEncoded(false));
+ byte[] encoding = point.GetEncoded(false);
#endif
+ return new BigInteger(1, encoding);
}
}
}
diff --git a/crypto/src/crypto/agreement/kdf/DHKekGenerator.cs b/crypto/src/crypto/agreement/kdf/DHKekGenerator.cs
index 7d75c2224..2dabe9d1f 100644
--- a/crypto/src/crypto/agreement/kdf/DHKekGenerator.cs
+++ b/crypto/src/crypto/agreement/kdf/DHKekGenerator.cs
@@ -120,7 +120,9 @@ namespace Org.BouncyCastle.Crypto.Agreement.Kdf
int cThreshold = (int)((oBytes + digestSize - 1) / digestSize);
- Span<byte> dig = stackalloc byte[digestSize];
+ Span<byte> dig = digestSize <= 128
+ ? stackalloc byte[digestSize]
+ : new byte[digestSize];
uint counter = 1;
diff --git a/crypto/src/crypto/agreement/srp/SRP6Utilities.cs b/crypto/src/crypto/agreement/srp/SRP6Utilities.cs
index 2176a7100..73be57c5a 100644
--- a/crypto/src/crypto/agreement/srp/SRP6Utilities.cs
+++ b/crypto/src/crypto/agreement/srp/SRP6Utilities.cs
@@ -42,7 +42,10 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
public static BigInteger CalculateX(IDigest digest, BigInteger N, ReadOnlySpan<byte> salt,
ReadOnlySpan<byte> identity, ReadOnlySpan<byte> password)
{
- Span<byte> output = stackalloc byte[digest.GetDigestSize()];
+ int digestSize = digest.GetDigestSize();
+ Span<byte> output = digestSize <= 128
+ ? stackalloc byte[digestSize]
+ : new byte[digestSize];
digest.BlockUpdate(identity);
digest.Update((byte)':');
@@ -119,20 +122,25 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
public static BigInteger CalculateKey(IDigest digest, BigInteger N, BigInteger S)
{
int paddedLength = (N.BitLength + 7) / 8;
+ int digestSize = digest.GetDigestSize();
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- Span<byte> bytes = stackalloc byte[paddedLength];
+ Span<byte> bytes = paddedLength <= 512
+ ? stackalloc byte[paddedLength]
+ : new byte[paddedLength];
BigIntegers.AsUnsignedByteArray(S, bytes);
digest.BlockUpdate(bytes);
- Span<byte> output = stackalloc byte[digest.GetDigestSize()];
+ Span<byte> output = digestSize <= 128
+ ? stackalloc byte[digestSize]
+ : new byte[digestSize];
digest.DoFinal(output);
#else
byte[] bytes = new byte[paddedLength];
BigIntegers.AsUnsignedByteArray(S, bytes, 0, bytes.Length);
digest.BlockUpdate(bytes, 0, bytes.Length);
- byte[] output = new byte[digest.GetDigestSize()];
+ byte[] output = new byte[digestSize];
digest.DoFinal(output, 0);
#endif
@@ -142,9 +150,12 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
private static BigInteger HashPaddedTriplet(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2, BigInteger n3)
{
int paddedLength = (N.BitLength + 7) / 8;
+ int digestSize = digest.GetDigestSize();
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- Span<byte> bytes = stackalloc byte[paddedLength];
+ Span<byte> bytes = paddedLength <= 512
+ ? stackalloc byte[paddedLength]
+ : new byte[paddedLength];
BigIntegers.AsUnsignedByteArray(n1, bytes);
digest.BlockUpdate(bytes);
BigIntegers.AsUnsignedByteArray(n2, bytes);
@@ -152,7 +163,9 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
BigIntegers.AsUnsignedByteArray(n3, bytes);
digest.BlockUpdate(bytes);
- Span<byte> output = stackalloc byte[digest.GetDigestSize()];
+ Span<byte> output = digestSize <= 128
+ ? stackalloc byte[digestSize]
+ : new byte[digestSize];
digest.DoFinal(output);
#else
byte[] bytes = new byte[paddedLength];
@@ -163,7 +176,7 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
BigIntegers.AsUnsignedByteArray(n3, bytes, 0, bytes.Length);
digest.BlockUpdate(bytes, 0, bytes.Length);
- byte[] output = new byte[digest.GetDigestSize()];
+ byte[] output = new byte[digestSize];
digest.DoFinal(output, 0);
#endif
@@ -173,15 +186,20 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
private static BigInteger HashPaddedPair(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2)
{
int paddedLength = (N.BitLength + 7) / 8;
+ int digestSize = digest.GetDigestSize();
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- Span<byte> bytes = stackalloc byte[paddedLength];
+ Span<byte> bytes = paddedLength <= 512
+ ? stackalloc byte[paddedLength]
+ : new byte[paddedLength];
BigIntegers.AsUnsignedByteArray(n1, bytes);
digest.BlockUpdate(bytes);
BigIntegers.AsUnsignedByteArray(n2, bytes);
digest.BlockUpdate(bytes);
- Span<byte> output = stackalloc byte[digest.GetDigestSize()];
+ Span<byte> output = digestSize <= 128
+ ? stackalloc byte[digestSize]
+ : new byte[digestSize];
digest.DoFinal(output);
#else
byte[] bytes = new byte[paddedLength];
@@ -190,7 +208,7 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
BigIntegers.AsUnsignedByteArray(n2, bytes, 0, bytes.Length);
digest.BlockUpdate(bytes, 0, bytes.Length);
- byte[] output = new byte[digest.GetDigestSize()];
+ byte[] output = new byte[digestSize];
digest.DoFinal(output, 0);
#endif
diff --git a/crypto/src/crypto/digests/ShortenedDigest.cs b/crypto/src/crypto/digests/ShortenedDigest.cs
index 9e9998560..0ea3cc1a1 100644
--- a/crypto/src/crypto/digests/ShortenedDigest.cs
+++ b/crypto/src/crypto/digests/ShortenedDigest.cs
@@ -78,7 +78,10 @@ namespace Org.BouncyCastle.Crypto.Digests
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
public int DoFinal(Span<byte> output)
{
- Span<byte> tmp = stackalloc byte[baseDigest.GetDigestSize()];
+ int baseDigestSize = baseDigest.GetDigestSize();
+ Span<byte> tmp = baseDigestSize <= 128
+ ? stackalloc byte[baseDigestSize]
+ : new byte[baseDigestSize];
baseDigest.DoFinal(tmp);
diff --git a/crypto/src/crypto/engines/SM2Engine.cs b/crypto/src/crypto/engines/SM2Engine.cs
index 36593cddc..e0734d424 100644
--- a/crypto/src/crypto/engines/SM2Engine.cs
+++ b/crypto/src/crypto/engines/SM2Engine.cs
@@ -138,14 +138,20 @@ namespace Org.BouncyCastle.Crypto.Engines
ECPoint c1P = multiplier.Multiply(mECParams.G, k).Normalize();
- Span<byte> c1 = stackalloc byte[c1P.GetEncodedLength(false)];
+ int c1PEncodedLength = c1P.GetEncodedLength(false);
+ Span<byte> c1 = c1PEncodedLength <= 512
+ ? stackalloc byte[c1PEncodedLength]
+ : new byte[c1PEncodedLength];
c1P.EncodeTo(false, c1);
AddFieldElement(mDigest, kPB.AffineXCoord);
mDigest.BlockUpdate(input);
AddFieldElement(mDigest, kPB.AffineYCoord);
- Span<byte> c3 = stackalloc byte[mDigest.GetDigestSize()];
+ int digestSize = mDigest.GetDigestSize();
+ Span<byte> c3 = digestSize <= 128
+ ? stackalloc byte[digestSize]
+ : new byte[digestSize];
mDigest.DoFinal(c3);
switch (mMode)
@@ -187,7 +193,9 @@ namespace Org.BouncyCastle.Crypto.Engines
mDigest.BlockUpdate(c2);
AddFieldElement(mDigest, c1P.AffineYCoord);
- Span<byte> c3 = stackalloc byte[mDigest.GetDigestSize()];
+ Span<byte> c3 = digestSize <= 128
+ ? stackalloc byte[digestSize]
+ : new byte[digestSize];
mDigest.DoFinal(c3);
int check = 0;
@@ -343,10 +351,13 @@ namespace Org.BouncyCastle.Crypto.Engines
private void Kdf(IDigest digest, ECPoint c1, byte[] encData)
{
int digestSize = digest.GetDigestSize();
+ int bufSize = System.Math.Max(4, digestSize);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- Span<byte> buf = stackalloc byte[System.Math.Max(4, digestSize)];
+ Span<byte> buf = bufSize <= 128
+ ? stackalloc byte[bufSize]
+ : new byte[bufSize];
#else
- byte[] buf = new byte[System.Math.Max(4, digestSize)];
+ byte[] buf = new byte[bufSize];
#endif
int off = 0;
@@ -426,7 +437,10 @@ namespace Org.BouncyCastle.Crypto.Engines
private void AddFieldElement(IDigest digest, ECFieldElement v)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- Span<byte> p = stackalloc byte[v.GetEncodedLength()];
+ int encodedLength = v.GetEncodedLength();
+ Span<byte> p = encodedLength <= 128
+ ? stackalloc byte[encodedLength]
+ : new byte[encodedLength];
v.EncodeTo(p);
digest.BlockUpdate(p);
#else
diff --git a/crypto/src/crypto/generators/BaseKdfBytesGenerator.cs b/crypto/src/crypto/generators/BaseKdfBytesGenerator.cs
index c0c4be217..a1839dc33 100644
--- a/crypto/src/crypto/generators/BaseKdfBytesGenerator.cs
+++ b/crypto/src/crypto/generators/BaseKdfBytesGenerator.cs
@@ -142,7 +142,9 @@ namespace Org.BouncyCastle.Crypto.Generators
int cThreshold = (int)((oBytes + digestSize - 1) / digestSize);
- Span<byte> dig = stackalloc byte[digestSize];
+ Span<byte> dig = digestSize <= 128
+ ? stackalloc byte[digestSize]
+ : new byte[digestSize];
Span<byte> C = stackalloc byte[4];
Pack.UInt32_To_BE((uint)counterStart, C);
diff --git a/crypto/src/crypto/io/CipherStream.cs b/crypto/src/crypto/io/CipherStream.cs
index e59f33679..145fa7fd3 100644
--- a/crypto/src/crypto/io/CipherStream.cs
+++ b/crypto/src/crypto/io/CipherStream.cs
@@ -258,7 +258,9 @@ namespace Org.BouncyCastle.Crypto.IO
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
int outputSize = m_writeCipher.GetOutputSize(0);
- Span<byte> output = stackalloc byte[outputSize];
+ Span<byte> output = outputSize <= 256
+ ? stackalloc byte[outputSize]
+ : new byte[outputSize];
int len = m_writeCipher.DoFinal(output);
m_stream.Write(output[..len]);
#else
diff --git a/crypto/src/crypto/modes/CtsBlockCipher.cs b/crypto/src/crypto/modes/CtsBlockCipher.cs
index 022e86675..e76049a36 100644
--- a/crypto/src/crypto/modes/CtsBlockCipher.cs
+++ b/crypto/src/crypto/modes/CtsBlockCipher.cs
@@ -294,7 +294,9 @@ namespace Org.BouncyCastle.Crypto.Modes
int blockSize = m_cipherMode.GetBlockSize();
int length = bufOff - blockSize;
- Span<byte> block = stackalloc byte[blockSize];
+ Span<byte> block = blockSize <= 64
+ ? stackalloc byte[blockSize]
+ : new byte[blockSize];
if (forEncryption)
{
@@ -319,7 +321,9 @@ namespace Org.BouncyCastle.Crypto.Modes
}
else
{
- Span<byte> lastBlock = stackalloc byte[blockSize];
+ Span<byte> lastBlock = blockSize <= 64
+ ? stackalloc byte[blockSize]
+ : new byte[blockSize];
m_cipherMode.UnderlyingCipher.ProcessBlock(buf, block);
diff --git a/crypto/src/crypto/modes/EAXBlockCipher.cs b/crypto/src/crypto/modes/EAXBlockCipher.cs
index 5d7f05d02..770c432e2 100644
--- a/crypto/src/crypto/modes/EAXBlockCipher.cs
+++ b/crypto/src/crypto/modes/EAXBlockCipher.cs
@@ -316,7 +316,11 @@ namespace Org.BouncyCastle.Crypto.Modes
InitCipher();
int extra = bufOff;
- Span<byte> tmp = stackalloc byte[bufBlock.Length];
+ int tmpLength = bufBlock.Length;
+
+ Span<byte> tmp = tmpLength <= 128
+ ? stackalloc byte[tmpLength]
+ : new byte[tmpLength];
bufOff = 0;
diff --git a/crypto/src/crypto/modes/KCcmBlockCipher.cs b/crypto/src/crypto/modes/KCcmBlockCipher.cs
index a733379cc..cc4a5060c 100644
--- a/crypto/src/crypto/modes/KCcmBlockCipher.cs
+++ b/crypto/src/crypto/modes/KCcmBlockCipher.cs
@@ -459,7 +459,9 @@ namespace Org.BouncyCastle.Crypto.Modes
Array.Copy(macBlock, 0, mac, 0, macSize);
- Span<byte> calculatedMac = stackalloc byte[macSize];
+ Span<byte> calculatedMac = macSize <= 64
+ ? stackalloc byte[macSize]
+ : new byte[macSize];
buffer.AsSpan(0, macSize).CopyTo(calculatedMac);
diff --git a/crypto/src/crypto/signers/HMacDsaKCalculator.cs b/crypto/src/crypto/signers/HMacDsaKCalculator.cs
index 25e36530c..67dadede8 100644
--- a/crypto/src/crypto/signers/HMacDsaKCalculator.cs
+++ b/crypto/src/crypto/signers/HMacDsaKCalculator.cs
@@ -58,7 +58,10 @@ namespace Org.BouncyCastle.Crypto.Signers
int size = BigIntegers.GetUnsignedByteLength(n);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- Span<byte> xm = stackalloc byte[size * 2];
+ int xmSize = size * 2;
+ Span<byte> xm = xmSize <= 512
+ ? stackalloc byte[xmSize]
+ : new byte[xmSize];
BigIntegers.AsUnsignedByteArray(d, xm[..size]);
BigIntegers.AsUnsignedByteArray(mInt, xm[size..]);
#else
diff --git a/crypto/src/crypto/signers/X931Signer.cs b/crypto/src/crypto/signers/X931Signer.cs
index 278410f2a..40255c40c 100644
--- a/crypto/src/crypto/signers/X931Signer.cs
+++ b/crypto/src/crypto/signers/X931Signer.cs
@@ -179,7 +179,10 @@ namespace Org.BouncyCastle.Crypto.Signers
CreateSignatureBlock();
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- Span<byte> fBlock = stackalloc byte[block.Length];
+ int fBlockSize = block.Length;
+ Span<byte> fBlock = fBlockSize <= 512
+ ? stackalloc byte[fBlockSize]
+ : new byte[fBlockSize];
BigIntegers.AsUnsignedByteArray(f, fBlock);
#else
byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f);
diff --git a/crypto/src/math/ec/ECAlgorithms.cs b/crypto/src/math/ec/ECAlgorithms.cs
index fcfab06f7..3059ca3b3 100644
--- a/crypto/src/math/ec/ECAlgorithms.cs
+++ b/crypto/src/math/ec/ECAlgorithms.cs
@@ -216,7 +216,10 @@ namespace Org.BouncyCastle.Math.EC
throw new ArgumentException("Point must be on the same curve", nameof(p));
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- Span<byte> encoding = stackalloc byte[p.GetEncodedLength(false)];
+ int encodedLength = p.GetEncodedLength(false);
+ Span<byte> encoding = encodedLength <= 512
+ ? stackalloc byte[encodedLength]
+ : new byte[encodedLength];
p.EncodeTo(false, encoding);
return c.DecodePoint(encoding);
#else
diff --git a/crypto/src/math/ec/rfc8032/Ed25519.cs b/crypto/src/math/ec/rfc8032/Ed25519.cs
index d6bf461cf..f3b63f3b3 100644
--- a/crypto/src/math/ec/rfc8032/Ed25519.cs
+++ b/crypto/src/math/ec/rfc8032/Ed25519.cs
@@ -433,7 +433,10 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
public static void GeneratePublicKey(ReadOnlySpan<byte> sk, Span<byte> pk)
{
IDigest d = CreateDigest();
- Span<byte> h = stackalloc byte[d.GetDigestSize()];
+ int digestSize = d.GetDigestSize();
+ Span<byte> h = digestSize <= 128
+ ? stackalloc byte[digestSize]
+ : new byte[digestSize];
d.BlockUpdate(sk[..SecretKeySize]);
d.DoFinal(h);
diff --git a/crypto/src/openpgp/PgpPublicKey.cs b/crypto/src/openpgp/PgpPublicKey.cs
index 6d5f35018..cdb8efd36 100644
--- a/crypto/src/openpgp/PgpPublicKey.cs
+++ b/crypto/src/openpgp/PgpPublicKey.cs
@@ -510,8 +510,10 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
BigInteger encodedPoint = ecK.EncodedPoint;
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
- int encodingLength = BigIntegers.GetUnsignedByteLength(encodedPoint);
- Span<byte> encoding = stackalloc byte[encodingLength];
+ int encodedLength = BigIntegers.GetUnsignedByteLength(encodedPoint);
+ Span<byte> encoding = encodedLength <= 512
+ ? stackalloc byte[encodedLength]
+ : new byte[encodedLength];
BigIntegers.AsUnsignedByteArray(encodedPoint, encoding);
ECPoint q = x9.Curve.DecodePoint(encoding);
#else
|