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");
long num = length;
int digestSize = digest.GetDigestSize();
if (num > 8589934591)
throw new ArgumentException("Output length too large");
int num2 = (int)((num + digestSize - 1) / digestSize);
byte[] array = new byte[digestSize];
byte[] array2 = new byte[4];
Pack.UInt32_To_BE((uint)counterStart, array2, 0);
uint num3 = (uint)(counterStart & -256);
for (int i = 0; i < num2; i++) {
digest.BlockUpdate(shared, 0, shared.Length);
digest.BlockUpdate(array2, 0, 4);
if (iv != null)
digest.BlockUpdate(iv, 0, iv.Length);
digest.DoFinal(array, 0);
if (length > digestSize) {
Array.Copy(array, 0, output, outOff, digestSize);
outOff += digestSize;
length -= digestSize;
} else
Array.Copy(array, 0, output, outOff, length);
if (++array2[3] == 0) {
num3 += 256;
Pack.UInt32_To_BE(num3, array2, 0);
}
}
digest.Reset();
return (int)num;
}
}
}