diff options
author | Oren Novotny <oren@novotny.org> | 2014-02-26 10:08:50 -0500 |
---|---|---|
committer | Oren Novotny <oren@novotny.org> | 2014-02-26 10:08:50 -0500 |
commit | 176743ab5faec2dd275b5efd3a2dd62c610f237a (patch) | |
tree | 1d2e50c534a479d749c266d7c52434d8f17f86aa /Crypto/src/crypto/generators/BaseKdfBytesGenerator.cs | |
parent | Add git files (diff) | |
download | BouncyCastle.NET-ed25519-1.7.0.tar.xz |
Add BouncyCastle PCL files v1.7.0
Diffstat (limited to 'Crypto/src/crypto/generators/BaseKdfBytesGenerator.cs')
-rw-r--r-- | Crypto/src/crypto/generators/BaseKdfBytesGenerator.cs | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/Crypto/src/crypto/generators/BaseKdfBytesGenerator.cs b/Crypto/src/crypto/generators/BaseKdfBytesGenerator.cs new file mode 100644 index 000000000..0366401d1 --- /dev/null +++ b/Crypto/src/crypto/generators/BaseKdfBytesGenerator.cs @@ -0,0 +1,141 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Basic KDF generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033 + * <br/> + * This implementation is based on ISO 18033/P1363a. + */ + public class BaseKdfBytesGenerator + : IDerivationFunction + { + private int counterStart; + private IDigest digest; + private byte[] shared; + private byte[] iv; + + /** + * Construct a KDF Parameters generator. + * + * @param counterStart value of counter. + * @param digest the digest to be used as the source of derived keys. + */ + protected BaseKdfBytesGenerator( + int counterStart, + IDigest digest) + { + this.counterStart = counterStart; + this.digest = digest; + } + + public void Init( + IDerivationParameters parameters) + { + if (parameters is KdfParameters) + { + KdfParameters p = (KdfParameters)parameters; + + shared = p.GetSharedSecret(); + iv = p.GetIV(); + } + else if (parameters is Iso18033KdfParameters) + { + Iso18033KdfParameters p = (Iso18033KdfParameters)parameters; + + shared = p.GetSeed(); + iv = null; + } + else + { + throw new ArgumentException("KDF parameters required for KDF Generator"); + } + } + + /** + * return the underlying digest. + */ + public IDigest Digest + { + get + { + return digest; + } + } + + /** + * fill len bytes of the output buffer with bytes generated from + * the derivation function. + * + * @throws ArgumentException if the size of the request will cause an overflow. + * @throws DataLengthException if the out buffer is too small. + */ + public int GenerateBytes( + byte[] output, + int outOff, + int length) + { + if ((output.Length - length) < outOff) + { + throw new DataLengthException("output buffer too small"); + } + + long oBytes = length; + int outLen = digest.GetDigestSize(); + + // + // this is at odds with the standard implementation, the + // maximum value should be hBits * (2^32 - 1) where hBits + // is the digest output size in bits. We can't have an + // array with a long index at the moment... + // + if (oBytes > ((2L << 32) - 1)) + { + throw new ArgumentException("Output length too large"); + } + + int cThreshold = (int)((oBytes + outLen - 1) / outLen); + + byte[] dig = new byte[digest.GetDigestSize()]; + + int counter = counterStart; + + for (int i = 0; i < cThreshold; i++) + { + digest.BlockUpdate(shared, 0, shared.Length); + + digest.Update((byte)(counter >> 24)); + digest.Update((byte)(counter >> 16)); + digest.Update((byte)(counter >> 8)); + digest.Update((byte)counter); + + if (iv != null) + { + digest.BlockUpdate(iv, 0, iv.Length); + } + + digest.DoFinal(dig, 0); + + if (length > outLen) + { + Array.Copy(dig, 0, output, outOff, outLen); + outOff += outLen; + length -= outLen; + } + else + { + Array.Copy(dig, 0, output, outOff, length); + } + + counter++; + } + + digest.Reset(); + + return (int)oBytes; + } + } +} \ No newline at end of file |