diff --git a/crypto/src/asn1/x9/DHValidationParms.cs b/crypto/src/asn1/x9/DHValidationParms.cs
index c63c50205..ec34f8912 100644
--- a/crypto/src/asn1/x9/DHValidationParms.cs
+++ b/crypto/src/asn1/x9/DHValidationParms.cs
@@ -17,7 +17,7 @@ namespace Org.BouncyCastle.Asn1.X9
public static DHValidationParms GetInstance(object obj)
{
- if (obj == null || obj is DHDomainParameters)
+ if (obj == null || obj is DHValidationParms)
return (DHValidationParms)obj;
if (obj is Asn1Sequence)
diff --git a/crypto/src/crypto/IMacDerivationFunction.cs b/crypto/src/crypto/IMacDerivationFunction.cs
new file mode 100644
index 000000000..7297cd854
--- /dev/null
+++ b/crypto/src/crypto/IMacDerivationFunction.cs
@@ -0,0 +1,7 @@
+namespace Org.BouncyCastle.Crypto
+{
+ public interface IMacDerivationFunction:IDerivationFunction
+ {
+ IMac GetMac();
+ }
+}
\ No newline at end of file
diff --git a/crypto/src/crypto/generators/KDFCounterBytesGenerator.cs b/crypto/src/crypto/generators/KDFCounterBytesGenerator.cs
new file mode 100644
index 000000000..9c2b2fdd8
--- /dev/null
+++ b/crypto/src/crypto/generators/KDFCounterBytesGenerator.cs
@@ -0,0 +1,154 @@
+using System;
+
+using Org.BouncyCastle.Crypto.Macs;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Generators
+{
+ public class KdfCounterBytesGenerator : IMacDerivationFunction
+ {
+
+ private static readonly BigInteger IntegerMax = BigInteger.ValueOf(0x7fffffff);
+ private static readonly BigInteger Two = BigInteger.Two;
+
+
+ private readonly IMac prf;
+ private readonly int h;
+
+ private byte[] fixedInputDataCtrPrefix;
+ private byte[] fixedInputData_afterCtr;
+ private int maxSizeExcl;
+ // ios is i defined as an octet string (the binary representation)
+ private byte[] ios;
+
+ // operational
+ private int generatedBytes;
+ // k is used as buffer for all K(i) values
+ private byte[] k;
+
+ public KdfCounterBytesGenerator(IMac prf)
+ {
+ this.prf = prf;
+ this.h = prf.GetMacSize();
+ this.k = new byte[h];
+ }
+
+ public void Init(IDerivationParameters param)
+ {
+ KdfCounterParameters kdfParams = param as KdfCounterParameters;
+ if (kdfParams == null)
+ {
+ throw new ArgumentException("Wrong type of arguments given");
+ }
+
+
+
+ // --- init mac based PRF ---
+
+ this.prf.Init(new KeyParameter(kdfParams.Ki));
+
+ // --- set arguments ---
+
+ this.fixedInputDataCtrPrefix = kdfParams.FixedInputDataCounterPrefix;
+ this.fixedInputData_afterCtr = kdfParams.FixedInputDataCounterSuffix;
+
+ int r = kdfParams.R;
+ this.ios = new byte[r / 8];
+
+ BigInteger maxSize = Two.Pow(r).Multiply(BigInteger.ValueOf(h));
+ this.maxSizeExcl = maxSize.CompareTo(IntegerMax) == 1 ?
+ Int32.MaxValue : maxSize.IntValue;
+
+ // --- set operational state ---
+
+ generatedBytes = 0;
+ }
+
+
+ public IMac GetMac()
+ {
+ return prf;
+ }
+
+ public IDigest Digest
+ {
+ get { return prf is HMac ? ((HMac)prf).GetUnderlyingDigest() : null; }
+ }
+
+ public int GenerateBytes(byte[] output, int outOff, int length)
+ {
+ int generatedBytesAfter = generatedBytes + length;
+ if (generatedBytesAfter < 0 || generatedBytesAfter >= maxSizeExcl)
+ {
+ throw new DataLengthException(
+ "Current KDFCTR may only be used for " + maxSizeExcl + " bytes");
+ }
+
+ if (generatedBytes % h == 0)
+ {
+ generateNext();
+ }
+
+ // copy what is left in the currentT (1..hash
+ int toGenerate = length;
+ int posInK = generatedBytes % h;
+ int leftInK = h - generatedBytes % h;
+ int toCopy = System.Math.Min(leftInK, toGenerate);
+ Array.Copy(k, posInK, output, outOff, toCopy);
+ generatedBytes += toCopy;
+ toGenerate -= toCopy;
+ outOff += toCopy;
+
+ while (toGenerate > 0)
+ {
+ generateNext();
+ toCopy = System.Math.Min(h, toGenerate);
+ Array.Copy(k, 0, output, outOff, toCopy);
+ generatedBytes += toCopy;
+ toGenerate -= toCopy;
+ outOff += toCopy;
+ }
+
+ return length;
+
+ }
+
+ private void generateNext()
+ {
+
+ int i = generatedBytes / h + 1;
+
+ // encode i into counter buffer
+ switch (ios.Length)
+ {
+ case 4:
+ ios[0] = (byte)(i >> 24);
+ goto case 3;
+ // fall through
+ case 3:
+ ios[ios.Length - 3] = (byte)(i >> 16);
+ // fall through
+ goto case 2;
+ case 2:
+ ios[ios.Length - 2] = (byte)(i >> 8);
+ // fall through
+ goto case 1;
+ case 1:
+ ios[ios.Length - 1] = (byte)i;
+ break;
+ default:
+ throw new InvalidOperationException("Unsupported size of counter i");
+ }
+
+
+
+ // special case for K(0): K(0) is empty, so no update
+ prf.BlockUpdate(fixedInputDataCtrPrefix, 0, fixedInputDataCtrPrefix.Length);
+ prf.BlockUpdate(ios, 0, ios.Length);
+ prf.BlockUpdate(fixedInputData_afterCtr, 0, fixedInputData_afterCtr.Length);
+ prf.DoFinal(k, 0);
+ }
+ }
+}
\ No newline at end of file
diff --git a/crypto/src/crypto/generators/KDFDoublePipelineIterationBytesGenerator.cs b/crypto/src/crypto/generators/KDFDoublePipelineIterationBytesGenerator.cs
new file mode 100644
index 000000000..9010ae2cb
--- /dev/null
+++ b/crypto/src/crypto/generators/KDFDoublePipelineIterationBytesGenerator.cs
@@ -0,0 +1,182 @@
+using System;
+
+using Org.BouncyCastle.Crypto.Macs;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Crypto.Generators
+{
+ public class KdfDoublePipelineIterationBytesGenerator : IMacDerivationFunction
+ {
+ private static readonly BigInteger IntegerMax = BigInteger.ValueOf(0x7fffffff);
+ private static readonly BigInteger Two = BigInteger.Two;
+
+ // fields set by the constructor
+ private readonly IMac prf;
+ private readonly int h;
+
+ // fields set by init
+ private byte[] fixedInputData;
+ private int maxSizeExcl;
+ // ios is i defined as an octet string (the binary representation)
+ private byte[] ios;
+ private bool useCounter;
+
+ // operational
+ private int generatedBytes;
+ // k is used as buffer for all K(i) values
+ private byte[] a;
+ private byte[] k;
+
+
+ public KdfDoublePipelineIterationBytesGenerator(IMac prf)
+ {
+ this.prf = prf;
+ this.h = prf.GetMacSize();
+ this.a = new byte[h];
+ this.k = new byte[h];
+ }
+
+
+ public void Init(IDerivationParameters parameters)
+ {
+ KdfDoublePipelineIterationParameters dpiParams = parameters as KdfDoublePipelineIterationParameters;
+ if (dpiParams == null)
+ {
+ throw new ArgumentException("Wrong type of arguments given");
+ }
+
+
+
+ // --- init mac based PRF ---
+
+ this.prf.Init(new KeyParameter(dpiParams.Ki));
+
+ // --- set arguments ---
+
+ this.fixedInputData = dpiParams.FixedInputData;
+
+ int r = dpiParams.R;
+ this.ios = new byte[r / 8];
+
+ if (dpiParams.UseCounter)
+ {
+ // this is more conservative than the spec
+ BigInteger maxSize = Two.Pow(r).Multiply(BigInteger.ValueOf(h));
+ this.maxSizeExcl = maxSize.CompareTo(IntegerMax) == 1 ?
+ Int32.MaxValue : maxSize.IntValue;
+ }
+ else
+ {
+ this.maxSizeExcl = IntegerMax.IntValue;
+ }
+
+ this.useCounter = dpiParams.UseCounter;
+
+ // --- set operational state ---
+
+ generatedBytes = 0;
+ }
+
+
+
+
+ private void generateNext()
+ {
+
+ if (generatedBytes == 0)
+ {
+ // --- step 4 ---
+ prf.BlockUpdate(fixedInputData, 0, fixedInputData.Length);
+ prf.DoFinal(a, 0);
+ }
+ else
+ {
+ // --- step 5a ---
+ prf.BlockUpdate(a, 0, a.Length);
+ prf.DoFinal(a, 0);
+ }
+
+ // --- step 5b ---
+ prf.BlockUpdate(a, 0, a.Length);
+
+ if (useCounter)
+ {
+ int i = generatedBytes / h + 1;
+
+ // encode i into counter buffer
+ switch (ios.Length)
+ {
+ case 4:
+ ios[0] = (byte)(i >> 24);
+ // fall through
+ goto case 3;
+ case 3:
+ ios[ios.Length - 3] = (byte)(i >> 16);
+ // fall through
+ goto case 2;
+ case 2:
+ ios[ios.Length - 2] = (byte)(i >> 8);
+ // fall through
+ goto case 1;
+ case 1:
+ ios[ios.Length - 1] = (byte)i;
+ break;
+ default:
+ throw new InvalidOperationException("Unsupported size of counter i");
+ }
+ prf.BlockUpdate(ios, 0, ios.Length);
+ }
+
+ prf.BlockUpdate(fixedInputData, 0, fixedInputData.Length);
+ prf.DoFinal(k, 0);
+ }
+
+ public IDigest Digest
+ {
+ get { return prf is HMac ? ((HMac)prf).GetUnderlyingDigest() : null; }
+ }
+
+ public int GenerateBytes(byte[] output, int outOff, int length)
+ {
+ int generatedBytesAfter = generatedBytes + length;
+ if (generatedBytesAfter < 0 || generatedBytesAfter >= maxSizeExcl)
+ {
+ throw new DataLengthException(
+ "Current KDFCTR may only be used for " + maxSizeExcl + " bytes");
+ }
+
+ if (generatedBytes % h == 0)
+ {
+ generateNext();
+ }
+
+ // copy what is left in the currentT (1..hash
+ int toGenerate = length;
+ int posInK = generatedBytes % h;
+ int leftInK = h - generatedBytes % h;
+ int toCopy = System.Math.Min(leftInK, toGenerate);
+ Array.Copy(k, posInK, output, outOff, toCopy);
+ generatedBytes += toCopy;
+ toGenerate -= toCopy;
+ outOff += toCopy;
+
+ while (toGenerate > 0)
+ {
+ generateNext();
+ toCopy = System.Math.Min(h, toGenerate);
+ Array.Copy(k, 0, output, outOff, toCopy);
+ generatedBytes += toCopy;
+ toGenerate -= toCopy;
+ outOff += toCopy;
+ }
+
+ return length;
+ }
+
+ public IMac GetMac()
+ {
+ return prf;
+ }
+ }
+}
\ No newline at end of file
diff --git a/crypto/src/crypto/generators/KDFFeedbackBytesGenerator.cs b/crypto/src/crypto/generators/KDFFeedbackBytesGenerator.cs
new file mode 100644
index 000000000..19ce0ea2e
--- /dev/null
+++ b/crypto/src/crypto/generators/KDFFeedbackBytesGenerator.cs
@@ -0,0 +1,177 @@
+using System;
+
+using Org.BouncyCastle.Crypto.Macs;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Crypto.Generators
+{
+ public class KdfFeedbackBytesGenerator : IMacDerivationFunction
+ {
+ private static readonly BigInteger IntegerMax = BigInteger.ValueOf(0x7fffffff);
+ private static readonly BigInteger Two = BigInteger.Two;
+
+ // please refer to the standard for the meaning of the variable names
+ // all field lengths are in bytes, not in bits as specified by the standard
+
+ // fields set by the constructor
+ private readonly IMac prf;
+ private readonly int h;
+
+ // fields set by init
+ private byte[] fixedInputData;
+ private int maxSizeExcl;
+ // ios is i defined as an octet string (the binary representation)
+ private byte[] ios;
+ private byte[] iv;
+ private bool useCounter;
+
+ // operational
+ private int generatedBytes;
+ // k is used as buffer for all K(i) values
+ private byte[] k;
+
+ public KdfFeedbackBytesGenerator(IMac prf)
+ {
+ this.prf = prf;
+ this.h = prf.GetMacSize();
+ this.k = new byte[h];
+ }
+
+
+ public void Init(IDerivationParameters parameters)
+ {
+ KdfFeedbackParameters feedbackParams = parameters as KdfFeedbackParameters;
+ if (feedbackParams == null)
+ {
+ throw new ArgumentException("Wrong type of arguments given");
+ }
+
+
+ // --- init mac based PRF ---
+
+ this.prf.Init(new KeyParameter(feedbackParams.Ki));
+
+ // --- set arguments ---
+
+ this.fixedInputData = feedbackParams.FixedInputData;
+
+ int r = feedbackParams.R;
+ this.ios = new byte[r / 8];
+
+ if (feedbackParams.UseCounter)
+ {
+ // this is more conservative than the spec
+ BigInteger maxSize = Two.Pow(r).Multiply(BigInteger.ValueOf(h));
+ this.maxSizeExcl = maxSize.CompareTo(IntegerMax) == 1 ?
+ Int32.MaxValue : maxSize.IntValue;
+ }
+ else
+ {
+ this.maxSizeExcl = Int32.MaxValue;
+ }
+
+ this.iv = feedbackParams.Iv;
+ this.useCounter = feedbackParams.UseCounter;
+
+ // --- set operational state ---
+
+ generatedBytes = 0;
+ }
+
+ public IDigest Digest
+ {
+ get { return prf is HMac ? ((HMac)prf).GetUnderlyingDigest() : null; }
+ }
+
+ public int GenerateBytes(byte[] output, int outOff, int length)
+ {
+ int generatedBytesAfter = generatedBytes + length;
+ if (generatedBytesAfter < 0 || generatedBytesAfter >= maxSizeExcl)
+ {
+ throw new DataLengthException(
+ "Current KDFCTR may only be used for " + maxSizeExcl + " bytes");
+ }
+
+ if (generatedBytes % h == 0)
+ {
+ generateNext();
+ }
+
+ // copy what is left in the currentT (1..hash
+ int toGenerate = length;
+ int posInK = generatedBytes % h;
+ int leftInK = h - generatedBytes % h;
+
+
+ int toCopy = System.Math.Min(leftInK, toGenerate);
+ Array.Copy(k, posInK, output, outOff, toCopy);
+
+ generatedBytes += toCopy;
+ toGenerate -= toCopy;
+ outOff += toCopy;
+
+ while (toGenerate > 0)
+ {
+ generateNext();
+ toCopy = System.Math.Min(h, toGenerate);
+ Array.Copy(k, 0, output, outOff, toCopy);
+ generatedBytes += toCopy;
+ toGenerate -= toCopy;
+ outOff += toCopy;
+ }
+
+ return length;
+ }
+
+ private void generateNext()
+ {
+
+ // TODO enable IV
+ if (generatedBytes == 0)
+ {
+ prf.BlockUpdate(iv, 0, iv.Length);
+ }
+ else
+ {
+ prf.BlockUpdate(k, 0, k.Length);
+ }
+
+ if (useCounter)
+ {
+ int i = generatedBytes / h + 1;
+
+ // encode i into counter buffer
+ switch (ios.Length)
+ {
+ case 4:
+ ios[0] = (byte)(i >> 24);
+ goto case 3;
+ // fall through
+ case 3:
+ ios[ios.Length - 3] = (byte)(i >> 16);
+ // fall through
+ goto case 2;
+ case 2:
+ ios[ios.Length - 2] = (byte)(i >> 8);
+ // fall through
+ goto case 1;
+ case 1:
+ ios[ios.Length - 1] = (byte)i;
+ break;
+ default:
+ throw new InvalidOperationException("Unsupported size of counter i");
+ }
+ prf.BlockUpdate(ios, 0, ios.Length);
+ }
+
+ prf.BlockUpdate(fixedInputData, 0, fixedInputData.Length);
+ prf.DoFinal(k, 0);
+ }
+
+ public IMac GetMac()
+ {
+ return prf;
+ }
+ }
+}
\ No newline at end of file
diff --git a/crypto/src/crypto/parameters/KDFCounterParameters.cs b/crypto/src/crypto/parameters/KDFCounterParameters.cs
new file mode 100644
index 000000000..49d6f7da3
--- /dev/null
+++ b/crypto/src/crypto/parameters/KDFCounterParameters.cs
@@ -0,0 +1,92 @@
+using System;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Parameters
+{
+ public class KdfCounterParameters : IDerivationParameters
+ {
+ private byte[] ki;
+ private byte[] fixedInputDataCounterPrefix;
+ private byte[] fixedInputDataCounterSuffix;
+ private int r;
+
+ /// <summary>
+ /// Base constructor - suffix fixed input data only.
+ /// </summary>
+ /// <param name="ki">the KDF seed</param>
+ /// <param name="fixedInputDataCounterSuffix">fixed input data to follow counter.</param>
+ /// <param name="r">length of the counter in bits</param>
+ public KdfCounterParameters(byte[] ki, byte[] fixedInputDataCounterSuffix, int r) : this(ki, null, fixedInputDataCounterSuffix, r)
+ {
+ }
+
+
+
+ /// <summary>
+ /// Base constructor - prefix and suffix fixed input data.
+ /// </summary>
+ /// <param name="ki">the KDF seed</param>
+ /// <param name="fixedInputDataCounterPrefix">fixed input data to precede counter</param>
+ /// <param name="fixedInputDataCounterSuffix">fixed input data to follow counter.</param>
+ /// <param name="r">length of the counter in bits.</param>
+ public KdfCounterParameters(byte[] ki, byte[] fixedInputDataCounterPrefix, byte[] fixedInputDataCounterSuffix, int r)
+ {
+ if (ki == null)
+ {
+ throw new ArgumentException("A KDF requires Ki (a seed) as input");
+ }
+ this.ki = Arrays.Clone(ki);
+
+ if (fixedInputDataCounterPrefix == null)
+ {
+ this.fixedInputDataCounterPrefix = new byte[0];
+ }
+ else
+ {
+ this.fixedInputDataCounterPrefix = Arrays.Clone(fixedInputDataCounterPrefix);
+ }
+
+ if (fixedInputDataCounterSuffix == null)
+ {
+ this.fixedInputDataCounterSuffix = new byte[0];
+ }
+ else
+ {
+ this.fixedInputDataCounterSuffix = Arrays.Clone(fixedInputDataCounterSuffix);
+ }
+
+ if (r != 8 && r != 16 && r != 24 && r != 32)
+ {
+ throw new ArgumentException("Length of counter should be 8, 16, 24 or 32");
+ }
+ this.r = r;
+ }
+
+ public byte[] Ki
+ {
+ get { return ki; }
+ }
+
+ public byte[] FixedInputData
+ {
+ get { return Arrays.Clone(fixedInputDataCounterSuffix); }
+ }
+
+ public byte[] FixedInputDataCounterPrefix
+ {
+ get { return Arrays.Clone(fixedInputDataCounterPrefix); }
+
+ }
+
+ public byte[] FixedInputDataCounterSuffix
+ {
+ get { return Arrays.Clone(fixedInputDataCounterSuffix); }
+ }
+
+ public int R
+ {
+ get { return r; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/crypto/src/crypto/parameters/KDFDoublePipelineIterationParameters.cs b/crypto/src/crypto/parameters/KDFDoublePipelineIterationParameters.cs
new file mode 100644
index 000000000..9e2a68b71
--- /dev/null
+++ b/crypto/src/crypto/parameters/KDFDoublePipelineIterationParameters.cs
@@ -0,0 +1,77 @@
+using System;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Parameters
+{
+ public class KdfDoublePipelineIterationParameters : IDerivationParameters
+ {
+ // could be any valid value, using 32, don't know why
+ private static readonly int UNUSED_R = 32;
+
+ private readonly byte[] ki;
+ private readonly bool useCounter;
+ private readonly int r;
+ private readonly byte[] fixedInputData;
+
+ private KdfDoublePipelineIterationParameters(byte[] ki, byte[] fixedInputData, int r, bool useCounter)
+ {
+ if (ki == null)
+ {
+ throw new ArgumentException("A KDF requires Ki (a seed) as input");
+ }
+
+ this.ki = Arrays.Clone(ki);
+
+ if (fixedInputData == null)
+ {
+ this.fixedInputData = new byte[0];
+ }
+ else
+ {
+ this.fixedInputData = Arrays.Clone(fixedInputData);
+ }
+
+ if (r != 8 && r != 16 && r != 24 && r != 32)
+ {
+ throw new ArgumentException("Length of counter should be 8, 16, 24 or 32");
+ }
+
+ this.r = r;
+
+ this.useCounter = useCounter;
+ }
+
+ public static KdfDoublePipelineIterationParameters CreateWithCounter(
+ byte[] ki, byte[] fixedInputData, int r)
+ {
+ return new KdfDoublePipelineIterationParameters(ki, fixedInputData, r, true);
+ }
+
+ public static KdfDoublePipelineIterationParameters CreateWithoutCounter(
+ byte[] ki, byte[] fixedInputData)
+ {
+ return new KdfDoublePipelineIterationParameters(ki, fixedInputData, UNUSED_R, false);
+ }
+
+ public byte[] Ki
+ {
+ get { return Arrays.Clone(ki); }
+ }
+
+ public bool UseCounter
+ {
+ get { return useCounter; }
+ }
+
+ public int R
+ {
+ get { return r; }
+ }
+
+ public byte[] FixedInputData
+ {
+ get { return Arrays.Clone(fixedInputData); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/crypto/src/crypto/parameters/KDFFeedbackParameters.cs b/crypto/src/crypto/parameters/KDFFeedbackParameters.cs
new file mode 100644
index 000000000..86ea232db
--- /dev/null
+++ b/crypto/src/crypto/parameters/KDFFeedbackParameters.cs
@@ -0,0 +1,92 @@
+using System;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Parameters
+{
+ public class KdfFeedbackParameters : IDerivationParameters
+ {
+ // could be any valid value, using 32, don't know why
+ private static readonly int UNUSED_R = -1;
+
+ private readonly byte[] ki;
+ private readonly byte[] iv;
+ private readonly bool useCounter;
+ private readonly int r;
+ private readonly byte[] fixedInputData;
+
+ private KdfFeedbackParameters(byte[] ki, byte[] iv, byte[] fixedInputData, int r, bool useCounter)
+ {
+ if (ki == null)
+ {
+ throw new ArgumentException("A KDF requires Ki (a seed) as input");
+ }
+
+ this.ki = Arrays.Clone(ki);
+
+ if (fixedInputData == null)
+ {
+ this.fixedInputData = new byte[0];
+ }
+ else
+ {
+ this.fixedInputData = Arrays.Clone(fixedInputData);
+ }
+
+ this.r = r;
+
+ if (iv == null)
+ {
+ this.iv = new byte[0];
+ }
+ else
+ {
+ this.iv = Arrays.Clone(iv);
+ }
+
+ this.useCounter = useCounter;
+ }
+
+ public static KdfFeedbackParameters CreateWithCounter(
+ byte[] ki, byte[] iv, byte[] fixedInputData, int r)
+ {
+ if (r != 8 && r != 16 && r != 24 && r != 32)
+ {
+ throw new ArgumentException("Length of counter should be 8, 16, 24 or 32");
+ }
+
+ return new KdfFeedbackParameters(ki, iv, fixedInputData, r, true);
+ }
+
+ public static KdfFeedbackParameters CreateWithoutCounter(
+ byte[] ki, byte[] iv, byte[] fixedInputData)
+ {
+ return new KdfFeedbackParameters(ki, iv, fixedInputData, UNUSED_R, false);
+ }
+
+ public byte[] Ki
+ {
+ get { return Arrays.Clone(ki); }
+ }
+
+ public byte[] Iv
+ {
+ get { return Arrays.Clone(iv); }
+ }
+
+ public bool UseCounter
+ {
+ get { return useCounter; }
+ }
+
+ public int R
+ {
+ get { return r; }
+ }
+
+ public byte[] FixedInputData
+ {
+ get { return Arrays.Clone(fixedInputData); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/crypto/src/crypto/signers/Ed25519Signer.cs b/crypto/src/crypto/signers/Ed25519Signer.cs
index ef8714188..a916601e6 100644
--- a/crypto/src/crypto/signers/Ed25519Signer.cs
+++ b/crypto/src/crypto/signers/Ed25519Signer.cs
@@ -99,6 +99,9 @@ namespace Org.BouncyCastle.Crypto.Signers
internal bool VerifySignature(Ed25519PublicKeyParameters publicKey, byte[] signature)
{
+ if (Ed25519.SignatureSize != signature.Length)
+ return false;
+
lock (this)
{
#if PORTABLE
diff --git a/crypto/src/crypto/signers/Ed25519ctxSigner.cs b/crypto/src/crypto/signers/Ed25519ctxSigner.cs
index 60c708019..ab7201b62 100644
--- a/crypto/src/crypto/signers/Ed25519ctxSigner.cs
+++ b/crypto/src/crypto/signers/Ed25519ctxSigner.cs
@@ -101,6 +101,9 @@ namespace Org.BouncyCastle.Crypto.Signers
internal bool VerifySignature(Ed25519PublicKeyParameters publicKey, byte[] ctx, byte[] signature)
{
+ if (Ed25519.SignatureSize != signature.Length)
+ return false;
+
lock (this)
{
#if PORTABLE
diff --git a/crypto/src/crypto/signers/Ed25519phSigner.cs b/crypto/src/crypto/signers/Ed25519phSigner.cs
index 548ca1f29..2538b16f5 100644
--- a/crypto/src/crypto/signers/Ed25519phSigner.cs
+++ b/crypto/src/crypto/signers/Ed25519phSigner.cs
@@ -75,6 +75,8 @@ namespace Org.BouncyCastle.Crypto.Signers
{
if (forSigning || null == publicKey)
throw new InvalidOperationException("Ed25519phSigner not initialised for verification");
+ if (Ed25519.SignatureSize != signature.Length)
+ return false;
byte[] pk = publicKey.GetEncoded();
return Ed25519.VerifyPrehash(signature, 0, pk, 0, context, prehash);
diff --git a/crypto/src/crypto/signers/Ed448Signer.cs b/crypto/src/crypto/signers/Ed448Signer.cs
index 0863e5dd1..b0563d544 100644
--- a/crypto/src/crypto/signers/Ed448Signer.cs
+++ b/crypto/src/crypto/signers/Ed448Signer.cs
@@ -101,6 +101,9 @@ namespace Org.BouncyCastle.Crypto.Signers
internal bool VerifySignature(Ed448PublicKeyParameters publicKey, byte[] ctx, byte[] signature)
{
+ if (Ed448.SignatureSize != signature.Length)
+ return false;
+
lock (this)
{
#if PORTABLE
diff --git a/crypto/src/crypto/signers/Ed448phSigner.cs b/crypto/src/crypto/signers/Ed448phSigner.cs
index 8f451f9e8..d656c1392 100644
--- a/crypto/src/crypto/signers/Ed448phSigner.cs
+++ b/crypto/src/crypto/signers/Ed448phSigner.cs
@@ -75,6 +75,8 @@ namespace Org.BouncyCastle.Crypto.Signers
{
if (forSigning || null == publicKey)
throw new InvalidOperationException("Ed448phSigner not initialised for verification");
+ if (Ed448.SignatureSize != signature.Length)
+ return false;
byte[] pk = publicKey.GetEncoded();
return Ed448.VerifyPrehash(signature, 0, pk, 0, context, prehash);
diff --git a/crypto/src/crypto/tls/BasicTlsPskIdentity.cs b/crypto/src/crypto/tls/BasicTlsPskIdentity.cs
index db5954422..7a3bbe72e 100644
--- a/crypto/src/crypto/tls/BasicTlsPskIdentity.cs
+++ b/crypto/src/crypto/tls/BasicTlsPskIdentity.cs
@@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Crypto.Tls
public virtual byte[] GetPsk()
{
- return mPsk;
+ return Arrays.Clone(mPsk);
}
}
}
diff --git a/crypto/src/crypto/tls/TlsProtocol.cs b/crypto/src/crypto/tls/TlsProtocol.cs
index 394967c37..388eb629f 100644
--- a/crypto/src/crypto/tls/TlsProtocol.cs
+++ b/crypto/src/crypto/tls/TlsProtocol.cs
@@ -729,11 +729,19 @@ namespace Org.BouncyCastle.Crypto.Tls
}
/**
+ * Equivalent to <code>OfferInput(input, 0, input.length)</code>
+ * @see TlsProtocol#OfferInput(byte[], int, int)
+ * @param input The input buffer to offer
+ * @throws IOException If an error occurs while decrypting or processing a record
+ */
+ public virtual void OfferInput(byte[] input)
+ {
+ OfferInput(input, 0, input.Length);
+ }
+
+ /**
* Offer input from an arbitrary source. Only allowed in non-blocking mode.<br/>
* <br/>
- * After this method returns, the input buffer is "owned" by this object. Other code
- * must not attempt to do anything with it.<br/>
- * <br/>
* This method will decrypt and process all records that are fully available.
* If only part of a record is available, the buffer will be retained until the
* remainder of the record is offered.<br/>
@@ -744,16 +752,18 @@ namespace Org.BouncyCastle.Crypto.Tls
* You should always check to see if there is any available output after calling
* this method by calling {@link #getAvailableOutputBytes()}.
* @param input The input buffer to offer
+ * @param inputOff The offset within the input buffer that input begins
+ * @param inputLen The number of bytes of input being offered
* @throws IOException If an error occurs while decrypting or processing a record
*/
- public virtual void OfferInput(byte[] input)
+ public virtual void OfferInput(byte[] input, int inputOff, int inputLen)
{
if (mBlocking)
throw new InvalidOperationException("Cannot use OfferInput() in blocking mode! Use Stream instead.");
if (mClosed)
throw new IOException("Connection is closed, cannot accept any more input");
- mInputBuffers.Write(input);
+ mInputBuffers.Write(input, inputOff, inputLen);
// loop while there are enough bytes to read the length of the next record
while (mInputBuffers.Available >= RecordStream.TLS_HEADER_SIZE)
|