BaseKdfBytesGenerator
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using System;
namespace Org.BouncyCastle.Crypto.Generators
{
public abstract class BaseKdfBytesGenerator : IDerivationFunction
{
private int counterStart;
private IDigest digest;
private byte[] ;
private byte[] iv;
public IDigest Digest => digest;
protected BaseKdfBytesGenerator(int counterStart, IDigest digest)
{
this.counterStart = counterStart;
this.digest = digest;
}
public void Init(IDerivationParameters parameters)
{
KdfParameters kdfParameters = parameters as KdfParameters;
if (kdfParameters != null) {
shared = kdfParameters.GetSharedSecret();
iv = kdfParameters.GetIV();
} else {
Iso18033KdfParameters iso18033KdfParameters = parameters as Iso18033KdfParameters;
if (iso18033KdfParameters == null)
throw new ArgumentException("KDF parameters required for KDF Generator");
shared = iso18033KdfParameters.GetSeed();
iv = null;
}
}
public int GenerateBytes(byte[] output, int outOff, int length)
{
Check.OutputLength(output, outOff, length, "output buffer too short");
return GenerateBytes(output.AsSpan(outOff, length));
}
public unsafe int GenerateBytes(Span<byte> output)
{
long num = output.Length;
int digestSize = digest.GetDigestSize();
if (num > 8589934591)
throw new ArgumentException("Output length too large");
int num2 = (int)((num + digestSize - 1) / digestSize);
Span<byte> span;
if (digestSize <= 128) {
int num3 = digestSize;
span = new Span<byte>(stackalloc byte[(int)(uint)num3], num3);
} else
span = new byte[digestSize];
Span<byte> output2 = span;
Span<byte> span2 = new Span<byte>(stackalloc byte[4], 4);
Pack.UInt32_To_BE((uint)counterStart, span2);
uint num4 = (uint)(counterStart & -256);
for (int i = 0; i < num2; i++) {
digest.BlockUpdate(shared);
digest.BlockUpdate(span2);
if (iv != null)
digest.BlockUpdate(iv);
digest.DoFinal(output2);
int length = output.Length;
if (length > digestSize) {
output2.CopyTo(output);
int num3 = digestSize;
output = output.Slice(num3, output.Length - num3);
} else {
span = output2.Slice(0, length);
span.CopyTo(output);
}
if (++span2[3] == 0) {
num4 += 256;
Pack.UInt32_To_BE(num4, span2);
}
}
digest.Reset();
return (int)num;
}
}
}