summary refs log tree commit diff
path: root/crypto/src
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2017-09-16 18:32:37 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2017-09-16 18:32:37 +0700
commit86a7490aaf8f0d9b35cc2fb094efae8409c095a6 (patch)
treef3e420b768d7265c398d90f8fd37d901359e5108 /crypto/src
parentPort of SM2Engine from Java (diff)
downloadBouncyCastle.NET-ed25519-86a7490aaf8f0d9b35cc2fb094efae8409c095a6.tar.xz
Port of ConcatenationKdfGenerator from Java
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/crypto/agreement/kdf/ConcatenationKdfGenerator.cs100
1 files changed, 100 insertions, 0 deletions
diff --git a/crypto/src/crypto/agreement/kdf/ConcatenationKdfGenerator.cs b/crypto/src/crypto/agreement/kdf/ConcatenationKdfGenerator.cs
new file mode 100644
index 000000000..d88f4dfdb
--- /dev/null
+++ b/crypto/src/crypto/agreement/kdf/ConcatenationKdfGenerator.cs
@@ -0,0 +1,100 @@
+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;
+        }
+    }
+}