summary refs log tree commit diff
path: root/crypto/src/crypto/agreement/kdf/ECDHKekGenerator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/crypto/agreement/kdf/ECDHKekGenerator.cs')
-rw-r--r--crypto/src/crypto/agreement/kdf/ECDHKekGenerator.cs36
1 files changed, 27 insertions, 9 deletions
diff --git a/crypto/src/crypto/agreement/kdf/ECDHKekGenerator.cs b/crypto/src/crypto/agreement/kdf/ECDHKekGenerator.cs
index 74464574c..dbb7ad535 100644
--- a/crypto/src/crypto/agreement/kdf/ECDHKekGenerator.cs
+++ b/crypto/src/crypto/agreement/kdf/ECDHKekGenerator.cs
@@ -11,10 +11,10 @@ namespace Org.BouncyCastle.Crypto.Agreement.Kdf
     /**
     * X9.63 based key derivation function for ECDH CMS.
     */
-    public class ECDHKekGenerator
+    public sealed class ECDHKekGenerator
         : IDerivationFunction
     {
-        private readonly IDerivationFunction kdf;
+        private readonly IDerivationFunction m_kdf;
 
         private DerObjectIdentifier	algorithm;
         private int					keySize;
@@ -22,10 +22,10 @@ namespace Org.BouncyCastle.Crypto.Agreement.Kdf
 
         public ECDHKekGenerator(IDigest digest)
         {
-            this.kdf = new Kdf2BytesGenerator(digest);
+            m_kdf = new Kdf2BytesGenerator(digest);
         }
 
-        public virtual void Init(IDerivationParameters param)
+        public void Init(IDerivationParameters param)
         {
             DHKdfParameters parameters = (DHKdfParameters)param;
 
@@ -34,12 +34,29 @@ namespace Org.BouncyCastle.Crypto.Agreement.Kdf
             this.z = parameters.GetZ(); // TODO Clone?
         }
 
-        public virtual IDigest Digest
+        public IDigest Digest => m_kdf.Digest;
+
+        public int GenerateBytes(byte[]	outBytes, int outOff, int length)
         {
-            get { return kdf.Digest; }
+            Check.OutputLength(outBytes, outOff, length, "output buffer too small");
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            return GenerateBytes(outBytes.AsSpan(outOff, length));
+#else
+            // TODO Create an ASN.1 class for this (RFC3278)
+            // ECC-CMS-SharedInfo
+            DerSequence s = new DerSequence(
+                new AlgorithmIdentifier(algorithm, DerNull.Instance),
+                new DerTaggedObject(true, 2, new DerOctetString(Pack.UInt32_To_BE((uint)keySize))));
+
+            m_kdf.Init(new KdfParameters(z, s.GetDerEncoded()));
+
+            return m_kdf.GenerateBytes(outBytes, outOff, length);
+#endif
         }
 
-        public virtual int GenerateBytes(byte[]	outBytes, int outOff, int len)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public int GenerateBytes(Span<byte> output)
         {
             // TODO Create an ASN.1 class for this (RFC3278)
             // ECC-CMS-SharedInfo
@@ -47,9 +64,10 @@ namespace Org.BouncyCastle.Crypto.Agreement.Kdf
                 new AlgorithmIdentifier(algorithm, DerNull.Instance),
                 new DerTaggedObject(true, 2, new DerOctetString(Pack.UInt32_To_BE((uint)keySize))));
 
-            kdf.Init(new KdfParameters(z, s.GetDerEncoded()));
+            m_kdf.Init(new KdfParameters(z, s.GetDerEncoded()));
 
-            return kdf.GenerateBytes(outBytes, outOff, len);
+            return m_kdf.GenerateBytes(output);
         }
+#endif
     }
 }