diff --git a/crypto/src/crypto/agreement/srp/SRP6Utilities.cs b/crypto/src/crypto/agreement/srp/SRP6Utilities.cs
index ef6d8f24c..2176a7100 100644
--- a/crypto/src/crypto/agreement/srp/SRP6Utilities.cs
+++ b/crypto/src/crypto/agreement/srp/SRP6Utilities.cs
@@ -20,7 +20,10 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
public static BigInteger CalculateX(IDigest digest, BigInteger N, byte[] salt, byte[] identity, byte[] password)
{
- byte[] output = new byte[digest.GetDigestSize()];
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ return CalculateX(digest, N, salt.AsSpan(), identity.AsSpan(), password.AsSpan());
+#else
+ byte[] output = new byte[digest.GetDigestSize()];
digest.BlockUpdate(identity, 0, identity.Length);
digest.Update((byte)':');
@@ -32,9 +35,29 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
digest.DoFinal(output, 0);
return new BigInteger(1, output);
+#endif
}
- public static BigInteger GeneratePrivateValue(IDigest digest, BigInteger N, BigInteger g, SecureRandom random)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public static BigInteger CalculateX(IDigest digest, BigInteger N, ReadOnlySpan<byte> salt,
+ ReadOnlySpan<byte> identity, ReadOnlySpan<byte> password)
+ {
+ Span<byte> output = stackalloc byte[digest.GetDigestSize()];
+
+ digest.BlockUpdate(identity);
+ digest.Update((byte)':');
+ digest.BlockUpdate(password);
+ digest.DoFinal(output);
+
+ digest.BlockUpdate(salt);
+ digest.BlockUpdate(output);
+ digest.DoFinal(output);
+
+ return new BigInteger(1, output);
+ }
+#endif
+
+ public static BigInteger GeneratePrivateValue(IDigest digest, BigInteger N, BigInteger g, SecureRandom random)
{
int minBits = System.Math.Min(256, N.BitLength / 2);
BigInteger min = BigInteger.One.ShiftLeft(minBits - 1);
@@ -95,59 +118,83 @@ namespace Org.BouncyCastle.Crypto.Agreement.Srp
*/
public static BigInteger CalculateKey(IDigest digest, BigInteger N, BigInteger S)
{
- int padLength = (N.BitLength + 7) / 8;
- byte[] _S = GetPadded(S, padLength);
- digest.BlockUpdate(_S, 0, _S.Length);
+ int paddedLength = (N.BitLength + 7) / 8;
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ Span<byte> bytes = stackalloc byte[paddedLength];
+ BigIntegers.AsUnsignedByteArray(S, bytes);
+ digest.BlockUpdate(bytes);
+
+ Span<byte> output = stackalloc byte[digest.GetDigestSize()];
+ 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()];
digest.DoFinal(output, 0);
+#endif
+
return new BigInteger(1, output);
}
private static BigInteger HashPaddedTriplet(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2, BigInteger n3)
{
- int padLength = (N.BitLength + 7) / 8;
-
- byte[] n1_bytes = GetPadded(n1, padLength);
- byte[] n2_bytes = GetPadded(n2, padLength);
- byte[] n3_bytes = GetPadded(n3, padLength);
-
- digest.BlockUpdate(n1_bytes, 0, n1_bytes.Length);
- digest.BlockUpdate(n2_bytes, 0, n2_bytes.Length);
- digest.BlockUpdate(n3_bytes, 0, n3_bytes.Length);
+ int paddedLength = (N.BitLength + 7) / 8;
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ Span<byte> bytes = stackalloc byte[paddedLength];
+ BigIntegers.AsUnsignedByteArray(n1, bytes);
+ digest.BlockUpdate(bytes);
+ BigIntegers.AsUnsignedByteArray(n2, bytes);
+ digest.BlockUpdate(bytes);
+ BigIntegers.AsUnsignedByteArray(n3, bytes);
+ digest.BlockUpdate(bytes);
+
+ Span<byte> output = stackalloc byte[digest.GetDigestSize()];
+ digest.DoFinal(output);
+#else
+ byte[] bytes = new byte[paddedLength];
+ BigIntegers.AsUnsignedByteArray(n1, bytes, 0, bytes.Length);
+ digest.BlockUpdate(bytes, 0, bytes.Length);
+ BigIntegers.AsUnsignedByteArray(n2, bytes, 0, bytes.Length);
+ digest.BlockUpdate(bytes, 0, bytes.Length);
+ BigIntegers.AsUnsignedByteArray(n3, bytes, 0, bytes.Length);
+ digest.BlockUpdate(bytes, 0, bytes.Length);
byte[] output = new byte[digest.GetDigestSize()];
digest.DoFinal(output, 0);
+#endif
return new BigInteger(1, output);
}
private static BigInteger HashPaddedPair(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2)
{
- int padLength = (N.BitLength + 7) / 8;
-
- byte[] n1_bytes = GetPadded(n1, padLength);
- byte[] n2_bytes = GetPadded(n2, padLength);
-
- digest.BlockUpdate(n1_bytes, 0, n1_bytes.Length);
- digest.BlockUpdate(n2_bytes, 0, n2_bytes.Length);
+ int paddedLength = (N.BitLength + 7) / 8;
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ Span<byte> bytes = stackalloc byte[paddedLength];
+ BigIntegers.AsUnsignedByteArray(n1, bytes);
+ digest.BlockUpdate(bytes);
+ BigIntegers.AsUnsignedByteArray(n2, bytes);
+ digest.BlockUpdate(bytes);
+
+ Span<byte> output = stackalloc byte[digest.GetDigestSize()];
+ digest.DoFinal(output);
+#else
+ byte[] bytes = new byte[paddedLength];
+ BigIntegers.AsUnsignedByteArray(n1, bytes, 0, bytes.Length);
+ digest.BlockUpdate(bytes, 0, bytes.Length);
+ BigIntegers.AsUnsignedByteArray(n2, bytes, 0, bytes.Length);
+ digest.BlockUpdate(bytes, 0, bytes.Length);
byte[] output = new byte[digest.GetDigestSize()];
digest.DoFinal(output, 0);
+#endif
- return new BigInteger(1, output);
- }
-
- private static byte[] GetPadded(BigInteger n, int length)
- {
- byte[] bs = BigIntegers.AsUnsignedByteArray(n);
- if (bs.Length < length)
- {
- byte[] tmp = new byte[length];
- Array.Copy(bs, 0, tmp, length - bs.Length, bs.Length);
- bs = tmp;
- }
- return bs;
- }
+ return new BigInteger(1, output);
+ }
}
}
diff --git a/crypto/src/crypto/signers/HMacDsaKCalculator.cs b/crypto/src/crypto/signers/HMacDsaKCalculator.cs
index 2641f58b6..25e36530c 100644
--- a/crypto/src/crypto/signers/HMacDsaKCalculator.cs
+++ b/crypto/src/crypto/signers/HMacDsaKCalculator.cs
@@ -46,55 +46,55 @@ namespace Org.BouncyCastle.Crypto.Signers
{
this.n = n;
- Arrays.Fill(V, (byte)0x01);
- Arrays.Fill(K, (byte)0);
-
- int size = BigIntegers.GetUnsignedByteLength(n);
- byte[] x = new byte[size];
- byte[] dVal = BigIntegers.AsUnsignedByteArray(d);
-
- Array.Copy(dVal, 0, x, x.Length - dVal.Length, dVal.Length);
-
- byte[] m = new byte[size];
+ Arrays.Fill(V, 0x01);
+ Arrays.Fill(K, 0);
BigInteger mInt = BitsToInt(message);
-
if (mInt.CompareTo(n) >= 0)
{
mInt = mInt.Subtract(n);
}
- byte[] mVal = BigIntegers.AsUnsignedByteArray(mInt);
+ int size = BigIntegers.GetUnsignedByteLength(n);
- Array.Copy(mVal, 0, m, m.Length - mVal.Length, mVal.Length);
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ Span<byte> xm = stackalloc byte[size * 2];
+ BigIntegers.AsUnsignedByteArray(d, xm[..size]);
+ BigIntegers.AsUnsignedByteArray(mInt, xm[size..]);
+#else
+ byte[] x = BigIntegers.AsUnsignedByteArray(size, d);
+ byte[] m = BigIntegers.AsUnsignedByteArray(size, mInt);
+#endif
hMac.Init(new KeyParameter(K));
hMac.BlockUpdate(V, 0, V.Length);
- hMac.Update((byte)0x00);
+ hMac.Update(0x00);
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ hMac.BlockUpdate(xm);
+#else
hMac.BlockUpdate(x, 0, x.Length);
hMac.BlockUpdate(m, 0, m.Length);
+#endif
InitAdditionalInput0(hMac);
-
hMac.DoFinal(K, 0);
hMac.Init(new KeyParameter(K));
-
hMac.BlockUpdate(V, 0, V.Length);
-
hMac.DoFinal(V, 0);
hMac.BlockUpdate(V, 0, V.Length);
- hMac.Update((byte)0x01);
+ hMac.Update(0x01);
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ hMac.BlockUpdate(xm);
+#else
hMac.BlockUpdate(x, 0, x.Length);
hMac.BlockUpdate(m, 0, m.Length);
-
+#endif
hMac.DoFinal(K, 0);
hMac.Init(new KeyParameter(K));
-
hMac.BlockUpdate(V, 0, V.Length);
-
hMac.DoFinal(V, 0);
}
@@ -109,7 +109,6 @@ namespace Org.BouncyCastle.Crypto.Signers
while (tOff < t.Length)
{
hMac.BlockUpdate(V, 0, V.Length);
-
hMac.DoFinal(V, 0);
int len = System.Math.Min(t.Length - tOff, V.Length);
@@ -120,19 +119,14 @@ namespace Org.BouncyCastle.Crypto.Signers
BigInteger k = BitsToInt(t);
if (k.SignValue > 0 && k.CompareTo(n) < 0)
- {
return k;
- }
hMac.BlockUpdate(V, 0, V.Length);
- hMac.Update((byte)0x00);
-
+ hMac.Update(0x00);
hMac.DoFinal(K, 0);
hMac.Init(new KeyParameter(K));
-
hMac.BlockUpdate(V, 0, V.Length);
-
hMac.DoFinal(V, 0);
}
}
diff --git a/crypto/src/crypto/signers/X931Signer.cs b/crypto/src/crypto/signers/X931Signer.cs
index 6c0aa9427..278410f2a 100644
--- a/crypto/src/crypto/signers/X931Signer.cs
+++ b/crypto/src/crypto/signers/X931Signer.cs
@@ -3,6 +3,7 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Zlib;
namespace Org.BouncyCastle.Crypto.Signers
{
@@ -82,12 +83,6 @@ namespace Org.BouncyCastle.Crypto.Signers
Reset();
}
- /// <summary> clear possible sensitive data</summary>
- private void ClearBlock(byte[] block)
- {
- Array.Clear(block, 0, block.Length);
- }
-
public virtual void Update(byte b)
{
digest.Update(b);
@@ -115,7 +110,7 @@ namespace Org.BouncyCastle.Crypto.Signers
CreateSignatureBlock();
BigInteger t = new BigInteger(1, cipher.ProcessBlock(block, 0, block.Length));
- ClearBlock(block);
+ Arrays.Fill(block, 0x00);
t = t.Min(kParam.Modulus.Subtract(t));
@@ -183,12 +178,17 @@ namespace Org.BouncyCastle.Crypto.Signers
CreateSignatureBlock();
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ Span<byte> fBlock = stackalloc byte[block.Length];
+ BigIntegers.AsUnsignedByteArray(f, fBlock);
+#else
byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f);
+#endif
bool rv = Arrays.ConstantTimeAreEqual(block, fBlock);
- ClearBlock(block);
- ClearBlock(fBlock);
+ Arrays.Fill(block, 0x00);
+ Arrays.Fill<byte>(fBlock, 0x00);
return rv;
}
diff --git a/crypto/src/openpgp/PgpPublicKey.cs b/crypto/src/openpgp/PgpPublicKey.cs
index 09c8b9743..6d5f35018 100644
--- a/crypto/src/openpgp/PgpPublicKey.cs
+++ b/crypto/src/openpgp/PgpPublicKey.cs
@@ -507,7 +507,17 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
{
ECPublicBcpgKey ecK = (ECPublicBcpgKey)publicPk.Key;
X9ECParameters x9 = ECKeyPairGenerator.FindECCurveByOid(ecK.CurveOid);
- ECPoint q = x9.Curve.DecodePoint(BigIntegers.AsUnsignedByteArray(ecK.EncodedPoint));
+ BigInteger encodedPoint = ecK.EncodedPoint;
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ int encodingLength = BigIntegers.GetUnsignedByteLength(encodedPoint);
+ Span<byte> encoding = stackalloc byte[encodingLength];
+ BigIntegers.AsUnsignedByteArray(encodedPoint, encoding);
+ ECPoint q = x9.Curve.DecodePoint(encoding);
+#else
+ ECPoint q = x9.Curve.DecodePoint(BigIntegers.AsUnsignedByteArray(encodedPoint));
+#endif
+
return new ECPublicKeyParameters(algorithm, q, ecK.CurveOid);
}
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs b/crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs
index faf6b4576..6a947c23b 100644
--- a/crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcTlsDHDomain.cs
@@ -24,7 +24,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
private static int GetValueLength(DHParameters dh)
{
- return (dh.P.BitLength + 7) / 8;
+ return BigIntegers.GetUnsignedByteLength(dh.P);
}
public static BcTlsSecret CalculateDHAgreement(BcTlsCrypto crypto, DHPrivateKeyParameters privateKey,
diff --git a/crypto/src/util/Arrays.cs b/crypto/src/util/Arrays.cs
index c2ba9c3e1..e8dd02148 100644
--- a/crypto/src/util/Arrays.cs
+++ b/crypto/src/util/Arrays.cs
@@ -620,6 +620,24 @@ namespace Org.BouncyCastle.Utilities
}
}
+ public static void Fill<T>(T[] ts, T t)
+ {
+ for (int i = 0; i < ts.Length; ++i)
+ {
+ ts[i] = t;
+ }
+ }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public static void Fill<T>(Span<T> ts, T t)
+ {
+ for (int i = 0; i < ts.Length; ++i)
+ {
+ ts[i] = t;
+ }
+ }
+#endif
+
public static byte[] CopyOf(byte[] data, int newLength)
{
byte[] tmp = new byte[newLength];
|