diff --git a/crypto/src/crmf/PKMacBuilder.cs b/crypto/src/crmf/PKMacBuilder.cs
index 7261a9daf..6db80325d 100644
--- a/crypto/src/crmf/PKMacBuilder.cs
+++ b/crypto/src/crmf/PKMacBuilder.cs
@@ -217,17 +217,31 @@ namespace Org.BouncyCastle.Crmf
/// <returns>IMacFactory</returns>
public IMacFactory Build(char[] password)
{
- if (parameters != null)
- return GenCalculator(parameters, password);
-
- byte[] salt = new byte[saltLength];
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ return Build(password.AsSpan());
+#else
+ PbmParameter pbmParameter = parameters;
+ if (pbmParameter == null)
+ {
+ pbmParameter = GenParameters();
+ }
- this.random = CryptoServicesRegistrar.GetSecureRandom(random);
+ return GenCalculator(pbmParameter, password);
+#endif
+ }
- random.NextBytes(salt);
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ public IMacFactory Build(ReadOnlySpan<char> password)
+ {
+ PbmParameter pbmParameter = parameters;
+ if (pbmParameter == null)
+ {
+ pbmParameter = GenParameters();
+ }
- return GenCalculator(new PbmParameter(salt, owf, iterationCount, mac), password);
+ return GenCalculator(pbmParameter, password);
}
+#endif
private void CheckIterationCountCeiling(int iterationCount)
{
@@ -235,8 +249,20 @@ namespace Org.BouncyCastle.Crmf
throw new ArgumentException("iteration count exceeds limit (" + iterationCount + " > " + maxIterations + ")");
}
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ private IMacFactory GenCalculator(PbmParameter parameters, ReadOnlySpan<char> password)
+ {
+ return GenCalculator(parameters, Strings.ToUtf8ByteArray(password));
+ }
+#else
private IMacFactory GenCalculator(PbmParameter parameters, char[] password)
{
+ return GenCalculator(parameters, Strings.ToUtf8ByteArray(password));
+ }
+#endif
+
+ private IMacFactory GenCalculator(PbmParameter parameters, byte[] pw)
+ {
// From RFC 4211
//
// 1. Generate a random salt value S
@@ -252,7 +278,6 @@ namespace Org.BouncyCastle.Crmf
// MAC = HASH( K XOR opad, HASH( K XOR ipad, data) )
//
// Where opad and ipad are defined in [HMAC].
- byte[] pw = Strings.ToUtf8ByteArray(password);
byte[] salt = parameters.Salt.GetOctets();
byte[] K = new byte[pw.Length + salt.Length];
@@ -280,5 +305,12 @@ namespace Org.BouncyCastle.Crmf
return new PKMacFactory(key, parameters);
}
+
+ private PbmParameter GenParameters()
+ {
+ byte[] salt = SecureRandom.GetNextBytes(CryptoServicesRegistrar.GetSecureRandom(random), saltLength);
+
+ return new PbmParameter(salt, owf, iterationCount, mac);
+ }
}
}
|