You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
2.9 KiB
100 lines
2.9 KiB
using System;
|
|
|
|
using Org.BouncyCastle.Crypto.Parameters;
|
|
using Org.BouncyCastle.Crypto.Utilities;
|
|
|
|
namespace Org.BouncyCastle.Crypto.Agreement.Kdf
|
|
{
|
|
/**
|
|
* Generator for Concatenation Key Derivation Function defined in NIST SP 800-56A, Sect 5.8.1
|
|
*/
|
|
public class ConcatenationKdfGenerator
|
|
: IDerivationFunction
|
|
{
|
|
private readonly IDigest mDigest;
|
|
|
|
private byte[] mShared;
|
|
private byte[] mOtherInfo;
|
|
private int mHLen;
|
|
|
|
/**
|
|
* @param digest the digest to be used as the source of generated bytes
|
|
*/
|
|
public ConcatenationKdfGenerator(IDigest digest)
|
|
{
|
|
this.mDigest = digest;
|
|
this.mHLen = digest.GetDigestSize();
|
|
}
|
|
|
|
public virtual void Init(IDerivationParameters param)
|
|
{
|
|
if (!(param is KdfParameters))
|
|
throw new ArgumentException("KDF parameters required for ConcatenationKdfGenerator");
|
|
|
|
KdfParameters p = (KdfParameters)param;
|
|
|
|
mShared = p.GetSharedSecret();
|
|
mOtherInfo = p.GetIV();
|
|
}
|
|
|
|
/**
|
|
* return the underlying digest.
|
|
*/
|
|
public virtual IDigest Digest
|
|
{
|
|
get { return mDigest; }
|
|
}
|
|
|
|
/**
|
|
* fill len bytes of the output buffer with bytes generated from
|
|
* the derivation function.
|
|
*
|
|
* @throws DataLengthException if the out buffer is too small.
|
|
*/
|
|
public virtual int GenerateBytes(byte[] outBytes, int outOff, int len)
|
|
{
|
|
if ((outBytes.Length - len) < outOff)
|
|
throw new DataLengthException("output buffer too small");
|
|
|
|
byte[] hashBuf = new byte[mHLen];
|
|
byte[] C = new byte[4];
|
|
uint counter = 1;
|
|
int outputLen = 0;
|
|
|
|
mDigest.Reset();
|
|
|
|
if (len > mHLen)
|
|
{
|
|
do
|
|
{
|
|
Pack.UInt32_To_BE(counter, C);
|
|
|
|
mDigest.BlockUpdate(C, 0, C.Length);
|
|
mDigest.BlockUpdate(mShared, 0, mShared.Length);
|
|
mDigest.BlockUpdate(mOtherInfo, 0, mOtherInfo.Length);
|
|
|
|
mDigest.DoFinal(hashBuf, 0);
|
|
|
|
Array.Copy(hashBuf, 0, outBytes, outOff + outputLen, mHLen);
|
|
outputLen += mHLen;
|
|
}
|
|
while ((counter++) < (len / mHLen));
|
|
}
|
|
|
|
if (outputLen < len)
|
|
{
|
|
Pack.UInt32_To_BE(counter, C);
|
|
|
|
mDigest.BlockUpdate(C, 0, C.Length);
|
|
mDigest.BlockUpdate(mShared, 0, mShared.Length);
|
|
mDigest.BlockUpdate(mOtherInfo, 0, mOtherInfo.Length);
|
|
|
|
mDigest.DoFinal(hashBuf, 0);
|
|
|
|
Array.Copy(hashBuf, 0, outBytes, outOff + outputLen, len - outputLen);
|
|
}
|
|
|
|
return len;
|
|
}
|
|
}
|
|
}
|
|
|