diff --git a/crypto/src/cmp/CertificateStatus.cs b/crypto/src/cmp/CertificateStatus.cs
index e697f73bc..53227d062 100644
--- a/crypto/src/cmp/CertificateStatus.cs
+++ b/crypto/src/cmp/CertificateStatus.cs
@@ -36,7 +36,7 @@ namespace Org.BouncyCastle.Cmp
byte[] digest = DigestUtilities.CalculateDigest(digAlg.Algorithm, cert.GetEncoded());
- return Arrays.ConstantTimeAreEqual(certStatus.CertHash.GetOctets(), digest);
+ return Arrays.FixedTimeEquals(certStatus.CertHash.GetOctets(), digest);
}
}
}
diff --git a/crypto/src/cmp/ProtectedPkiMessage.cs b/crypto/src/cmp/ProtectedPkiMessage.cs
index 6304b5200..8c9a4b152 100644
--- a/crypto/src/cmp/ProtectedPkiMessage.cs
+++ b/crypto/src/cmp/ProtectedPkiMessage.cs
@@ -116,7 +116,7 @@ namespace Org.BouncyCastle.Cmp
IBlockResult result = Process(pkMacBuilder.Build(password).CreateCalculator());
- return Arrays.ConstantTimeAreEqual(result.Collect(), m_pkiMessage.Protection.GetBytes());
+ return Arrays.FixedTimeEquals(result.Collect(), m_pkiMessage.Protection.GetBytes());
}
private TResult Process<TResult>(IStreamCalculator<TResult> streamCalculator)
diff --git a/crypto/src/cms/SignerInformation.cs b/crypto/src/cms/SignerInformation.cs
index bb74c86cc..84256d9f8 100644
--- a/crypto/src/cms/SignerInformation.cs
+++ b/crypto/src/cms/SignerInformation.cs
@@ -595,7 +595,7 @@ namespace Org.BouncyCastle.Cms
byte[] sigHash = digInfo.GetDigest();
- return Arrays.ConstantTimeAreEqual(digest, sigHash);
+ return Arrays.FixedTimeEquals(digest, sigHash);
}
else if (algorithm.Equals("DSA"))
{
diff --git a/crypto/src/crypto/agreement/SM2KeyExchange.cs b/crypto/src/crypto/agreement/SM2KeyExchange.cs
index 986d98421..5db156f9c 100644
--- a/crypto/src/crypto/agreement/SM2KeyExchange.cs
+++ b/crypto/src/crypto/agreement/SM2KeyExchange.cs
@@ -127,7 +127,7 @@ namespace Org.BouncyCastle.Crypto.Agreement
byte[] s1 = S1(mDigest, U, inner);
- if (!Arrays.ConstantTimeAreEqual(s1, confirmationTag))
+ if (!Arrays.FixedTimeEquals(s1, confirmationTag))
throw new InvalidOperationException("confirmation tag mismatch");
return new byte[][] { rv, S2(mDigest, U, inner)};
diff --git a/crypto/src/crypto/engines/DesEdeWrapEngine.cs b/crypto/src/crypto/engines/DesEdeWrapEngine.cs
index e05f9f555..c1f93eef9 100644
--- a/crypto/src/crypto/engines/DesEdeWrapEngine.cs
+++ b/crypto/src/crypto/engines/DesEdeWrapEngine.cs
@@ -305,7 +305,7 @@ namespace Org.BouncyCastle.Crypto.Engines
byte[] key,
byte[] checksum)
{
- return Arrays.ConstantTimeAreEqual(CalculateCmsKeyChecksum(key), checksum);
+ return Arrays.FixedTimeEquals(CalculateCmsKeyChecksum(key), checksum);
}
private static byte[] reverse(byte[] bs)
diff --git a/crypto/src/crypto/engines/IesEngine.cs b/crypto/src/crypto/engines/IesEngine.cs
index 307cc7a80..33fc4141b 100644
--- a/crypto/src/crypto/engines/IesEngine.cs
+++ b/crypto/src/crypto/engines/IesEngine.cs
@@ -139,7 +139,7 @@ namespace Org.BouncyCastle.Crypto.Engines
byte[] T1 = Arrays.CopyOfRange(in_enc, inOff, inOff + macBuf.Length);
- if (!Arrays.ConstantTimeAreEqual(T1, macBuf))
+ if (!Arrays.FixedTimeEquals(T1, macBuf))
throw (new InvalidCipherTextException("Invalid MAC."));
return M;
diff --git a/crypto/src/crypto/engines/RC2WrapEngine.cs b/crypto/src/crypto/engines/RC2WrapEngine.cs
index 91ac7ded2..bc50f0db4 100644
--- a/crypto/src/crypto/engines/RC2WrapEngine.cs
+++ b/crypto/src/crypto/engines/RC2WrapEngine.cs
@@ -361,7 +361,7 @@ namespace Org.BouncyCastle.Crypto.Engines
byte[] key,
byte[] checksum)
{
- return Arrays.ConstantTimeAreEqual(CalculateCmsKeyChecksum(key), checksum);
+ return Arrays.FixedTimeEquals(CalculateCmsKeyChecksum(key), checksum);
}
}
}
diff --git a/crypto/src/crypto/engines/RFC3394WrapEngine.cs b/crypto/src/crypto/engines/RFC3394WrapEngine.cs
index 4bb0e2114..e68e45365 100644
--- a/crypto/src/crypto/engines/RFC3394WrapEngine.cs
+++ b/crypto/src/crypto/engines/RFC3394WrapEngine.cs
@@ -169,7 +169,7 @@ namespace Org.BouncyCastle.Crypto.Engines
}
}
- if (!Arrays.ConstantTimeAreEqual(a, iv))
+ if (!Arrays.FixedTimeEquals(a, iv))
throw new InvalidCipherTextException("checksum failed");
return block;
diff --git a/crypto/src/crypto/modes/CcmBlockCipher.cs b/crypto/src/crypto/modes/CcmBlockCipher.cs
index 3569ac2b7..e002c1f71 100644
--- a/crypto/src/crypto/modes/CcmBlockCipher.cs
+++ b/crypto/src/crypto/modes/CcmBlockCipher.cs
@@ -345,7 +345,7 @@ namespace Org.BouncyCastle.Crypto.Modes
CalculateMac(output, outOff, outputLen, calculatedMacBlock);
- if (!Arrays.ConstantTimeAreEqual(macBlock, calculatedMacBlock))
+ if (!Arrays.FixedTimeEquals(macBlock, calculatedMacBlock))
throw new InvalidCipherTextException("mac check in CCM failed");
}
@@ -439,7 +439,7 @@ namespace Org.BouncyCastle.Crypto.Modes
CalculateMac(output[..outputLen], calculatedMacBlock);
- if (!Arrays.ConstantTimeAreEqual(macBlock, calculatedMacBlock))
+ if (!Arrays.FixedTimeEquals(macBlock, calculatedMacBlock))
throw new InvalidCipherTextException("mac check in CCM failed");
}
diff --git a/crypto/src/crypto/modes/ChaCha20Poly1305.cs b/crypto/src/crypto/modes/ChaCha20Poly1305.cs
index 2fce81e22..4b0ad0cca 100644
--- a/crypto/src/crypto/modes/ChaCha20Poly1305.cs
+++ b/crypto/src/crypto/modes/ChaCha20Poly1305.cs
@@ -588,7 +588,7 @@ namespace Org.BouncyCastle.Crypto.Modes
FinishData(State.DecFinal);
- if (!Arrays.ConstantTimeAreEqual(MacSize, mMac, 0, mBuf, resultLen))
+ if (!Arrays.FixedTimeEquals(MacSize, mMac, 0, mBuf, resultLen))
throw new InvalidCipherTextException("mac check in ChaCha20Poly1305 failed");
break;
@@ -648,7 +648,7 @@ namespace Org.BouncyCastle.Crypto.Modes
FinishData(State.DecFinal);
- if (!Arrays.ConstantTimeAreEqual(MacSize, mMac, 0, mBuf, resultLen))
+ if (!Arrays.FixedTimeEquals(MacSize, mMac, 0, mBuf, resultLen))
throw new InvalidCipherTextException("mac check in ChaCha20Poly1305 failed");
break;
diff --git a/crypto/src/crypto/modes/GCMBlockCipher.cs b/crypto/src/crypto/modes/GCMBlockCipher.cs
index ce5faf91f..f75235cf2 100644
--- a/crypto/src/crypto/modes/GCMBlockCipher.cs
+++ b/crypto/src/crypto/modes/GCMBlockCipher.cs
@@ -730,7 +730,7 @@ namespace Org.BouncyCastle.Crypto.Modes
// Retrieve the T value from the message and compare to calculated one
byte[] msgMac = new byte[macSize];
Array.Copy(bufBlock, extra, msgMac, 0, macSize);
- if (!Arrays.ConstantTimeAreEqual(this.macBlock, msgMac))
+ if (!Arrays.FixedTimeEquals(this.macBlock, msgMac))
throw new InvalidCipherTextException("mac check in GCM failed");
}
@@ -842,7 +842,7 @@ namespace Org.BouncyCastle.Crypto.Modes
// Retrieve the T value from the message and compare to calculated one
Span<byte> msgMac = stackalloc byte[macSize];
bufBlock.AsSpan(extra, macSize).CopyTo(msgMac);
- if (!Arrays.ConstantTimeAreEqual(this.macBlock, msgMac))
+ if (!Arrays.FixedTimeEquals(this.macBlock, msgMac))
throw new InvalidCipherTextException("mac check in GCM failed");
}
diff --git a/crypto/src/crypto/modes/GcmSivBlockCipher.cs b/crypto/src/crypto/modes/GcmSivBlockCipher.cs
index 14f908da3..7246b59c1 100644
--- a/crypto/src/crypto/modes/GcmSivBlockCipher.cs
+++ b/crypto/src/crypto/modes/GcmSivBlockCipher.cs
@@ -670,7 +670,7 @@ namespace Org.BouncyCastle.Crypto.Modes
/* Derive and check the tag */
byte[] myTag = CalculateTag();
- if (!Arrays.ConstantTimeAreEqual(myTag, myExpected))
+ if (!Arrays.FixedTimeEquals(myTag, myExpected))
{
Reset();
throw new InvalidCipherTextException("mac check failed");
diff --git a/crypto/src/crypto/modes/KCcmBlockCipher.cs b/crypto/src/crypto/modes/KCcmBlockCipher.cs
index 5fb8d77c6..c13c41543 100644
--- a/crypto/src/crypto/modes/KCcmBlockCipher.cs
+++ b/crypto/src/crypto/modes/KCcmBlockCipher.cs
@@ -354,7 +354,7 @@ namespace Org.BouncyCastle.Crypto.Modes
Array.Copy(buffer, 0, calculatedMac, 0, macSize);
- if (!Arrays.ConstantTimeAreEqual(mac, calculatedMac))
+ if (!Arrays.FixedTimeEquals(mac, calculatedMac))
{
throw new InvalidCipherTextException("mac check failed");
}
@@ -465,7 +465,7 @@ namespace Org.BouncyCastle.Crypto.Modes
calculatedMac.CopyFrom(buffer);
- if (!Arrays.ConstantTimeAreEqual(mac.AsSpan(0, macSize), calculatedMac))
+ if (!Arrays.FixedTimeEquals(mac.AsSpan(0, macSize), calculatedMac))
throw new InvalidCipherTextException("mac check failed");
Reset();
diff --git a/crypto/src/crypto/modes/OCBBlockCipher.cs b/crypto/src/crypto/modes/OCBBlockCipher.cs
index e67b4e9af..9ae60805e 100644
--- a/crypto/src/crypto/modes/OCBBlockCipher.cs
+++ b/crypto/src/crypto/modes/OCBBlockCipher.cs
@@ -439,7 +439,7 @@ namespace Org.BouncyCastle.Crypto.Modes
else
{
// Compare the tag from the message with the calculated one
- if (!Arrays.ConstantTimeAreEqual(macBlock, tag))
+ if (!Arrays.FixedTimeEquals(macBlock, tag))
throw new InvalidCipherTextException("mac check in OCB failed");
}
@@ -529,7 +529,7 @@ namespace Org.BouncyCastle.Crypto.Modes
else
{
// Compare the tag from the message with the calculated one
- if (!Arrays.ConstantTimeAreEqual(macBlock, tag))
+ if (!Arrays.FixedTimeEquals(macBlock, tag))
throw new InvalidCipherTextException("mac check in OCB failed");
}
diff --git a/crypto/src/crypto/signers/GenericSigner.cs b/crypto/src/crypto/signers/GenericSigner.cs
index 2a416eeb7..36a9cc9a5 100644
--- a/crypto/src/crypto/signers/GenericSigner.cs
+++ b/crypto/src/crypto/signers/GenericSigner.cs
@@ -109,7 +109,7 @@ namespace Org.BouncyCastle.Crypto.Signers
sig = tmp;
}
- return Arrays.ConstantTimeAreEqual(sig, hash);
+ return Arrays.FixedTimeEquals(sig, hash);
}
catch (Exception)
{
diff --git a/crypto/src/crypto/signers/RsaDigestSigner.cs b/crypto/src/crypto/signers/RsaDigestSigner.cs
index 296e4b016..77d9b9ac3 100644
--- a/crypto/src/crypto/signers/RsaDigestSigner.cs
+++ b/crypto/src/crypto/signers/RsaDigestSigner.cs
@@ -176,7 +176,7 @@ namespace Org.BouncyCastle.Crypto.Signers
if (sig.Length == expected.Length)
{
- return Arrays.ConstantTimeAreEqual(sig, expected);
+ return Arrays.FixedTimeEquals(sig, expected);
}
else if (sig.Length == expected.Length - 2) // NULL left out
{
diff --git a/crypto/src/crypto/signers/X931Signer.cs b/crypto/src/crypto/signers/X931Signer.cs
index e40ad88a7..9db4e1642 100644
--- a/crypto/src/crypto/signers/X931Signer.cs
+++ b/crypto/src/crypto/signers/X931Signer.cs
@@ -184,7 +184,7 @@ namespace Org.BouncyCastle.Crypto.Signers
byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f);
#endif
- bool rv = Arrays.ConstantTimeAreEqual(block, fBlock);
+ bool rv = Arrays.FixedTimeEquals(block, fBlock);
Arrays.Fill(block, 0x00);
Arrays.Fill<byte>(fBlock, 0x00);
diff --git a/crypto/src/openpgp/PgpEncryptedData.cs b/crypto/src/openpgp/PgpEncryptedData.cs
index bad4cb8cd..0a8bd6c42 100644
--- a/crypto/src/openpgp/PgpEncryptedData.cs
+++ b/crypto/src/openpgp/PgpEncryptedData.cs
@@ -176,7 +176,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
byte[] streamDigest = new byte[digest.Length];
Array.Copy(lookAhead, 2, streamDigest, 0, streamDigest.Length);
- return Arrays.ConstantTimeAreEqual(digest, streamDigest);
+ return Arrays.FixedTimeEquals(digest, streamDigest);
}
}
}
diff --git a/crypto/src/pkcs/Pkcs12Store.cs b/crypto/src/pkcs/Pkcs12Store.cs
index bf7e68363..9cb81a412 100644
--- a/crypto/src/pkcs/Pkcs12Store.cs
+++ b/crypto/src/pkcs/Pkcs12Store.cs
@@ -202,7 +202,7 @@ namespace Org.BouncyCastle.Pkcs
byte[] mac = CalculatePbeMac(algId.Algorithm, salt, itCount, password, false, data);
byte[] dig = dInfo.GetDigest();
- if (!Arrays.ConstantTimeAreEqual(mac, dig))
+ if (!Arrays.FixedTimeEquals(mac, dig))
{
if (password.Length > 0)
throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");
@@ -210,7 +210,7 @@ namespace Org.BouncyCastle.Pkcs
// Try with incorrect zero length password
mac = CalculatePbeMac(algId.Algorithm, salt, itCount, password, true, data);
- if (!Arrays.ConstantTimeAreEqual(mac, dig))
+ if (!Arrays.FixedTimeEquals(mac, dig))
throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");
wrongPkcs12Zero = true;
diff --git a/crypto/src/pqc/crypto/crystals/kyber/KyberEngine.cs b/crypto/src/pqc/crypto/crystals/kyber/KyberEngine.cs
index e30115a95..132bd73b3 100644
--- a/crypto/src/pqc/crypto/crystals/kyber/KyberEngine.cs
+++ b/crypto/src/pqc/crypto/crystals/kyber/KyberEngine.cs
@@ -148,7 +148,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Crystals.Kyber
m_indCpa.Encrypt(cmp, Arrays.CopyOf(buf, SymBytes), pk, Arrays.CopyOfRange(kr, SymBytes, kr.Length));
- bool fail = !Arrays.ConstantTimeAreEqual(cipherText, cmp);
+ bool fail = !Arrays.FixedTimeEquals(cipherText, cmp);
Symmetric.Hash_h(kr, cipherText, SymBytes);
diff --git a/crypto/src/pqc/crypto/lms/LMSPublicKeyParameters.cs b/crypto/src/pqc/crypto/lms/LMSPublicKeyParameters.cs
index f8d0970af..e8c5d07e5 100644
--- a/crypto/src/pqc/crypto/lms/LMSPublicKeyParameters.cs
+++ b/crypto/src/pqc/crypto/lms/LMSPublicKeyParameters.cs
@@ -93,7 +93,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Lms
internal bool MatchesT1(byte[] sig)
{
- return Arrays.ConstantTimeAreEqual(T1, sig);
+ return Arrays.FixedTimeEquals(T1, sig);
}
public byte[] GetI()
diff --git a/crypto/src/security/JksStore.cs b/crypto/src/security/JksStore.cs
index 9f4aced96..c5ef92a70 100644
--- a/crypto/src/security/JksStore.cs
+++ b/crypto/src/security/JksStore.cs
@@ -80,7 +80,7 @@ namespace Org.BouncyCastle.Security
// integrity check
byte[] checksum = GetKeyChecksum(digest, password, pkcs8Key);
- if (!Arrays.ConstantTimeAreEqual(20, encryptedData, pkcs8Len + 20, checksum, 0))
+ if (!Arrays.FixedTimeEquals(20, encryptedData, pkcs8Len + 20, checksum, 0))
throw new IOException("cannot recover key");
return PrivateKeyFactory.CreateKey(pkcs8Key);
@@ -393,7 +393,7 @@ namespace Org.BouncyCastle.Security
{
byte[] checksum = CalculateChecksum(password, rawStore, 0, checksumPos);
- if (!Arrays.ConstantTimeAreEqual(20, checksum, 0, rawStore, checksumPos))
+ if (!Arrays.FixedTimeEquals(20, checksum, 0, rawStore, checksumPos))
{
Array.Clear(rawStore, 0, rawStore.Length);
throw new IOException("password incorrect or store tampered with");
diff --git a/crypto/src/tls/DtlsClientProtocol.cs b/crypto/src/tls/DtlsClientProtocol.cs
index 0a4a711ae..92478dc46 100644
--- a/crypto/src/tls/DtlsClientProtocol.cs
+++ b/crypto/src/tls/DtlsClientProtocol.cs
@@ -805,7 +805,7 @@ namespace Org.BouncyCastle.Tls
*/
securityParameters.m_secureRenegotiation = true;
- if (!Arrays.ConstantTimeAreEqual(renegExtData,
+ if (!Arrays.FixedTimeEquals(renegExtData,
TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
{
throw new TlsFatalAlert(AlertDescription.handshake_failure);
diff --git a/crypto/src/tls/DtlsProtocol.cs b/crypto/src/tls/DtlsProtocol.cs
index 3d72bca9f..745535148 100644
--- a/crypto/src/tls/DtlsProtocol.cs
+++ b/crypto/src/tls/DtlsProtocol.cs
@@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Tls
TlsProtocol.AssertEmpty(buf);
- if (!Arrays.ConstantTimeAreEqual(expected_verify_data, verify_data))
+ if (!Arrays.FixedTimeEquals(expected_verify_data, verify_data))
throw new TlsFatalAlert(AlertDescription.handshake_failure);
}
diff --git a/crypto/src/tls/DtlsServerProtocol.cs b/crypto/src/tls/DtlsServerProtocol.cs
index 5edd5595e..43d4e5539 100644
--- a/crypto/src/tls/DtlsServerProtocol.cs
+++ b/crypto/src/tls/DtlsServerProtocol.cs
@@ -769,7 +769,7 @@ namespace Org.BouncyCastle.Tls
*/
securityParameters.m_secureRenegotiation = true;
- if (!Arrays.ConstantTimeAreEqual(renegExtData,
+ if (!Arrays.FixedTimeEquals(renegExtData,
TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
{
throw new TlsFatalAlert(AlertDescription.handshake_failure);
diff --git a/crypto/src/tls/DtlsVerifier.cs b/crypto/src/tls/DtlsVerifier.cs
index edadeae70..e691685e6 100644
--- a/crypto/src/tls/DtlsVerifier.cs
+++ b/crypto/src/tls/DtlsVerifier.cs
@@ -57,14 +57,14 @@ namespace Org.BouncyCastle.Tls
//}
//case 1:
//{
- // if (Arrays.ConstantTimeAreEqual(expectedCookie, request.ClientHello.Cookie))
+ // if (Arrays.FixedTimeEquals(expectedCookie, request.ClientHello.Cookie))
// return request;
// break;
//}
//}
- if (Arrays.ConstantTimeAreEqual(expectedCookie, request.ClientHello.Cookie))
+ if (Arrays.FixedTimeEquals(expectedCookie, request.ClientHello.Cookie))
return request;
DtlsReliableHandshake.SendHelloVerifyRequest(sender, request.RecordSeq, expectedCookie);
diff --git a/crypto/src/tls/PskIdentity.cs b/crypto/src/tls/PskIdentity.cs
index 1887d0af4..2d4a0b0c7 100644
--- a/crypto/src/tls/PskIdentity.cs
+++ b/crypto/src/tls/PskIdentity.cs
@@ -58,7 +58,7 @@ namespace Org.BouncyCastle.Tls
return false;
return this.m_obfuscatedTicketAge == that.m_obfuscatedTicketAge
- && Arrays.ConstantTimeAreEqual(this.m_identity, that.m_identity);
+ && Arrays.FixedTimeEquals(this.m_identity, that.m_identity);
}
public override int GetHashCode()
diff --git a/crypto/src/tls/TlsClientProtocol.cs b/crypto/src/tls/TlsClientProtocol.cs
index b7295bcc5..ec1cd28d5 100644
--- a/crypto/src/tls/TlsClientProtocol.cs
+++ b/crypto/src/tls/TlsClientProtocol.cs
@@ -1211,7 +1211,7 @@ namespace Org.BouncyCastle.Tls
*/
securityParameters.m_secureRenegotiation = true;
- if (!Arrays.ConstantTimeAreEqual(renegExtData, CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
+ if (!Arrays.FixedTimeEquals(renegExtData, CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
throw new TlsFatalAlert(AlertDescription.handshake_failure);
}
}
diff --git a/crypto/src/tls/TlsProtocol.cs b/crypto/src/tls/TlsProtocol.cs
index 437a51447..16bc1385e 100644
--- a/crypto/src/tls/TlsProtocol.cs
+++ b/crypto/src/tls/TlsProtocol.cs
@@ -1517,7 +1517,7 @@ namespace Org.BouncyCastle.Tls
/*
* Compare both checksums.
*/
- if (!Arrays.ConstantTimeAreEqual(expected_verify_data, verify_data))
+ if (!Arrays.FixedTimeEquals(expected_verify_data, verify_data))
{
/*
* Wrong checksum in the finished message.
@@ -1557,7 +1557,7 @@ namespace Org.BouncyCastle.Tls
/*
* Compare both checksums.
*/
- if (!Arrays.ConstantTimeAreEqual(expected_verify_data, verify_data))
+ if (!Arrays.FixedTimeEquals(expected_verify_data, verify_data))
{
/*
* Wrong checksum in the finished message.
diff --git a/crypto/src/tls/TlsServerProtocol.cs b/crypto/src/tls/TlsServerProtocol.cs
index bf4b9119a..72c1b2ea5 100644
--- a/crypto/src/tls/TlsServerProtocol.cs
+++ b/crypto/src/tls/TlsServerProtocol.cs
@@ -512,7 +512,7 @@ namespace Org.BouncyCastle.Tls
*/
securityParameters.m_secureRenegotiation = true;
- if (!Arrays.ConstantTimeAreEqual(clientRenegExtData,
+ if (!Arrays.FixedTimeEquals(clientRenegExtData,
CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
{
throw new TlsFatalAlert(AlertDescription.handshake_failure);
diff --git a/crypto/src/tls/TlsUtilities.cs b/crypto/src/tls/TlsUtilities.cs
index e1a8ead58..424fca133 100644
--- a/crypto/src/tls/TlsUtilities.cs
+++ b/crypto/src/tls/TlsUtilities.cs
@@ -5630,7 +5630,7 @@ namespace Org.BouncyCastle.Tls
byte[] calculatedBinder = CalculatePskBinder(crypto, isExternalPsk, pskCryptoHashAlgorithm,
earlySecret, transcriptHash);
- if (Arrays.ConstantTimeAreEqual(calculatedBinder, binder))
+ if (Arrays.FixedTimeEquals(calculatedBinder, binder))
return new OfferedPsks.SelectedConfig(index, psk, pskKeyExchangeModes, earlySecret);
}
}
diff --git a/crypto/src/tsp/TSPUtil.cs b/crypto/src/tsp/TSPUtil.cs
index 1ba289ae6..6f1d07b0a 100644
--- a/crypto/src/tsp/TSPUtil.cs
+++ b/crypto/src/tsp/TSPUtil.cs
@@ -99,7 +99,7 @@ namespace Org.BouncyCastle.Tsp
GetDigestAlgName(tstInfo.MessageImprintAlgOid),
signerInfo.GetSignature());
- if (!Arrays.ConstantTimeAreEqual(expectedDigest, tstInfo.GetMessageImprintDigest()))
+ if (!Arrays.FixedTimeEquals(expectedDigest, tstInfo.GetMessageImprintDigest()))
throw new TspValidationException("Incorrect digest in message imprint");
timestamps.Add(timeStampToken);
diff --git a/crypto/src/tsp/TimeStampResponse.cs b/crypto/src/tsp/TimeStampResponse.cs
index 069521111..702194911 100644
--- a/crypto/src/tsp/TimeStampResponse.cs
+++ b/crypto/src/tsp/TimeStampResponse.cs
@@ -136,7 +136,7 @@ namespace Org.BouncyCastle.Tsp
throw new TspValidationException("time stamp token found in failed request.");
}
- if (!Arrays.ConstantTimeAreEqual(request.GetMessageImprintDigest(), tstInfo.GetMessageImprintDigest()))
+ if (!Arrays.FixedTimeEquals(request.GetMessageImprintDigest(), tstInfo.GetMessageImprintDigest()))
{
throw new TspValidationException("response for different message imprint digest.");
}
diff --git a/crypto/src/tsp/TimeStampToken.cs b/crypto/src/tsp/TimeStampToken.cs
index 93b372720..f2f86da67 100644
--- a/crypto/src/tsp/TimeStampToken.cs
+++ b/crypto/src/tsp/TimeStampToken.cs
@@ -161,7 +161,7 @@ namespace Org.BouncyCastle.Tsp
byte[] hash = DigestUtilities.CalculateDigest(
certID.GetHashAlgorithmName(), cert.GetEncoded());
- if (!Arrays.ConstantTimeAreEqual(certID.GetCertHash(), hash))
+ if (!Arrays.FixedTimeEquals(certID.GetCertHash(), hash))
throw new TspValidationException("certificate hash does not match certID hash.");
if (certID.IssuerSerial != null)
diff --git a/crypto/src/util/Arrays.cs b/crypto/src/util/Arrays.cs
index bd2a4faea..41e3c3195 100644
--- a/crypto/src/util/Arrays.cs
+++ b/crypto/src/util/Arrays.cs
@@ -1,4 +1,8 @@
using System;
+using System.Runtime.CompilerServices;
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+using System.Security.Cryptography;
+#endif
using System.Text;
using Org.BouncyCastle.Math;
@@ -93,34 +97,46 @@ namespace Org.BouncyCastle.Utilities
return true;
}
- /// <summary>
- /// A constant time equals comparison - does not terminate early if
- /// test will fail.
- /// </summary>
- /// <param name="a">first array</param>
- /// <param name="b">second array</param>
- /// <returns>true if arrays equal, false otherwise.</returns>
+ [Obsolete("Use 'FixedTimeEquals' instead")]
public static bool ConstantTimeAreEqual(byte[] a, byte[] b)
{
+ return FixedTimeEquals(a, b);
+ }
+
+ [Obsolete("Use 'FixedTimeEquals' instead")]
+ public static bool ConstantTimeAreEqual(int len, byte[] a, int aOff, byte[] b, int bOff)
+ {
+ return FixedTimeEquals(len, a, aOff, b, bOff);
+ }
+
+#if !(NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER)
+ [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
+#endif
+ public static bool FixedTimeEquals(byte[] a, byte[] b)
+ {
if (null == a || null == b)
return false;
- if (a == b)
- return true;
- int len = System.Math.Min(a.Length, b.Length);
- int nonEqual = a.Length ^ b.Length;
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ return CryptographicOperations.FixedTimeEquals(a, b);
+#else
+ int len = a.Length;
+ if (len != b.Length)
+ return false;
+
+ int d = 0;
for (int i = 0; i < len; ++i)
{
- nonEqual |= (a[i] ^ b[i]);
- }
- for (int i = len; i < b.Length; ++i)
- {
- nonEqual |= (b[i] ^ ~b[i]);
+ d |= a[i] ^ b[i];
}
- return 0 == nonEqual;
+ return 0 == d;
+#endif
}
- public static bool ConstantTimeAreEqual(int len, byte[] a, int aOff, byte[] b, int bOff)
+#if !(NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER)
+ [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
+#endif
+ public static bool FixedTimeEquals(int len, byte[] a, int aOff, byte[] b, int bOff)
{
if (null == a)
throw new ArgumentNullException("a");
@@ -133,27 +149,28 @@ namespace Org.BouncyCastle.Utilities
if (bOff > (b.Length - len))
throw new IndexOutOfRangeException("'bOff' value invalid for specified length");
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ return CryptographicOperations.FixedTimeEquals(a.AsSpan(aOff, len), b.AsSpan(bOff, len));
+#else
int d = 0;
for (int i = 0; i < len; ++i)
{
d |= a[aOff + i] ^ b[bOff + i];
}
return 0 == d;
+#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ [Obsolete("Use 'FixedTimeEquals' instead")]
public static bool ConstantTimeAreEqual(Span<byte> a, Span<byte> b)
{
- if (a.Length != b.Length)
- throw new ArgumentException("Spans to compare must have equal length");
-
- int d = 0;
- for (int i = 0, count = a.Length; i < count; ++i)
- {
- d |= a[i] ^ b[i];
- }
- return 0 == d;
+ return CryptographicOperations.FixedTimeEquals(a, b);
+ }
+ public static bool FixedTimeEquals(ReadOnlySpan<byte> a, ReadOnlySpan<byte> b)
+ {
+ return CryptographicOperations.FixedTimeEquals(a, b);
}
#endif
diff --git a/crypto/test/src/tls/test/MockSrpTlsServer.cs b/crypto/test/src/tls/test/MockSrpTlsServer.cs
index 287b32219..1354214c8 100644
--- a/crypto/test/src/tls/test/MockSrpTlsServer.cs
+++ b/crypto/test/src/tls/test/MockSrpTlsServer.cs
@@ -146,7 +146,7 @@ namespace Org.BouncyCastle.Tls.Tests
public TlsSrpLoginParameters GetLoginParameters(byte[] identity)
{
- if (Arrays.ConstantTimeAreEqual(TEST_IDENTITY, identity))
+ if (Arrays.FixedTimeEquals(TEST_IDENTITY, identity))
{
Srp6VerifierGenerator verifierGenerator = new Srp6VerifierGenerator();
verifierGenerator.Init(TEST_GROUP.N, TEST_GROUP.G, new Sha1Digest());
|